2009-07-28 113 views
33

我不知道,如果你把它叫做規範的制定,但是結合本地函數,我由GNU手冊建議使用「FLET」:讓和FLET中的Emacs Lisp

(defun adder-with-flet (x) 
    (flet ((f (x) (+ x 3))) 
    (f x)) 
) 

然而,偶然我嘗試了(在Scheme中玩了一下之後)下面的表達式,其中我使用'let'將lambda表達式綁定到一個變量,並且如果我將該函數傳遞給mapcar,它也可以工作*:

(defun adder-with-let (x) 
    (let ((f (lambda (x) (+ x 3)))) 
    (car (mapcar* f (list x)))) 
) 

而且這兩個功能都起作用:

(adder-with-flet 3) ==> 6 
(adder-with-let 3) ==> 6 

爲什麼第二個工作?我找不到任何'let'可用於將函數綁定到符號的文檔。

+0

爲了任何人試圖這一點,注意`flet`可能不會在你使用emacs的版本,在這種情況下嘗試`(需要「CL )`事先如下所述(`flet`是CommonLisp thingy)。 – Robert 2013-05-01 13:47:17

+0

哪個GNU手冊推薦在這裏使用`flet`? – Stefan 2013-06-27 15:05:40

+1

來自Emacs 25.1.1描述函數:flet自24.3起,此宏已過時;使用'cl-flet'或'cl-letf' – AAAfarmclub 2017-01-01 06:29:58

回答

37

與Scheme不同,Emacs Lisp是一個2-lisp,這意味着每個符號都有兩個單獨的綁定:值綁定和函數綁定。在函數調用(a b c d)中,使用函數綁定查找第一個符號(a),其餘(b c d)使用值綁定進行查找。特殊格式let創建一個新的(本地)值綁定,flet創建一個新的函數綁定。

注意是否綁定用於查找值或功能取決於位置(a b c d)函數調用,而不是在類型查找到的價值。特別是,值綁定可以解析爲功能。

在你的第一個例子,你的功能綁定f(通過flet),然後做一個功能查找:

(f ...) 

在你的第二個例子,你值綁定f的功能(通過let) ,然後用一個值查找:

(... f ...) 

雙方的工作,因爲你使用同一種在每種情況下綁定和查詢。

http://en.wikipedia.org/wiki/Common_Lisp#Comparison_with_other_Lisps

18

我做了快速搜索的Emacs口齒不清手動和找不到任何參考'flet,這還不是特別令人驚訝,因爲這是一個cl部分 - common-lisp package

let也會做一個本地綁定,但它不會綁定到該符號的"function cell"

即這個工程:

(let ((myf (lambda (x) (list x x)))) 
    (eval (list myf 3))) 

(let ((myf (lambda (x) (list x x)))) 
    (myf 3)) 

失敗,出現錯誤: 「Lisp的錯誤:(空隙功能了Myf)」

flet,另一方面,確實做功能單元綁定,所以這個工程:

(flet ((myf (x) (list x x))) 
    (myf 3)) 

注意不同之處在於,flet允許您直接使用符號myf,而let不會 - 您必須使用某種間接方式將函數從「值單元格」中取出並適當地應用。

在你的例子中,'mapcar'和我使用的'eval等價。

+0

感謝您的迴應!與zielaj的解釋一起,我看到這個'eval'事物是如何工作的。是的,flet似乎在cl擴展中。我原本讀到在使用flet之前需要(需要'cl'),但是我認爲在更新的emacs中不再是這種情況... – hatmatrix 2009-07-29 10:50:08

7

@ d11wq存在就是爲了這個目的`funcall」。以下作品:

(defun adder-with-let (x) 
    (let ((f #'(lambda (x) (+ x 3)))) 
    (funcall f 3))) 

(adder-with-let 3) ;=> 6 
0

您不必使用flet,如果你不想。你把一個函數使用let在下面的例子中定義的本地符號的功能細胞:

(let ((ALocalSymbol)) 
    (fset 'ALocalSymbol (lambda (x) (* 2 x))) 
    (ALocalSymbol 4) 
) 

評估這將返回8.不要注意到的ALocalSymbol前報價在(let ((ALocalSymbol))...)。而setq報價符號,fset沒有。

flet是一種類型的語法糖。使用普通的let定義無符號的符號,可以讓您選擇要設置符號的哪個「單元」。您可以使用setq來設置符號的值單元或fset來設置函數單元。

希望這有助於

巴勃羅