2015-06-11 50 views
3

說我有這樣的代碼:有沒有辦法在球拍中看到拉姆達的身體?

#lang racket 

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

我直覺這lambda表達式是(外延上)等於(λ (z) z)知道

我的問題是,如果有一種方法的情況下,打印出的a身體我想看看Racket在內部簡化了多少功能。


的更多信息:

默認情況下,如果我輸入a入解釋,我得到#<procedure:y>(這似乎給一個提示,多評價如何發生的)。我可以將輸出樣式更改爲「構造函數」,然後結果是(lambda (a1) ...),它更接近我想要的,但我仍然不知道身體中哪些是重要部分。

我想象一個可以與球拍的評價策略進行更徹底的知識回答這個問題,但我仍然有興趣,如果顯示過程主體是一般可以發生的事。

+1

相關(但_not_重複):http://stackoverflow.com/questions/20349543/how- do-you-return-the-description-of-a-procedure-in-scheme/20362858#20362858和http://stackoverflow.com/questions/10114295/is-there-a-way-to-view-a-功能 - 源代碼由內最球拍REPL –

回答

5

一般來說是沒有辦法看到一個封閉體在運行。 「正文」是源代碼的一部分。它被編譯成字節碼(後來被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)) 
相關問題