在 Common Lisp 中将 FUNCTION 转换为 STRING 或 SYMBOL
Posted
技术标签:
【中文标题】在 Common Lisp 中将 FUNCTION 转换为 STRING 或 SYMBOL【英文标题】:Convert a FUNCTION to a STRING or SYMBOL in Common Lisp 【发布时间】:2019-04-18 17:45:56 【问题描述】:在普通的 lisp 中是否可以将函数转换为符号或字符串以供进一步使用?我的意思是从#'+
获得"+"
或#:|+|
。
【问题讨论】:
我想知道这个需求从何而来。 @zut 在 Python 等其他一些语言中,函数对象有一个 name 属性,这在某些时候可能很有用(例如使用装饰器在 Python 中实现多方法)。也许OP正在研究类似的东西。尽管 OP 可以将其包装在 [function, name] 的 cons 单元中,但更容易知道 CL 是否已经具有这样的 name 属性,而不必将函数对象包装在这样的接口中。只是猜测。 @Byte 在 CL 中则相反。函数是符号(名称)的属性,而不是名称是函数的属性。如果两者都需要,则应使用符号并通过它访问函数。 @jkiiski 同意,但我认为这不适用于使用 'flet 或 'let with #'(lambda ...) 词法定义的函数对象。如果我没记错 letoverlambda 书,编译器在使用 'let 时不会创建符号对象,因此 (symbol-function ...) 没有意义。 let 绑定只是我认为指向函数对象的指针的堆栈槽。 没错,用FLET
/LABELS
/LAMBDA
定义的函数不会分配给符号(也就是说,您当然可以自己分配它们)。出于调试目的,至少在 SBCL 上,答案中建议的 FUNCTION-LAMBDA-EXPRESSION
似乎为他们返回了一个列表 (FLET <name>)
/(LABELS <name>)
/(LAMBDA <lambda-list>)
,但这些当然不是实际的函数名称(即使返回这些函数是手动分配给符号的符号函数槽的,这表明了 sds 所说的“不保证返回任何有用的东西”。
【参考方案1】:
唯一的标准方式是
function-lambda-expression
不保证返回任何有用的东西。
永远不会,CLISP 和 SBCL 都返回实际的函数名:
(nth-value 2 (function-lambda-expression #'+))
==> +
或者,如果你愿意,
(symbol-name (nth-value 2 (function-lambda-expression #'+)))
==> "+"
【讨论】:
【参考方案2】:CL-USER> (nth-value 2 (function-lambda-expression #'sin))
SIN
【讨论】:
【参考方案3】:(defun function-name (fn)
(string-downcase (symbol-name (nth-value 2 (function-lambda-expression fn)))))
(function-name #'atom) => "atom"
【讨论】:
以上是关于在 Common Lisp 中将 FUNCTION 转换为 STRING 或 SYMBOL的主要内容,如果未能解决你的问题,请参考以下文章