如何从Common Lisp中的函数符号中获取函数表达式?

时间:2015-03-20 09:53:59

标签: common-lisp

我将在Elisp中显示我想要的Common Lisp:

(defun square (x)
  (* x x))
(symbol-function 'square)
;; => (lambda (x) (* x x))

因此,只要知道符号square,我就想要检索它的整个身体。 我看过CL&#39>:

(function-lambda-expression #'square)
;; =>
(SB-INT:NAMED-LAMBDA SQUARE
    (X)
  (BLOCK SQUARE (* X X)))
NIL
SQUARE

返回结果接近我的需要,但它只在某些情况下有效。 大多数时候,我得到:

(function-lambda-expression #'list)
;; =>
NIL
T
LIST

是否有更可靠的功能呢?我很清楚swank-backend:arglist 擅长检索参数,但我找不到那里的尸体的猎犬。

更新

似乎普通解决方案在普通的lisp中是不可能的。这可以在SLIME中做到吗? 假设我总是运行SLIME,并且所有代码都是通过那里加载的。代码可以吗? 获得比仅使用SLIME的goto-definition并从那里复制文本更可靠?

3 个答案:

答案 0 :(得分:5)

没有。标准不强制保存符号中的源代码,因此任何实现都可以选择不执行此操作(这也会影响性能)。

我想你可能会通过声明optimize (debug 3)来更频繁地获得这种行为,但我没有尝试过;它很可能取决于实现。

更新答案:由于您希望实现与Lisp图像交互的编辑器功能,我说使用Lisp交互模式(SLIME中的LIM)正是您的意思需要做的。

答案 1 :(得分:1)

也许原因是系统/核心功能,如#'list,在构建图像时已经编译了速度?也许如果你自己引导SBCL,你可以制作一个速度较慢且有更多信息的。或者您可以查看源sode:

(describe #'list)

#<FUNCTION LIST>
  [compiled function]

Lambda-list: (&REST ARGS)
Declared type: (FUNCTION * (VALUES LIST &OPTIONAL))
Derived type: (FUNCTION (&REST T) (VALUES LIST &OPTIONAL))
Documentation:
  Return constructs and returns a list of its arguments.
Known attributes: flushable, unsafely-flushable, movable
Source file: SYS:SRC;CODE;LIST.LISP

最后一行是正确的,因为在src/code/list.lisp下你实际上找到了定义。

请注意describefunction-lambda-expression的行为取决于实现。例如。在CLISP中,输出完全不同。

答案 2 :(得分:0)

(function-lambda-expression #'list)来检索内置函数的代码。并非每个内置函数都需要使用Lisp代码作为其实现。

我还没有尝试过,但也许您可以自己构建SBCL,以便记录源代码并将其保存在图像中。

对于SBCL的标准图像,我不希望它包含源代码。