我将在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并从那里复制文本更可靠?
答案 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下你实际上找到了定义。
请注意describe
和function-lambda-expression
的行为取决于实现。例如。在CLISP中,输出完全不同。
答案 2 :(得分:0)
(function-lambda-expression #'list)
来检索内置函数的代码。并非每个内置函数都需要使用Lisp代码作为其实现。
我还没有尝试过,但也许您可以自己构建SBCL,以便记录源代码并将其保存在图像中。
对于SBCL的标准图像,我不希望它包含源代码。