[plt-scheme] binding construct scoping issue
Use Chech Syntax and look at the arrows originating from the odd? and
even? identifiers.
Use this in the Module language:
#lang scheme
(let ((even? (lambda (n)
(if (= n 0)
#t
(odd? (- n 1)))))
(odd? (lambda (n)
(if (= n 0)
#f
(even? (- n 1))))))
(even? 20))
((lambda (even? odd?)
(even? 20)) (lambda (n)
(if (= n 0)
#t
(odd? (- n 1))))
(lambda (n)
(if (= n 0)
#f
(even? (- n 1)))))
On Dec 23, 2008, at 2:09 PM, Carl Eastlund wrote:
> 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?
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme