(define n 100)
(define (f a) n)
(define (g n) n)
(define (h n) (f 0))
Why (define (h n) (f 0))
evaluate to 100 instead of 10 when calling (h 10)
?
When calling (h 10)
, will n
be redefined as 10 or still 100? How about (g 10)
?
So when you make a procedure and introduce a binding it is only accessible withing the scope of that binding:
((lambda (w) (+ w 10)) 2) ; ==> 12
w ; ERROR: Undefined variable (it only exists inside the lambda)
You can rename any parameter as long as you rename all of it's use. Eg. this is the exact same:
((lambda (w2) (+ w2 10)) 2) ; w renamed to w2 and has not effect on the outcome.
Actually, many compilers rename all identifiers so that they are unique. I'll do that with your code now:
(define n_1 100)
(define (f_1 a_1) n_1)
(define (g_1 n_2) n_2)
(define (h_1 n_3) (f_1 0))
(h_1 10) ; ==> 100
This is the same code as in your question. All I've done is rename so that bindings are not shadowed by new closures that use the same names.
Do you see now why (h_1 10)
evaluates to 100 now that there are no shadowed bindings?
Fun fact: In a lisp language without closures we have dynamic binding. There the variables created last in runtime dictates what n
is. In a dynamic Scheme my rewrite would work the same as in a normal lexical Scheme, but your original code would evaluate (h 10) ; ==> 10
since the local dynamic binding n
to 10 is the closest.