From: Vassil Nikolov
Subject: &AUX---caveat emptor
Date: 
Message-ID: <l03130300b3d257f88fb5@195.138.129.100>
I used to like &AUX (in spite of all recommendations against it),
but now I saw the light and I repent.

Consider this simplified example:

  (defun integer-interval-p (x low high
                             &aux (type `(integer ,low ,high)))
    (check-type low integer)
    (check-type high integer)
    (typep x type))

and the call

  (integer-interval-p 10 'foo 20)

where the user continues from the error signalled by the
first CHECK-TYPE by supplying e.g. 0.

I hope no one makes the same mistake.


Vassil Nikolov
Permanent forwarding e-mail: ········@poboxes.com
For more: http://www.poboxes.com/vnikolov
  Abaci lignei --- programmatici ferrei.





 Sent via Deja.com http://www.deja.com/
 Share what you know. Learn what you don't.

From: Kent M Pitman
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <sfwr9leduld.fsf@world.std.com>
Vassil Nikolov <········@poboxes.com> writes:

> I used to like &AUX (in spite of all recommendations against it),
> but now I saw the light and I repent.
> 
> Consider this simplified example:
> 
>   (defun integer-interval-p (x low high
>                              &aux (type `(integer ,low ,high)))
>     (check-type low integer)
>     (check-type high integer)
>     (typep x type))
> 
> and the call
> 
>   (integer-interval-p 10 'foo 20)
> 
> where the user continues from the error signalled by the
> first CHECK-TYPE by supplying e.g. 0.
> 
> I hope no one makes the same mistake.

Right, some of us would make this mistake instead:

 (defun integer-interval-p (x low high)
   (let ((type `(integer ,low ,high)))
     (check-type low integer)
     (check-type high integer)
     (typep x type)))

Heh...

My point is only that &aux is not the uniquely determined villain
here.  I don't like &aux but for a completely different reason: it's
not part of the function's argument signature and just doesn't belong
there.

You're probably right that &AUX accidentally invites this particular
bug but only because common style with check-type is to put it right
inside the binding of the variable it's checking.  For almost any
other computation, you probably would have put the LET around all the
forms in the body--or I would have--rather than just around the TYPEP
(as I assume you meant me to do).
From: Vassil Nikolov
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <l03130300b3d399f1db39@195.138.129.77>
Kent M Pitman wrote:                [1999-08-08 17:56 +0000]

  [...]
  > >   (defun integer-interval-p (x low high
  > >                              &aux (type `(integer ,low ,high)))
  > >     (check-type low integer)
  > >     (check-type high integer)
  > >     (typep x type))
  [...]
  > 
  > Right, some of us would make this mistake instead:
  > 
  >  (defun integer-interval-p (x low high)
  >    (let ((type `(integer ,low ,high)))
  >      (check-type low integer)
  >      (check-type high integer)
  >      (typep x type)))

It appears to me, though, that this mistake is less likely as it
is more apparent that the checks do not occur at `top level
within the function body.'

  [...]
  > I don't like &aux but for a completely different reason: it's
  > not part of the function's argument signature and just doesn't belong
  > there.

Now that &AUX is in the language, it could at best be deprecated, but
now I am wondering how it did get there in the first place.  (Not that
this is very important to know, but if there was a definite need for
it, it is far from obvious, and it seems more like some sort of second
system effect or something like that.)

  > You're probably right that &AUX accidentally invites this particular
  > bug but only because common style with check-type is to put it right

I am quite sure I wouldn't have stumbled on that bug if I hadn't
used &AUX.  But that was a win in a way as it opened my eyes.

  > inside the binding of the variable it's checking.  For almost any
  > other computation, you probably would have put the LET around all the
  > forms in the body--or I would have--rather than just around the TYPEP
  > (as I assume you meant me to do).

Yes, I meant that the right way was

  (defun integer-interval-p (x low high)
    (check-type low integer)
    (check-type high integer)
    (let ((type `(integer ,low ,high)))
      (typep x type)))

This exercise has also led me to think that it might be nice to give
validity checks a more prominent place, syntactically, in a function
definition (similarly to the way declarations and doc-strings are
given a dedicated syntactic role).


Vassil Nikolov
Permanent forwarding e-mail: ········@poboxes.com
For more: http://www.poboxes.com/vnikolov
  Abaci lignei --- programmatici ferrei.





 Sent via Deja.com http://www.deja.com/
 Share what you know. Learn what you don't.
From: Barry Margolin
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <SWBr3.100$34.5017@burlma1-snr2>
In article <·····················@195.138.129.77>,
Vassil Nikolov  <········@poboxes.com> wrote:
>Now that &AUX is in the language, it could at best be deprecated, but
>now I am wondering how it did get there in the first place.

When the &-keywords were added to Maclisp's DEFUN, LET was also pretty new.
At that time, the common way to create a bunch of local variables for a
function was to enclose the body in a PROG.  This was considered a waste of
PROG (which has other semantic effects -- it creates a RETURNable block and
allows GO tags) and a waste of an indentation level.  &AUX was created as a
simple convenience.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Kent M Pitman
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <sfwzp004unm.fsf@world.std.com>
Barry Margolin <······@bbnplanet.com> writes:

> In article <·····················@195.138.129.77>,
> Vassil Nikolov  <········@poboxes.com> wrote:
> >Now that &AUX is in the language, it could at best be deprecated, but
> >now I am wondering how it did get there in the first place.
> 
> When the &-keywords were added to Maclisp's DEFUN, LET was also pretty new.
> At that time, the common way to create a bunch of local variables for a
> function was to enclose the body in a PROG.  This was considered a waste of
> PROG (which has other semantic effects -- it creates a RETURNable block and
> allows GO tags) and a waste of an indentation level.  &AUX was created as a
> simple convenience.

And, as I recall, the extra LET* (it surprises a lot of people it's
not a LET) was thought a waste of screen real estate.  Many of us were
using 24x80 vt52 screens, and the extra line of vertical space
mattered as much to some people as the indentation Barry mentions.
From: Vassil Nikolov
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <l03130300b3d508775ca5@195.138.129.104>
Kent M Pitman wrote:                [1999-08-09 19:32 +0000]

  > Barry Margolin <······@bbnplanet.com> writes:
  [why &AUX]
  > > a waste of an indentation level.
  [...]
  > a waste of screen real estate.  Many of us were
  > using 24x80 vt52 screens, and the extra line of vertical space
  > mattered as much to some people as the indentation Barry mentions.

I think that even in the age of huge displays &AUX still prevents
waste of `cognitive real estate,' by making code simpler, but one
*must be careful*.

(Stylistic issues aside, i.e. whether &AUX belongs to the lambda list
at all.)


Vassil Nikolov
Permanent forwarding e-mail: ········@poboxes.com
For more: http://www.poboxes.com/vnikolov
  Abaci lignei --- programmatici ferrei.





 Sent via Deja.com http://www.deja.com/
 Share what you know. Learn what you don't.
From: Vassil Nikolov
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <l03130303b3d5d1ae92ca@195.138.129.87>
Erik Naggum wrote:                [1999-08-10 09:00 +0000]

  > * Vassil Nikolov <········@poboxes.com>
  > | I think that even in the age of huge displays &AUX still prevents waste
  > | of `cognitive real estate,' by making code simpler, but one *must be
  > | careful*.
  > 
  >   I don't understand why one must be more careful about it than any other
  >   reference-assignment-reference sequence, as in silly stuff like this:
  > 
  > (let ((vars (list a b c)))
  >   (setq a 3)
  >   (apply #'+ vars))

It just appears to me that the mistake in the example above is a little
more apparent than in the &AUX case, but I don't have an objective way
of measuring apparentness.

  >   it appears to me that the lesson you have learned is much too specific:
  >   it isn't &AUX that you need to look out for, it's assignments to
  >   variables whose values have previously been used elsewhere not affected
  >   by the assignments and the "surprise" that those places retain the old
  >   values.  this is a broad category of errors, however, and looking out for
  >   &AUX may have the very undesirable effect that you think the problem is
  >   localized and contained when it isn't.

Yes, you are right that it is more general than &AUX itself.  But still I
believe &AUX is particularly inducive of that error.

  > 
  > #:Erik
  > -- 
  >   (defun pringles (chips)
  >     (loop (pop chips)))

By the way, what is `pringles'?


Vassil Nikolov
Permanent forwarding e-mail: ········@poboxes.com
For more: http://www.poboxes.com/vnikolov
  Abaci lignei --- programmatici ferrei.





 Sent via Deja.com http://www.deja.com/
 Share what you know. Learn what you don't.
From: John M. Miller
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <7opv5r$r60$1@nnrp1.deja.com>
In article <·····················@195.138.129.87>,
  Vassil Nikolov <········@poboxes.com> wrote:
> Erik Naggum wrote:                [1999-08-10 09:00 +0000]
>
>   >
>   > #:Erik
>   > --
>   >   (defun pringles (chips)
>   >     (loop (pop chips)))
>
> By the way, what is `pringles'?
>

A particularly dangerous form of junk food (mostly due to its addictive
nature, succintly stated in the Pringles' marketing moniker: "Once you
pop, you can't stop," though I much prefer Erik's way of stating it)
popular in the US (I can't speak for their
popularity outside the US).  I find them quite tasty myself; along with
pizza and highly caffeinated pop it represents the base nutritional
needs for many of us within the "nerd" subculture.

Cheers,

John Miller

> Vassil Nikolov
> Permanent forwarding e-mail: ········@poboxes.com
> For more: http://www.poboxes.com/vnikolov
>   Abaci lignei --- programmatici ferrei.
>
>  Sent via Deja.com http://www.deja.com/
>  Share what you know. Learn what you don't.
>


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
From: Kent M Pitman
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <sfwiu6npfv5.fsf@world.std.com>
Vassil Nikolov <········@poboxes.com> writes:

> It just appears to me that the mistake in the example above is a little
> more apparent than in the &AUX case, but I don't have an objective way
> of measuring apparentness.

I think if you investigated this closely, you'd find that your "understanding"
of programming is not always what you drive off of when doing the action of
"doing" programming.  That is, there are "practice effects" (in the Newell
and Simon sense) which allow you to construct programs without thinking about
all the details of the semantics of the language once you're used to it.
And one of the "practice effects" is to have a compiled rule that says
"if i have a CHECK-TYPE it should be the first executable thing in the body".
And this is a modularity clash with variables introduced ahead of that.

I'm reminded of a story, I think from risks, about how someone designed into
a plane a feature whereby if you pulled back on the stick (or whatever
changes your vertical attitude) too fast, it would resist letting you
subject yourself to large G-forces that might kill you.  Apparently there
was a problem when this was deployed--I'm not sure whether it was discovered
in action or just in a test--where if you're flying toward a mountain and
try to pull up, the plane resists keeping you from hitting the mountain for
fear the G-forces of pulling out of the way will kill you.  Modular design
is not *always* your friend.

[Off topic from here]

>   > #:Erik
>   > -- 
>   >   (defun pringles (chips)
>   >     (loop (pop chips)))
> 
> By the way, what is `pringles'?
 
It's a kind of very tasty artificially generated potato chip (poured from
stuff and formed into a perfect and quite tasty chip--oh, sorry, they call
them "crisps" in Europe, I guess).  They come in a pop-top can and a very
neat little compact cylindrical stack, and the slogan in the US (which is
precisely correct) is "once you start to pop, you just can't stop" or some
slight variant of that.  Erik's little slogan there captures it exactly
in any case.  Quite funny.
From: Vassil Nikolov
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <l03130300b3d6d74725e3@195.138.129.96>
Kent M Pitman wrote:                [1999-08-10 19:58 +0000]

  > Vassil Nikolov <········@poboxes.com> writes:
  > 
  > > It just appears to me that the mistake in the example above is a little
  > > more apparent than in the &AUX case, but I don't have an objective way
  > > of measuring apparentness.
  > 
  > I think if you investigated this closely, you'd find that your "understanding"
  > of programming is not always what you drive off of when doing the action of
  > "doing" programming.  That is, there are "practice effects" (in the Newell
  > and Simon sense) which allow you to construct programs without thinking about
  > all the details of the semantics of the language once you're used to it.
  > And one of the "practice effects" is to have a compiled rule that says
  > "if i have a CHECK-TYPE it should be the first executable thing in the body".
  > And this is a modularity clash with variables introduced ahead of that.

Just one thing: I am not sure I understand correctly what `modularity clash'
means.  Is it a conflict between two different principles of modularity,
or a conflict between modularity and another necessity?

  [...]

Thanks for explaining Pringles.


Vassil Nikolov
Permanent forwarding e-mail: ········@poboxes.com
For more: http://www.poboxes.com/vnikolov
  Abaci lignei --- programmatici ferrei.





 Sent via Deja.com http://www.deja.com/
 Share what you know. Learn what you don't.
From: Kent M Pitman
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <sfwlnbid7w6.fsf@world.std.com>
Vassil Nikolov <···@einet.bg> writes:

>   > And this is a modularity clash with variables introduced ahead of that.
> 
> Just one thing: I am not sure I understand correctly what `modularity clash'
> means.  Is it a conflict between two different principles of modularity,
> or a conflict between modularity and another necessity?

I don't know if it's a general-purpose term.  But I meant it to mean
the problem that results from the fact that modularity is about having
only a well-understood and relatively loose coupling between to items
developed and tested in parallel.  Sometimes, you find that although
this is convenient, you basically have sacrificed intimate understanding
between modules for a cleaner interface.  When  the intimate understanding
isn't being relied on for something critical, this can be good. 
When the lack of intimate understanding means the modular units 
communicate in a way that pessimizes their paired outcome, that's what
I mean by a modularity clash.
From: Vassil Nikolov
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <l03130300b3d738fe1a2d@195.138.129.80>
Kent M Pitman wrote:                [1999-08-11 08:43 +0000]

  > [I asked what a modularity clash was.]
  [the explanation]
  > When the lack of intimate understanding means the modular units 
  > communicate in a way that pessimizes their paired outcome, that's what
  > I mean by a modularity clash.

I see, thanks.  So a modularity clash is when the desire to obtain better
results clashes with the avoidance of violations of modularity.


Vassil Nikolov
Permanent forwarding e-mail: ········@poboxes.com
For more: http://www.poboxes.com/vnikolov
  Abaci lignei --- programmatici ferrei.





 Sent via Deja.com http://www.deja.com/
 Share what you know. Learn what you don't.
From: Kent M Pitman
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <sfwk8r2f57u.fsf@world.std.com>
Vassil Nikolov <···@einet.bg> writes:

> Kent M Pitman wrote:                [1999-08-11 08:43 +0000]
> 
>   > [I asked what a modularity clash was.]
>   [the explanation]
>   > When the lack of intimate understanding means the modular units 
>   > communicate in a way that pessimizes their paired outcome, that's what
>   > I mean by a modularity clash.
> 
> I see, thanks.  So a modularity clash is when the desire to obtain better
> results clashes with the avoidance of violations of modularity.

Yes.

Or, put anothe way, it's when the way in which you have modularly
cleaved the problem was ill-chosen.  Often there is more than one way
to divide a problem, and there can be better and worse divisions.  In
the study of "virtue ethics" (per Aristotle), one is in the constant
struggle to find happy means between harsh extremes.  Modularity, one
might claims, is the virtuous mean between the chaos of complete
openness and the uncooperativeness of no openness.  But each end of
that provides an advantage the other lacks--with a fully open system,
you can see all sorts of things that might be useful.  With a closed
system, you can more easily debug your part without worrying about
another's.  To someone building componentware, they want both of
these, and they trade a bit of each to get the other.  Sometimes,
though, the trading away of openness is a bad trade, just as sometimes
the trading away of closedness is a bad one.

I found the following link very fun reading and I recommend it to anyone
not familiar with this treatment of ethics.
 http://people.delphi.com/gkemerling/hy/2s.htm

-----
Oh, and apropos of nothing in particular (other than that it was right
next to the above bookmark when I went to look it up), I also
recommend the following reference about H.P. Grice on the topic of
linguistic interpretation of truth and meaning.  Don't know when I
would have occasion to otherwise recommend reading about Grice's
stuff, but I've been greatly influenced by some papers I've read by
him (most notably one on the rules of conversational implicature).  I
think it's well worth others checking out at least this reference if
they don't know his work and are just looking for fun things to read:
 http://mh.cla.umn.edu/grice.html
From: Erik Naggum
Subject: Re: &AUX---caveat emptor
Date: 
Message-ID: <3143264449599564@naggum.no>
* Vassil Nikolov <········@poboxes.com>
| I think that even in the age of huge displays &AUX still prevents waste
| of `cognitive real estate,' by making code simpler, but one *must be
| careful*.

  I don't understand why one must be more careful about it than any other
  reference-assignment-reference sequence, as in silly stuff like this:

(let ((vars (list a b c)))
  (setq a 3)
  (apply #'+ vars))

  it appears to me that the lesson you have learned is much too specific:
  it isn't &AUX that you need to look out for, it's assignments to
  variables whose values have previously been used elsewhere not affected
  by the assignments and the "surprise" that those places retain the old
  values.  this is a broad category of errors, however, and looking out for
  &AUX may have the very undesirable effect that you think the problem is
  localized and contained when it isn't.

#:Erik
-- 
  (defun pringles (chips)
    (loop (pop chips)))