2012-11-01 53 views
4

我想創建一個函數,該函數返回的其他幾個函數組合,使得有沒有一種方法可以編寫函數來在Elisp中編寫函數?

(funcall (compose 'f 'g) x) == (f (g x)) 

我覺得我悲慘地失敗了這一點。到目前爲止,我最好的嘗試:

(defun compose (funcs) 
    "composes several funcitons into one" 
    (lambda (arg) 
    (if funcs 
     (funcall (car funcs) (funcall (compose (cdr funcs)) arg)) 
     arg))) 

但由於某些原因,下面仍返回0:

(funcall (compose '(
      (lambda (a) (* a 3)) 
      (lambda (a) (+ a 2)) 
)) 0) 

有沒有辦法解決呢?

回答

6

您的代碼需要詞法範圍的lambdas,Emacs Lisp默認不支持。如果您使用Emacs 24,請將lexical-binding設置爲t,您的示例將按照書面方式工作。

如果你使用的是老式的Emacs,你可以使用一個明確的lexical-let形式創建一個詞法範圍的λ:

(require 'cl) 

(defun compose (funcs) 
    "composes several funcitons into one" 
    (lexical-let ((funcs funcs)) 
    (lambda (arg) 
     (if funcs 
      (funcall (car funcs) (funcall (compose (cdr funcs)) arg)) 
     arg)))) 
在我的原代碼
+0

因此,拉姆達沒有關閉過'funcs',所以它的執行時間的價值是零? – Rogach

+0

未定義的值在elisp中是錯誤的。事實上,當我未修改代碼時,出現了'(void-variable funcs)'錯誤。據推測'funcs'在你的環境中被意外地定義爲一個全局變量,給你的印象是代碼不起作用,因爲一個無關的錯誤。 – user4815162342

相關問題