代码之家  ›  专栏  ›  技术社区  ›  hatmatrix

emacs lisp-mapcar不将函数应用于所有元素?

  •  3
  • hatmatrix  · 技术社区  · 15 年前

    我有一个函数,它接受一个列表并替换一些元素。我把它构造为一个闭包,这样自由变量就不能在函数之外被修改。

    (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"))
    

    它似乎没有将该函数应用于提供给测试人员()的列表的第二个元素。但是,如果我显式地将这个函数应用于单个元素,它会工作…

    (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)
    

    谢谢

    1 回复  |  直到 14 年前
        1
  •  2
  •   huaiyuan    15 年前

    闭上变量 elems 在第一次调用闭包之后设置为nil;因此所有后续调用只看到nil。第二个示例是有效的,因为 transform 生成新的闭包。

    这应该有效:

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