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