2017-03-22 29 views
1

我在看R6RS(在算法語言計劃Revised6報告),在「引言」部分有一個總結:叫什麼好處「來區分lambda表達式和符號程序」

「計劃是Lisp的第一個主要方言,它將程序與lambda表達式和符號區分開來,爲所有變量使用單個詞法環境,並以 作爲操作數位置來評估過程調用的操作符位置。

我的問題是:

什麼的「區分lambda表達式和符號的程序」有什麼好處?

什麼是單一的詞彙環境?我的理解是,由於詞法範圍的原因,Scheme中的所有內容都是「詞法」的,沒有運行時間範圍,源代碼中的位置/位置意味着更多關於環境。

如何理解「以與操作數位置相同的方式評估過程調用的操作符位置」? 我的理解是操作符位置處的符號被評估爲操作數位置。例如:

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

的「(如果(> X 0)+ - )」是在操作者位置,其評價是相同其它操作數位置的評價。

+2

如果您熟悉其他Lisp(如Common Lisp),則這些語句更有意義。 – molbdnilo

回答

1

什麼是單一的詞彙環境?

那麼,計劃有一個單一的詞彙環境,但舊的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?

2

方案是拳頭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