繁体   English   中英

有没有办法在Racket中看到lambda的身体?

[英]Is there a way to see the body of a lambda in Racket?

说我有这个代码:

#lang racket

(define a
  ((λ (x) x)
   ((λ (y) y)
    (λ (z)
      ((λ (w) w) z)))))

我直观地知道这个lambda表达式(扩展)等于(λ (z) z)

我的问题是,如果有一种方法来打印出的身体a的情况下,我想看看有多少功能得到了由球拍内部简化。


更多信息:

默认情况下,如果我在解释器中键入a ,我会得到#<procedure:y> (这似乎提示了评估发生了多少)。 我可以将输出样式更改为“构造函数”,然后结果是(lambda (a1) ...) ,它更接近我想要的,但我仍然不知道正文中的重要内容是什么部分。

我想有人可以通过对Racket的评估策略有更全面的了解来回答这个问题,但是如果显示程序主体是一件可以发生的事情,我仍然感兴趣。

通常,在运行时无法查看闭包的主体。 “body”是源代码的一部分。 它被编译成字节码(稍后由JIT编译成机器代码)。 闭包在运行时包含正文中自由变量的捕获值和指向代码的指针。

也就是说,您可能对研究expandcompile的输出感到满意。

现在expand只扩展语法,因此您将无法看到任何优化:

> (expand-syntax #'(define a
                     ((λ (x) x)
                      ((λ (y) y)
                       (λ (z)
                         ((λ (w) w) z))))))
(define-values (a) 
   (#%app (lambda (x) x) 
            (#%app (lambda (y) y) 
                   (lambda (z) 
                     (#%app (lambda (w) w) z)))))

请注意, #%app表示“应用程序”。

要在应用优化后查看结果,我们需要调用编译器。 内置compile产生字节码,因此我们使用compile-zo将字节码转换为表示字节码的结构(并且它们在repl中很好地打印)。

> (compile-zo '((λ (x) x)
                ((λ (y) y)
                 (λ (z)
                   ((λ (w) w) z)))))
'#s((compilation-top zo 0)
    1
    #s((prefix zo 0) 0 () ())
    #s((application expr 0 form 0 zo 0)
       #s((closure expr 0 form 0 zo 0)
          #s((lam expr 0 form 0 zo 0)
             ()
             (preserves-marks single-result)
             1
             (val)
             #f
             #()
             ()
             #f
             6
             #s((localref expr 0 form 0 zo 0) #f 0 #f #f #f))
          closure64862)
       (#s((closure expr 0 form 0 zo 0)
           #s((lam expr 0 form 0 zo 0)
              y
              (preserves-marks single-result)
              1
              (val)
              #f
              #()
              ()
              #f
              6
              #s((localref expr 0 form 0 zo 0) #f 0 #f #f #f))
           y64863))))

只剩下一个应用程序,因此在编译期间确实简化了程序。

有关compile-zo的定义,请参阅https://github.com/soegaard/meta/blob/master/runtime/racket-eval.rkt

最后,另一个选择是查看JIT生成的机器代码。 请参阅https://github.com/samth/disassemble

UPDATE

如果我正确读取字节码,它对应于:

((λ (x) x)
 (λ (y) y))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM