用 elixir 中的概念学习 lisp

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值