【问题标题】:What are 'if ,define, lambda' in scheme?方案中的“if ,define, lambda”是什么?
【发布时间】:2015-06-23 09:05:56
【问题描述】:

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

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

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

【问题讨论】:

  • 这些是核心“表单”或宏。你在编译器中实现它们。
  • 在你的实现中,如果你这样做(if #f (display true) (display false))会发生什么?
  • 我的实现没有关键字'display',所以表达式会出错。但是如果它变成(if #f (print 'true) (print 'false)), (#f (print 'true) (print 'false)) 将传递给程序if,它会首先eval #f 并找到条件为假,然后它会eval(打印'false),所以它会打印出“假”
  • 我必须澄清一下,我所实现的只是一个解释器,而不是一个编译器
  • @KaoLian sepp2k 试图说明的一点是,您描述的条件评估类型(检查条件,然后执行 either then 或 else 部分)是不是 function 应用程序通常在 Scheme(以及 Lisp 家族中的大多数其他语言)中处理的方式。例如,如果您评估 (foo (print 'true) (print 'false)),则评估两个参数。如果您的解释器以不同方式处理if,那么您并没有真正将其视为函数/过程。这很好,因为您不想评估ifdefinelambda 等的所有参数。

标签: c++ lambda scheme lisp


【解决方案1】:

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

Scheme 报告不使用此术语。它称函数为“过程”。 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)))。该过程本身将对语法进行任何必要的解构,并检查有效性:参数是否过多或过少等等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-29
    • 2019-08-08
    • 1970-01-01
    • 2012-12-18
    • 2010-11-02
    • 2016-01-11
    • 2011-09-24
    • 1970-01-01
    相关资源
    最近更新 更多