1 引言
在众多的编程语言中,不少开发人员熟悉Java、C#、PHP等。但是很早以前,也有一些小众的语言,比如Lisp语言,它是一种适用于符号处理和自动推理的编程语言,内部使用表结构来表达非数值计算。而Clojure语言是在JVM上实现的Lisp风格的语言,语法与Lisp类似,且可以和Java语言进行互操作,因此,在任何安装了Java 虚拟机的设备上,我们都可以利用Clojure来发挥Lisp的强大功能,特别是符号处理方面。
2 快速环境搭建
学习一门语言,最可靠的就是官网。Clojure的入门可以通过官网进行学习:https://www.clojure.org/guides/getting_started 。其中有不同的操作系统上的环境搭建指导。这里基于Window 10操作系统,可以基于源码进行编译并运行REPL界面进行代码运行。假设计算机上已经正确安装了JDK 8和Maven,且配置了Git工具。下面可以用命令行运行如下命令下载源码并用Maven打包:
git clone https://github.com/clojure/clojure.git cd clojure mvn -Plocal-Dmaven.test.skip=true package
编译成功后,界面如下:
而启动本地的REPL 界面则可以用如下命令:
java -jar clojure.jar
启动的交互界面如下:
3 语法入门
前面提到,Clojure语言和Lisp语言类似,它和Java语言的语法差异比较大。因此初学者会感觉语法有点奇怪。其实,不同的语言其思考的方式不同,面向对象的编程语言转化到函数式编程的一个不适应在于,二者的编程思维模式不同。Clojure语言是一个列表化的编程语言,代码放于圆括号中,中间用空格进行分割。下面给出Clojure语言的基本语法示例:
user=> ; 这是注释user=> (nsmynamespace) ; ns命名空间nilmynamespace=> (str"Hello"" ""World") ; str创建字符串"Hello World"mynamespace=> (+12) ; 1+23mynamespace=> (*12) 2mynamespace=> (/12) 1/2mynamespace=> (-12) -1mynamespace=> (=12) falsemynamespace=> (not (=12)) truemynamespace=> (*3 (+12)) 9mynamespace=> (class2.6) java.lang.Doublemynamespace=> (class"hello") java.lang.Stringmynamespace=> (classfalse) java.lang.Booleanmynamespace=>'(* 2 3)(*23) mynamespace=>eval'(* 2 3)#object[clojure.core$eval 0x5733f295 "clojure.core$eval@5733f295"](*23) mynamespace=> (eval'(* 2 3))6mynamespace=> (coll? [12345]) truemynamespace=> (seq? [12345]) falsemynamespace=> (seq?'(1 2 3 4 5))truemynamespace=> (range7) (0123456) mynamespace=> (cons7 [123]) (7123) mynamespace=> (conj [123] 7) [1237] mynamespace=> (concat [12] [34]) (1234) mynamespace=> (reduce* (range5)) 0mynamespace=> (reduce* (mapinc (range5))) 120mynamespace=> (defpi3.14) #'mynamespace/pimynamespace=> (*mynamespace/pi2) 6.28
Clojure语言中的代码,要放于()中用于执行,另外就是它的操作符或者方法在前,参数在后。支持语句的嵌套定义。下面给出函数基本语法,示例如下:
mynamespace=> (defnhello [name] (str"Hello,"name)) #'mynamespace/hellomynamespace=> (hello"demo") "Hello,demo"mynamespace=> (defsay#(str "Say " %1))#'mynamespace/saymynamespace=> (mynamespace/say"Coljure") "Say Coljure"mynamespace=>mynamespace=> (defnsay ([] "Hello Clojure") ([msg] "Hello "msg) ) #'mynamespace/saymynamespace=> (say) "Hello Clojure"mynamespace=> (say"Clojure 2") "Clojure 2"mynamespace=> (defnsum [&args] (str"sum=" (reduce+args)) ) #'mynamespace/summynamespace=> (sum12) "sum=3"mynamespace=> (sum123) "sum=6"mynamespace=> (defnmyfunc [n] "函数示例:(myfunc 7)" (cond (<n0) "<0" (>n7) ">7" :else"[0-7]")) #'mynamespace/myfuncmynamespace=> (myfunc7) "[0-7]"
关于其他的语法可参考 :https://www.clojure.org/guides/learn/syntax