【问题标题】:Determine definition and parameter of a Scheme function in the interpreter? / How are functions stored in Scheme?在解释器中确定 Scheme 函数的定义和参数? / Scheme中的函数是如何存储的?
【发布时间】:2014-09-14 21:10:04
【问题描述】:

我想创建一个函数,可以确定方案中任意函数的定义。如果我们称这样的函数为“定义”,它会这样工作:

(define (triple x) (* 3 x))

(definition triple) would return "(triple x) (* 3 x)".

会有一些实现问题(例如使用 n-arity),但我主要关心的是单个函数的定义是否可以在 Scheme 中轻松检索。

作为延续,有没有办法创建一个可以确定任意函数参数的函数?这样:

(parameters +) 返回(number number) 或类似的东西。

这些问题都属于如何在 Scheme 中存储函数的问题——我发现一些资料来源声称函数定义与函数名称一起存储,但我无法找出它们的存储方式。

如果这是不可能的 - 是否有一种语言可以轻松检索函数定义?

【问题讨论】:

  • Scheme 中没有标准的自省机制。可能存在依赖于实现的方法,请查看 Scheme 解释器的文档。
  • 谢谢 - 我认为 Scheme 没有内省有点奇怪,因为我认为整个 LISP 家族都是关于反射的,但我想事情就是这样。
  • @user124577 实际上,Lisp 语言在反射方面并不很大。 Lisp 的标志是宏,它生成代码(通常来自某种模板)而不是窥探现有代码。
  • 此外,许多 Lisp(和 Scheme)系统会立即编译 lambda 表达式(通常编译成中间形式而不是直接编译成目标代码)并且不保留原始源代码。对于此类实现,您将无法恢复原始代码。
  • @Chris Jester-Young:我认为这与 Scheme 不同。几个 Common Lisp 变体对反射有很多支持。从代码即数据到 CLOS 的元对象协议。

标签: scheme lisp


【解决方案1】:

Scheme 中没有类似的东西。不过,个别实现可能会有这种情况。

在 Common Lisp 中有标准函数 function-lambda-expression,它可能能够检索源代码 - 取决于实现。

LispWorks 中的示例(此处重新格式化以提高可读性):

CL-USER 65 > (defun triple (x) (* 3 x))
TRIPLE

CL-USER 66 > (function-lambda-expression #'triple)
(LAMBDA (X)
  (DECLARE (SYSTEM::SOURCE-LEVEL #<EQ Hash Table{0} 42201D392B>))
  (DECLARE (LAMBDA-NAME TRIPLE))
  (* 3 X))
NIL
TRIPLE

SBCL:

* (defun triple (x) (* 3 x))

TRIPLE
* (function-lambda-expression #'triple)

(SB-INT:NAMED-LAMBDA TRIPLE
    (X)
  (BLOCK TRIPLE (* 3 X)))
NIL
TRIPLE

如你所见,它返回三个值:代码、是否为闭包以及函数名。

【讨论】:

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