Common Lisp Binding in Loop Macro
Asked Answered
B

1

10

I want to rebind a special variable inside of a loop. Now, normally, this is accomplished using a let.

(let ((*read-eval* nil))
  (do-something-here))

But since the loop macro has these nice with clauses, I thought I might be able to do so in there. The expression (macroexpand '(loop with *read-eval* = nil)) ends up expanding the binding to a let, so it will definitely work on my implementation specifically. But I can't find anything in the standard indicating that this is standardized behavior. So, I suppose, my question is this:

(loop with *read-eval* = nil
      for i from 1 to 10
      do (something-involving-the-read-function))

Are conforming implementations required to modify the existing *read-eval* variable, or is there a risk that they might create a new lexical variable of the same name?

Biestings answered 30/10, 2015 at 2:22 Comment(0)
R
8

*read-eval* is a global special variable. There is no way to undo that, i.e., create a local lexical binding for it.

with clause is described as using bindings (as opposed to mere setting) which means that, indeed, once the loop is done, we'll be back to the original value (to answer @joshua-tailor's question).

Let us think rationally. (loop with foo = nil ...) definitely does establish a binding for foo. So, for (loop with *read-eval* = nil ...) not to establish that binding, the implementation has to check (at macroexpansion or compile time) whether *read-eval* will be a dynamic variable at run time. This sounds insane.

Rawdin answered 30/10, 2015 at 2:50 Comment(1)
This is true, but it's still not clear that loop has to rebind, as opposed to just assigning. Do we know that once the loop is done, we'll be back to the original value? I'm pretty sure the answer is yes, based on lispworks.com/documentation/HyperSpec/Body/06_abb.htm, which says that the variables cease to exist outside the loop. The phrasing doesn't work particularly well for special variables, but it looks like the only reasonable interpretations are a local binding of the name, which would mean let (or lambda, etc.).Clarendon

© 2022 - 2024 — McMap. All rights reserved.