2009-12-05 110 views

回答

12

他們是可以互換的。答案是function使得的lambda被字節編譯,而另外兩個不(和等同的)。 注意:這並不意味着function實際上字節編譯lambda。

一個人怎麼可能出來?有點Emacs lisp內省提供了一些線索。啓動:C-H f函數RET

功能是在 'C 源代碼' 的特殊形式。

(功能ARG)

喜歡 '報價',但優選用於 對象它們的功能。在編譯的字節 中,'函數'會導致編譯它的參數 。 'quote' 不能這樣做。

好,所以這是(function (lambda ...))'(lambda ...)之間的區別,第一個告知字節編譯器,它可以安全地編譯表達式。而版表情未必編譯(因爲他們可能只是數字的列表

什麼只是裸(lambda ...)章˚F拉姆達RET顯示:?

拉姆達是一個Lisp宏`subr.el」。

(拉姆達ARGS [文檔字符串] [互動] 體)

返回lambda表達式。甲調用 的形式(lambda args docstring 互動體)是自引用的;評估λ 表達式的 結果是表達式本身。 Lambda表達式然後可以 視爲功能,即,存儲作爲 符號的函數值,傳遞給 「funcall」或「mapcar」等

因此,(lambda ...)'(lambda ...)是當量。

此外,還有符號#'(lambda ...),它是(function (lambda ...))的語法糖。

有關Emacs lisp中功能的更多信息,請閱讀Functions info pages

只是爲了檢查這一切,你可以鍵入以下到*刮*緩衝區和計算表達式:

(caddr '(lambda (x) (+ x x))) 
(+ x x) 

(caddr (lambda (x) (+ x x))) 
(+ x x) 

(caddr (function (lambda (x) (+ x x)))) 
(+ x x) 

(equal '(lambda (x) (+ x x)) 
     (function (lambda (x) (+ x x)))) 
t 

(equal '(lambda (x) (+ x x)) 
     (lambda (x) (+ x x))) 
t 

所以,使用lambda只是建立了可以用作列出的所有三個變種函數(其中一個可能是字節編譯)。

+0

但是在表達式前面沒有使用單引號使得LISP解釋器按原樣返回並且沒有對它進行評估?這意味着,'(+ 1 2)將返回爲(+ 1 2)和(+ 1 2)將返回3 ... – Joscha 2009-12-06 00:12:25

+0

@Joscha,不知道你要評論哪部分。 Lambda是自引用的,這就意味着當解釋器評估一個lambda表達式時,結果就是這個lambda表達式。由於Emacs使用了變量查找(無限範圍和動態範圍),我相信這與其他大多數lisp不同。由於詞彙範圍(我相信),Scheme對於一些環境信息幾乎沒有關閉。 – 2009-12-06 00:36:04

+2

'(lambda ...)'實際上等同於'(函數(lambda ...))'而不是''(lambda ...)',您可以通過評估'(macroexpand(lambda(x) + xx)))' – nschum 2012-01-08 11:44:54

3

那麼(quote (lambda...))(lambda...)是不相等的(當字節編譯時)。引用的lambda表達式不是字節編譯的,而是其他所有內容。

例如:

(defun foo (a) 
    (byte-code-function-p a)) 

(defun bar() 
    (foo '(lambda() (ignore 'me)))) 

(defun bar2() 
    (foo (lambda() (ignore 'me)))) 

(defun bar3() 
    (foo (function (lambda() (ignore 'me))))) 

(defun bar4() 
    (foo #'(lambda() (ignore 'me)))) 

(byte-compile 'bar) 
(byte-compile 'bar2) 
(byte-compile 'bar3) 
(byte-compile 'bar4) 

(bar) ; -> nil 

(bar2) ; -> t 
(bar3) ; -> t 
(bar4) ; -> t 

你通常不希望引用一個lambda,除非功能你要傳遞給正在做與別的東西不僅僅是funcall它的拉姆達。

+1

我相信這已經隨着時間而改變。看看'(info「(elisp)匿名函數」),它說:「現在可以完全省略'函數'......這是因爲'lambda'本身就意味着'函數'。 這個頁面在第一次閱讀時有點混亂,但是你的例子很好的解釋了:) (a)'(function(lambda ...))'是'(quote(lambda ...) '這使字節編譯。 (b)* un *引用的'(lambda ...)'(現在)與'(function(lambda ...))'相同! – phils 2010-08-24 22:28:33

相關問題