当前访客身份:游客 [ 登录 | 加入开源中国 ]

技术翻译

已有文章 1883
当前位置: 译文列表 »  编程语言技巧 , 投递原文

Clojure 入门

英文原文:getting started with clojure

标签: Clojure
0人收藏此文章, oschina 推荐于 2年前 (共 14 段, 翻译完成于 03-01) (12评)

我将尝试教一些人(主要是Python开发者,在OS X操作系统运行)如何使用Clojure, 因为我觉得目前已经存在的一些教人如何从零开始学习Clojure的文档不尽如人意。 当我自己在几个月前亲身经历这一切,这是一个奇怪的时期, 好几个星期我一直处于迷茫中, 我基本上找不到一个关于Clojure生态系统的概念路线图,也不知道如何组织一个。

我这篇文章的目标是创建该资源(我本该六个月前就创建它)。我将假设您正使用OS X操作系统并且有些许编程经验。

0595
0595
翻译于 2年前

0人顶

 翻译的不错哦!

关于 Clojure 的书籍

你首先应该购买并开始阅读 Clojure Programming. 还有另外一本叫“Programming Clojure” (书名有点容易混淆) ,我不能保证说它更好或者更差, 但我喜欢 “Clojure Programming” 并且一直使用它,所以我推荐它。 写这本书的人都是那些你搜索Clojure社区时常常见到的大牛们的名字。在Clojure社区, 所有主要的人物似乎都毫无人性地多产。

0595
0595
翻译于 2年前

0人顶

 翻译的不错哦!

让我们开始吧

现在,让我们开始配置你的环境。 获取Homebrew -“OS X缺省的包管理器” - 准备好后, 运行下面的命令:

brew install clojure

这个命令将安装一个Clojure 副本,你可以通过‘clj’ 命令进行访问。 继续并运行它,你会看到REPL启动, 随便发挥吧。 你会发现自己并不是常常用到这个副本, 但是有它总是好的,特别是当你想直接运行一个Clojure 文件可以通过命令`clj a_file.clj`进行。

你不会经常用到'clj' 是因为REPL默认的原始的Clojure环境非常的垃圾。它不支持使用向上箭头访问之前计算的表达式; 它不支持使用'C-a' 和'C-e'到达每一行的开始/末尾;这真的非常气人, 你会讨厌它的, 因此别使用它。

你下一个步骤是安装Leiningen, 从现在开始你几乎会从不间断地用到它。通常, 你需要安装 Leiningen 2, 虽然它目前还不是Leiningen的公开的发行版本,但相信我它就是你要安装的版本。你可以通过运行下面的命令得到它:

brew install leiningen --devel

这个 --devel 标记, 告诉Homebrew 我们需要的是 Leiningen 2 而不是 Leiningen 1.x. 我花了不少时间才搞懂它。

0595
0595
翻译于 2年前

0人顶

 翻译的不错哦!

那么Leiningen究竟是什么鬼东西?

Leiningen是你的主要工具, 它用于:

  • 启动一个 REPL
  • 下载+安装类库
  • 运行你的程序
  • 启动一个服务器, 运行你所写的webapps

接着运行 `lein repl`. 它会启动一个真正有用的 REPL, 任何时候,当你需要一个REPL,用这个命令就行。 使用向上方向键你会得到之前用过的计算表达式, 而快捷键 C-a 和 C-e 也能生效(到达行首/行尾), 一切都像你所期望的那样。另外,如果你在顶级目录运行一个Clojure 项目,它会根据实际情况处理连接类路径和诸如此类的东西,这样你就可以导入和玩玩你项目的代码和库了。 稍后我们再讨论这个。现在,让我们通过下面的命令创建一个骨架项目玩玩:

lein new foo

命令完成后, cd 到 foo 目录,你会看到它已经有了一些文件和目录:

[jrheard@jrheard-air:~/dev/foo] $ ll
total 16
-rw-r--r--  1 jrheard  staff   193B Jan  5 15:17 README.md
drwxr-xr-x  3 jrheard  staff   102B Jan  5 15:17 doc
-rw-r--r--  1 jrheard  staff   263B Jan  5 15:17 project.clj
drwxr-xr-x  3 jrheard  staff   102B Jan  5 15:17 src
drwxr-xr-x  3 jrheard  staff   102B Jan  5 15:17 test
0595
0595
翻译于 2年前

0人顶

 翻译的不错哦!

当你写一个Clojure 库/程序/或者任何东西,你的源代码都保存在“src”目录,你的测试代码则保存在“test”目录。非常简单。 让我们来看看 src 目录:
[jrheard@jrheard-air:~/dev/foo] $ cat src/foo/core.clj
(ns foo.core) (defn foo "I don't do a whole lot." [x] (println x "Hello, World!"))

看起来 Leiningen 已经创建了一个叫 “src/foo/core.clj” 的文件。这是一个Clojure程序, 它定义了一个“foo.core”的命名空间, 然后声明该命名空间包含一个名为“foo”的函数。 我们来看看它。用`lein repl`启动一个REPL 并浏览一下。 还记得我前面提到过Leiningen会负责处理你的类路径和相关的goop,这样你就可以从REPL访问你的项目代码了? 看看这个:

user=> (use 'foo.core) nil
user=> foo #<core$foo foo.core$foo@6ad591a6>
user=> (foo "jrheard") jrheard Hello, World!
nil


0595
0595
翻译于 2年前

0人顶

 翻译的不错哦!

真棒 - 我们已经能够导入我们的代码并运行它。 `use` 提供了类似于Python里面的`from foo.core import *` 相同 的功能,因此不鼓励在源代码中再使用它( from foo.core import *), 出于相同的原因, import *也不再鼓励使用。不过像 import * ( 这样的功能), 在你查找(浏览)REPL 的时候是相当有用的。

嘿,非常酷 - 我们已经创建了一个项目, 里面还生成一些代码, 我们已经知道如何启动一个能运行的REPL 还可以在里面浏览那些代码。 第一阶段已经完成啦, 让我们来看看第二个阶段:

0595
0595
翻译于 2年前

0人顶

 翻译的不错哦!

下装并安装类库

你可能习惯在命令行运行一些命令来获取类库。例如 `pip install this_great_library_i_found`, 它会下载你指定的类库, 并安装到全局的或者你当前的虚拟环境中(virtualenv)。 但是在 Clojure 里, 有一点点不一样。

首先,你必须找到一个看起来还不错的类库。 Clojure Toolbox 是一个奇妙的工具,这是我发现的最好的资源。 我们选择一个库玩玩: 创建HTTP请求很有意思 - 让我们先到 “HTTP Clients” 的章节, 看看我们都有哪些选择。 看起来我们得在 clj-http 和 http.async.client 之间挑一个 - 但是选哪一个呢?

0595
0595
翻译于 2年前

0人顶

 翻译的不错哦!

目前,在多个存在竞争关系的类库之间做选择时,我最喜欢的方式是:把它们从github仓库里拉下来,然后比较加星数和fork数之和,如果最近两个月有提交代码可以加分,用这个数代表社区的健壮性、影响力或适应能力,可能不是特别科学,不过我用着挺好的。在写这篇文章的时候,clj-http有242个星号,http.async.client只有127个,所以我选择clj-http。

所以… 怎么搞到它?

让我们打开 clj-http’s github repo。README中关于安装那一段有如下代码:

[clj-http "0.6.3"]
SeabornLee
SeabornLee
翻译于 2年前

1人顶

 翻译的不错哦!

这就是我们需要的信息 - 这是一个 Clojure vector,它包含两个条目,第一个条目是类库的名字, 第二个条目标识最新的稳定版本。我们打算把它添加到我们的(你之前在查看'foo' 目录的内容看到的那一个) project.clj. 打开 project.clj, 看起来就像这样:

(defproject foo "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.4.0"]]) 

注意:dependencies 那段 - 这是一个包含一个条目的Clojure vector, 该条目本身也是一个包含两个条目的的 Clojure vector. 这个 vector 告诉 Leiningen 我们的项目要运行在版本是1.4.0的Clojure 上.够公平的了,现在让我们添加我们之前看到的那个clj-http vector。 现在 project.clj 看起来应该像这样:

(defproject foo "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.4.0"]
                 [clj-http "0.6.3"]])

0595
0595
翻译于 2年前

0人顶

 翻译的不错哦!

就是这样!现在我们已经指定了我们需要的clj-http类库和版本号。让我们试一下 -使用`lein repl`命令启动一个REPL,来测试我们精选的新类库。要注意的是,在REPL启动的时候Leiningen会首先下载clj-http,这是因为基本上在我们的所有操作之前,它会先在后台执行`lein deps`命令扫描 project.clj文件,并且确保已经获取到了所有我们需要的依赖类库。
好的,回到我们的REPL会话,这里有一个从clj-http的github上返回的README,它告诉我们需要在REPL上运行
(require ‘[clj-http.client :as client])

好吧我们运行一下,-这跟Python中'from clj.http import client'是一样的(与`from clj.http.client import *`截然相反,这也是'use'函数的工作)

user=> (require '[clj-http.client :as client]) nil
user=> (client/get "http://www.yelp.com") ;; a big huge blob of data pops out!


LeeGanity
LeeGanity
翻译于 2年前

0人顶

 翻译的不错哦!

哇,好了,看到它能运行了!那些排列读起来很糟糕——你会发现以"}"结束的超大块的数据,那大概是Clojure map类型的小许数据。接下来试试下面的代码:

user=> (def resp (client/get "http://www.yelp.com")) #'user/resp
user=> (type resp) clojure.lang.PersistentArrayMap
user=> (keys resp) (:cookies :trace-redirects :request-time :status :headers :body)
user=> (:status resp) 200
user=> (:headers resp) {"server" "Apache", "content-encoding" "gzip", "x-proxied" "lb2",
"content-type" "text/html; charset=UTF-8", "date" "Sun, 06 Jan 2013 00:02:58 GMT",
"cache-control" "private", "vary" "Accept-Encoding,User-Agent",
"transfer-encoding" "chunked", "x-node" "wsgi, web40, www_all",
"x-mode" "ro", "connection" "close"}
运行之后,我们发现了一个HTTP客户端库,下载它,并且指出怎样在REPL中交互使用。

把它们都找出会花掉我一些时间——在用头撞了一天墙之后,我终于不得不来到#clojure IRC 频道请示帮助。现在你不用那样做了!想进一步阅读的,请看 the official Leiningen tutorial

showme
showme
翻译于 2年前

0人顶

 翻译的不错哦!

把它们全部放一起

让我们通过弄清如何实际运行一个Clojure程序来完成。我们尝试一个典型的`lein run`:

[jrheard@jrheard-air:~/dev/foo] $ lein run
No :main namespace specified in project.clj.
好的,这没成功运行。返回之前提到过的Leiningen手册然后搜索下:main,我们看到你可以第一个一个:main关键字在你的project.clj定义里来指定`lein run`会执行的命名空间,也就是说这个命名空间必需包含一个`-main`的函数来为你的程序提供入口点。让我们把这行代码加入到我们的project.clj定义里:
:main foo.core
最后我们修改src/foo/core.clj,然后它的代码如下:
(ns foo.core
  (:require [clj-http.client :as client]))

(defn -main
  "Prints the first 50 characters of the HTML source of yelp.com."
  [& args]
  (println (apply str
                  (take 50
                        (:body (client/get "http://www.yelp.com"))))))
到这里,我们继续尝试`lein run`:
[jrheard@jrheard-air:~/dev/foo] $ lein run
Compiling foo.core
<!DOCTYPE HTML>

<!--[if lt IE 7 ]> <html xmlns:fb
它成功了!

目前来说-你现在有了一个可运行的REPL来玩耍,安装和使用库的能力,让你的程序访问这些库以及运行的知识,还有一本真正能给你一切你所需知道的关于Clojure语言的好书。

excepiton
excepiton
翻译于 2年前

0人顶

 翻译的不错哦!

我为何必须写这篇文章

Clojure还是一门非常年轻的语言。跟Python比的话,它的社区也还特别小。尽管我说过它的核心API非常稳定,但很多周边工具都是新的而且还在快速变化。最重要的是你会发现很多最新的文档都没有做好SEO,大部分的Google搜索结果都会转到richhickey.github.com,而它上面的很多东西都过时了。所以你会觉得Clojure很难上手。

希望本文能让你少迷茫几个星期,避免重蹈我的覆辙。我保证成长的痛苦是值得的,Clojure会让你享受到编程真正乐趣。

SeabornLee
SeabornLee
翻译于 2年前

1人顶

 翻译的不错哦!

各种资源

  •   我花了过去的几个星期看了所有有关clojure的演讲。官方youtube频道不错 official Clojure youtube channel ,  InfoQ也有很多不错的内容( great content on InfoQ ),我在这最少看了25个演讲。
  • The Clojure Toolbox, 寻找现成的库
  • Where Did Clojure.Contrib Go - 你要查看一些库的手册,比如“clojure.contrib.monads, 正像你看到的,  clojure.contrib 这个库不会存在多久,  这个页面会告诉你 库被合并到哪去了。 
  • This example project.clj  展示了很多Leiningen提供的钩子(hooks)不同的高级用法,轻松定制,构建你的项目 
  •  你可以在twitter上 following clojure 社团的核心成员 @cgrand, @cemerick, @marick, @weavejester, @stuartsierra, @seancorfield, @Baranonsky, @richhickey
  •  “The Joy of Clojure”  如果你已经看完了 “Clojure Programming”. 
  • 特别注意,Noir已经不维护了,使用Compojure代替吧


lidashuang
lidashuang
翻译于 2年前

0人顶

 翻译的不错哦!

回页面顶部发表评论 网友评论12

  • 吉迪恩
    吉迪恩 发表于 2013-03-02 10:20
    LISP派系有点像武侠中的日月神教和逍遥派
  • mmpp33
    mmpp33 发表于 2013-03-02 11:33
    看到这些乱七八糟的代码,就赶到恶心。。。其实c语言才是最好的语言。
  • lidashuang
    lidashuang 发表于 2013-03-02 12:44

    引用来自“mmpp33”的评论

    看到这些乱七八糟的代码,就赶到恶心。。。其实c语言才是最好的语言。

    肤浅
  • pitttttttt
    pitttttttt 发表于 2013-03-02 15:45

    引用来自“lidashuang”的评论

    引用来自“mmpp33”的评论

    看到这些乱七八糟的代码,就赶到恶心。。。其实c语言才是最好的语言。

    肤浅

    不了解就乱说,楼上的评语很给力,提供了正能量。哈哈
  • MikeManilone
    MikeManilone 发表于 2013-03-02 20:45
    其實Common Lisp有SLIME+Quicklisp足矣 :-D
  • 赵紫川
    赵紫川 发表于 2013-03-03 11:25

    引用来自“赵长青”的评论

    引用来自“lidashuang”的评论

    引用来自“mmpp33”的评论

    看到这些乱七八糟的代码,就赶到恶心。。。其实c语言才是最好的语言。

    肤浅

    不了解就乱说,楼上的评语很给力,提供了正能量。哈哈

    哈哈,mmpp33真捉急,一看就是菜鸟。(我说的菜鸟指的不是认为C好的人,而是什么都一知半解就妄下定论。。。另外放个地图炮,说XXX是最好语言的都是菜鸟。。。
  • 鳄鱼先生
    鳄鱼先生 发表于 2013-03-04 12:06
    mmpp33这两个常识都不懂,的确是菜鸟一只。
    说C是一门好语言的人肯定会惹怒一批C开发者。
    说PHP是一门坏语言的人肯定会惹怒所有PHP开发者。
  • Paul.Joe
    Paul.Joe 发表于 2013-03-04 16:42
    语言没有好坏,只有合适的
  • GDP_搞地皮
    GDP_搞地皮 发表于 2013-03-14 12:45
    DrClojure — 推荐一个简单好用的Closure IDE
    https://bitbucket.org/ktg/drclojure/overview
  • 长工
    长工 发表于 2013-03-28 09:54
    看不出有什么特点,不是说是JAVA虚拟机上的lisp么,也不给点和Java结合的列子,这些个破程序都能干啥啊....

  • duyi
    duyi 发表于 2013-10-14 09:35
    建立去看下Storm(最新版本),基本是用Clojure写的
  • mahengyang
    mahengyang 发表于 2014-03-01 20:42

    引用来自“吉迪恩”的评论

    LISP派系有点像武侠中的日月神教和逍遥派

    逍遥派+1