[plt-scheme] binding construct scoping issue
The even? and odd? functions are defined in PLT Scheme -- some of your
code is calling the builtins, rather than your own definitions.
--Carl
On Tue, Dec 23, 2008 at 1:58 PM, apatinoii at gmail.com
<apatinoii at gmail.com> wrote:
> I've become a bit befuddled over binding constructs.
> In particular, I was under the impression that a normal let expression
> was not able to define mutually recursive procedures. The r6rs and the
> plt-reference imply this through their explanation of letrec. Yet,
>
> (let ((even? (lambda (n)
> (if (= n 0)
> #t
> (odd? (- n 1)))))
> (odd? (lambda (n)
> (if (= n 0)
> #f
> (even? (- n 1))))))
> (even 20))
> => #t
>
> works just fine using both mzscheme and ypsilon.
> TSPL3 describes let as a syntactic extension, expanding into an
> application of a lambda expression. Therefore, I assumed that the
> previous expression would be expanded into the form:
>
> ((lambda (even? odd?)
> (even? 20)) (lambda (n)
> (if (= n 0)
> #t
> (odd? (- n 1))))
> (lambda (n)
> (if (= n 0)
> #f
> (even? (- n 1)))))
> => #t
>
> which works as well. Why does this work? Both lambda arguments are
> defined outside of the body of the calling lambda. Therefore, the
> variables within them should be resolved outside. Isn't this dynamic
> scoping? For example, the following expressions work as expected:
>
> ((lambda (x f) (f)) 1 (lambda () x))
> ((lambda (g) (define x 1) (g)) (lambda () x))
>
> which both result in errors; x is unidentified.
> So, exactly what does let expand to?
>
> Another difficulty I'm having, concerning the same topic, but focused
> more on the algorithm, involves defining the same mutually recursive
> functions, only using named-let instead:
>
> (let even? ([n 20] [odd? (lambda (n)
> (and (not (= n 0))
> (even? (- n 1))))])
> (or (= n 0)
> (odd? (- n 1))))
>
> which works as well, although by looking at its presumed expansion:
>
> ((lambda (n odd?)
> (define even?
> (lambda (x f)
> (or (= x 0)
> (f (- x 1)))))
> (even? n odd?)) 20 (lambda (n)
> (and (not (= n 0))
> (even? (- n 1)))))
>
> appears it shouldn't, since again, the lambda is passed from outside.
> In this case, can anyone tell me why this works given that the even?
> procedure called inside of the lambda argument only takes one
> argument (even? (- n 1)), while inside it is defined to take two
> arguments?