代码之家  ›  专栏  ›  技术社区  ›  David S.

如何在elisp的表达式中传递运算符?

  •  1
  • David S.  · 技术社区  · 8 年前

    我在读书 Lisp的根 ,并遇到此示例:

    (
     (lambda (f) (f '(b c)))
     '(lambda (x) (cons 'a x)))
    

    然而,如果我在 Emacs ,我有

    Symbol's function definition is void: f
    

    如果我试穿一下 https://repl.it/languages/scheme ,它使用Schema作为lisp解释器,我得到

    Error: ('lambda ('x) ('cons ('quote 'a) 'x)) is not a function [(anon), (anon)]
    

    如果我移除 quote 在第二个lambda表达式上,此示例适用于repl。但在Emacs上仍然出现相同的错误。

    1 回复  |  直到 8 年前
        1
  •  4
  •   Simon Fromme    8 年前

    应用功能 f '(b c) 必须使用 funcall 因此,以下工作是有效的:

    (
     (lambda (f) (funcall f '(b c)))
     '(lambda (x) (cons 'a x)))
    

    并计算为 (a b c) .

    Paul Graham可能使用了lisp的一些变体,其中只有一个名称空间用于函数名和数据变量( Lisp-1型 或Scheme模型) article 而Elisp是一个 Lisp-2型 函数/变量具有不同名称空间的语言。这允许函数和变量具有相同的名称。

    所以对于这样的事情

    (some-function some arguments)
    

    elisp执行器仅搜索 some-function 在函数名称空间中,其构造类似 函数调用 apply 当您想从变量名称空间调用与变量关联的函数时,这是必需的。

    如果不理解,elisp中单独的函数/变量名称空间可能会导致意外行为:

    (defun do-something () (1))
    (setq do-something #'(lambda () (2)))
    
    (do-something) ;; => 1
    (funcall do-something) ;; => 2