2017-03-13 96 views
0

我有一個問題,當我想執行以下代碼:如何正確使用emacs lisp語言中的lambda?

(defun sum1 
     (lambda (n) 
     (+ n 1))) 

當我的Mx ielm運行出現一條消息:

無效的功能:(拉姆達(拉姆達(N) (+ N + 1))無)

我想弄清楚的是,雖然我可能會使用下面的代碼:

(defun sum1(n) 
     (+ n 1)) 

我想知道如何在這種情況下定義lambda。

所有信息均被接受,我是新手。

+3

您可以宏展開「defun」並查看它是否正在執行'(defalias'sum1(lambda(n)(+ n 1)))' – jenesaisquoi

+3

Lambda是一個匿名函數。真的不清楚你在問什麼。你可以有,例如。 '(defun make-adder(n)(lambda(x)(+ x n)))'返回一個將n加到數字上的函數。你可以有一個匿名函數作爲變量的值:'(let((adder(lambda(x)(+ x 2))))...)'。 –

+0

我試圖寫一個適合新手的答案,但我意識到真正的答案是:如果你想學習lisp *不要從elisp *開始。取而代之的是Common Lisp(一種傳統的,但比elisp更清晰的lisp),Scheme(更現代的lisp)或者其他的東西(Clojure?)。 elisp並沒有錯,但它確實是老式的:它的功能很好,但它不是如何學習Lisp,因爲它會讓你感到困惑。 (如果你想知道如何做的是黑客emacs,那麼elisp是一個很好的開始當然。) – tfb

回答

2

defun用於聲明一個函數。

在你用來聲明一個變量並賦予它一個變量表達式這樣方案:(define x variable-expression),並宣佈一個功能,當你用來寫這樣的事情(define x function-expression)。 Ofc variable-expression可以是先前聲明的另一個變量或文字(即define x 5,define x y)。

同爲一個函數表達式,而是寫一個函數,當「文字」你使用這樣一個匿名函數是:

(define x (lambda (x) (....))) 

其中lambda (x) (...)是實際返回的函數,分配函數表達式到x。所以這樣x被聲明爲一個函數。

defun實際上聲明瞭一個函數,而不是define在方案中做的變量。所以,當你寫:

(defun sum1 
(lambda (n) 
    (+ n 1))) 

真正的情況是,SUM1被聲明爲沒有參數,返回實際接受可變n並返回n+1另一個函數的函數。

你真正想要的是sum1被宣佈爲功能而不是函數返回另一個函數,這是你實際上在同一片段使用defunlambda得到。

EDIT1:您可以使用函數這樣((sum1) 5)

+0

實際上你需要'(defun sum1()(lambda ...))':你需要arglist,也沒有詞法作用域(elisp沒有默認)這個定義根本不起作用 – tfb

+0

這是一個很長的解釋,但並不是最清楚的,請告訴他如何解決他的問題\正確編寫他的代碼,就像@tfb在上面做的那樣。 – user2141046

2

lambda使一個功能,但並沒有給它一個名字。無論何時需要創建一個功能,都可以使用它,但不需要命名。一個很好的例子是一個比較函數,它只用於一次排序列表。

(let ((l (number-sequence 1 10))) 
    (sort l (lambda (a b) (> a b)))) ;; reversed 

這可能是惱人的defun,你永遠不會再次使用的功能。只需花一點點努力就可以得到一個名字,並且你需要確保你沒有覆蓋現有的函數(這並不是很難,我通常用我的首字母加前綴)。

lambda(IMO)的常見濫用的示例是鉤子。許多人會將lambda s添加到鉤子,但是如果您查看鉤子變量的值,則會有一堆lisp,而不是可以運行describe-function的函數名稱。但更糟的是,您不能使用remove-hook,或者在編寫或調試函數時重新定義函數。