【问题标题】:Convert a FUNCTION to a STRING or SYMBOL in Common Lisp在 Common Lisp 中将 FUNCTION 转换为 STRING 或 SYMBOL
【发布时间】: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 所说的“不保证返回任何有用的东西”。

标签: function common-lisp symbols


【解决方案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"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多