【问题标题】:How can eval handle a function in this wayeval 如何以这种方式处理函数
【发布时间】:2013-11-15 06:16:26
【问题描述】:

我正在尝试查看在函数中使用 eval 之类的东西时数据与代码替换的工作原理,该函数允许我传递任何打印命令,如 print princ 等和一些文本,它使用它输出中的命令:

(defun print-test (fn text)
  (eval '(fn 'text)))

我尝试了各种方法,但无法让它运行。我也试过了:

(defun print-test (fn text)
  (eval ('fn 'text)))

..和其他变体。所以我显然错过了一些东西。我希望能够做到这一点:

(print-test 'princ 'some-text)

我通常会收到错误 fn is undefined。但由于我是实时评估代码,我认为它可以从我的输入中得到fn

我意识到还有其他方法可以做到这一点,比如传入一个实际的函数对象,如 #'princ,但我很好奇 eval 机制如何用于动态生成代码。

【问题讨论】:

    标签: lisp common-lisp


    【解决方案1】:

    fn is undefined 这样的错误并不是告诉您princ 是未定义的,而是符号fn 没有函数绑定。你不想调用符号fn,你想调用变量fn

    您似乎想要评估一个列表,其第一个元素的值是fn,第二个元素的值是text。您可以使用(list fn text) 中的函数list 创建这样一个列表。那你可以用它打电话给eval吗:

    (defun print-test (fn text)
      (eval (list fn text)))
    

    你也可以使用反引号,然后做

    (defun print-test (fn text)
      (eval `(,fn ,text)))
    

    在这些情况下,如果您想获得与(princ 'hi) 相同的效果,则需要fn 成为符号princtext 成为列表 'hi (是的,列表,因为'hi(quote hi) 的简写)。你会这样打电话,然后:

    (print-test 'princ ''hi)
    

    如果第二个参数应该总是在生成的文本中被引用,你也可以使用以下任何一种:

    (eval `(,fn ',text))
    (eval `(,fn (quote ,text)))
    (eval (list fn (list 'quote text)))
    

    尽管如此,这似乎是使用eval 的一种非常奇怪的方式。除非有特别好的理由,否则为什么不直接使用funcall?毕竟,如果fn 作为要评估的形式的汽车是合法的,而text 是一个参数,那么这不能简单地如下吗?

    (defun print-test (fn text)
      (funcall fn text))
    

    当然,这会有点不同。在这里,如果您想要与(princ 'hi) 相同的效果,您只需传递符号princhi

    (print-test 'princ 'hi)
    

    【讨论】:

    • 我意识到这是一个微不足道的例子,但我试图了解 eval 的工作原理。但是,在尝试使用您的版本时我仍然遇到错误:(print-test 'princ 'hi)The variable HI is unbound.
    • @OpenLearner 如果您尝试评估 (princ hi),这难道不是您所期望的吗?当我在 REPL 中输入(princ hi) 时,我得到hi is undefined。我希望eval 能给我同样的东西。
    • 我会尝试评估 (princ 'hi) 所以 hi 需要传入但仍被引用
    • @OpenLearner 如果你想生成代码(princ 'hi) == (princ (quote hi)),那么你需要fn作为符号princtext作为列表'hi == (quote hi)。所以你会做(print-test 'princ ''hi)
    • 好的,很有趣。另外,为什么需要(list fn text)'(fn text) 不起作用?这将是我第一次看到两者不相等
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    • 2018-09-02
    • 1970-01-01
    • 2020-04-07
    相关资源
    最近更新 更多