有没有办法在球拍中看到lambda的身体? [英] Is there a way to see the body of a lambda in Racket?

查看:74
本文介绍了有没有办法在球拍中看到lambda的身体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有这个代码:

#lang racket

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

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

I know intuitively that this lambda expression is (extensionally) equal to (λ (z) z)

我的问题是,是否有一种方法可以打印出a的主体,以防万一我想看看Racket在内部简化了多少功能.

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,我会得到#<procedure:y>(这似乎暗示了发生了多少评估).我可以将输出样式更改为构造函数",然后结果是(lambda (a1) ...),它更接近我想要的内容,但是我仍然不知道体内的重要部分.

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). 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.

我想人们可以通过更全面地了解Racket的评估策略来回答这个问题,但是我仍然对显示过程主体是否会普遍发生感兴趣.

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.

推荐答案

通常,无法在运行时查看闭包的主体. 主体"是源代码的一部分.它被编译成字节码(后来被JIT编译成机器码).闭包由运行时捕获的体内自由变量的值和指向代码的指针组成.

In general there is no way to see body of a closure at runtime. The "body" is part of the source code. It gets compiled into bytecode (and later to machine code by the JIT). The closure consists at runtime of the captured values for the free variables in the body and a pointer to the code.

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

That said, you might be satisfied with studying the output of expand or compile.

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

Now expand only expands syntax, so you won't be able to see any optimizations yet:

> (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表示应用程序".

Note that #%app means "application".

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

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-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.

请参见 https://github.com/soegaard/meta /blob/master/runtime/racket-eval.rkt 获取compile-zo的定义.

最后,还有一个选择是查看JIT生成的机器代码. 参见 https://github.com/samth/disassemble

Finally yet another option is to look at the machine code produced by the JIT. See https://github.com/samth/disassemble

更新

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

If I read the bytecode correctly, it corresponds to:

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

这篇关于有没有办法在球拍中看到lambda的身体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆