【问题标题】:What's the benefit of "to distinguish procedures from lambda expressions and symbols"“将过程与 lambda 表达式和符号区分开来”有什么好处?
【发布时间】:2017-08-14 01:47:03
【问题描述】:

我正在阅读 r6rs(Revised6 Report on the Algorithmic Language Scheme),在“介绍”部分有一个总结:

“Scheme 是 Lisp 的第一个主要方言,用于区分过程与 lambda 表达式和符号,为所有变量使用单一的词法环境,并以相同的方式评估过程调用的运算符位置 作为操作数位置。”

我的问题是:

“区分过程与 lambda 表达式和符号”有什么好处?

什么是单一的词法环境? 我的理解是,由于词法范围,Scheme 中的所有内容都是“词法”,那里没有运行时范围,源代码中的位置/位置更多地意味着环境。

如何理解“以与操作数位置相同的方式评估过程调用的运算符位置”? 我的理解是运算符位置的符号被评估为操作数位置。例如:

(define test
    (lambda (x)
        ((if (> x 0) + -) 1 2)))

“(if (> x 0) + -)”在算子位置,它的求值与其他操作数位置的求值相同。

【问题讨论】:

  • 如果您对其他 Lisp 有一定的了解,比如 Common Lisp,这些陈述会更有意义。

标签: lambda scheme evaluation lexical r6rs


【解决方案1】:

Scheme 是第一个拥有词法环境和闭包的 Lisp。它对 Common Lisp 的设计产生了相当大的影响。词法环境的替代方案是动态绑定。示例:

;; setup (on both)
(define v 10)

(define (adder v)
  (lambda (x) (+ x v))))

;; lexical scheme results
(define add5 (adder 5))
(add5 3) ; ==> 8
(let ((v 6))
  (add5 3)) ; ==> 8

;; dynamic scheme results
(define add5 (adder 5))
(add5 3) ; ==> 13 (since y is the global variable 10)
(let ((v 6))
  (add5 3)) ; ==> 9 (since v is bound to 6 during the call to add5)

方案没有动态变量,所以最后一部分不会发生。 Common Lisp 实际上具有全局定义变量的动态范围,因此如果您可以在 CL 中实际测试它:

(defparameter *v* 10)
(defparameter *x* 0)

(defun adder (*v*)
  (lambda (*x*) (+ *x* *v*))))

;; lexical scheme results
(defparameter *add5* (adder 5))
(funcall *add5* 3)    ; ==> 13
(let ((*v* 6))
  (funcall *add5* 3)) ; ==> 9

有些 lisp 方言只有动态绑定。 picoLisp 和 elisp 的早期版本就是例子。

请注意,Common Lisp 使用 funcall,因为我已将函数绑定到变量。那是因为它们有两个命名空间。一种用于评估操作员位置的表格,另一种用于其余位置。因此,在 CL 中,您可以拥有函数 list 和名为 list 的参数,它们是不同的值。下面是在 Scheme 中无法使用但在 CL 中可以正常使用的代码:

(let ((list '(1 2 3)))
  (list list list))

; ==> ((1 2 3) (1 2 3)) in CL
; ==> Application: (1 2 3) is not a procedure error in Scheme

【讨论】:

    【解决方案2】:

    什么是单一的词法环境?

    嗯,Scheme 有一个词法环境,但是旧的 lisps 可以有多个词法环境。例如,如果您为函数(名称)和参数(名称)维护单独的环境,那么您可以编写:

    > (define (foo foo) (+ foo 3))
    > (foo 4)
    7
    

    " 以相同的方式评估过程调用的操作员位置 操作数位置”?

    当您有一个环境用于函数而另一个环境用于参数时,过程调用使用函数参数来查找运算符,并使用另一个环境来查找参数。

    另请参阅此答案(由 Kent Pittman 撰写)并点击链接到有关 lisp-1 与 lisp-2 的论文。

    Is "Lisp-1 vs Lisp-2" relevant in a language with static types?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-21
      • 1970-01-01
      • 2019-11-29
      • 1970-01-01
      相关资源
      最近更新 更多