用 elixir 中的概念學習 lisp

let's rock!數據結構

((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))函數

寫得代碼越多,越感受到本身應該學習使用 lisp。程序老是在處理數據,若是代碼自己的數據結構就和數據相相似,那麼代碼自己也能夠很容易地被處理。學習

7 種原語:

注意lisp的reql中返回的能夠是未被賦值的變量。而elixir不能。atom

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信息。spa

lisp 中變量的字面量便是 atom, 而elixir裏變量的字面量雖然也會使用一個對應的atom,但其自己是一個三元組的結構。code

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])
複製代碼

函數也可做爲參數:it

> ((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])
複製代碼

定義一個遞歸的函數, 功能是在各個層級進行替換:io

> (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..function

相關文章
相關標籤/搜索