Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

resonable use of internal functions

3 views
Skip to first unread message

Friedrich Dominicus

unread,
Nov 16, 1999, 3:00:00 AM11/16/99
to
On a question in an newsgroup about algorithms on asked for an
algrorithms from sin. I grabbed my old Bronstein and found a definiton
there. I tried to translate that into Common Lisp (I'm aware, that sin
is there ready for use, I just take it as an exercise for me;-)

So I come up with this implementation

(defun sine (x)
(flet ((next-factor (val n)
(+ val (* (expt -1 n)
(/ (expt x (+ (* 2 n) 1))
(fact (+ (* 2 n) 1)))))))
(labels ((inner-sine (val n)
(let ((new-val (next-factor val n)))
(if (good-enough (abs val) (abs new-val))
(float new-val)
(inner-sine new-val (1+ n))))))
(inner-sine 0 0))))

My question is about the style in which it is written and if the usage
of inner functions seems to be appropriate here.

And I have another questoin about flet and labels. And I wonder if there
is a case where I just can use flet but not labels. Just for the fun of
it (and despite what was writte in the Hyperspec), I changed the labels
before inner-sine to flet and of course then this function can't be
found. But I really don't know when I should use flet and labels. In
recursive functions the answer is clear, I just can use labels but
instead of flet I used labels and that worked quite fine. So some
comments would be very welcome

Regards
Friedrich

Robert Monfera

unread,
Nov 16, 1999, 3:00:00 AM11/16/99
to
Friedrich Dominicus wrote:

> And I wonder if there
> is a case where I just can use flet but not labels. Just for the fun of
> it (and despite what was writte in the Hyperspec), I changed the labels
> before inner-sine to flet and of course then this function can't be
> found. But I really don't know when I should use flet and labels. In
> recursive functions the answer is clear, I just can use labels but
> instead of flet I used labels and that worked quite fine. So some
> comments would be very welcome

Quite often you may achieve the same thing in CL various ways, of
various generalization. You may consider LABELS a generalization of
FLET, and use it all the time. It's the same thing with LET vs. LET* or
IF vs. WHEN. For two reasons, you may want to prefer using the more
specific of the alternatives, because your code will be clearer (looking
at FLET, you know there is no recursion - looking at LABELS, you would
not know, and many people would be quick to assume there _is_
recursion), and the same goes with your compiler (though they may figure
it out anyway).

Robert

Barry Margolin

unread,
Nov 16, 1999, 3:00:00 AM11/16/99
to
In article <38318307...@inka.de>,

Friedrich Dominicus <Friedrich...@inka.de> wrote:
>On a question in an newsgroup about algorithms on asked for an
>algrorithms from sin. I grabbed my old Bronstein and found a definiton
>there. I tried to translate that into Common Lisp (I'm aware, that sin
>is there ready for use, I just take it as an exercise for me;-)
>
>So I come up with this implementation
>
>(defun sine (x)
> (flet ((next-factor (val n)
> (+ val (* (expt -1 n)
> (/ (expt x (+ (* 2 n) 1))
> (fact (+ (* 2 n) 1)))))))
> (labels ((inner-sine (val n)
> (let ((new-val (next-factor val n)))
> (if (good-enough (abs val) (abs new-val))
> (float new-val)
> (inner-sine new-val (1+ n))))))
> (inner-sine 0 0))))
>
>My question is about the style in which it is written and if the usage
>of inner functions seems to be appropriate here.

Yes, it does. By defining the NEXT-FACTOR function, you simplify the
definition of INNER-SINE; the alternative would be to put that complex
formula in the LET. It could have been defined as a global function, but
if it's only useful for defining SINE then there's no need to add it to the
external namespace; this lets readers know that this isn't a general
purpose function, but just a name for an internal computation used for this
function.

The same thing goes for INNER-SINE. It's a helper function that's only
useful for SINE. Since nothing else can use it, it might as well be
internal.

>And I have another questoin about flet and labels. And I wonder if there


>is a case where I just can use flet but not labels. Just for the fun of
>it (and despite what was writte in the Hyperspec), I changed the labels
>before inner-sine to flet and of course then this function can't be
>found. But I really don't know when I should use flet and labels. In
>recursive functions the answer is clear, I just can use labels but
>instead of flet I used labels and that worked quite fine. So some
>comments would be very welcome

It's mostly a matter of style. By using FLET for non-recursive functions,
you let other readers of the program know your intentions better. When I
looked at the above function, I knew to scan INNER-SINE looking for the
recursion, but I could tell that NEXT-FACTOR doesn't have this complication
because it was defined with FLET. It's like the decision about whether to
use LET or LET* -- in many cases it doesn't make a difference to the
program, but LET* is used to alert readers that there are dependencies
between the variables being bound.

--
Barry Margolin, bar...@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.

Friedrich Dominicus

unread,
Nov 17, 1999, 3:00:00 AM11/17/99
to
Barry Margolin wrote:

>
> Yes, it does. By defining the NEXT-FACTOR function, you simplify the
> definition of INNER-SINE; the alternative would be to put that complex
> formula in the LET. It could have been defined as a global function, but
> if it's only useful for defining SINE then there's no need to add it to the
> external namespace; this lets readers know that this isn't a general
> purpose function, but just a name for an internal computation used for this
> function.


I thought about this remarks and played a bit around with that stuff.
The chains seem to be very simular between e.g sin, cos ...

So I came up with this:
(defun next-val (add-to nom-factor denom-factor alternating)
(+ add-to (* alternating
(/ nom-factor
denom-factor))))

of course one can argue about add-to. should it be in that function or
not. I put it here. Now sine looks like

(defun next-sine-val (val x n)
(let ((alternating (expt -1 n))
(nom-factor (expt x (+ (* 2 n) 1)))
(denom-factor (fact (+ (* 2 n) 1))))
(next-val val nom-factor denom-factor alternating)))

the thing is as easy for cos now
(defun next-cosine-val (val x n)
(let ((alternating (expt -1 n))
(nom-factor (expt x (* 2 n)))
(denom-factor (fact (* 2 n))))
(next-val val nom-factor denom-factor alternating)))

and so on. So it may be that next-val should be a global function and
that I just internalise nexe-sine-val in sine or the like. Because here
the nom-factor and denom-factor are so simular one can grasp this
commonalities and simplify again a bit. I guess playing around with this
definition sin Common Lisp will lead me to a better understanding of
Lisp programming.

And I think as simple as next-val is, it's nevertheless a useful
abstraction worth capturing in a own function.

Regards
Friedrich

Rainer Joswig

unread,
Nov 17, 1999, 3:00:00 AM11/17/99
to

> (defun next-sine-val (val x n)
> (let ((alternating (expt -1 n))
> (nom-factor (expt x (+ (* 2 n) 1)))
> (denom-factor (fact (+ (* 2 n) 1))))
> (next-val val nom-factor denom-factor alternating)))

Actually I don't think it is generally necessary to
LET-bind every expression.

(defun next-sine-val (val x n)

(next-val val


(expt x (+ (* 2 n) 1))

(fact (+ (* 2 n) 1))

(expt -1 n)))

Above would be enough for me, given that the
variable and function names are "speaking".
Remember that in Lisp you have expressions that
return values and writing additional variables
and bindings is often a waste of time and space.
Also a development environment (hopefully) has documentation
and arglist info available either instantly or on keypress.

Rainer Joswig, ISION Internet AG, Harburger Schlossstraße 1,
21079 Hamburg, Germany, Tel: +49 40 77175 226
Email: rainer...@ision.de , WWW: http://www.ision.de/

Robert Monfera

unread,
Nov 17, 1999, 3:00:00 AM11/17/99
to
Rainer Joswig wrote:

> (defun next-sine-val (val x n)

> (next-val val
> (expt x (+ (* 2 n) 1))
> (fact (+ (* 2 n) 1))
> (expt -1 n)))
>
> Above would be enough for me, given that the
> variable and function names are "speaking".

Hi Rainer,

It wouldn't tell you that the second arg to next-val is nom-factor and
the third one is denom-factor, which may not be a problem in this case,
as the formal next-val parameter list should be revealing.

What do you think about this version, however, as a way of doing the
same thing as LET, but saving on typing? I would guess it compiles the
exact same way as if it used LET instead.

(defun next-sine-val (val x n &aux (nominator (expt x (+ (* 2 n) 1)))
(denominator (fact (+ (* 2 n) 1)))
(alternating (expt -1 n)))
(next-val val nominator denominator alternating))



> Remember that in Lisp you have expressions that
> return values and writing additional variables
> and bindings is often a waste of time and space.

Sometimes I find myself doing LETs solely for documentation reasons, or
when I suspect the calculations will get more complex. It is nice to
_name_ temporary calculation results, as they may represent something
meaningful on their own, which is useful to make easily readable. Of
course it does not apply to the code quoted above, because, as you say,
the necessary information can be found in the lambda-list or
documentation of next-val.

Robert

Friedrich Dominicus

unread,
Nov 17, 1999, 3:00:00 AM11/17/99
to
Rainer Joswig wrote:

>
> In article <38325B95...@inka.de>, Friedrich...@inka.de wrote:
>
> > (defun next-sine-val (val x n)
> > (let ((alternating (expt -1 n))
> > (nom-factor (expt x (+ (* 2 n) 1)))
> > (denom-factor (fact (+ (* 2 n) 1))))
> > (next-val val nom-factor denom-factor alternating)))
>
> Actually I don't think it is generally necessary to
> LET-bind every expression.
>
> (defun next-sine-val (val x n)
> (next-val val
> (expt x (+ (* 2 n) 1))
> (fact (+ (* 2 n) 1))
> (expt -1 n)))

Of course one can write it this way but I personally think that your
solution does not give hints on what's going on. But of course that
would work fine too. And maybe the function next-val is some lines above
where it is used than it's maybe not so clear what is going on.

So I think I prefer using local-variables, but of course YMMV.

>
> Above would be enough for me, given that the
> variable and function names are "speaking".

> Remember that in Lisp you have expressions that
> return values and writing additional variables
> and bindings is often a waste of time and space.

Now, maybe but I trade normaly readability for time and space. I think
that may pay off sooner or later.

> Also a development environment (hopefully) has documentation
> and arglist info available either instantly or on keypress.

This is a good point and I've to admit documentation is completely
missing here. This should be improved. But for now it was just playing
around with figuring out common behaviar and with that simple next-val I
can buile chains of sum and the like. And I think for that reason
next-val is quite a good candidate for a function on it's own.

Regards
Friedrich

Barry Margolin

unread,
Nov 17, 1999, 3:00:00 AM11/17/99
to
In article <3832B499...@fisec.com>,

Robert Monfera <mon...@fisec.com> wrote:
>Sometimes I find myself doing LETs solely for documentation reasons, or
>when I suspect the calculations will get more complex. It is nice to
>_name_ temporary calculation results, as they may represent something
>meaningful on their own, which is useful to make easily readable. Of
>course it does not apply to the code quoted above, because, as you say,
>the necessary information can be found in the lambda-list or
>documentation of next-val.

Me too. Also, I find code easier to read when a function call fits on one
or two lines, so I don't like to have lots of calculations in every
parameter.

I think the performance implications of naming these temporary results
should be negligible, and avoiding them for efficiency reasons would be one
of the worst cases of premature optimization I can think of.

Rainer Joswig

unread,
Nov 17, 1999, 3:00:00 AM11/17/99
to

> It wouldn't tell you that the second arg to next-val is nom-factor and
> the third one is denom-factor, which may not be a problem in this case,
> as the formal next-val parameter list should be revealing.

Learn to use the tools to look up the information.
If you need documentation, write **documentation**.
Don't waste your time with writing unused code.
It also makes code manipulation (-> editing) hard if you have
a lot of bloat like that one. If I'd have to read
through lots of code that is written like the one
I responded to, I get tired very fast.

> What do you think about this version, however, as a way of doing the
> same thing as LET, but saving on typing? I would guess it compiles the
> exact same way as if it used LET instead.
>
> (defun next-sine-val (val x n &aux (nominator (expt x (+ (* 2 n) 1)))
> (denominator (fact (+ (* 2 n) 1)))
> (alternating (expt -1 n)))
> (next-val val nominator denominator alternating))
>

> > Remember that in Lisp you have expressions that
> > return values and writing additional variables
> > and bindings is often a waste of time and space.

Explanation:
Time to write your code and to manipulate it!
Space on the screen with unneccessary stuff.

> Sometimes I find myself doing LETs solely for documentation reasons, or
> when I suspect the calculations will get more complex. It is nice to
> _name_ temporary calculation results, as they may represent something
> meaningful on their own, which is useful to make easily readable.

I only do it sometimes for debugging purposes. The payback
of short and really tightly written code is not to
underestimate. Reduce the clutter in the code a
clear documented algorithm implementation is much
better than introducing "unnecessary" variables. Try
to write reusable building blocks.

Rainer Joswig

Rainer Joswig

unread,
Nov 17, 1999, 3:00:00 AM11/17/99
to

> Of course one can write it this way but I personally think that your
> solution does not give hints on what's going on.

That's what documentation is for.

> > Above would be enough for me, given that the
> > variable and function names are "speaking".

> > Remember that in Lisp you have expressions that
> > return values and writing additional variables
> > and bindings is often a waste of time and space.
>

> Now, maybe but I trade normaly readability for time and space. I think
> that may pay off sooner or later.

-> Time to write code and space on your screen.

> This is a good point and I've to admit documentation is completely
> missing here. This should be improved. But for now it was just playing
> around with figuring out common behaviar and with that simple next-val I
> can buile chains of sum and the like. And I think for that reason
> next-val is quite a good candidate for a function on it's own.

One of the most important things people are often not really
using is the interactive and self-documenting environment of many
Lisp systems. Learn to use it and try to understand why
it's there. Source code is just m-. away. Documentation
and all kinds of introspective stuff (inspect, trace, arglist,
who-calls, step, describe, breakpoints, debugger, disassemble,
compiler messages, macro expand, code walker, ...) is also
available. Your own tools are easily written.

Robert Monfera

unread,
Nov 17, 1999, 3:00:00 AM11/17/99
to
Rainer Joswig wrote:

> Source code is just m-. away.

Although I am using this, I have difficulties when going back to where I
came from. Yes, I have a key binding for the previous history element,
but that fails if
- the source code is in the same file as the one I was in
- there are nested searches, possibly touching one file more than once.

What I would need is something like the go back button in SAP, so that
the source lookup becomes a jump that is quick (cheap) to get out of.
Maybe it's available, but I haven't found it in LW. Is there something
similar for the Allegro IDE? Does it have a clean way of getting back
from arbitrarily nested lookups?

If we already talk about IDE's, I'm wondering why duplicates are
collected in history lists. When I evaluate the same thing three times,
it will be on the history list three times for no benefit. It would be
easy to do an EQUAL.

Robert

Barry Margolin

unread,
Nov 18, 1999, 3:00:00 AM11/18/99
to
In article <joswig-1711...@194.163.195.67>,

Rainer Joswig <jos...@lavielle.com> wrote:
>Learn to use the tools to look up the information.
>If you need documentation, write **documentation**.
>Don't waste your time with writing unused code.

Taken to the extreme, this would justify:

;; This function computes factorials
(defun func1 (arg)
...)
;; This function writes the printed representation of an object.
;; ARG1 is the object to print, :ARG2 is the stream to print it on,
;; :ARG3 is the radix to use for integers, ...
(defun func2 (arg1 &key (arg2 *standard-output*) (arg3 *print-radix) ...)
...)

Why do we need mnemonic function names as long as we have good
documentation?

Barry Margolin

unread,
Nov 18, 1999, 3:00:00 AM11/18/99
to
In article <joswig-1711...@194.163.195.67>,
Rainer Joswig <jos...@lavielle.com> wrote:
>Learn to use the tools to look up the information.
>If you need documentation, write **documentation**.
>Don't waste your time with writing unused code.

Self-documenting code is better than manually documented code. Manual
documentation can more easily become inconsistent with the code. Self
documentation shows up in the debugger, pretty-printing code, etc.

Friedrich Dominicus

unread,
Nov 18, 1999, 3:00:00 AM11/18/99
to
Rainer Joswig wrote:
>
> In article <3832E8EE...@inka.de>, Friedrich...@inka.de wrote:
>
> > Of course one can write it this way but I personally think that your
> > solution does not give hints on what's going on.
>
> That's what documentation is for.

Of course documentation it one way but self-documenting code is another
one. And I prefer to name a temporary calculation than the calculation
in place. And just in case docs are not available for whatever reason
the code is there.

> >
> > Now, maybe but I trade normaly readability for time and space. I think
> > that may pay off sooner or later.
>
> -> Time to write code and space on your screen.

I try to keep my functions short and in fact your code is just one line
or so shorter than mine, I think this is quite a prive worth to pay. And
to write some-variabels and a let is IMO not too time-cosuming.

But I would agree that one should spend some time learning what's there
for getting ones work done.

Regards
Friedrich

Erik Naggum

unread,
Nov 18, 1999, 3:00:00 AM11/18/99
to
[ I have reindented the quoted code according to more standard conventions. ]

* Friedrich Dominicus <Friedrich...@inka.de>


| So I came up with this:
|
| (defun next-val (add-to nom-factor denom-factor alternating)
| (+ add-to (* alternating
| (/ nom-factor
| denom-factor))))
|
| of course one can argue about add-to. should it be in that function or
| not. I put it here. Now sine looks like
|

| (defun next-sine-val (val x n)
| (let ((alternating (expt -1 n))
| (nom-factor (expt x (+ (* 2 n) 1)))
| (denom-factor (fact (+ (* 2 n) 1))))
| (next-val val nom-factor denom-factor alternating)))
|

| the thing is as easy for cos now

| (defun next-cosine-val (val x n)


| (let ((alternating (expt -1 n))

| (nom-factor (expt x (* 2 n)))
| (denom-factor (fact (* 2 n))))

| (next-val val nom-factor denom-factor alternating)))
|

| and so on. So it may be that next-val should be a global function and
| that I just internalise nexe-sine-val in sine or the like.

in this particular case, very little is gained by a global function, and
some performance opportunity may easily be lost, so for such a simple
function, I would recommend an FLET binding around the two functions that
use it. incidentally, your compiler may not do common subexpression
elimination on (+ (* 2 n) 1), and in the absence of declarations they
might be quite expensive.

| And I think as simple as next-val is, it's nevertheless a useful
| abstraction worth capturing in a own function.

that doesn't necessarily imply _global_ function. it would also make
sense to write this with a MACROLET (instead of FLET) to capture the
abstraction without the function call overhead and need to re-declare
everything. you could condense your code quite a bit with a macro:

(macrolet ((define-next-val-function (name cfse)
"Define a helper next-val function, NAME, with common factor
subexpression CFSE. NAME takes arguments VAL, X, N, which may be used by
CFSE. given C = the value of CFSE, NAME returns
n x^c
val + (-1) -------
c!"
`(defun ,name (val x n)
(declare (fixnum n)) ;ASSUMPTION!
(let* ((cfse ,expression)
(increment (/ (expt x cse) (fact cse))))
(if (evenp n)
(+ val increment)
(- val increment))))))
(define-next-val-function next-sine-val (+ (* 2 n) 1))
(define-next-val-function next-cosine-val (* 2 n)))

the use of simpler subexpressions, no extra function calls and avoiding a
call to EXPT of -1 should result in significantly tighter code, even
without declarations. this may not be your concern, of course, but I
also consider the documentation of the above to be far superior to your
use of several temporary variables. that this captures the mathematical
abstraction in one place, rather than a trivial abstraction with the
mathematical abstraction in two different places, would at least to make
make it much more readable to me. the simple reason is that I want to
avoid looking at the internals of a function once it has been written and
debugged. for that reason, I might also use FLETs instead of global
functions since these functions are used only inside your SIN and COS.
there's no point in externalizing what should not be externally used.

if the above flagged assumption is wrong, replace FIXNUM with INTEGER.

(also note that when the scope of a macro is carefully constrained, you
don't need as much "cover" as when it is used globally. the above macro
would be a bad macro if it were made globally available.)

#:Erik
--
Attention Microsoft Shoppers! MS Monopoly Money 6.0 are now worthless.

Fernando Mato Mira

unread,
Nov 18, 1999, 3:00:00 AM11/18/99
to
Robert Monfera wrote:

> What do you think about this version, however, as a way of doing the
> same thing as LET, but saving on typing? I would guess it compiles the
> exact same way as if it used LET instead.
>
> (defun next-sine-val (val x n &aux (nominator (expt x (+ (* 2 n) 1)))
> (denominator (fact (+ (* 2 n) 1)))
> (alternating (expt -1 n)))
> (next-val val nominator denominator alternating))

What I _personally_ think is "Yuck". I never liked &aux. I always thought
it was more of a legacy thing, and gives me a bad AutoLisp vibe.

Friedrich Dominicus

unread,
Nov 18, 1999, 3:00:00 AM11/18/99
to

Erik Naggum schrieb:

>
> in this particular case, very little is gained by a global function, and
> some performance opportunity may easily be lost, so for such a simple
> function, I would recommend an FLET binding around the two functions that
> use it. incidentally, your compiler may not do common subexpression
> elimination on (+ (* 2 n) 1), and in the absence of declarations they
> might be quite expensive.

That are points I would consider after I get it right and maybe there is
not much gained here. But this function can easily applied to other
chains of rationals. (e.g epxt ...)

>
> | And I think as simple as next-val is, it's nevertheless a useful
> | abstraction worth capturing in a own function.
>
> that doesn't necessarily imply _global_ function.

This is or might be true. And maybe it's even not a good decision ot
make it a global function, but it's useful and avoids some some
repetition.


it would also make
> sense to write this with a MACROLET (instead of FLET) to capture the
> abstraction without the function call overhead and need to re-declare
> everything. you could condense your code quite a bit with a macro:
>
> (macrolet ((define-next-val-function (name cfse)
> "Define a helper next-val function, NAME, with common factor
> subexpression CFSE. NAME takes arguments VAL, X, N, which may be used by
> CFSE. given C = the value of CFSE, NAME returns
> n x^c
> val + (-1) -------
> c!"
> `(defun ,name (val x n)
> (declare (fixnum n)) ;ASSUMPTION!
> (let* ((cfse ,expression)
> (increment (/ (expt x cse) (fact cse))))
> (if (evenp n)
> (+ val increment)
> (- val increment))))))

This is a bit beyond my horizont and I do not know enough about Common
Lisp to judge when which construct should be used. But I thought about
something simular but haven't followed that path further. So I take it
as a thing on my list I should learn ;-)


> (define-next-val-function next-sine-val (+ (* 2 n) 1))
> (define-next-val-function next-cosine-val (* 2 n)))
>
> the use of simpler subexpressions, no extra function calls and avoiding a
> call to EXPT of -1 should result in significantly tighter code, even
> without declarations. this may not be your concern, of course, but I
> also consider the documentation of the above to be far superior to your
> use of several temporary variables. that this captures the mathematical
> abstraction in one place, rather than a trivial abstraction with the
> mathematical abstraction in two different places, would at least to make
> make it much more readable to me.

I agree. It seems to be a nicer solution.

> the simple reason is that I want to
> avoid looking at the internals of a function once it has been written and
> debugged. for that reason, I might also use FLETs instead of global
> functions since these functions are used only inside your SIN and COS.
> there's no point in externalizing what should not be externally used.

That is a good point.

Regards
Friedrich

Robert Monfera

unread,
Nov 18, 1999, 3:00:00 AM11/18/99
to
Barry Margolin wrote:
>
> In article <joswig-1711...@194.163.195.67>,
> Rainer Joswig <jos...@lavielle.com> wrote:
> >Learn to use the tools to look up the information.
> >If you need documentation, write **documentation**.
> >Don't waste your time with writing unused code.
>
> Self-documenting code is better than manually documented code. Manual
> documentation can more easily become inconsistent with the code. Self
> documentation shows up in the debugger, pretty-printing code, etc.

What are the pros and conses (sic) of &aux, as an alternative to let in
some cases? I like &aux, but I have a vague recollection that it may be
retrograde to use it (I can not think of the reason).

Robert

Erik Naggum

unread,
Nov 18, 1999, 3:00:00 AM11/18/99
to
* Robert Monfera <mon...@fisec.com>

| What are the pros and conses (sic) of &aux, as an alternative to let in
| some cases?

this may sound silly, but if you can avoid a few LET bindings among many,
it's going to impact your maximum indentation favorably. such concerns
should not be dismissed _too_ lightly, although it might be a good
argument in its favor.

in some cases, however, &AUX is useful to avoid a LET binding or a SETQ
that does nothing but resolve a designator or some other relevant work on
an argument. it's a difficult to spell out any rules for when this is
good style, though.

| I like &aux, but I have a vague recollection that it may be retrograde to
| use it (I can not think of the reason).

I like having &AUX in the language. it tells me somebody thought about
something important and came up with a solution. I'm not sure _exactly_
what they thought about all that time, but it's evidence of intelligence
at work. in fact, the whole lambda list concept in Common Lisp gives me
that feeling, with all its variations and intriguing details.

Kaelin Colclasure

unread,
Nov 18, 1999, 3:00:00 AM11/18/99
to
Erik Naggum <er...@naggum.no> wrote in message
news:31519402...@naggum.no...
> * Robert Monfera <mon...@fisec.com>

[...]


> | I like &aux, but I have a vague recollection that it may be retrograde
to
> | use it (I can not think of the reason).
>
> I like having &AUX in the language. it tells me somebody thought about
> something important and came up with a solution. I'm not sure _exactly_
> what they thought about all that time, but it's evidence of intelligence
> at work. in fact, the whole lambda list concept in Common Lisp gives me
> that feeling, with all its variations and intriguing details.

One place where &aux is often much more convenient than let is in macro
expansions and other "generated" code. Where you accomodate a lambda-list,
you also automatically accomodate lexical locals as well with no additional
coding or syntax.

I too privately considered that &aux was probably some hold-over from an
elder dialect -- until I hit upon this usage, and suddenly it made perfect
sense to me why it should be retained. :-)

-- Kaelin


0 new messages