2015-10-30 21 views
10

Desidero riassociare una variabile speciale all'interno di un ciclo. Ora, normalmente, questo è realizzato utilizzando un let.Common Lisp Binding in Loop Macro

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

Ma dal momento che la macro loop ha queste belle with clausole, ho pensato che potrei essere in grado di farlo in là. L'espressione (macroexpand '(loop with *read-eval* = nil)) termina con l'espansione del binding su un let, quindi funzionerà in modo specifico sulla mia implementazione. Ma non riesco a trovare nulla in the standard indicando che questo è un comportamento standardizzato. Quindi, suppongo, la mia domanda è questa:

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

sono conformi implementazioni necessarie per modificare la *read-eval* variabile esistente, o c'è il rischio che si potrebbe creare una nuova variabile lessicale con lo stesso nome?

risposta

7

*read-eval* è una variabile speciale globale. Non c'è modo di annullarlo, cioè creare un binding lessicale locale per questo.

with clausola viene descritto come utilizzare bindings (al contrario di mera impostazione) il che significa che, in effetti, una volta che il ciclo è finito, saremo di nuovo al valore originale (per rispondere @ Joshua-sarto domanda).

Pensiamo razionalmente. (loop with foo = nil ...) stabilisce definitivamente un binding per foo. Quindi, per (loop with *read-eval* = nil ...)non per stabilire quell'associazione, l'implementazione deve verificare (in macroexpansion o in fase di compilazione) se *read-eval* sarà un dynamic variable in fase di esecuzione. Questo suona folle.

+2

Questo è vero, ma non è ancora chiaro che ** loop ** debba rebindare, al contrario dell'assegnazione. Sappiamo che una volta terminato il ciclo, torneremo al valore originale? Sono abbastanza sicuro che la risposta è sì, sulla base di http://www.lispworks.com/documentation/HyperSpec/Body/06_abb.htm, che dice che le variabili cessano di esistere al di fuori del ciclo. Il fraseggio non funziona particolarmente bene per variabili speciali, ma sembra che le sole interpretazioni ragionevoli siano un legame locale del nome, che significherebbe * let * (o * lambda *, ecc.). –