在 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的主要内容,如果未能解决你的问题,请参考以下文章

common-lisp:绑定和符号之间的区别

安装 Common Lisp 要求的问题

Common Lisp学习之七:LISP的面向对象编程

Common Lisp学习之七:LISP的面向对象编程

Common Lisp 中的整数除法

ANSI Common Lisp中文版