我正在阅读r6rs(修订版6关于算法语言方案的报告),在"简介"部分有一个摘要:
" Scheme是Lisp的第一个主要方言,用于区分过程与lambda表达式和符号,对所有变量使用单个词法环境,以及以相同方式评估过程调用的操作员位置 作为操作数位置。"
我的问题是:
"区分程序与lambda表达式和符号的好处"?
单一的词汇环境是什么? 我的理解是,由于词法范围,Scheme中的所有内容都是" lexical",没有运行时范围,源代码中的位置/位置意味着更多关于环境。
如何理解"以与操作数位置相同的方式评估过程调用的操作员位置"? 我的理解是操作员位置的符号被评估为操作数位置。例如:
(define test
(lambda (x)
((if (> x 0) + -) 1 2)))
"(if(> x 0)+ - )"在操作员位置,其评估与其他操作数位置的评估相同。
答案 0 :(得分:2)
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)
Scheme没有动态变量,所以最后一部分不会发生。 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
答案 1 :(得分:1)
单一的词汇环境是什么?
嗯,Scheme有一个单一的词汇环境,但是较旧的lisps可以有多个词汇环境。例如,如果您为函数(名称)和参数(名称)维护单独的环境,那么您可以编写:
> (define (foo foo) (+ foo 3))
> (foo 4)
7
“以与以下相同的方式评估过程调用的操作员位置 操作数位置“?
如果有一个函数环境而另一个环境用于参数,则过程调用使用函数参数来查找运算符,使用其他环境来查找参数。
另见这个答案(肯特皮特曼以外的其他人),并点击关于lisp-1 vs lisp-2的论文的链接。
Is "Lisp-1 vs Lisp-2" relevant in a language with static types?