On 07/06/2013 08:07 PM, Nathan Sorenson wrote:
Another option would be to unwind all lets and lambdas so each body only can contain one expression, such that
(let () 1 (define two 2) two) => (let () 1 (let () (two 2) two))
Gambit follows R5RS, where internal defines are required to be at the beginning of a lambda body (which a let body really is) and where those defines are equivalent to a letrec. So the following prints #t:
(let () (define (myeven? x) (cond ((zero? x) #t) ((< x 0) (myodd? (+ x 1))) (else (myodd? (- x 1))))) (define (myodd? x) (cond ((zero? x) #f) ((< x 0) (myeven? (+ x 1))) (else (myeven? (- x 1))))) (display (myodd? 3)) (newline))
and is equivalent to
(let () (letrec ((myeven? (lambda (x) (cond ((zero? x) #t) ((< x 0) (myodd? (+ x 1))) (else (myodd? (- x 1)))))) (myodd? (lambda (x) (cond ((zero? x) #f) ((< x 0) (myeven? (+ x 1))) (else (myeven? (- x 1))))))) (display (myodd? 3)) (newline)))
Your transformation would mean that the binding of odd? would not be visible to the definition of even?: Loading
(let () (define (myeven? x) (cond ((zero? x) #t) ((< x 0) (myodd? (+ x 1))) (else (myodd? (- x 1))))) (let () (define (myodd? x) (cond ((zero? x) #f) ((< x 0) (myeven? (+ x 1))) (else (myeven? (- x 1))))) (let () (display (myodd? 3)) (let () (newline)))))
gives
frying-pan:~> gsi crap.scm *** ERROR IN myeven?, "crap.scm"@5.14 -- Unbound variable: myodd?
I believe that systems that allow interleaving expressions and definitions interpret a body using something called letrec* semantics, but since I'm not clear what that entails, someone else will need to explain it.
Brad