2010-06-05 42 views
3

我有一個函數,它接受一個列表並替換一些元素。我已經將它構造爲閉包,以便自由變量不能在函數外部修改。Emacs Lisp - mapcar不會將函數應用於所有元素?

(defun transform (elems) 
    (lexical-let ((elems elems)) 
    (lambda (seq) 
     (let (e) 
    (while (setq e (car elems)) 
     (setf (nth e seq) e) 
     (setq elems (cdr elems))) 
    seq)))) 

我在列表中調用它。

(defun tester (seq-list) 
    (let ((elems '(1 3 5))) 
    (mapcar (transform elems) seq-list))) 

(tester (list (reverse (number-sequence 1 10)) 
      '("a" "b" "c" "d" "e" "f"))) 
=> ((10 1 8 3 6 5 4 3 2 1) ("a" "b" "c" "d" "e" "f")) 

它似乎沒有將該函數應用於提供給tester()的列表的第二個元素。不過,如果我明確應用此功能的單個元素,它的工作原理...

(defun tester (seq-list) 
    (let ((elems '(1 3 5))) 
    (list (funcall (transform elems) (car seq-list)) 
      (funcall (transform elems) (cadr seq-list))))) 

(tester (list (reverse (number-sequence 1 10)) 
      '("a" "b" "c" "d" "e" "f"))) 
=> ((10 1 8 3 6 5 4 3 2 1) ("a" 1 "c" 3 "e" 5)) 

如果我寫了使用與上述相同的概念的簡單功能,mapcar似乎工作...我能怎麼做錯誤?

(defun transform (x) 
    (lexical-let ((x x)) 
    (lambda (y) 
     (+ x y)))) 

(defun tester (seq) 
    (let ((x 1)) 
    (mapcar (transform x) seq))) 

(tester (list 1 3))  
=> (2 4) 

由於

回答

2

的封閉變量elems被設置爲封閉件的第一次調用後零;所有後續的調用只能看到零。你的第二個例子工作,因爲transform的每個實例產生一個新的閉包。

這應該工作:

(defun transform (elems) 
    (lexical-let ((elems elems)) 
    (lambda (seq) 
     (dolist (e elems seq) 
     (setf (nth e seq) e))))) 
+0

dolist是太好了!我猜詞法 - 不會保護自由變量免受修改...(並且我的第二個例子與第一個例子不夠接近,我想我可以抓住它...)。 – hatmatrix 2010-06-05 08:23:27

相關問題