叫什么好处“来区分lambda表达式和符号程序”
我在看R6RS(在算法语言计划Revised6报告),在“引言”部分有一个总结:叫什么好处“来区分lambda表达式和符号程序”
“计划是Lisp的第一个主要方言,它将程序与lambda表达式和符号区分开来,为所有变量使用单个词法环境,并以 作为操作数位置来评估过程调用的操作符位置。
我的问题是:
什么的“区分lambda表达式和符号的程序”有什么好处?
什么是单一的词汇环境?我的理解是,由于词法范围的原因,Scheme中的所有内容都是“词法”的,没有运行时间范围,源代码中的位置/位置意味着更多关于环境。
如何理解“以与操作数位置相同的方式评估过程调用的操作符位置”? 我的理解是操作符位置处的符号被评估为操作数位置。例如:
(define test
(lambda (x)
((if (> x 0) + -) 1 2)))
的“(如果(> X 0)+ - )”是在操作者位置,其评价是相同其它操作数位置的评价。
什么是单一的词汇环境?
那么,计划有一个单一的词汇环境,但旧的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?
方案是拳头Lisp的有lexcical环境和*。它很大程度上影响了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
有口齿不清的方言,只有具有动态绑定。例如,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
如果您熟悉其他Lisp(如Common Lisp),则这些语句更有意义。 – molbdnilo