【问题标题】:How to get the function expression from the function symbol in Common Lisp?如何从 Common Lisp 中的函数符号中获取函数表达式?
【发布时间】:2015-03-20 09:53:58
【问题描述】:

我将展示我想要的 Common Lisp 中已经在 Elisp 中工作的东西:

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

所以只要知道符号square,我就想找回它的整个身体。 我看过 CL 的:

(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 并从那里复制文本更可靠吗?

【问题讨论】:

  • 您还可以通过其他实现获得更可靠的结果。例如,CLISP 可能会保存更多关于定义的数据。 (这只是一个猜测,基于最近的一个问题,Strange behavior in Common Lisp。)
  • 你真正想做什么?
  • 我正在尝试为 CL 实现一个 flatten-at-point 操作:在 point 处进行函数调用并将参数替换为函数体。我已经为 Elisp 和 Clojure 准备了一个。
  • 你将如何处理闭包?您如何在 elisp 和 clojure 中处理它们?你为什么要在 SLIME 下做这件事?听起来您正在尝试某种形式的内联,但您没有足够的信息来知道您是否可以实际执行它。
  • 关闭 Elisp 的工作。内联是交互式的,纯粹是为了加快编辑速度。如果它有效,它就有效。如果它没有 - 哦,好吧,我仍然可以手动完成。

标签: common-lisp


【解决方案1】:

没有。标准没有强制要求在符号处保存源代码,因此任何实现都可以选择不这样做(这也有性能影响)。

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

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

【讨论】:

  • 谢谢,我该如何优化声明?
  • 除了性能影响(内存?)之外,它还涉及操作:可能捕获的词法环境。
【解决方案2】:

也许原因是系统/核心函数,如#'list,在构建映像时已经编译了速度?也许如果您自己引导 SBCL,您可以制作一个速度较慢且包含更多信息的程序。或者您可以只查看源代码:

(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 中,输出完全不同。

【讨论】:

    【解决方案3】:

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

    我没试过,不过也许你可以自己构建SBCL,这样它会记录源代码并保存在图像中。

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

    【讨论】:

      猜你喜欢
      • 2018-01-29
      • 1970-01-01
      • 2014-06-27
      • 2012-05-18
      • 1970-01-01
      • 1970-01-01
      • 2022-11-12
      • 2017-07-26
      • 2015-12-12
      相关资源
      最近更新 更多