What’s the sequence of evaluation concerning `parameterize' and `let' in Racket?

evaluation, let, lisp, racket, scheme

Solution

This is a common problem with dynamically-scoped values in many languages (not just Racket). Here's what happens when you evaluate the code:

- The `location` parameter is defined with value `"here"`

- Enter the `let`...

- Enter `parameterize`...

- The parameter `location` is dynamically updated with the value `"with a fox"`

- The `lambda` expression is evaluated to create a closure which closes over `location`

- Return from `parameterized` block—parameter `location` reverts to its original value of `"here"`

- The resulting `lambda` is bound to `get`

- Evaluate `let` body...

- You call `(get)`, and it looks up the current value of `location`, which is `"here"`, and that's the result.

If you carefully read the documentation on parameters it explains that the parameter always takes the value of the closest update in the stack. Since your update with the value `"with a fox"` gets popped off the stack before going into the `let` body, it's no longer visible when you make the actual call to `get`. A simple fix is to copy the value from the parameter and let the closure close over the copy:

(define location (make-parameter "here"))

(let ([get (parameterize ([location "with a fox"])
             (let ([loc (location)])
                (lambda () loc)))])
  (get))

Now the `lambda` closes over `loc`, which should have the expected value.

Problem

In The Racket Guide about parameterize, there's the following piece of code: ``` (define location (make-parameter "here")) (let ([get (parameterize ([location "with a fox"]) (lambda () (location)))]) (get)) ``` The code returns `"here"`. What's the sequence of evaluating this piece of code? Thank you.

Original source