Program to check if the scoping is lexical or dynamic
Asked Answered
M

2

6

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

Madly answered 2/9, 2015 at 4:21 Comment(0)
T
7

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.

Teacher answered 2/9, 2015 at 7:39 Comment(0)
R
6

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.

Runyan answered 2/9, 2015 at 5:13 Comment(2)
I understood the programs in the link and the stack concept explained here.Thanks for the info. But when the test function is called from the second 'let',the code inside the define block is executed and the let block inside the test function should again push the value 'lexical to the stack before the lambda block is executed, right?... or what is the problem in my understanding of the execution?Madly
@SubinP The define isn't executed when you call the function, the function is already defined to be (lambda () scope).Teacher

© 2022 - 2024 — McMap. All rights reserved.