multiple-value binding let and let*

168 views
Skip to first unread message

Mark Stickel

unread,
Aug 17, 1999, 3:00:00 AM8/17/99
to
http://www.ai.sri.com/~stickel/mvlet.lisp
contains macros for MVLET and MVLET* that extend the LET and LET*
forms to include bindings of the form

((:values var1 var2 var*) [init-form])
((:list var1 var2 var*) [init-form])
((:list* var1 var2 var*) [init-form])

This does not include multilevel or lambda-list destructuring (which I
think might be too complex functionality to add to let), but satisfies
my desire for binding multiple results from a function when the
results are returned either as multiple values or in a list.


Tim Bradshaw

unread,
Aug 18, 1999, 3:00:00 AM8/18/99
to
* Mark Stickel wrote:
> http://www.ai.sri.com/~stickel/mvlet.lisp
> contains macros for MVLET and MVLET* that extend the LET and LET*
> forms to include bindings of the form

> ((:values var1 var2 var*) [init-form])
> ((:list var1 var2 var*) [init-form])
> ((:list* var1 var2 var*) [init-form])

One thing that occurred to me about these complex multipurpose
LET-like syntaxes being proposed is that, if they are intended
eventually to replace LET, then one needs to think about the status of
LET itself. If they are *not* then the remainder of this article is
not particularly interesting, but I think that they are intended so to
do at least be some proposers.

LET is currently a special operator in CL. But these extensions would
make it much more complex than any other special operator in the
language. Further, some of these extensions are naturally defined in
terms of other operators (MULTIPLE-VALUE-BIND for instance), which are
themselves in fact macros.

So really, a LET extended like this should not be a special operator.
If there are problems with its being written as a macro (which I think
must only be declaration handling), then they should be fixed so it
can be. So, there's then a choice of making LET not be special at all
-- it can be defined as a macro easily enough (I think!), or of
providing some kind of primitive SUBLET which just did what LET does
now, and was special.

I presume the reasons that LET is defined as special now would still
hold, so there should still be some special operator provided to do
the basic variable-binding thing.

--tim

Dave Bakhash

unread,
Aug 18, 1999, 3:00:00 AM8/18/99
to
this syntax is very similar to what I suggested recently. I think it
can be done better, and even w/o keywords, but this is nice, for now.
People can experiment with it, and see if they like it.

thanks for opening it up.

Dave Bakhash

unread,
Aug 18, 1999, 3:00:00 AM8/18/99
to
The reasons why LET is a special operator are valid, though I've seen
a macro version of let using LAMBDA:

(let ((x 2)
(y 3))
(declare ...)
<body>)

==

(funcall #'(lambda (x y)
(declare ...)
<body>)
2 3)

and so on. Whatever.

My own opinion, is that LET should remain a special operator with
backwards-compatibility, but extend the syntax to handle both MVs and
destructuring. It is great the the CAR of each binding is an atom,
because now the language designers will be able to provide new meaning
to lists in the CAR position, i.e.:

(let* ((x 3)
(y 4)
((q r) (truncate x y)))
<body>)

or something along these lines. Personally, I'd like LET handle both
MVs and destructuring. If they decided to pick only one of those two,
I'd imagine they'd pick destructuring, though everyone seems to want
MVs. You can get the list back with MULTIPLE-VALUE-LIST anyway. I'm
guessing that b/c that's what happened with LOOP (AFAIK, LOOP doesn't
easily handle MV bindings in the prologue).

The reason for making the new LET backwards compatible is to prevent
Lisp from adding another operator; plus, if they did, and it worked
out nicely, then it would render so several current operators/macros
obsolete, like LET, LET*, and MULTIPLE-VALUE-BIND. Better to just
make LET more general and do away with MULTIPLE-VALUE-BIND. They've
already de-necessitated MULTIPLE-VALUE-SETQ with (SETF VALUES).

dave


Erik Naggum

unread,
Aug 18, 1999, 3:00:00 AM8/18/99
to
* Dave Bakhash <ca...@bu.edu>

| (let* ((x 3)
| (y 4)
| ((q r) (truncate x y)))
| <body>)

I prefer

(let ((x 3) (y 4) q r)
(setf (values q r) (truncate x y)))

although I can see the value of these binding forms, we should not forget
that DESTRUCTURING-BIND and MULTIPLE-VALUE-BIND go through a lot more
work than they appear to be and that it's a lot harder to specify exactly
how these things are supposed to interact with missing values than one
might believe from watching the trivial cases.

I note in passing that the generated machine code for the following two
forms are identical in Allegro CL 5.0.1 for all the machines I have
tested it on. (Duane?)

(let (a b) (setf (values a b) (truncate pi 3)) (list a b))
(multiple-value-bind (a b) (truncate pi 3) (list a b))

| Personally, I'd like LET handle both MVs and destructuring.

I think MULTIPLE-VALUE-BIND and DESTRUCTURING-BIND abuse indentation and
clutter up the binding/setting distinction, and I see no reason why we
should now fix that non-problem by cluttering up the meaning of binding
so much we don't know what we're getting, anymore.

when I use MULTIPLE-VALUE-BIND and DESTRUCTURING-BIND, it is around short
pieces of code because I frequently need to rearrange the returned values
before using them as arguments for another function call, or even to
avoid the overhead of MULTIPLE-VALUE-CALL, which I would much prefer to
be implemented at least as efficiently as APPLY (and perhaps with the
same underlying machinery, even possibly exposed as an argument sequence).

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

Tim Bradshaw

unread,
Aug 18, 1999, 3:00:00 AM8/18/99
to
* Dave Bakhash wrote:

> My own opinion, is that LET should remain a special operator with
> backwards-compatibility, but extend the syntax to handle both MVs and
> destructuring. It is great the the CAR of each binding is an atom,
> because now the language designers will be able to provide new meaning
> to lists in the CAR position, i.e.:

That's exactly what I was trying to argue against. Special operators
should *not* be vast complex things partly defined in terms of other
macros like this proposed LET, they should be primitive, simple things
like QUOTE.

If LET is going to get big & hairy then it should lose its status as a
special operator. Assuming the reasons for LET being special in the
first place are still valid, then a new special operator, (`SUBLET')
needs to be added, which does what LET does now.

(Or the new hairy operator could be called something else, like BIND,
which leaves the base language undisturbed, but some people seem
allergic to that.)

--tim

Vassil Nikolov

unread,
Aug 18, 1999, 3:00:00 AM8/18/99
to comp.la...@list.deja.com
Tim Bradshaw wrote: [1999-08-18 16:52 +0100]

[...]


> If LET is going to get big & hairy then it should lose its status as a
> special operator. Assuming the reasons for LET being special in the
> first place are still valid, then a new special operator, (`SUBLET')
> needs to be added, which does what LET does now.
>
> (Or the new hairy operator could be called something else, like BIND,
> which leaves the base language undisturbed, but some people seem
> allergic to that.)

I'm not; I agree that LET should be left as it is. If we are to have a
new and improved Swiss army knife of a binding construct (I don't
know if it is really such a good idea), the proper approach I think
is the one taken by LOOP. None of the other iteration constructs in
Lisp were disturbed; for some time people used it as an extension
to the language, and after experience with it was accumulated, it
was adopted as part of the standard. So let it be with binding.
After all, an omnipotent binding construct is a matter of macrology;
then, if it is useful, people will start using it and after some time,
perhaps, there will be enough voices saying `we want BIND into the
language, it is indispensable.'

My 2e-2.


Vassil Nikolov
Permanent forwarding e-mail: vnik...@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.

Duane Rettig

unread,
Aug 18, 1999, 3:00:00 AM8/18/99
to
Erik Naggum <er...@naggum.no> writes:

> I note in passing that the generated machine code for the following two
> forms are identical in Allegro CL 5.0.1 for all the machines I have
> tested it on. (Duane?)
>
> (let (a b) (setf (values a b) (truncate pi 3)) (list a b))
> (multiple-value-bind (a b) (truncate pi 3) (list a b))

Yes. One internal tool I use to figure out what the compiler is
doing is excl::compiler-walk. It doesn't always tell the truth,
(thus its obscurity) because it can't always emulate the precise
environment that the compiler will actually see. And in this case,
it is not quite right, but with a little insider help I can get it
close enough:

USER(3): (let ((comp::.for-value. 'comp::multiple))
(excl::compiler-walk
'(let (a b) (setf (values a b) (truncate pi 3)) (list a b))))
(LET (A B)
(LET* ()
(MULTIPLE-VALUE-BIND (#:G43 #:G44)
(TRUNCATE 3.141592653589793d0 3)
(LET () (SETQ A #:G43) (SETQ B #:G44) (VALUES #:G43 #:G44))))
(EXCL::.PRIMCALL 'SYSTEM::QLIST2 A B))
USER(4): (let ((comp::.for-value. 'comp::multiple))
(excl::compiler-walk
'(multiple-value-bind (a b) (truncate pi 3) (list a b))))
(MULTIPLE-VALUE-BIND (A B)
(TRUNCATE 3.141592653589793d0 3)
(EXCL::.PRIMCALL 'SYSTEM::QLIST2 A B))
USER(5):

If you try this without the magic in front the walker gets the wrong
idea about where the results are going and so tries to use the one-return
version of truncate. The awkwardness of these tools is one reason why
I am working on compiler-environments to provide access to the compilation
and macroexpasion process.

--
Duane Rettig Franz Inc. http://www.franz.com/ (www)
1995 University Ave Suite 275 Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253 du...@Franz.COM (internet)

Tim Bradshaw

unread,
Aug 18, 1999, 3:00:00 AM8/18/99
to
* Erik Naggum wrote:
> (let ((x 3) (y 4) q r)
> (setf (values q r) (truncate x y)))

The problem with this is that you can't put reasonable declarations
in. You'd like to be able to say:

(let (a b)
(declare (type good-type a b))
(setf (values a b) ...))

But you can't because A and B aren't always of GOOD-TYPE. You could
wrap a LOCALLY around the inner bit, but that's kind of obviously a
hack. At least one compiler (CMUCL) cares about these things quite a
lot. Of course for your case it's easy because you can just invent
cheap initial values, but if the values are large objects there may be
no easy way to get useful initial values.

At least in the case of multidimensional arrays, type declarations for
large objects really can help, because a suitable declaration with
information about bounds can help compilers generate much better
indexing code.

(The SERIES package has exactly this problem, which is why I know
about it...)

--tim

Erik Naggum

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
* Tim Bradshaw <t...@tfeb.org>

| The problem with this is that you can't put reasonable declarations in.
| You'd like to be able to say:
|
| (let (a b)
| (declare (type good-type a b))
| (setf (values a b) ...))
|
| But you can't because A and B aren't always of GOOD-TYPE.

I would insist that they are, and that a compiler that barfs on this is
missing the point and is just being too anal about its type checking. if
there are no references to a local binding prior to its first being set,
who cares that it has to be NIL if ever there WERE a reference to it?
the only way that could happen is if you change the code and recompile,
and then it should barf. note that the language specification on this
point may be interpreted to death to support both your point and mine.

Tim Bradshaw

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
* Erik Naggum wrote:

> I would insist that they are, and that a compiler that barfs on this is
> missing the point and is just being too anal about its type
> checking.

I think that's kind of reasonable, but ...

> note that the language specification on this
> point may be interpreted to death to support both your point and mine.

it seems to me that the standard is reasonably clear, in particular
the `Declaration TYPE' entry in 3.8 says:

At the moment the scope of the declaration is entered, the
consequences are undefined if the value of the declared variable is
not of the declared type.

And I think that's reasonably clear. But there may be other things
which lead to other interpretations (my experience of this is just
based on talking to CMUCL people when I discovered that CMUCL took
this interpretation).

--tim

Erik Naggum

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
* Tim Bradshaw <t...@tfeb.org>

| At the moment the scope of the declaration is entered, the
| consequences are undefined if the value of the declared variable is
| not of the declared type.
|
| And I think that's reasonably clear.

well, it sort of depends on how you interpret "the value of a variable".
I would argue that if a variable isn't actually accessed, neither does it
have a value. I'm aware that the specification isn't fully with me on
this one, but in my view, there's a distinction between A and B in this
respect in the form (LET ((A NIL) B) ...), if for no other reason than
that it communicates a different intent.

in any case, when the behavior is undefined for value references, and
there aren't any references, no undefined behavior will occur, right?

Duane Rettig

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to

About (let (a b) (declare (something-non-nil a b)) (setf (values a b) ...

Erik Naggum <er...@naggum.no> writes:

> * Tim Bradshaw <t...@tfeb.org>
> | At the moment the scope of the declaration is entered, the
> | consequences are undefined if the value of the declared variable is
> | not of the declared type.
> |
> | And I think that's reasonably clear.

[ ... ]

> in any case, when the behavior is undefined for value references, and
> there aren't any references, no undefined behavior will occur, right?

I may want to talk later about some of the specific compiler issues
brought up in this thread about scope, liveness, and trees falling
in the desert ... but for now I'd like to address an issue that this
conversation triggers in me that we don't talk about very much. Perhaps
that is because we don't have a name for it, and so I took the liberty
of coining a phrase "implementationally portable", to which I modified
the subject line. If anyone has a better name for it, I'm open to
suggestions. Hopefully its name defines itself relatively obviously, at
least after my discussion below.

Tim is entirely correct that this is nonconformant code, and thus should
not be done in conforming, or portable, code. However, Erik has a point
of practical significance, and that is that practice does not always
include strict conformance. Specifically, the "is undefined" is not the
same as "is an error", and means that the vendor/implementor of the lisp
is free to assign defined semantics, either by default or in a public
interface, as to what might happen. Thus, as long as the user stays within
the vendor's prescribed interface, the code is portable, at least within
the particular lisp or lisps for which the interface is prescribed.

Obviously, implementational portability is not covered in the spec; it
is never the duty of any spec to specify the unspecified :-) But I
believe that it is a useful concept, and may deserve some attention.

I won't have time to expand on this much, but here are some thoughts:

1. If every vendor prescribed the same semantics to otherwise nonconforming
code, then it becomes a de-facto standard. Code written to this standard
can't be considered conformant, but is nonetheless usable. The downside
is that if a new implementation enters the fray, it has a hard time living
up to the de-facto standards set by the other implementations. A good example
of this is the PCL implementation, which was the basis for many (but not
all) CLOS implementations. If a user started counting on functionality
provided by PCL extensions, then the code might be portable to all
PCL-based CLOS implementations, but not to non-PCL based versions.

2. A widely used technique for establishing implementational portability
is the use of #+/#- to conditionalize. The plus side is that since the
number of implementations is finite, any source can be made implementationally
portable by porting to all implementations, but the down side is that
new implementations will almost certainly not fit into the #+/#-
portability, without changing the source to add the new version.

3. Within any one lisp implementation, but not necessarily on the same
architecture, implementational portability is somewhat practical, to the
extent that the vendor/implementor implements the same extensions to all
of their lisps. To my knowledge, most CL vendors do a fairly good job of
providing implementational portability within their rang of architectures.

The major danger of relying on implementational portability is that
since it is not part of the CL spec, and in fact it may not even be
documented or spec'd explicitly by the implementor, it thus may change
later, breaking your program (and angering you). Protection from this
requires a good relationship with the supplier of your lisp (or, if you
have source code, a willingness to get in a change it).

Duane Rettig

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Duane Rettig <du...@franz.com> writes:

> include strict conformance. Specifically, the "is undefined" is not the
> same as "is an error", and means that the vendor/implementor of the lisp
> is free to assign defined semantics, either by default or in a public
> interface, as to what might happen. Thus, as long as the user stays within
> the vendor's prescribed interface, the code is portable, at least within
> the particular lisp or lisps for which the interface is prescribed.

In my haste, I forgot to add a thought to this paragraph:

In other words, "is an error" means "don't do it", whereas "is undefined"
implies "ask your vendor or don't do it", and asking your vendor may either
yield extra functionality, or it may also yield "don't do it".

Kent M Pitman

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Erik Naggum <er...@naggum.no> writes:

> I'm aware that the specification isn't fully with me on
> this one, but in my view, there's a distinction between A and B in this
> respect in the form (LET ((A NIL) B) ...), if for no other reason than
> that it communicates a different intent.

Well, fwiw, the spec says (as you admit) they're the same but *stylistically*
I personally make the same distinction you do.

On a related point, I also try hard always to do
&optional (foo nil)
or &optional (foo '())
when I mean to have one of these get used for value before some check that
the value was supplied. I mostly do not like
&optional foo

Tim Bradshaw

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
* Duane Rettig wrote:
> In my haste, I forgot to add a thought to this paragraph:

> In other words, "is an error" means "don't do it", whereas "is undefined"
> implies "ask your vendor or don't do it", and asking your vendor may either
> yield extra functionality, or it may also yield "don't do it".

I agree, and the problem with the particular case of LET & initial
values is that of the three compilers I use regularly, one (CMUCL)
complains always, one (Allegro) allows it (always, I think?) and one
(Genera) complains in a particular funny case (arrays). Unfortunately
there's a large package for Lisp (series) which generates exactly this
kind of code and which is sufficiently obscure in it's implementation
that I couldn't work out how to fix it and eventually gave up using
it as a result (because CMUCL is an important implementation for me).

So I wasn't really trying to make the gratuitous language-lawyer point
that it might have seemed I was (if it did!), I've actually been
bitten by exactly this problem in various nasty ways, which perhaps
causes me to overreact.

--tim

Kent M Pitman

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Tim Bradshaw <t...@tfeb.org> writes:

> * Duane Rettig wrote:
> > In my haste, I forgot to add a thought to this paragraph:
>
> > In other words, "is an error" means "don't do it", whereas "is undefined"
> > implies "ask your vendor or don't do it", and asking your vendor may either
> > yield extra functionality, or it may also yield "don't do it".

I think "is unspecified" means ask the vendor what the funny value is that
comes back here or what mostly benign thing happens or whether there is an
extension hiding.

I think "is undefined" means ask the vendor but expect them to tell you that
you will fry your disk or crash your machine if you try.

I think "is an error" means we didn't think hard enough about this at
language design time to have a considered opinion on which of the above two
categories something falls into.

None of these opinions should be interpreted as me interpreting the spec.
These are just my private, personal beliefs as a user.

As a rule, I did not feel that as the editor I had the ability to casually
change things from one category to another. I pretty much tried to preserve
what CLTL said except in specific places where I was directed to do otherwise
by X3J13, usually through an approved vote on an issue writeup. So don't
assume that because I held the "pen", my interpretations above are what is
reflected in the actual text.

Barry Margolin

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
In article <sfwg11f...@world.std.com>,

Kent M Pitman <pit...@world.std.com> wrote:
>I think "is an error" means we didn't think hard enough about this at
>language design time to have a considered opinion on which of the above two
>categories something falls into.

I thought we got rid of the phrase "is an error". That was the language
that CLTL used, but in the ANS it became "consequences are undefined".

--
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.

Kent M Pitman

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Barry Margolin <bar...@bbnplanet.com> writes:

> In article <sfwg11f...@world.std.com>,
> Kent M Pitman <pit...@world.std.com> wrote:
> >I think "is an error" means we didn't think hard enough about this at
> >language design time to have a considered opinion on which of the above two
> >categories something falls into.
>
> I thought we got rid of the phrase "is an error". That was the language
> that CLTL used, but in the ANS it became "consequences are undefined".

As a matter of policy, I'm sure you're right. At the detail level, I can't
remember if the policy was carried through or how the undefined/unspecified
split was handled. It might be that I just defaulted everything to the
scarier "undefined" or it might be I left some as were originally. It's been
a while and my memory is pretty uncertain. Maybe sometime I'll look it up
to be sure. But it won't be today.

Vassil Nikolov

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to comp.la...@list.deja.com
Kent M Pitman wrote: [1999-08-20 01:37 +0000]

[...]
> scarier "undefined"
[...]

Trying it out:

It will be an error if you don't brush your teeth.

Go brush your teeth or the consequences are undefined.

Yes, the latter is scarier...

William Deakin

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Duane Rettig wrote:

> ...I took the liberty of coining a phrase "implementationally portable"...if
> anyone has a better name for it, I'm open to suggestions...

What about "implementationally potable?" as in easily consumed :-)

> Tim is entirely correct that this is nonconformant code, and thus should not be
> done in conforming, or portable, code. However, Erik has a point of practical

> significance, and that is that practice does not always include strict


> conformance. Specifically, the "is undefined" is not the same as "is an
> error", and means that the vendor/implementor of the lisp is free to assign
> defined semantics, either by default or in a public interface, as to what might
> happen.

From tim's posting it seems that implementations deal with undefined in different
ways. I'm am interested by all of this. And I will now make what I'm sure is a
blindingly obvious point: If a compiler finds something that is undefined, that
is something that is not an error or not valid, would it not be better to carp
rather that barf (like you do with an error) or purr silently (like when
everything is right with the world). Whether this is something you would want to
do at compile time or read time I don't know ;-)

Although I accept the point about 'contact your vendor', these seem to me to be
subtle errors, (as highlighted by this thread), and who would you know to do
this? Only those who are sufficiently experienced or with access to the ANSI
standard (or is this to be a requirement of all cl programmers?) I could see
somebody as cack handed as myself getting seriously burnt some day and spending
alot of time recovering. So here is a heart felt request for more carping.

Please flame away, as I realise that I have probably missed the point (again).

Best Regards,

:-) will


Barry Margolin

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
In article <sfwlnb7...@world.std.com>,

Kent M Pitman <pit...@world.std.com> wrote:
>Barry Margolin <bar...@bbnplanet.com> writes:
>> I thought we got rid of the phrase "is an error". That was the language
>> that CLTL used, but in the ANS it became "consequences are undefined".
>
>As a matter of policy, I'm sure you're right. At the detail level, I can't
>remember if the policy was carried through or how the undefined/unspecified
>split was handled. It might be that I just defaulted everything to the
>scarier "undefined" or it might be I left some as were originally. It's been
>a while and my memory is pretty uncertain. Maybe sometime I'll look it up
>to be sure. But it won't be today.

Actually, I think this was something that Kathy did before you took over,
which may be why you don't remember making the changes.

Barry Margolin

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
In article <37BD6A2B...@pindar.com>,

William Deakin <w.de...@pindar.com> wrote:
>From tim's posting it seems that implementations deal with undefined in different
>ways. I'm am interested by all of this. And I will now make what I'm sure is a
>blindingly obvious point: If a compiler finds something that is undefined, that
>is something that is not an error or not valid, would it not be better to carp
>rather that barf (like you do with an error) or purr silently (like when
>everything is right with the world). Whether this is something you would want to
>do at compile time or read time I don't know ;-)

There's no single answer to this, because there are a number of reasons why
some things are left undefined. Sometimes it's because they're difficult
to detect, particularly at compile time; if they require run-time checks,
the programmer may want to disable them for optimization purposes. Other
times it's because we didn't have agreement that a particular behavior was
necessary, and wishes to allow implementations leeway (undefined situations
allow for implementation extensions).

Kent M Pitman

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Barry Margolin <bar...@bbnplanet.com> writes:

> In article <sfwlnb7...@world.std.com>,
> Kent M Pitman <pit...@world.std.com> wrote:
> >Barry Margolin <bar...@bbnplanet.com> writes:
> >> I thought we got rid of the phrase "is an error". That was the language
> >> that CLTL used, but in the ANS it became "consequences are undefined".
> >
> >As a matter of policy, I'm sure you're right. At the detail level,
> >I can't remember if the policy was carried through or how the
> >undefined/unspecified split was handled. It might be that I just
> >defaulted everything to the scarier "undefined" or it might be I
> >left some as were originally. It's been a while and my memory is
> >pretty uncertain. Maybe sometime I'll look it up to be sure. But
> >it won't be today.
>
> Actually, I think this was something that Kathy did before you took over,
> which may be why you don't remember making the changes.

That could well be. She did a lot of the rearranging of the structure
of the document in that time, and might have done some
microrearranging, too. I know it was under her tenure that we took
some votes on various policies of overall look and feel. I still have
copies of all the states of the document as it evolved through that
time. Maybe sometime I'll put that up on an ftp site just for grins
in case anyone wants to research it. And I have the hardcopy of each
of the drafts, which I either need to get a bigger house for (since I
don't have room for a display area at my current house) or I need to
offer up on ebay... They're kinda cool, really. Like the symbolics doc
set, which is also in storage. Had to make some sacrifices to the fun
of having it all out in order to find semi-affordable housing in Boston
area. Real estate is too high even around here. And I understand it's
dirt cheap compared to the Bay Area. Dunno how they can stand it.
Pay must be awesome out there... though I imagein it must all go straight
into real estate interest...

Erik Naggum

unread,
Aug 23, 1999, 3:00:00 AM8/23/99
to
* William Deakin

| Although I accept the point about 'contact your vendor', these seem to me
| to be subtle errors, (as highlighted by this thread), and who would you
| know to do this? Only those who are sufficiently experienced or with
| access to the ANSI standard (or is this to be a requirement of all cl
| programmers?) I could see somebody as cack handed as myself getting
| seriously burnt some day and spending alot of time recovering.

a serious programmer who does not know what to expect from his compiler
is a contradiction in terms. I don't think _any_ programmer who has not
actually read and actually understood the specification of his language,
or at least the parts thereof that he uses, should be allowed to write
code for other people than himself unless it occurs under very close
supervision by someone who does know the specification.

of course, this is predicated on the desire to see programming as a
professional discipline on par with law, medicine, auditing, etc, not the
(continuation of) largely unskilled labor that happens to get paid to do
any kind of non-quality work because the market is in desperate need of
just about _anything_ to solve their mostly perceived problems or to keep
going after making a seriously misguided decision about which software to
invest in in the first place.

William Deakin

unread,
Aug 23, 1999, 3:00:00 AM8/23/99
to
Erik Naggum wrote:

> a serious programmer who does not know what to expect from his compiler is a
> contradiction in terms. I don't think _any_ programmer who has not actually
> read and actually understood the specification of his language, or at least
> the parts thereof that he uses, should be allowed to write code for other
> people than himself unless it occurs under very close supervision by someone
> who does know the specification.

I think this is a valid. For languages in which I have more experience, I have
a better day-to-day knowledge of the relevant specifications. For example: any
C work will keep strictly to the current ISO and POSIX standards.

But how do you become a serious programmer? This is something I would hope to
become one day. But I do not have anybody to tutor or supervise me and I do not
have access to the ANSI cl specification.

> of course, this is predicated on the desire to see programming as a
> professional discipline on par with law, medicine, auditing, etc,

I agree with this. This is an important thing that should happen.

Anyway back to the point I was trying to make was: if something is being
implemented to do something that is explicitly not defined in the standard, why
not tell me that is what you are doing? Even if I had read and though that I
understood the specification of the language, there are still grey areas that
are subject to interpretation.

This raises the point about what is the "value of a variable?" This is clearly
subject to interpretation (bringing back the sound of a tree falling in the
forest) and it would help if there was a bit more carping.

Best Regards,

:-) will


Pierre R. Mai

unread,
Aug 23, 1999, 3:00:00 AM8/23/99
to
William Deakin <wi...@pindar.com> writes:

> But how do you become a serious programmer? This is something I
> would hope to become one day. But I do not have anybody to tutor or
> supervise me and I do not have access to the ANSI cl specification.

For nearly all intents and purposes (besides legal ones), the
HyperSpec is indeed a faithful representation of the ANSI CL
specification (since it is a mechanical translation of the source
code for the printed ANSI CL specification). Since the HyperSpec is
available freely, it is much easier to get access to the meat of the
ANSI CL specification for CL. It is also more readable than nearly
any other standard I've come across, and more useful for daily work,
too. In the words of Jerry Pournelle: Highly Recommended!

Download at: http://www.harlequin.com/books/HyperSpec

Regs, Pierre.

--
Pierre Mai <pm...@acm.org> PGP and GPG keys at your nearest Keyserver
"One smaller motivation which, in part, stems from altruism is Microsoft-
bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]

Erik Naggum

unread,
Aug 23, 1999, 3:00:00 AM8/23/99
to
* William Deakin

| But how do you become a serious programmer? This is something I would
| hope to become one day. But I do not have anybody to tutor or supervise
| me and I do not have access to the ANSI cl specification.

actually, you do. http://www.harlequin.com/education/books/HyperSpec/
download it if you can't use the Net in real time.

| Even if I had read and though that I understood the specification of the
| language, there are still grey areas that are subject to interpretation.

there always will be in any specification useful to intelligent people.
if intelligent people can't disagree on what something means, it isn't
worth writing down. (now, somebody disagree on this, please. ;)

| This raises the point about what is the "value of a variable?" This is
| clearly subject to interpretation (bringing back the sound of a tree
| falling in the forest) and it would help if there was a bit more carping.

even if it were worded differently, someone might decide to carp more
than others, as CMUCL does, and people would find it difficult to ignore
a warning, such as when they disagreed about the exact condition under
which something is unspecified or even argue that it is underspecified.

I believe in conforming to standards, but as a baseline, not as the end.
conformance means you can trust something to be the way the specification
says it should be, but it doesn't make sense to ask the specification a
question like "what does it mean to do something that doesn't have fully
specified behavior?". the proper answer is "why do you want to do that?".

note also that when the specification doesn't say anything at all, it
does in fact say "all that we say nothing about has unspecified behavior"
and it equally invalid to use a specification to prove a point outside of
exactly what it says.

to answer your first question: you become a serious programmer by going
through a stage where you are fully aware of the degree to which you know
the specification, meaning both the explicit and the tacit specification
of your language and of your problem. "hey, it works most of the time"
is the very antithesis of a serious programmer, and certain languages can
only support code like that. over time, you get a good gut feeling for
the failure mode of your assumptions, and when you can trust that you are
unlikely to make grossly invalid assumptions, the dangers that people run
into in the absence of that trust vanish in a puff of standardization:
it's the kind of trust you buy from somebody who claims to be conformant.
non-conformance is about violating this sense of trust.

certain languages support serious programmers, and others don't. e.g., I
don't think it is at all possible to become a serious programmer using
Visual Basic or Perl. if you think hard about what Perl code will do on
the borders of the known input space, your head will explode. if you
write Perl code to handle input problems gracefully, your programs will
become gargantuan: the normal failure mode is to terminate with no idea
how far into the process you got or how much of an incomplete task was
actually performed. in my view, serious programmers don't deal with
tools that _force_ them to hope everything works.

#:Erik
--
save the children: just say NO to sex with pro-lifers

William Deakin

unread,
Aug 23, 1999, 3:00:00 AM8/23/99
to
"Pierre R. Mai" wrote:

> In the words of Jerry Pournelle: Highly Recommended!

Thank you for your recommendation. It is something that I currently use and find
very,very useful. My problem is that in my hasty and confused state I did not
read the small print on the Common Lisp HyperSpec (tm) first page. As it says
'While the paper version remains the official standard, we think that as a
matter of practice you'll find the Common Lisp HyperSpec much easier to navigate
and use than its paper alternative. While the paper version remains the official
standard, we think that as a matter of practice you'll find the Common Lisp
HyperSpec much easier to navigate and use than its paper alternative.'

RTFM.

Thank you for your kindness,

Best Regards,

:-) will


William Deakin

unread,
Aug 23, 1999, 3:00:00 AM8/23/99
to
Erik Naggum wrote:

> actually, you do. http://www.harlequin.com/education/books/HyperSpec/
> download it if you can't use the Net in real time.

As I said in my reply to Pierre Mai, I need to RTFM. Thank you also for your
kindness.

> ...if intelligent people can't disagree on what something means, it isn't
> worth writing down...

I, of course, must now disagree with this. ;)

> even if it were worded differently, someone might decide to carp more than

> others ... and people would find it difficult to ignore a warning, such as


> when they disagreed about the exact condition under which something is
> unspecified or even argue that it is underspecified.

Sure.

The things that helps me when I'm in a bind with a C program is the gcc compiler
and lint. Both of which produce copious warnings or carps. I then either fix or
ignore these warning, but then am aware of that I have decided to ignore
somethings. caviat programmatici. (apologies to Vassil Nikolov).

> I believe in conforming to standards, but as a baseline, not as the end.

'Rules are for the guidance of wise men and the obediance of fools.' I am
currently in the fool camp.

[...elided an excellent statement about serious programmers...]

> certain languages support serious programmers, and others don't. e.g., I
> don't think it is at all possible to become a serious programmer using Visual
> Basic or Perl.

However, I would argue that you can do some useful things using these languages.
If you are so inclined.

> if you think hard about what Perl code will do on the borders of the known
> input space, your head will explode.

BANG ;)

> if you write Perl code to handle input problems gracefully, your programs will
> become gargantuan

To do that is not to use perl in the way in which it is intended (IMHO).

Best Regards,

:-) will


Pierre R. Mai

unread,
Aug 23, 1999, 3:00:00 AM8/23/99
to
William Deakin <wi...@pindar.com> writes:

> > certain languages support serious programmers, and others don't.
> > e.g., I don't think it is at all possible to become a serious
> > programmer using Visual Basic or Perl.
>
> However, I would argue that you can do some useful things using
> these languages. If you are so inclined.

You can do some pretty useful things with band-aid or tape, in a
fix. Yet no-one in his/her right mind makes band-aid or tape an
integral part of the design of new products. ;)

> > if you write Perl code to handle input problems gracefully, your
> > programs will become gargantuan
>
> To do that is not to use perl in the way in which it is intended (IMHO).

A very true statement. See the intended uses for band-aid and tape.
Given this, the large use of Perl in our industry should be quite
telling: Either we are constantly in a fix, or out of our minds. It
seems to me that we are quite often both, and as long as we continue
this, we will only create more trouble to fix. ;)

William Deakin

unread,
Aug 24, 1999, 3:00:00 AM8/24/99
to
"Pierre R. Mai" wrote:

> You can do some pretty useful things with band-aid or tape, in a fix. Yet
> no-one in his/her right mind makes band-aid or tape an integral part of the
> design of new products. ;)

Agreed. Though it is quite useful if you have a cut finger or want to send a
parcel in the post ;)

Best Regards,

:-)~ will


Vassil Nikolov

unread,
Aug 25, 1999, 3:00:00 AM8/25/99
to comp.la...@list.deja.com
Erik Naggum wrote: [1999-08-23 06:10 +0000]

[...]


> the desire to see programming as a
> professional discipline on par with law, medicine, auditing, etc

[...]

I notice that this list does not include anything like electrical or civil
engineering (i.e. disciplines that are based on some science,^1 e.g.
physics), and I wonder if this was deliberate or just to keep the list short.
__________
^1 I believe that medicine is an art; it may become a science one day,
but is not one yet. I know others may disagree, and I don't think I am
going to argue about it.

Erik Naggum

unread,
Aug 25, 1999, 3:00:00 AM8/25/99
to
* Vassil Nikolov <v...@einet.bg>

| I notice that this list does not include anything like electrical or
| civil engineering (i.e. disciplines that are based on some science,^1
| e.g. physics), and I wonder if this was deliberate or just to keep the
| list short.

the underlying science of a discipline doesn't dictate how professional
practitioners will or can be, and it isn't even relevant. a scientific
attitude is orthogonal with the profession, too. I'm purposely leaving
such disciplines out because I don't think programming is anywhere close
to the hard engineering disciplines nor that it ever will be, and I don't
want to open up for the impression that I believe in even more staticityš
when I want to argue dynamism and dealing with people professionally.

the similarity between engineering disciplines and programming lies in
how they deal with legal and communal requirements, ever changing user
requirements, sharing knowledge among practitioners, standardization,
etc, not in the underlying scientificityš. therefore, it is better to
use professions where the potential for confusion is much more limited.

| ^1 I believe that medicine is an art; it may become a science one day,
| but is not one yet. I know others may disagree, and I don't think I am
| going to argue about it.

I believe medicine is a science and programming an art because I know
both of them well, not just programming.

#:Erik
-------
š if these aren't words today, they will be in the future.

Vassil Nikolov

unread,
Aug 25, 1999, 3:00:00 AM8/25/99
to comp.la...@list.deja.com
Erik Naggum wrote: [1999-08-25 11:05 +0000]

[a response to my question about the list of professional disciplines to
which programming should be close]

Thanks for the clarifications.

Paolo Amoroso

unread,
Aug 26, 1999, 3:00:00 AM8/26/99
to
On 25 Aug 1999 11:05:59 +0000, Erik Naggum <er...@naggum.no> wrote:

> want to open up for the impression that I believe in even more staticityน
[...]
> etc, not in the underlying scientificityน. therefore, it is better to
[...]
> น if these aren't words today, they will be in the future.

Italian already has both words: "staticita`" and "scientificita`".


Paolo
--
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/

Reply all
Reply to author
Forward
0 new messages