计划中的'if,define,lambda'是什么?

时间:2015-06-23 09:05:56

标签: c++ lambda scheme lisp

我们有一门课程,其目的是用C ++实现一个微计划解释器。在我的实现中,我将'if','define','lambda'视为程序,因此它在我的实现中对eval有效' if','define'或'lambda',也可以编写像'(apply define(quote(a 1)))'这样的表达式,它将'a'绑定到1。

但是我发现在球拍和mit方案中,'if','define','lambda'是不可评估的。例如,

enter image description here

似乎它们不是程序,但我无法弄清楚它们是什么以及它们是如何实现的。 有人可以向我解释这些吗?谢谢你提前。

1 个答案:

答案 0 :(得分:1)

在Lisp术语中,要评估的表达式是 forms 。复合形式(使用列表语法的形式)分为特殊形式(以 let 之类的特殊运算符开头),宏形式和函数调用形式。

“方案”报告未使用此术语。它称函数为“程序”。 Scheme的特殊形式称为“语法”。宏是“派生的表达式类型”,分别作为“库语法”引入。 (这样做的动机可能是通过擦洗一些不熟悉的Lisp术语,有意识地决定融入CS学术主流。Algol具有过程和BNF定义的语法,Scheme具有过程和BNF定义的语法。这勾勒了某种熟悉度复选框。)

特殊形式(或“语法”)被解释器和编译器识别为一组特殊情况。解释器或编译器可以通过某些内部表的函数式绑定来处理这些形式,该内部表以符号为键,但不是程序可见的绑定名称空间。

在常规名称空间中设置这些关联不一定是错误的,但可能会出现问题。如果您既需要编译器又需要解释器,但是 let 仅具有一个顶级绑定,那么将是一个问题:谁可以将其过程安装到该绑定中:解释器还是编译器? (一种简单的解决方法:将绑定值cons成对:car可以是解释器函数,cdr是编译器函数。但是这些绑定不是过程,您还可以应用。)

将这些绑定公开给应用程序还是有问题的,因为解释和编译之间的语义是如此不同。如果您的解释得到了解释,则可以将define绑定作为一个函数来调用;它具有执行定义的作用。但是在经过编译的解释中,依赖于此的代码将不起作用。 define是一个实际上没有定义任何东西,而是编译的函数:它计算并返回以某种中间表示形式编写的已编译片段。

关于您的实现,(apply define (quote (a 1)))在您的实现中起作用的事实引起了一些危险。您已将函数的环境参数设置为可选参数,或者它不需要一个参数。实现特殊运算符(或“语法”)的函数需要一个环境参数,而不仅仅是语法。 (至少如果我们正在开发词法范围内的Scheme或Lisp!)

(apply define (quote (a 1)))有效的事实也表明您的define函数使用quote(a 1)作为参数。虽然可行,但这类语法过程的通常方法是将整个形式作为一个参数(而词法环境作为另一个参数)。如果可以调用这样的函数,则调用看起来像(apply define (list '(define a 1) (null-environment 5)))。该过程本身将对语法进行任何必要的分解,并检查有效性:参数是否过多或如此等等。