Reputation: 55
So here's a question about scheme variable binds. Let's say I have the following function:
(define undefinedTest (lambda (y) (list x y)))
This will warn of x being an unbound variable when run in Guile-Scheme 2.0.3. If I then execute the following statement
> (let ((x 'something)) (undefinedTest 'else))
I will get an error and the option to debug it. However if I execute the following statements:
> (define x 'something)
> (undefinedTest 'else)
I get the expected answer of (something else). Why is scheme able to bind x when it is defined at the top-level, but not when it is bound by let. Is this because when the function is defined it is also defined at the top-level, and so when scheme go to search its nearest enclosing environment, the let environment is not actually "enclosing" as it still starts its search at the "top-level"?
Upvotes: 2
Views: 568
Reputation: 235984
When undefinedTest
was defined, it enclosed the environment in which it was defined; given that it was defined at the top level, it will only "see" its formal parameter y
and the global environment - and the global environment doesn't contain x
at that point. It's like that because Scheme is lexically scoped.
I tested the code in the question in Racket and the first line fails with the error: expand: unbound identifier in module in: x
- meaning that it's not even a valid definition as interpreted by Racket.
The same example would work in a language with dynamic scoping, Scheme uses lexical scoping (a.k.a. static scoping.)
Upvotes: 1
Reputation: 4843
Lexical scope is a core feature of Scheme. With lexical scoping, you can always tell which bindings are visible to a function, because they are those visible at the point where the function is defined. Dynamic scoping, in contrast, has a tendency to create surprises which can be hard to foresee and equally difficult to debug.
Upvotes: 1
Reputation: 223003
Scheme uses lexical scoping, not dynamic scoping. So the x
the undefinedTest
sees is the x
that is lexically visible from that function, which in this case, as you've already noted, is the top-level scope.
Upvotes: 5