简体   繁体   English

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

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

Say I have this code: 说我有这个代码:

#lang racket

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

I know intuitively that this lambda expression is (extensionally) equal to (λ (z) z) 我直观地知道这个lambda表达式(扩展)等于(λ (z) z)

My question is if there is a way to print out the body of a in case I want to see how much the function got simplified internally by Racket. 我的问题是,如果有一种方法来打印出的身体a的情况下,我想看看有多少功能得到了由球拍内部简化。


More information: 更多信息:

By default, if I type a into the interpreter, I get #<procedure:y> (This seems to give a hint as to how much evaluation happened). 默认情况下,如果我在解释器中键入a ,我会得到#<procedure:y> (这似乎提示了评估发生了多少)。 I can change the output style to "constructor", say, and then the result is (lambda (a1) ...) which is closer to what I want, but I still don't know what's in the body which is the important part. 我可以将输出样式更改为“构造函数”,然后结果是(lambda (a1) ...) ,它更接近我想要的,但我仍然不知道正文中的重要内容是什么部分。

I imagine one could answer this with a more thorough knowledge of Racket's evaluation strategy, but I'm still interested if displaying procedure bodies is a thing that can happen in general. 我想有人可以通过对Racket的评估策略有更全面的了解来回答这个问题,但是如果显示程序主体是一件可以发生的事情,我仍然感兴趣。

In general there is no way to see body of a closure at runtime. 通常,在运行时无法查看闭包的主体。 The "body" is part of the source code. “body”是源代码的一部分。 It gets compiled into bytecode (and later to machine code by the JIT). 它被编译成字节码(稍后由JIT编译成机器代码)。 The closure consists at runtime of the captured values for the free variables in the body and a pointer to the code. 闭包在运行时包含正文中自由变量的捕获值和指向代码的指针。

That said, you might be satisfied with studying the output of expand or compile . 也就是说,您可能对研究expandcompile的输出感到满意。

Now expand only expands syntax, so you won't be able to see any optimizations yet: 现在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)))))

Note that #%app means "application". 请注意, #%app表示“应用程序”。

To see the result after optimizations are applied we need to invoke the compiler. 要在应用优化后查看结果,我们需要调用编译器。 The builtin compile produces bytecodes, so we use compile-zo which converts the bytecode into structures representing bytecode (and they print nicely in the repl). 内置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))))

There is only one application left, so the program was indeed simplified during compilation. 只剩下一个应用程序,因此在编译期间确实简化了程序。

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

Finally yet another option is to look at the machine code produced by the JIT. 最后,另一个选择是查看JIT生成的机器代码。 See https://github.com/samth/disassemble 请参阅https://github.com/samth/disassemble

UPDATE UPDATE

If I read the bytecode correctly, it corresponds to: 如果我正确读取字节码,它对应于:

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

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

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