From: Justin Dubs
Subject: Implicit local variables vs macros
Date: 
Message-ID: <2e262238.0305181425.33461cc1@posting.google.com>
I was reading through Paul Graham's Arc pages again.  In particular,
this page has the passages I'm referring to:

http://www.paulgraham.com/arclessons.html

He comments that he had added implicit locals to the language.  In
other words, you can create a local variable just by assigning to it. 
He made these new variables local to the blocks in which they were
defined and then commented that this didn't work well because it
interfaced poorly with macros.  So, he gave up on implicit locals, it
seems.

A block-local variable is only visible within the block it is defined,
not within the containing blocks or within contained blocks.  This of
course works poorly with macros because they can create lexical
contours that you didn't expect via implicit progn's and the like.

So:

(let ()
  (setq a 4) ; this is a new, implicit local
  (when t
    (setq a (+ a 1))) ; which "a" is this?
  a)

This may return either 4 or 5 depending on the implementation of when.
 If when uses an implicit progn, then the inner setq would act on a
new binding for "a" rather than the original.

So, now to my question.  Why not use lexical scope for the implicit
locals?  If they were given lexical scope then they would seem to
interact with macro's as expected.  Does this have other, evil
side-effects that I can't seem to imagine?

Thanks to anyone who can clear this up for me.  It just seems that
Paul gave up on implicit local's pretty quickly...

Justin Dubs

From: Pascal Costanza
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <costanza-B63382.00520819052003@news.netcologne.de>
In article <····························@posting.google.com>,
 ······@eos.ncsu.edu (Justin Dubs) wrote:

> So, now to my question.  Why not use lexical scope for the implicit
> locals?  If they were given lexical scope then they would seem to
> interact with macro's as expected.  Does this have other, evil
> side-effects that I can't seem to imagine?

Consider this example.

(let () ; outer block
  (let () ; inner block
    (setq a 5)))

Should a be visible in the outer block or not?

If yes you would get global scope since the rule should be transitive.

If no then what about this?


(setq a 4) ; first "a"

(let () ; outer block
  (let () ; inner block
    (setq a 5))) ; second "a"

What's the value of a in this example?

If it's still 4 the first "a" would not have lexical scope. If it's 5 
you would get a very messy rule for the situations in which a name is 
visible in an outer scope. qed ;)

(This is my first take on this, so I might be overlooking something.)

Pascal
From: Matthew Danish
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <20030518205251.B11522@mapcar.org>
On Mon, May 19, 2003 at 12:52:08AM +0200, Pascal Costanza wrote:
> (setq a 4) ; first "a"
> 
> (let () ; outer block
>   (let () ; inner block
>     (setq a 5))) ; second "a"
> 
> What's the value of a in this example?

5

> If it's still 4 the first "a" would not have lexical scope. If it's 5 
> you would get a very messy rule for the situations in which a name is 
> visible in an outer scope. qed ;)

I don't see how it's complicated, or at least, that example doesn't show it.

Paul Graham uses DO as his PROGN replacement, and it had also been the
lexical-contour limiter for these local variables.

(do                      
  (do
    (setq a 0)         ----
    (do                   |- first a's lexical scope
      ...))            ----
  (setq a 1)           ----
  (do                     |
    (do                   |- second a's lexical scope
      (setq a 2)))        |
  a)                   ----

Naturally, you can't shadow lexical variables with the SETQ operator like this.
You would still need LET for that.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Matthew Danish
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <20030518211905.C11522@mapcar.org>
On Sun, May 18, 2003 at 08:52:51PM -0400, Matthew Danish wrote:
> On Mon, May 19, 2003 at 12:52:08AM +0200, Pascal Costanza wrote:
> > (setq a 4) ; first "a"
> > 
> > (let () ; outer block
> >   (let () ; inner block
> >     (setq a 5))) ; second "a"
> > 
> > What's the value of a in this example?
> 
> 5
> 
> > If it's still 4 the first "a" would not have lexical scope. If it's 5 
> > you would get a very messy rule for the situations in which a name is 
> > visible in an outer scope. qed ;)
> 
> I don't see how it's complicated, or at least, that example doesn't show it.
> 
> Paul Graham uses DO as his PROGN replacement, and it had also been the
> lexical-contour limiter for these local variables.
> 
> (do                      
>   (do
>     (setq a 0)         ----
>     (do                   |- first a's lexical scope
>       ...))            ----
>   (setq a 1)           ----
>   (do                     |
>     (do                   |- second a's lexical scope
>       (setq a 2)))        |
>   a)                   ----
> 
> Naturally, you can't shadow lexical variables with the SETQ operator like this.
> You would still need LET for that.

And now that I have finished with some pressing business, here is the twist to
this rule:

Let's say there is a function

(defun frob ()
  ;; implicit DO
  (setq a nil)
  do something with a...)

defined somewhere, and one day a user is working away at a piece of data which
he stores in a variable called A

* (setq a (compute-my-data))

Then the user compiles/loads and calls the function FROB, for whatever reason,
and discovers that

* a
NIL

That would be a problem, I think.  Admittedly, one that packages alleviate to
some extent.  And (defvar a) would be a problem too.

Python 2.2, incidentally, uses the model that assignment in an enclosing
lexical-block shadows the outer binding.  It is this model I believe Arc was
using, since this would certainly cause a lot of problems with macros.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Justin Dubs
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <2e262238.0305182052.1fd2c88f@posting.google.com>
Matthew Danish <·······@andrew.cmu.edu> wrote in message news:<·····················@mapcar.org>...
> On Sun, May 18, 2003 at 08:52:51PM -0400, Matthew Danish wrote:
> > On Mon, May 19, 2003 at 12:52:08AM +0200, Pascal Costanza wrote:
> > > (setq a 4) ; first "a"
> > > 
> > > (let () ; outer block
> > >   (let () ; inner block
> > >     (setq a 5))) ; second "a"
> > > 
> > > What's the value of a in this example?
> > 
> > 5
> > 
> > > If it's still 4 the first "a" would not have lexical scope. If it's 5 
> > > you would get a very messy rule for the situations in which a name is 
> > > visible in an outer scope. qed ;)
> > 
> > I don't see how it's complicated, or at least, that example doesn't show it.
> > 
> > Paul Graham uses DO as his PROGN replacement, and it had also been the
> > lexical-contour limiter for these local variables.
> > 
> > (do                      
> >   (do
> >     (setq a 0)         ----
> >     (do                   |- first a's lexical scope
> >       ...))            ----
> >   (setq a 1)           ----
> >   (do                     |
> >     (do                   |- second a's lexical scope
> >       (setq a 2)))        |
> >   a)                   ----
> > 
> > Naturally, you can't shadow lexical variables with the SETQ operator like this.
> > You would still need LET for that.
> 
> And now that I have finished with some pressing business, here is the twist to
> this rule:
> 
> Let's say there is a function
> 
> (defun frob ()
>   ;; implicit DO
>   (setq a nil)
>   do something with a...)
> 
> defined somewhere, and one day a user is working away at a piece of data which
> he stores in a variable called A
> 
> * (setq a (compute-my-data))
> 
> Then the user compiles/loads and calls the function FROB, for whatever reason,
> and discovers that
> 
> * a
> NIL
> 
> That would be a problem, I think.  Admittedly, one that packages alleviate to
> some extent.  And (defvar a) would be a problem too.
> 
> Python 2.2, incidentally, uses the model that assignment in an enclosing
> lexical-block shadows the outer binding.  It is this model I believe Arc was
> using, since this would certainly cause a lot of problems with macros.

Hah.  Yes.  Very good.  It all makes sense now.  Thanks a lot for the help.

Justin Dubs
From: Simon Andr�s
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <vcd1xyvkcqs.fsf@tarski.math.bme.hu>
······@eos.ncsu.edu (Justin Dubs) writes:

> So, now to my question.  Why not use lexical scope for the implicit
> locals?  If they were given lexical scope then they would seem to
> interact with macro's as expected.  Does this have other, evil
> side-effects that I can't seem to imagine?

Perhaps it's just that if it has lexical scope, you can't shadow an
implicit local with another one. 

Andras
From: Tim Bradshaw
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <ey3brxzm4w8.fsf@cley.com>
* Justin Dubs wrote:

> Thanks to anyone who can clear this up for me.  It just seems that
> Paul gave up on implicit local's pretty quickly...

The fact that he considered them is kind of worrying, since it renders
code like:

(let ((state-variable 3))
  ...
  (setf state-vairable 4)
  ...
  state-viarable)

legal.  Who would want this?

--tim
From: Pascal Costanza
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <baaqpn$vra$1@f1node01.rhrz.uni-bonn.de>
Tim Bradshaw wrote:
> * Justin Dubs wrote:
> 
>>Thanks to anyone who can clear this up for me.  It just seems that
>>Paul gave up on implicit local's pretty quickly...
> 
> The fact that he considered them is kind of worrying, since it renders
> code like:
> 
> (let ((state-variable 3))
>   ...
>   (setf state-vairable 4)
>   ...
>   state-viarable)
> 
> legal.  Who would want this?

He thinks along the division of languages for the masses (LFM) and 
languages for smart people (LFSP). The conjecture was that, very much 
like enforced static type checking, the requirement to define a variable 
before using it is a restriction that has its origins in the 
underestimation of hackers' abilities.

I think it's an interesting idea to try to design a language along these 
lines. [1]


Pascal


[1] As always, "interesting" doesn't necessarily mean "useful". ;)

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Tim Bradshaw
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <ey3ptmesuj1.fsf@cley.com>
* Pascal Costanza wrote:

> He thinks along the division of languages for the masses (LFM) and
> languages for smart people (LFSP). The conjecture was that, very much
> like enforced static type checking, the requirement to define a
> variable before using it is a restriction that has its origins in the
> underestimation of hackers' abilities.

Curiously enough, most of the LFMs out there have precisely this kind
of implicit-variable-binding-by-assignment thing (Unix shells, perl,
basic, blah)

--tim
From: Kalle Olavi Niemitalo
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <873cj42ima.fsf@Astalo.kon.iki.fi>
Tim Bradshaw <···@cley.com> writes:

> Curiously enough, most of the LFMs out there have precisely this kind
> of implicit-variable-binding-by-assignment thing (Unix shells, perl,
> basic, blah)

Does any of them restrict the scope of the implicit binding to
the block where the variable was assigned?
From: Nikodemus Siivola
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <baonsm$5joca$1@midnight.cs.hut.fi>
Kalle Olavi Niemitalo <···@iki.fi> wrote:

> Does any of them restrict the scope of the implicit binding to
> the block where the variable was assigned?

Yes, depending on the environment. For example:

Ruby

 If the variable assigned to exist in the *next* surrounding lexical
 environment it is assigned to. Otherwise a new local varible is created.

Shell

 If the varible assigned to exists in *some* surrounding
 dynamic environment, it is assigned to. Otherwise a new local variable is
 created.

Hm. I hope I got that right.

Cheers,

  -- Nikodemus
From: Andreas Eder
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <m365o63m6c.fsf@elgin.eder.de>
Pascal Costanza <········@web.de> writes:

> He thinks along the division of languages for the masses (LFM) and
> languages for smart people (LFSP).

Shouldn't that be 'languages intended for smart people (LISP)'?

Andreas
-- 
Wherever I lay my .emacs, there�s my $HOME.
From: Pascal Costanza
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <bab48b$o5q$1@f1node01.rhrz.uni-bonn.de>
Andreas Eder wrote:
> Pascal Costanza <········@web.de> writes:
> 
>>He thinks along the division of languages for the masses (LFM) and
>>languages for smart people (LFSP).
> 
> Shouldn't that be 'languages intended for smart people (LISP)'?

:)

That's nice! This should be included in some list of what LISP means...


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Ray Blaak
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <ufznaglz4.fsf@STRIPCAPStelus.net>
Pascal Costanza <········@web.de> writes:
> Tim Bradshaw wrote:
> > The fact that he considered them [implicit locals] is kind of worrying, since it renders
> > code like:
> > 
> > (let ((state-variable 3))
> >   ...
> >   (setf state-vairable 4)
> >   ...
> >   state-viarable)
> > 
> > legal.  Who would want this?
> 
> He thinks along the division of languages for the masses (LFM) and 
> languages for smart people (LFSP). The conjecture was that, very much 
> like enforced static type checking, the requirement to define a variable 
> before using it is a restriction that has its origins in the 
> underestimation of hackers' abilities.

The problem with that idea is that being smart is not really all that
correlated with being able to type.

If typos are accepted without complaint then you *will* get bugs, hard bugs,
that are difficult to find because things *look* correct (compare
"state-variable" and "state-vairable" quickly).

Real hackers want and use powerful tools that are enabling and increase
expressivity, not those that create problems.

--
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
········@STRIPCAPStelus.net                    The Rhythm has my soul.
From: Pascal Costanza
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <bacm2e$62k$1@f1node01.rhrz.uni-bonn.de>
Ray Blaak wrote:
> Pascal Costanza <········@web.de> writes:
> 
>>Tim Bradshaw wrote:
>>
>>>The fact that he considered them [implicit locals] is kind of worrying, since it renders
>>>code like:
>>>
>>>(let ((state-variable 3))
>>>  ...
>>>  (setf state-vairable 4)
>>>  ...
>>>  state-viarable)
>>>
>>>legal.  Who would want this?
>>
>>He thinks along the division of languages for the masses (LFM) and 
>>languages for smart people (LFSP). The conjecture was that, very much 
>>like enforced static type checking, the requirement to define a variable 
>>before using it is a restriction that has its origins in the 
>>underestimation of hackers' abilities.
> 
> The problem with that idea is that being smart is not really all that
> correlated with being able to type.
> 
> If typos are accepted without complaint then you *will* get bugs, hard bugs,
> that are difficult to find because things *look* correct (compare
> "state-variable" and "state-vairable" quickly).
> 
> Real hackers want and use powerful tools that are enabling and increase
> expressivity, not those that create problems.

Sure. However, Paul Graham clearly states that he wanted to experiment 
with new ideas, so this is actually an example of experimental language 
design. Part of such a process is to question everything in order to get 
some new ideas. I like that approach. I also like the fact that he 
documents bad ideas and the reasons why he rejected them.


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Ray Blaak
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <uof1xr32e.fsf@STRIPCAPStelus.net>
Pascal Costanza <········@web.de> writes:
> Sure. However, Paul Graham clearly states that he wanted to experiment 
> with new ideas, so this is actually an example of experimental language 
> design. Part of such a process is to question everything in order to get 
> some new ideas. I like that approach. I also like the fact that he 
> documents bad ideas and the reasons why he rejected them.

Now that is a fair point. Finally some computer *science*.

-- 
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
········@STRIPCAPStelus.net                    The Rhythm has my soul.
From: Tim Bradshaw
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <ey3k7cls1lm.fsf@cley.com>
* Ray Blaak wrote:

> If typos are accepted without complaint then you *will* get bugs,
> hard bugs, that are difficult to find because things *look* correct
> (compare "state-variable" and "state-vairable" quickly).

Yes, indeed these kinds of problems are almost the most common error I
make (maybe I am not smart though - surely no one who is smart *still*
uses CL...).

--tim
From: Drew McDermott
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <bae58s$ki3$1@news.wss.yale.edu>
Justin Dubs wrote:
> I was reading through Paul Graham's Arc pages again.  In particular,
> this page has the passages I'm referring to:
> 
> http://www.paulgraham.com/arclessons.html
> 
> He comments that he had added implicit locals to the language.  In
> other words, you can create a local variable just by assigning to it. 
> He made these new variables local to the blocks in which they were
> defined and then commented that this didn't work well because it
> interfaced poorly with macros.  So, he gave up on implicit locals, it
> seems.

This proposal seems incoherent to me.  A "new" variable is presumably 
one that has no value so far.  But whether a variable has a value or not 
is a runtime issue.  It's at best undecidable and at worst unanswerable 
whether a particular execution of an assignment statement will be to a 
hitherto unassigned variable.

E.g.:

(cond ((big-hairy-computation) (setq a 'global)))

(defun foo ()
    (setq a 'local)
     ...)

It's undecidable whether 'a' is local or global when 'foo' is defined, 
and ill-formulated to enquire whether it will be local or global at 
various future times when 'foo' is called.

Obviously, I'm misunderstanding something, but I can't see what.

     -- Drew McDermott
From: Matthew Danish
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <20030521011427.F11522@mapcar.org>
On Tue, May 20, 2003 at 05:04:28PM -0400, Drew McDermott wrote:
> E.g.:
> (cond ((big-hairy-computation) (setq a 'global)))

I suppose that A here will have scope limited to its branch of the COND expression.

Then it is quite clear that A is local.  I think this is how Python does it.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Kent M Pitman
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <sfwhe7orcut.fsf@shell01.TheWorld.com>
Matthew Danish <·······@andrew.cmu.edu> writes:

> On Tue, May 20, 2003 at 05:04:28PM -0400, Drew McDermott wrote:
> > E.g.:
> > (cond ((big-hairy-computation) (setq a 'global)))
> 
> I suppose that A here will have scope limited to its branch of the
> COND expression.
> 
> Then it is quite clear that A is local.  I think this is how Python
> does it.

Surely you _can_ define a meaning to it, but not everything that is
not forbidden in life is something you should race to do.

IMO, this is just a nutty idea.  One of the big virtues of Lisp is that
you can see parens around the various places that bindings exist.
Trying to destroy this property creates a heap of problems that we 
escaped from when we originally eschewed parsed languages.  

If you say that the "scope" of a binding is the form that first mentions
it, then you get:

  (defun f (x)
    (when x (setq a 3))
    a) ;<-- this is unbound

  (defun f (x)
    (setq a 4)
    (when x (setq a 3))
    a) ;this is bound

That's not very modular or intuitive if you ask me.

There was a brief attempt to indulge this kind of (pardon my feeling
compelled to characterize it) nonsense when we introduced &aux into
bound variable lists so that 

 (defun f (x &aux a)
   (when x (setq a 3))
   a)

could work without the so-called "horror" of doing

 (defun f (x)
   (let (a)
     (when x (setq a 3))
     a))

but personally I don't recommend that _anyone_ use &aux.

This also creates questions about what happens in the case of

 (cond ((= (setq x 3) z) ...)
       ((oddp x) ...))

That is, if the x is local to the clause, is that true in the test, too?
If it is, then you are forced to write

 (setq x 3)
 (cond ((= x z) ...)
       ((oddp x) ...))

which isn't that bad to force someone to do, but is the reverse effect
in terms of being textually concise that you're trying to achieve.

And it creates weird questions like whether:

 (cond (t ...code...))

is equivalent to (progn ...code...) because if you do t his, it implies
that PROGN has the same block-like structure that COND clauses have.
If that's so, then you have to wonder if:

 (progn (setq a 3) a)

is the same as

 (progn (progn (setq a 3)) a)

-- -- --

Another case where we tried to do this a long time ago was with blocks.
People wanted to have implicit blocks here and there, but the problem
is that people writing RETURN _really_ had to know where they were
returning to and it was hard to know in the face of macro expansion.
Every single form that has a (BLOCK NIL ...) in it has to be documented
as such, and cannot be substituted for one that does not, just as in the
case you're talking about with bindings in the variable namespace.
It just wasn't worth it.

So when I say this sucks, all I can say is that "it's been tried" and
the community didn't react well to it.

You're welcome to waste a lot of public verbiage on this if you want,
but I really don't recommend it.

I've said many times, but not recently, that languages are like ecologies
and certain features work together well as part of a good ecosystem while
other features fight each other.  Goodness or badness must be viewed in
the context of a language.  I think that vague variable boundaries are
common in languages that are parsed, where people invest a lot of energy
learning all the parse rules and a bunch of idiosyncratic context 
information; I think that they don't work well in Lisp because we've gone
to a lot of trouble to make boundaries explicit that other languages don't,
and it's not good to fight that.  But that's just my opinion.

That's really all I have to say on this.
There are so many more important things to worry about.
From: Matthew Danish
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <20030521121634.G11522@mapcar.org>
On Wed, May 21, 2003 at 03:13:46AM -0400, Kent M Pitman wrote:
> That's not very modular or intuitive if you ask me.

I wasn't saying that it is.  I was merely offering an interpretation that was
not undecidable, as Drew put it.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Kalle Olavi Niemitalo
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <871xysq79i.fsf@Astalo.kon.iki.fi>
Kent M Pitman <······@world.std.com> writes:

> but personally I don't recommend that _anyone_ use &aux.

Not even in a boa lambda list?
From: Kent M Pitman
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <sfwiss3et9b.fsf@shell01.TheWorld.com>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> Kent M Pitman <······@world.std.com> writes:
> 
> > but personally I don't recommend that _anyone_ use &aux.
> 
> Not even in a boa lambda list?

Heh.  Well, I'm not big on structs either...   But yeah, they have a bit
more purpose there than perhaps in other contexts.
From: Ray Blaak
Subject: Re: Implicit local variables vs macros
Date: 
Message-ID: <uiss4rgqu.fsf@STRIPCAPStelus.net>
Drew McDermott <··················@at.yale.dot.edu> writes:
> This proposal seems incoherent to me.  A "new" variable is presumably 
> one that has no value so far.  But whether a variable has a value or not 
> is a runtime issue.  It's at best undecidable and at worst unanswerable 
> whether a particular execution of an assignment statement will be to a 
> hitherto unassigned variable.
> 
> E.g.:
> 
> (cond ((big-hairy-computation) (setq a 'global)))
> 
> (defun foo ()
>     (setq a 'local)
>      ...)
> 
> It's undecidable whether 'a' is local or global when 'foo' is defined, 

Why? Isn't it a matter of lexical scoping? In this case, a is not defined in
foo, so is necessarily global or special (right? Unless I am drastically
ignorant of some basic aspect of CL).

Now I don't know how Arc deals with globals, but the idea is that unknown vars
(presumably unknown in terms of lexical visibility) are implicitly declared in
the enclosing scope upon first usage.

Thus in this case, "a" would have a scope to the end of "foo".

Not a good idea, but that's how I understood implicit bindings to work in Arc.

--
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
········@STRIPCAPStelus.net                    The Rhythm has my soul.