对于一个过程是否有一个Scheme-toString方法?

对于一个过程是否有一个Scheme-toString方法?,scheme,racket,tostring,Scheme,Racket,Tostring,我想做一个手术,看看它是什么样子。这可能吗 例如,假设我有: (define (some-func x) (+ x 1)) 我想做的是对一些func应用一些惊人的功能(比如,stringify),并能够看到它的本质 \> (stringify some-func) "(lambda (x) (+ x 1))" 我还没有找到任何这样做的Racket库。能做到吗 在R6RS中,无法确定两种程序是否等效;即使像(let((p(lambda()42))(eqv?p))这样的表达式也不能保证

我想做一个手术,看看它是什么样子。这可能吗

例如,假设我有:

(define (some-func x)
  (+ x 1))
我想做的是对
一些func
应用一些惊人的功能(比如,stringify),并能够看到它的本质

\> (stringify some-func)
"(lambda (x) (+ x 1))"

我还没有找到任何这样做的Racket库。能做到吗

在R6RS中,无法确定两种程序是否等效;即使像
(let((p(lambda()42))(eqv?p))
这样的表达式也不能保证为真

R7RS通过使用“位置标记”的概念来解决这个问题,其中每个
lambda
表达式生成一个唯一的位置标记。然后,
eqv?
通过比较位置标记对过程起作用:因此,
(let((p(lambda()42))(eqv?p))
为真,
(eqv?(lambda()42)(lambda()42))
为假


没有可靠的方法获取过程的源代码(许多实现宏扩展和编译过程,丢弃原始源代码),即使可以,也无法使用它来比较两个过程是否“相等”,因为闭包(并且两个过程可能具有相同的“源代码”)但将其自由变量绑定到不同的对象)。例如,考虑这两个表达式<代码>(让((x 1))(lambda()x))< /> >和<代码>(让((x 2))(lambda(x))< /代码>。它们有相同的“源代码”,但头脑正常的人不会声称它们在任何方面都是等效的。

注意,您可以轻松实现一个
定义
替代方案来保留源代码。你不能避免词汇问题,但是,通过模化,你得到了一些使用有限的东西

(define name->source-mapping '())

(define (name->source name)
  (cond ((assq name name->source-mapping) => cdr)
        (else #f)))

(define (name->source-extend name source)
  (set! name->source-mapping (cons (cons name source) name->source-mapping))

(define-syntax define-with-source
  ((_ (name args ...) body1 body2 ...)
   (define name
     (begin (name->source-mapping-extend 'name '(lambda (args ...) body1 body2 ...))
                                             name->source-mapping))
            (lambda (args ...) body1 body2 ...)))))

以上不替换<代码>(定义名称值)< /C>语法;只考虑上面的一个例子。

你知道有多少种语言可以“漂亮地打印”(或显示)一种方法?编辑:你想要的是一个反编译器。调试信息在这里可能会有所帮助。一些方案可能支持这一点。IIRC查找
过程源代码
(SRFI之类)。很好,您不介意误判,因为通常无法确定两个表达式是否相等。