Given: (defun pr() (declare(special *x*)) (print *x*))
(loop for *x* in '(1 2) do (pr))
-> Error: unbound variable `*X*'
(let((*x*'x1))(declare(special *x*))
(loop for *x* in '(1 2) do (pr)))
-> x1 x1 nil
(locally(proclaim'(special *x*))
(loop for *x* in '(1 2) do (pr)))
-> 1 2 nil <- What I want
However, now
(loop for *x* in '(1 2) do (pr))
-> 1 2 nil
shows, that the variable *x* is globally special, because
proclaim has a global effect.
May be I'd need to undo the proclamation after the loop
expression but I don't know how and whether there is
a better way to define dynamic loop variables.
Thanks in advance
Marc Dzaebel
In article <·················@rose.de>, Marc Dzaebel <····@rose.de> wrote:
>(locally(proclaim'(special *x*))
> (loop for *x* in '(1 2) do (pr)))
>
>-> 1 2 nil <- What I want
You normally use a DECLARE inside a LOCALLY, not a PROCLAIM. PROCLAIM and
DECLAIM are intended to be persistent declarations.
--
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
In article <·····················@burlma1-snr1.gtei.net>,
Barry Margolin <······@bbnplanet.com> wrote:
>In article <·················@rose.de>, Marc Dzaebel <····@rose.de> wrote:
>>(locally(proclaim'(special *x*))
>> (loop for *x* in '(1 2) do (pr)))
>>
>>-> 1 2 nil <- What I want
>
>You normally use a DECLARE inside a LOCALLY, not a PROCLAIM. PROCLAIM and
>DECLAIM are intended to be persistent declarations.
That doesn't seem to "solve" the problem. The LOOP variables are created
in a new lexical scoop. Unless LOCALLY penetrates all the nested
lexical scopes it encloses, you'll end up with *x* undefined.
[ some quick experimentation seems to back this up. ]
The following seems like a better approach (but perhaps I have my
functional paradigm hat screwed on too tight). :-)
(map nil #'(lambda (*x*) (declare (special *x*)) (pr)) '( 1 2 ))
If you want to stick with explicit iteration constructs then the
following works.
(dolist ( *x* '( 1 2 ))
(declare (special *x*))
(pr))
or the more complicated....
(let ( *x* )
(declare (special *x* ))
(loop for x in '( 1 2 )
do (progn
(setq *x* x )
(pr))))
or if you don't like LOOP.
(let ( *x* )
(declare (special *x* ))
(do ( (lst '(1 2) (rest lst)) )
((null lst))
(setq *x* (first lst ))
(pr)))
You can stuff the above two into a macro to hide the
mechaninics so it is "neat" like the non working loop version.
Something like:
(sequentially-set *x* with '( 1 2 )
do (pr))
I'm not sure it is a "bad thing" that loop can't be used to sequentially
set psuedo global variables to different values. It seems better, IHMO,
to eplicitly do that.
--
Lyman S. Taylor "Any sufficiently advanced technology is
(·····@cc.gatech.edu) indistinguishable from a rigged demo. "
-- paraphrased Arthur C. Clarke
seen somewhere on the USENET
Lyman S. Taylor wrote:
> (let ( *x* )
> (declare (special *x* ))
> (loop for x in '( 1 2 )
> do (progn
> (setq *x* x )
> (pr))))
Hi Lyman,
Thanks a lot for your answer!
This is probably the only workaround even if it looks
very ugly and is inefficient. (+ duplicated names)
> (sequentially-set *x* with '( 1 2 ) do (pr))
I don't use loop if I can avoid it. However complex
assigments are sometimes more readable with loop.
So this solution doesn't help to change loop behavior.
>I'm not sure it is a "bad thing" that loop can't be used to sequentially
>set psuedo global variables to different values. It seems better, IHMO,
>to eplicitly do that.
I completely agree. However, I had to fix some code
which I probably need to rewrite according to your proposal.
Yours, Marc