Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Common Lisp Binding in Loop Macro

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?

like image 466
Silvio Mayolo Avatar asked Oct 30 '15 02:10

Silvio Mayolo


People also ask

How do you stop a loop in a Lisp?

Use loop-finish to provide a normal exit from a nested condition inside a loop. You can use loop-finish inside nested Lisp code to provide a normal exit from a loop.

Does Lisp have for loops?

The loop for construct in common LISP is used to iterate over an iterable, similar to the for loop in other programming languages. It can ber used for the following: This is used to set up variables for iteration. It can be used for conditionally terminate the iteration.

How do I iterate over a list in Lisp?

To iterate over a list, 2 items at a time we use a combination of on , by and destructuring. We use on to loop over the rest (the cdr ) of the list.


1 Answers

*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.

like image 139
sds Avatar answered Oct 05 '22 17:10

sds