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=> (ns mynamespace) ; ns 命名空間
nil
mynamespace=> (str "Hello" " " "World") ; str 建立字元串
"Hello World"
mynamespace=> (+ 1 2) ; 1 + 2
3
mynamespace=> (* 1 2)
2
mynamespace=> (/ 1 2)
1/2
mynamespace=> (- 1 2)
-1
mynamespace=> (= 1 2)
false
mynamespace=> (not (= 1 2))
true
mynamespace=> (* 3 (+ 1 2))
9
mynamespace=> (class 2.6)
java.lang.Double
mynamespace=> (class "hello")
java.lang.String
mynamespace=> (class false)
java.lang.Boolean
mynamespace=> '(* 2 3)
(* 2 3)
mynamespace=> eval '(* 2 3)
#object[clojure.core$eval 0x5733f295 "clojure.core$eval@5733f295"]
(* 2 3)
mynamespace=> (eval '(* 2 3))
6
mynamespace=> (coll? [1 2 3 4 5])
true
mynamespace=> (seq? [1 2 3 4 5])
false
mynamespace=> (seq? '(1 2 3 4 5))
true
mynamespace=> (range 7)
(0 1 2 3 4 5 6)
mynamespace=> (cons 7 [1 2 3])
(7 1 2 3)
mynamespace=> (conj [1 2 3] 7)
[1 2 3 7]
mynamespace=> (concat [1 2] [3 4])
(1 2 3 4)
mynamespace=> (reduce * (range 5))
0
mynamespace=> (reduce * (map inc (range 5)))
120
mynamespace=> (def pi 3.14)
#'mynamespace/pi
mynamespace=> (* mynamespace/pi 2)
6.28
Clojure語言中的代碼,要放于()中用于執行,另外就是它的操作符或者方法在前,參數在後。支援語句的嵌套定義。下面給出函數基本文法,示例如下:
mynamespace=> (defn hello [name]
(str "Hello," name))
#'mynamespace/hello
mynamespace=> (hello "demo")
"Hello,demo"
mynamespace=> (def say #(str "Say " %1))
#'mynamespace/say
mynamespace=> (mynamespace/say "Coljure")
"Say Coljure"
mynamespace=>
mynamespace=> (defn say
([] "Hello Clojure")
([msg] "Hello " msg)
)
#'mynamespace/say
mynamespace=> (say)
"Hello Clojure"
mynamespace=> (say "Clojure 2")
"Clojure 2"
mynamespace=> (defn sum [& args]
(str "sum=" (reduce + args))
)
#'mynamespace/sum
mynamespace=> (sum 1 2)
"sum=3"
mynamespace=> (sum 1 2 3)
"sum=6"
mynamespace=> (defn myfunc [n]
"函數示例:(myfunc 7)"
(cond
(< n 0) "<0"
(> n 7) ">7"
:else "[0-7]"))
#'mynamespace/myfunc
mynamespace=> (myfunc 7)
"[0-7]"
關于其他的文法可參考 :
https://www.clojure.org/guides/learn/syntax