美文网首页
lisp解释器的本质

lisp解释器的本质

作者: 牛头酋长 | 来源:发表于2020-10-28 21:39 被阅读0次

LISP解释器的本质载体就是这两个简单的程序:eval和apply,解释器就像其他普通程序一样处理的是Data,只不过这里的data要符合解释器定义的语言规则(也就是编程语言表达式expression)
用户输入一段代码也就是expression,先进入到eval,eval干的事就是:分。 分完之后,将分好的多个data传给apply。apply干的事就是合,合在一起之后,将合的data再传给eval。eval在重复上面的逻辑继续分,然后传给apply。他俩就这么一分一合,直到data成为无法分/合的归一。

1)解释器的本质就是分/合的递归,直到无法分/合的归一。
2)eval代表分,apply代表合
3)物理视角的伪代码:
eval的分:将expression分为procedure和arguments两句,再传给apply

(apply
    (operator expression)
    (operands expression))

apply的合:将算法和数据合并为一句到eval中去

(eval expression environment)
;; expression代表算法
;; environment代表数据

4)procedure就是data,data就是procedure,色即是空,空即是色。
色隐喻着procedure,空隐喻着data。
同时空又有一层表达,物质的存在不是有更小的物质组合而成,而是有什么都没有的虚空模拟而成。
data的最基本概念为Pair,pair的定义是基于cons/car/cdr这三个procedure。
procedure的构成又是基于list,list的本质就是pair的变形,
看代码:
1.data由procedure模拟而成:

(define (cons x y)
 (lambda (m) (m x y)))

(define (car z)
 (z (lambda (p q) p)))

(define (cdr z)
 (z (lambda (p q) q)))

2.procedure由data模拟而成:

(define (make-procedure parameters body env)
 (list 'procedure parameters body env))

5)信息,是procedure和data的统一视角。
6)计算机科学的第一性原理就是解释器,解释器的第一性原理就是信息的分/合的递归。见下图:


image.png

7)抽象到宇宙观,宇宙的第一性原理也是信息的分/合,宇宙的本质就是信息,宇宙的行为就是信息的分/合。从宏观来看,宇宙就是在做着如同呼吸一样的扩张(分)与收缩(合)
8)所以,我们解决任何问题的思路,无非就是分/合。一切尽在分/合之间。

What - lisp解释器的本质update:定位出解释器的概念体系。

1)lisp的解释器由eval/apply这两个procedure来承载。
2)从抽象视角来看,eval/apply本质上就是再实现lambda演算中的Beta-Reduction,即,((λx.M) E) → (M [x:= E]),Replacing the bound variables with the argument expression in the body of the abstraction.

3)Beta-Reduction本质上就是在做组装,将参数装入到Lambda的body中。
4)计算的本质就是Beta-Reduction的这一组装/变形的动作。
5)只不过Eval/Apply将这个组装动作进行了分解:
首先,一个像这样的最简单的application:((lambda (x) (x)) 3),作为expression传入到Eval中。
然后,Eval对这个expression做分解,将((lambda (x) (x)) 3)分解为连个部分:
procedure部分:(operator expression) 对应着 (lambda(x) (x))
argument部分:(operands expression) 对应着 3
再将这两部分传给Apply
Apply干了两件事:1.将procedure提取出body部分:(x),2.将procedure中的parameter:x,绑定argument:3,也就是将x=3存入到一个table中,即,env出现。
Apply再将body和env传入给Eval
Eval,拿到body和env干的事,才是真正的组装,即,发现body中遇到的变量x,去evn中寻找x对应的value:3,然后将value装入到body中(x)就变成了最终的结果:3.
所以说,eval/apply将lambda演算中的Bate-Reduction进行了分解动作。
6)Why?为什么要分解动作?难道不能用一个procedure直接的进行Bata-Reduction的组装吗?即,直接将expression中的operand组装到operator中去。
答案是,因为要兼容赋值模型Assignment,eval运行时并不知道一个procedure的body中是否包含Assignment,所以要兼容,当作可能有Assignment来处理。Assignment就不能直接将operand直接装入到operator中去,因为body中的变量可能随时被别人修改。所以要引入Env来由一个中间环节来存储body中的变量。
当然,如果能够确定,要处理的所有expression都没有assignment,那么解释器就可以简化成,不再需要evn。
7)所以,抽象来看解释器的精髓点就是Beta-Reduction的实现。
8)当然,解释器的非核心部分还实现了Lambda演算中的其他概念:变量variable,抽象体abstraction,应用application。
9)所以,更全面,但是没有精髓感的说,抽象来看解释器就是Lambda演算的实现。
10)Lisp解释器与Lambda演算的对应关系:
1.变量Variable的实现对应的代码是:

((variable? exp) (lookup-variable-value exp env))

2.抽象体Abstraction的实现对的代码是:

((lambda? exp)
    (make-procedure (lambda-parameters exp)
                    (lambda-body exp)
                    env))

3.应用Application的实现对应的代码是:

((application? exp)
    (apply (eval (operator exp) env)
                 (list-of-values (operands exp) env)))

11)Lisp解释器为了让语言更加高效而加入的衍生规则,当然这些衍生规则都可以用上面的那三个原则来推演而得。但是为了构建逻辑更加高效,而增加的中间层。
1.原始元素:数字(1,2,3等)和数字运算操作符(+ - 等)

((self-evaluationg? exp) exp)

2.字符串

((quoted? exp) (text-of-quotation exp))

3.赋值语句

((assignment? exp) (eval-assignment exp env))

4.定义

((definition? exp) (eval-definition exp env))

5.条件语句

((if? exp) (eval-if exp env))
;; and
((cond? exp) (eval (cond->if exp) env))

6.begin语句

((begin? exp)
            (eval-sequence (begin-actions exp) env))

相关文章

网友评论

      本文标题:lisp解释器的本质

      本文链接:https://www.haomeiwen.com/subject/eyxhvktx.html