Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Program to check if the scoping is lexical or dynamic

I found that the program to check if the scoping is lexical or dynamic is the one given below (source: http://inst.eecs.berkeley.edu/~cs61a/su10/resources/sp11-Jordy/scope/)

(define test 
  (let ((scope 'lexical)) 
    (lambda () scope)))

(let ((scope 'dynamic)) 
  (test))

But how can this work? This should always print 'lexical (irrespective of whether the scope is lexical or dynamic) right? since in the local scope of the body of the first 'let' , scope is always defined to be 'lexical.. Please correct me if i am wrong

like image 671
Subin Pulari Avatar asked Sep 02 '15 04:09

Subin Pulari


2 Answers

The value of test is not

(let ((scope 'lexical)) 
    (lambda () scope))

it is just

(lambda () scope)

When you call it, (test), the function body is evaluated, and it consists only of

scope

With lexical scope, this would be the value in the binding that was in effect when the definition was evaluated, i.e the lexically enclosing let-binding.

With dynamic scope, the binding of scope isn't looked up until the function is called.
At that time, the binding to 'lexical is long gone — it only exists during the definition of test.

When you

(let ((scope 'dynamic)) 
  (test))

a new binding is introduced in the environment, and this is the binding that is found when looking up scope.

The similar function

(define test  
    (lambda () 
        (let ((scope 'whatever))
            scope)))

would work the way you suggest — always returning 'whatever — as the binding to 'whatever is in effect during the evaluation of scope even in a dynamic setting.

like image 196
molbdnilo Avatar answered Oct 31 '22 14:10

molbdnilo


Scheme uses lexical scoping, so of course that code always returns lexical. However, in a Lisp system that uses dynamic scoping, scope would indeed be dynamic inside that (let ((scope 'dynamic)) ...) expression….

In order to understand that, you have to understand how dynamic scoping is implemented. Think of each variable as having a stack of values. So, when the lambda expression was being evaluated, the value lexical has been pushed to scope's value stack (via the let). When the let block is exited, the value is popped off. Later, the second let block pushes the value dynamic to scope's value stack, which is what your function then sees.

I highly appreciate the explanation from the Emacs Lisp manual about how dynamic bindings work in terms of a stack. It's helped me really understand the concept in concrete terms.

like image 31
Chris Jester-Young Avatar answered Oct 31 '22 16:10

Chris Jester-Young