Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Does re-assigning a non-function to be a function with set! create a new frame?

The following code is confusing me:

(define (even-or-odd-letrec x)
  ((lambda (internal-even? internal-odd?)
     (set! internal-even? (lambda (n)
                (if (= n 0) 'even
                    (internal-odd? (- n 1)))))
     (set! internal-odd? (lambda (n)
               (if (= n 0) 'odd
                   (internal-even? (- n 1)))))
     (internal-even? x))
   #f #f))

As I read it, the environments are as follows:

  1. Inside the environment of even-or-odd-letrec, internal-even? and internal-odd? are initially bound to #f. Their parent environment is the global environment.
  2. set! then changes these two values to the obvious lambdas, but does not change the environments.
  3. Because the environments haven’t changed, any calls to internal-even? will look in the global environment for internal-odd? and find nothing.

So how does this code work?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Answering the title of your question: no, setting does not create any new frames.

Setting sets the value of a binding in the current environment frame. Whatever the old and new values might be. Function or no, makes no difference.

Again, set! does not change values. It changes bindings’ values. A binding is a pairing of a name and its value. Set!ting changes that name’s bound value.

Seen as a named pointer, after being re-set!, a name points to a new value — that value which was supplied to set! as the second argument.

So contrary to what you say, set! does change the current environment frame — it mutates its binding for the given name that is sets.

  +---------------+                  +---------------+
  |  n1 ---> v1   |                  |  n1 ---> x    |
  |  n2 ---> v2   |   (set! n1 x)    |  n2 ---> v2   | 
  |---------------|  ------------->  |---------------| 
  |  ..code...    |                  |  ..code...    |
  |_______________|                  |_______________|

"Any call to internal-even? will" ….. stop! this isn’t the right way to look at it.

Any reference to internal-even? inside the lambda-created frame will be resolved by looking up the value under the name internal-even? in that same frame, and all will work out fine.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading