Lisp eval如何以这种方式处理函数
我试图了解在函数中使用类似于Lisp eval如何以这种方式处理函数,lisp,common-lisp,Lisp,Common Lisp,我试图了解在函数中使用类似于eval的东西时,数据与代码替换是如何工作的,该函数允许我传入任何打印命令,如printprinc等,以及一些文本,并在输出中使用该命令: (defun print-test (fn text) (eval '(fn 'text))) 我尝试过各种方法,但都无法运行。我还尝试: (defun print-test (fn text) (eval ('fn 'text))) …和其他变体。所以我显然错过了一些东西。我希望能够做到这一点: (打印测试“原则”某
eval
的东西时,数据与代码替换是如何工作的,该函数允许我传入任何打印命令,如print
princ
等,以及一些文本,并在输出中使用该命令:
(defun print-test (fn text)
(eval '(fn 'text)))
我尝试过各种方法,但都无法运行。我还尝试:
(defun print-test (fn text)
(eval ('fn 'text)))
…和其他变体。所以我显然错过了一些东西。我希望能够做到这一点:
(打印测试“原则”某些文本)
我通常会得到一个错误fn未定义
。但由于我在实时评估代码,我认为它可以从我的输入中获得fn
我意识到还有其他方法可以做到这一点,比如传入一个实际的函数对象,比如
#princ
,但我很好奇eval
机制如何在运行中生成代码。一个错误,比如fn是未定义的
并没有告诉您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
作为符号princ
,text
作为列表'hi
(是的,列表,因为'hi
是(quote hi)
)的缩写)。你会这样打电话,然后:
(print-test 'princ ''hi)
如果生成的文本中应始终引用第二个参数,则您也可以使用以下任一选项:
(eval `(,fn ',text))
(eval `(,fn (quote ,text)))
(eval (list fn (list 'quote text)))
尽管如此,使用eval
似乎是一种非常奇怪的方式。除非有特别好的理由,为什么不直接使用funcall
?毕竟,如果fn
作为评估表单的car是合法的,而text
是一个参数,那么这难道不能简单地如下所示吗
(defun print-test (fn text)
(funcall fn text))
当然,这个名字会有点不同。在这里,如果您想要与(princ'hi)
相同的效果,只需传递符号princ
和hi
:
(print-test 'princ 'hi)
像
fn未定义
这样的错误不会告诉您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
作为符号princ
,text
作为列表'hi
(是的,列表,因为'hi
是(quote hi)
)的缩写)。你会这样打电话,然后:
(print-test 'princ ''hi)
如果生成的文本中应始终引用第二个参数,则您也可以使用以下任一选项:
(eval `(,fn ',text))
(eval `(,fn (quote ,text)))
(eval (list fn (list 'quote text)))
尽管如此,使用eval
似乎是一种非常奇怪的方式。除非有特别好的理由,为什么不直接使用funcall
?毕竟,如果fn
作为评估表单的car是合法的,而text
是一个参数,那么这难道不能简单地如下所示吗
(defun print-test (fn text)
(funcall fn text))
当然,这个名字会有点不同。在这里,如果您想要与(princ'hi)
相同的效果,只需传递符号princ
和hi
:
(print-test 'princ 'hi)
像
fn未定义
这样的错误不会告诉您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
作为符号princ
,text
作为列表'hi
(是的,列表,因为'hi
是(quote hi)
)的缩写)。你会这样打电话,然后:
(print-test 'princ ''hi)
如果生成的文本中应始终引用第二个参数,则您也可以使用以下任一选项:
(eval `(,fn ',text))
(eval `(,fn (quote ,text)))
(eval (list fn (list 'quote text)))
尽管如此,使用eval
似乎是一种非常奇怪的方式。除非有特别好的理由,为什么不直接使用funcall
?毕竟,如果fn
作为评估表单的car是合法的,而text
是一个参数,那么这难道不能简单地如下所示吗
(defun print-test (fn text)
(funcall fn text))
当然,这个名字会有点不同。在这里,如果您想要与(princ'hi)
相同的效果,只需传递符号princ
和hi
:
(print-test 'princ 'hi)
像
fn未定义
这样的错误不会告诉您princ
未定义,而是告诉您符号fn
没有函数绑定。您不想调用符号fn