我正在读r6rs(Revised6 Report on the Algorithmic Language Scheme),在“简介”部分有一个总结:
Scheme是Lisp的第一个主要方言,它将过程与lambda表达式和符号区分开来,对所有变量使用单一的词法环境,并以与操作数位置相同的方式计算过程调用的运算符位置。
我的问题是:
“将过程与lambda表达式和符号区分开来”有什么好处?
单词环境是什么?我的理解是,由于词法作用域的原因,Scheme中的一切都是“词法的”,没有运行时作用域,源代码中的位置/位置意味着更多关于环境的信息。
如何理解“以与操作数位置相同的方式计算过程调用的运算符位置”?我的理解是,运算符位置的符号被计算为操作数位置。例如:
(define test
(lambda (x)
((if (> x 0) + -) 1 2)))
"(if (> x0)+ -)“位于运算符位置,其求值与其他操作数位置的求值相同。
发布于 2017-03-24 20:11:25
Scheme是第一个拥有lexcical环境和闭包的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
发布于 2017-03-23 01:06:29
单词环境是什么?
虽然Scheme只有一个词法环境,但较旧的lisp可以有多个词法环境。例如,如果您为函数(名称)和参数(名称)维护单独的环境,则可以这样写:
> (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?
https://stackoverflow.com/questions/42943297
复制相似问题