let's rock!
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
写得代码越多,越感觉到自己应该学习使用 lisp。程序总是在处理数据,如果代码本身的数据结构就和数据相类似,那么代码本身也可以很容易地被处理。
7 种原语:
注意lisp的reql中返回的可以是未被赋值的变量。而elixir不能。
1. (quote x)
> (quote a)
a
> 'a
a
> (quote (a b c))
(a b c)
复制代码
> quote do a end
{:a, [], Elixir}
> quote(do: a)
{:a, [], Elixir}
> quote do [a, b, c] end
[{:a, [], Elixir}, {:b, [], Elixir}, {:c, [], Elixir}]
复制代码
2. (atom x)
> (atom 'a)
t
> (atom '(a b c))
()
> (atom '())
t
复制代码
> is_atom quote(do: :a)
true
> is_atom quote(do: [:a, :b, :c])
false
> is_atom quote(do: nil)
true
复制代码
区别在于lisp里面变量quote之后并不保存context信息,直接变成了atom;而在elixir里面只有本身是 atom 的情况下,被quote之后才会为 atom 状态,普通变量被quote之后会带有context信息。
lisp 中变量的字面量即是 atom, 而elixir里变量的字面量虽然也会使用一个对应的atom,但其本身是一个三元组的结构。
3. (eq x y)
> (eq 'a 'a)
t
> (eq 'a 'b)
()
> (eq '() '())
t
复制代码
> quote(do: a) == quote(do: a)
true
> quote(do: a) == quote(do: b)
false
> nil == nil
true
复制代码
4. (car x)
> (car '(a b c))
a
复制代码
> hd quote(do: [a, b, c])
quote(do: a)
复制代码
5. (cdr x)
> (cdr '(a b c))
(b c)
复制代码
> tl quote(do: [a, b, c])
quote(do: [b, c])
复制代码
6. (cons x y)
> (cons 'a '(b c))
(a b c)
> (cons 'a (cons 'b (cons 'c '()) ) )
(a b c)
> (car (cons 'a '(b c)) )
a
> (cdr (cons 'a '(b c) ))
(b c)
复制代码
> [quote(do: a) | quote(do: [b, c]) ]
quote(do: [a, b, c])
> [quote(do: a) | [ quote(do: b) | [ quote(do: c) | [] ] ]
quote(do: [a, b, c])
> hd [quote(do: a) | quote(do: [b, c])]
quote(do: a)
> tl [quote(do: a) | quote(do: [b, c])]
quote(do: [b, c])
复制代码
lisp里空列表 () 代表 false; 而elixir里 nil 和 false 的布尔值才是 false,而 [] 的布尔值是 true。
(cond (p1 e1) ... (pn en) )
> (cond ((eq 'a 'b) 'first)
((atom 'a) 'second))
second
复制代码
> cond do
> :a == :b -> :first
> is_atom :a -> :second
> end
:second
复制代码
定义函数
> ( (lambda (x) (cons x '(b) ) ) 'a )
(a b)
> ( (lambda (x y) ( cons x (cdr y) ) )
'z
'(a b c))
(z b c)
复制代码
> (&([&1 | quote(do: [b])])).( quote(do: a))
quote(do: [a, b])
> fn x, y -> [x | tl(y)] end.(quote(do: z), quote(do: [a, b, c]))
quote(do: [z, b, c])
复制代码
函数也可作为参数:
> ((lambda (f) (f '(b c)))
(lambda (x) (cons 'a x)))
(a b c)
复制代码
> fn f -> f.(quote(do: [b, c])) end.(fn x -> [quote(do: a) | x] end)
quote(do: [a, b, c])
复制代码
定义一个递归的函数, 功能是在各个层级进行替换:
> (subst 'm 'b '(a b (a b c) d))
(a m (a m c) d)
复制代码
>
复制代码
def subst(x, x, z), do: z
def subst(x, y, [h|t]), do: [subst(x, y, h) | subst(x, y, t)]
def subst(_, _, []), do: []
def subst(x, y, y), do: x
def subst(x, y, z), do: z
> subst :m, :b, [:a, :b, [:a, :b, :c], :d]
[:a, :m, [:a, :m, :c], :d]
复制代码
TO BE CONTINUE..