======================================
symbol
符号绑定到不可变值。可理解为引用。
Clojure没有变量。
(symbol? aaa) 判断是否是符号
list
形式
用途:
函数调用
macro
special form
list
list (list 1 2 3)
语法糖 '(1 2 3)
first (first '(1 2 3)) => 1
rest (rest '(1 2 3)) => (2 3)
vector
[1 2 "three"]
下标求值 ([7 8 9] 2) => 9
vector自己作为运算符
map
{"a" 1, "b" 2, "c" "aaa"}
按key求值 (get {"a" 1, "b" 2, "c" "aaa"} "c") => "aaa"
语法糖 ({"a" 1, "b" 2, "c" "aaa"} "c") => "aaa"
第三种形式 (:a {:a 1, :b 2, :c 3}) => 1
def
bind symbol to value
clojure没有变量,但是symbol的绑定可以修改。
(def x 5) => #'JiurenTest/x
x => 5
(def x 9) => #'JiurenTest/x
x => 9
defn = def + fn
定义函数 (defn add1
[x]
(+ x 1))
函数名是一个symbol
参数列表是一个vector
defn是一个macro. def + fn
正规形式,(def funcName
(fn [argList...]
(body)))
fn定义匿名函数,lambda函数
(fn? +) => true 判断是否是函数
(fn? add1) => true add1函数作为fn?的参数
(fn? fn?) => true
doc
查看doc (doc xxx)
返回值nil,输出是副作用。
(defn add1
"add argument by one"
[x]
(+ x 1))
str
创建string的函数
(fn? str) => true
(str) => ""
(str xxx) 类似于 xxx.toString()
(str +) => "clojure.core$_PLUS_@14627a"
(str 1 2) => "12" 拼接
if
(if true "yes") => "yes"
(if false "yes") => nil else分支默认值为nil
(if (= 1 2) 5 10) => 10
(if 0 true) => true
(if "" true) => true
(if nil "yes" "no") => "no"
非boolean值转boolean值,nil转为false,其他转为true
do
顺序执行 (do (expression)*) 返回最后一个表达式的值
(do (println "Hello.") (+ 2 2))
Hello.
4
when
没有else分支。if分支可以有多个expression
when是一个宏。when = if + do
(when true 1 2 3) => 3
(when false 1 2 3) => nil
let
创建临时symbol。类似于局部变量。
(fn? let) 发现let貌似也是一个宏。???
(let [x 2] (+ x 8)) => 10
(let [x 2 y 8] (= (+ x y) 10)) => true
loop
(loop [bindings*] exprs*)
和let只有一点不同,在开始处设置了回归点。see recur.
也就是说,如果内部没有recur的话,就没有循环。
(loop [i 0]
(when (< i 5)
(println "i:" i)
(inc i)))
=> 1
输出:
i: 0
recur
(recur exprs*) exprs个数和loop中的bindings个数相同
Evaluates the exprs in order, then, in parallel, rebinds the bindings of the recursion point to the values of the exprs. If the recursion point was a fn method, then it rebinds the params. If the recursion point was a loop, then it rebinds the loop bindings. Execution then jumps back to the recursion point.
Note that recur is the only non-stack-consuming looping construct in Clojure. There is no tail-call optimization and the use of self-calls for looping of unknown bounds is discouraged. recur is functional and its use in tail-position is verified by the compiler.
计算 + 重新绑定 + goto
(loop [i 0]
(when (< i 5)
(println "i:" i)
(recur (inc i))))
=> nil
输出:
i: 0
i: 1
i: 2
i: 3
i: 4
从后向前
(defn factorial [n]
(loop [i n acc 1]
(if (= i 1)
acc
(recur (dec i) (* i acc)))))
从前向后
(defn factorial2 [n]
(loop [i 2 acc 1]
(if (> i n)
acc
(recur (inc i) (* i acc)))))
sequence
Seqs differ from iterators in that they are persistent and immutable, not stateful cursors into a collection.
发现
高阶函数体现出: code as data
clojure的expression都是嵌套的,因此执行过程是栈式的。







