小站重新装修,欢迎到访。
标签 #Clojure

4clojure

最近开始在4clojure上刷题,推荐对clojure有兴趣的同学一起来玩。

正好刷到第38题,贴出来分享下。

Write a function which takes a variable number of parameters and returns the maximum value.

1
2
3
4
5
6
(= (__ 1 8 3 4) 8)
(= (__ 30 20) 30)
(= (__ 45 67 11) 67)

不得使用max和max-key

##解

1
(fn [x & other] (reduce #(if (> %1 %2) %1 %2) x other))

clojure工程构建之lein篇

最近为了看storm的源码,开始了clojure的系统学习。clojure因为背负了Java这个历史大包袱,在语法上相对于其他Lisp方言,还是稍显复杂和罗嗦。JVM语言似乎都很难摆脱JAVA的身影,互操作是件很难做得优雅的事情。不过FP的魅力还是让我坚持下来,准备长期作战,不断学习和积累。本文不进一步讨论clojure,只简单介绍下使用lein进行clojure工程的构建,因为我个人对gradle很感兴趣(出于对groovy的好感)后续可能会再写一篇使用gradle的构建。

storm的源码就采用了lein构建,可以看下工程根目录下有project.clj文件。就目前看到的clojure开源项目,用lein的还是居多的。

##lein的安装##
查看lein的github主页:https://github.com/technomancy/leiningen,对于lein在*nix上的安装,比较简单的步骤是下载此脚本,放到PATH里,并执行chmod 755 /path/to/lein即可。首次执行该脚本会下载相关的文件并默认安装到~/.lein

##创建新工程##
这里我们创建一个简单的示例工程:

$ lein new app leinexample

控制台输出:

Generating a project called leinexample based on the 'app' template.

也就是说,app是工程的模板名,lein默认的模板是default。模板是插件化的,所以可以很容易扩展,这里就有很多模板。下图是我们用find .列出的lein的默认目录结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
billmac:leinexample jingege$ find .
.
./.gitignore
./doc
./doc/intro.md
./project.clj
./README.md
./src
./src/leinexample
./src/leinexample/core.clj
./test
./test/leinexample
./test/leinexample/core_test.clj

重点是project.clj

1
2
3
4
5
6
7
(defproject leinexample "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.5.1"]]
:main leinexample.core)

默认只列出了lein project的一部分属性,包括工程名以及相关元信息、license、依赖等等。这里有最全面的工程定义样例可以参考。

##导入到IDE##

起初像学习erlang一样,我使用emacs进行clj的练习,但尽管我个人对emacs很有好感,不过对于阅读代码这种事情,还是使用IDE的好。

如果需要使用eclipse或IntellijIdea等支持maven的IDE,可以使用lein pom来生成pom文件,然后直接使用IDE导入maven工程。个人感觉IntellijIdea真的是非常强悍的IDE,当然不仅仅是说对clojure的支持。

##管理依赖##

在project.clj中可以添加依赖包,比如,我们在project.clj的dependencies中添加一条:

:dependencies [[org.clojure/clojure "1.5.1"] [clj-http "0.6.5" :exclusions [crouton]]]

执行lein deps,控制台输出:

1
2
3
4
5
6
Retrieving clj-http/clj-http/0.6.5/clj-http-0.6.5.pom from clojars
Retrieving org/apache/httpcomponents/httpcore/4.2.3/httpcore-4.2.3.pom from central
……
Retrieving clj-http/clj-http/0.6.5/clj-http-0.6.5.jar from clojars
RetrievingRetrieving slingshot/slingshot/0.10.3/slingshot-0.10.3.jar cheshire/cheshire/5.0.2/cheshire-5.0.2.jarfrom from clojars
clojars

你可能发现,下载的依赖包,并不在工程目录里,其实lein是整合了maven,上述包其实已经下载到maven的本地仓库了。

##运行测试用例##

lein会默认生成一个clj和对应的测试用例文件,打开leinexample/test/leinexample/core_test.clj,修改a-test函数的返回值为true,即修改最后一行为(is (= 0 0))即可。然后执行:

lein test

控制台会打印出测试用例的运行结果:

1
2
3
4
lein test leinexample.core-test
Ran 1 tests containing 1 assertions.
0 failures, 0 errors.

##编译代码##

此时如果直接运行lein compile,你会发现,target目录里没有.class文件。这个起初也让我很不解。查阅了相关文档发现需要开启aotcompile Ahead Of Time,在project.clj的defproject函数添加metadata:

:aot [leinexample.core]

之后再执行lein compile,即可在target/classes里看到对应的.class文件了。

注意,上述大多数目录,如target、classes等,都可以在project.clj中修改。

##打包##

lein支持jar、uberjar等等打包方式,具体可以使用lein -h可以查看lein的其他子命令。应该也可以直接打出war包,这个我没有尝试过,有兴趣的充分发挥google的力量吧。

1

博主是一个不是很聪明的码农。完美主义者,强迫症中期。这里会记录一些回忆和点滴,以博为镜。

武器库:

该博客使用基于  Hexo  的  simpleblock  主题。博客内容使用  CC BY-NC-SA 3.0  授权发布。最后生成于 2017-02-20.