1. 程式人生 > >Clojure 學習筆記 1

Clojure 學習筆記 1

能夠 包含 getting 符號 圖片 藍色 ges java 給人

Clojure 是一門運行在 JVM 上的 Lisp 方言。我的學習方式是通過看官網的Getting Started。

Mac OS 下配置開發環境

用 homebrew 先安裝 Java:

brew install java

然後安裝 Clojure 的 REPL 解釋器:

brew install clojure

暫時只安裝了這麽多,沒有安裝 Leiningen 和 Boot。

字面值(Literals)

Clojure 有下面幾種數據類型:

;; 數字類型
42              ; Long - 64 bits 整數
6.022e23        ; Double - 64 bits 浮點數
42N ; BigInt - 高精度整數 1.0M ; BigDecimal - 高精度定點數 22/7 ; 分數 ;; 字符類型 "hello" ; 字符串 \e ; 字符 ;; 其他類型 nil ; 空值 true ; Boolean 類型(還有 false) #"[0-9]+" ; 正則表達式 :alpha ; 關鍵字 :release/alpha ; 帶 namespace 的關鍵字 map ; 符號(symbol)
+ ; 符號可以是標點符號 clojure.core/+ ; Namespaced symbol

; 表示註釋,兩個分號表示首行。

另外還有四種 collection 類型:

‘(1 2 3)     ; 列表(list)
[1 2 3]      ; 向量(vector)
#{1 2 3}     ; 集合
{:a 1, :b 2} ; map

求值(Evaluation)

Clojure 不同於傳統的 源代碼 -> 編譯 -> 運行的方式,Clojure 的每一個表達式都能夠求值,通過 Reader 讀取用戶輸入,然後編譯到 JVM 的字節碼,然後在 JVM 上運行求值。

結構(Structure)和語義(Semantics)

技術分享圖片

示意圖種的綠字表示符號,藍色字表示語義。大部分 Clojure 的表達式對自身求值,除了符號和列表。

如圖所示,(+ 3 4) 讀入一個列表,包含一個符號(+)和兩個數字(3、4),列表中的第一個元素(圖片中 + 所在的位置)被稱作“function position“,表示要調用的函數。

Delaying evaluation with quoting

不知道這裏怎麽翻譯,簡單的說就是用引號表示“推遲求值”,暫時不求出來。

舉個例子:

user=> ‘x
x

這裏 x 前面加了一個引號,解釋器不會對這個符號進行求值,而是保留了這個符號。

我們還可以用引號表示一個列表(list),而不進行求值:

user=> ‘(1 2 3)
(1 2 3)

REPL

REPL(Read-Eval-Print-Loop) 由以下四步組成:

  1. 讀出表達式
  2. 對 #1 的表達式進行求值
  3. 輸出 #2 中求出的值
  4. 回到最開始

探索 REPL

絕大多數 REPL 環境都有一些小技巧可以交互使用。比如:

  • *1 表示上一個結果
  • *2 表示上上個結果
  • *3 表示上上上個結果
user=> (+ 3 4)
7
user=> (+ 10 *1)
17
user=> (+ *1 *2)
24

還有一個 namespace 叫 clojure.repl 包含了標準 Clojure 庫,裏面有幾個有用的函數,首先我們要載入這個庫:

(require ‘[clojure.repl :refer :all])

然後我們就可以用這幾個函數了:docfind-docapropossourcedir

這幾個函數的具體作用可以在官網上看,我就不列舉出來了。

Clojure 基礎

def

如果你想要在 REPL 環境中用你求值後的值,可以這樣寫:

user=> (def x 7)
#‘user/x

然後我們就把符號(symbol)x 和值(var) 7 關聯起來了,接下來就可以直接用這個符號了:

user=> (+ x x)
14

需要註意的是這個符號默認是 user 這個namespace 中的符號。我們調用的時候也默認實在 user 這個 namespace 中。

打印

Clojure 提供了四種打印函數:

  • println 是給人讀的帶換行的打印函數
  • prn 是給機器讀的帶換行的打印函數
  • print 是給人讀的不帶換行的打印函數
  • pr 是給機器讀的不帶換行的打印函數

簡單的說,給人讀的會對字符進行轉義,而且會把其中的表達式的值求出來:

user=> (println "This is a\ttest" (+ 1 2 3))     
This is a   test 6

機器讀的不會轉義,而且也不會把表達式的值求出來。

Clojure 學習筆記 1