2014-05-05 98 views
2

我在做lambda微積分,在我的教科書中,它說如何使用lambda微積分寫let*如何實現讓*使用lambda

我的回答:x,y和z是參數; v1,v2和v3的參數; e是體:

((lambda (x y z) (e)) v1 v2 v3) 

答案在書:

((lambda(x) 
    ((lambda(y) 
     ((lambda(z) e) v3)) 
     v2)) 
    v1) 

我不知道如果我的回答是等價的。如果沒有,爲什麼我的答案錯了,原來的答案如何得出?

+1

可能重複[如何表達讓\ *爲lambda表達式(不是正規LET) ](http://stackoverflow.com/questions/16698548/how-to-express-let-as-a-lambda-expression-not-the-regular-let) – GoZoner

回答

10

更新2:我已經意識到我的原始答案是正確的,回滾到原來的,但會添加一些澄清說明

在方案中,let*允許以後的值取決於較早的值。因此,例如,你可以寫(在通常的語法):

(let* ((foo 3) 
     (bar (+ foo 1)) 
     (baz (* bar 2))) 
    (* foo bar baz)) 

結合foo 3,bar至4,baz至8,並返回72課本的實現允許這一點。

但是,您的實現不允許這樣做 - 它要求獨立評估所有值。然而,它是let的正確實現,而不是let*

您的教科書答案的工作方式是早期的值在之前的值之前被綁定。 因此,例如,在教科書的執行上面的代碼如下:

((lambda (foo) 
    ((lambda (bar) 
    ((lambda (baz) (* foo bar baz)) (* bar 2))) 
    (+ foo 1))) 
    3) 

但是,如果您嘗試使用您的實現以同樣的方式:

((lambda (foo bar baz) (* foo bar baz)) 8 (+ foo 1) (* bar 2)) 
; Error - foo and bar aren't bound 

那麼foo(+ foo 1)會是未結合的,作爲foo是在範圍上並不存在(相同於(* bar 2)bar


請注意,在您的實現中,(e)應該只是e,就像教科書的實現一樣;前者是一個熱門的電話,而後者只是一個表達。

0

Istvan的回答是正確的,但基本上,您的代碼和您的教科書之間的區別是letlet*之間的差異。基本上,let*是嵌套一系列let s,而在事實上,let*典型的定義如下:

(define-syntax let* 
    (syntax-rules() 
    ;; if no bindings, same as let 
    ((let*() body ...) 
    (let() body ...)) 

    ;; otherwise, take one binding, then nest the rest 
    ((let* (binding next ...) body ...) 
    (let (binding) 
     (let* (next ...) 
     body ...)))))