在Common Lisp中将一个函数转换为字符串或符号

4

在Common Lisp中,是否可以将函数转换为符号或字符串以进行进一步使用?我的意思是从#'+获取"+"#:|+|


我想知道这个需求来自哪里。 - zut
1
@zut 在一些其他编程语言中,比如Python,函数对象有一个名字属性,有时可能会很有用(例如使用装饰器在Python中实现多方法)。也许OP正在寻找类似的东西。虽然OP可以将其包装在[function,name]的cons单元格中,但如果CL已经具有这样的名称属性,那么知道这一点会更容易,而不必将函数对象包装在这样的接口中。只是猜测。 - Byte
1
在CL中,情况恰好相反。函数是符号(名称)的属性,而不是名称是函数的属性。如果您需要两者,应使用符号并通过它访问函数。 - jkiiski
@jkiiski 同意,但我认为对于使用'flet或'#(lambda ...)在词法上定义的函数对象并不适用。如果我记得《letoverlambda》这本书正确的话,编译器在使用'let时不会创建符号对象,因此(symbol-function ...)没有意义。我认为let绑定只是一个指向函数对象的堆栈插槽。 - Byte
1
使用FLET/LABELS/LAMBDA定义的函数不会自动分配给符号(当然,您可以手动分配)。至少在SBCL上进行调试时,建议使用FUNCTION-LAMBDA-EXPRESSION返回一个列表(FLET <name>)/(LABELS <name>)/(LAMBDA <lambda-list>),但这些当然不是实际的函数名称(即使将函数手动分配给符号函数槽,也会返回这些内容,这证明了"sds"所说的“不能保证返回任何有用的信息”)。 - jkiiski
3个回答

8
唯一的标准方法是function-lambda-expression,但它不能保证返回有用的信息。
然而,CLISP和SBCL都返回实际的函数名:
(nth-value 2 (function-lambda-expression #'+))
==> +

或者,如果你希望的话,

(symbol-name (nth-value 2 (function-lambda-expression #'+)))
==> "+"

5
CL-USER> (nth-value 2 (function-lambda-expression #'sin))
SIN

0
(defun function-name (fn)
  (string-downcase (symbol-name (nth-value 2 (function-lambda-expression fn)))))

(function-name #'atom) => "atom"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接