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

On conditionals

178 views
Skip to first unread message

Erik Naggum

unread,
Nov 21, 2001, 2:45:42 AM11/21/01
to
Many other programming languages have statements and expressions, but
Common Lisp has not made that distinction quite as explicit, although the
value of a lot of forms are not usually used. Still, when we turn to the
conditionals, it is somewhat different. Common Lisp the Language (CLtL)
introduces the conditionals by talking about cond being the primary Lisp
conditional, but if being like if-then-else in other languages, it would
be covered first. However, there is a significant difference that has
made me think that this is not accurate. Lisp's if returns a value. The
ifs of other programming languages are generally _statements_ that do not
return a value. If they have a conditional that can return a value, it
is usually very different from the usual if statement for one significant
reason: It has to have a value for both the consequent and the alternate,
while the traditional if forms have an optional alternate. In Common
Lisp, an else-less if form works because nil is useful value, but this is
not a good thing. The if form has some properties of both statement and
expression.

One question is whether a form has an implicit progn. This is a clue
that it is has statement nature. So if it does not have an implicit
progn, but only one value-returning form, this is a clue that it is an
expression.

One question is whether a form should be used for its value or not. The
forms when and unless should clearly not be used for their value. They
also have implicit progns. There is no point in a progn unless you have
other forms satisfying another clue to statement nature: their value(s)
are discarded and ignored.

The if form is both statement and expression, and it is neither, because
it does not quite have either nature. As an expression, it is not a good
idea to leave out the alternate, even if you want that value to be nil.
As a statement, adding explicit progns can be somewhat annoying.

The general conditional cond also has some of this dual nature. It has
implicit progn, but returns values. Leaving out the final branch is a
known source of annoying bugs, whether it be the unexamined fall-through
case or an unexpected nil return value. Still, cond is the smartest of
the conditional forms I have seen in any number of programming languages:
a long chain of "else if" looks like whoever designed that excuse for a
language forgot to design it for more than either-or style cases. Also,
the verbosity of the conditionals in inferior languages in this style
gets in the way of the task at hand, so cond is the definite winner.

The specialized conditionals case (with ccase and ecase) and typecase
(with ctypecase and etypecase) cover common comparison cases that are
easy to optimize and whose similarities would be totally obscured by a
cond. E.g.,, a test for (<= 0 x 99) may be significantly more expensive
than a test for the type (integer 0 99). A case "dispatching" on a set
of characters may be implemented as a very fast table lookup that would
otherwise be hard to do as efficiently.

The one-branch conditionals when and unless might seem to be redundant,
but they communicate something that neither if nor cond can communicate:
A promise that there will not be any other alternatives, or that if its
condition is not met, nothing needs to be done. If it is merely an
accident that there is one branch now, which might change in the future,
do not use when or unless, because you are lying to yourself. Both when
and unless communicate an expectation. I think when and unless should be
used such that the condition is expected to be true, in which case when
evaluates the body and unless does not. In other words, unless says that
when the condition is false, that is an exceptional thing, but when says
that when the condition is false, that is nothing special. That is, you
should expect both (when (not/null ...)) and (unless (not/null ...)).

There are no serious coding standards that apply to the rich set of
Common Lisp conditionals. I would, however, appeal to those who seek to
use them all to their fullest not use if as a statement, but always as an
expression with both branches specified. Even if the alternate branch is
nil, specify it explicitly. (This may be read to imply that I think it
was a mistake to make the alternate branch optional, but it was probably
made optional because if looks so much like programming languages that
had a statement-only if.) While other programming languages may have an
if statement, e.g., C, Common Lisp's if is much closer in meaning to C's
conditional expression, ?:, which is usually not abused to chain a whole
lot of them together as you lose track of which condition must hold to
reach each expression. In that case, use cond or one of the case forms
as an expression, meaning: without using the option to include statements
with the implicit progn in each body form, and ensure that you specify
the value when none of the conditions or cases are met, even if it is nil.

For the conditional statement, I would likewise appeal to those who seek
to use the most of te language to use when and unless when there is only
one known branch, but not use them for their value. However, there may
be an implicit alternate branch even when using when or unless: They may
throw or return or signal an error. I favor using unless for this, as
explained above about unless being somewhat exceptional in nature. When
there are more than one branch in the conditional statement, use cond.
In the statement capacity, I favor _not_ terminating it with a final
alternate branch unless that branch includes some statements of its own,
so as not to confuse it with an expression. A final alternate branch
like (t nil) tells me the value of the whole cond is used for something
and thus I need to look for the return value for each condition. To make
this abundantly clear, it may be prudent in a complex form to use values
forms explicitly, even if returning only a single value, but this, too,
may decrease readability if it is not obviously seen as useful.

Whareas most programming language have a single conditional statement
and, if you are lucky, maybe a conditional expression, Common Lisp once
again proves itself as the language that communicates with programmers
and captures their intent through the choice of which of several forms to
use. Using only one form for a slew of different purposes is the same
kind of impoverished literary style that you find in bad authors, but if
you come from a language that has only one conditional, embrace the set
of options you have in this new language. It may even be true that in
the natural language of the programmer, even be it English, the set of
conditional expressions fit the single if-then-else form of programming
languages (the writing styles of many programmers may indicate that they
would appreciate a limited vocabulary so as not to feel alienated), but
then using Common Lisp would be an opportunity to improve both styles.

///
--
Norway is now run by a priest from the fundamentalist Christian People's
Party, the fifth largest party representing one eighth of the electorate.
--
Carrying a Swiss Army pocket knife in Oslo, Norway, is a criminal offense.

Vassil Nikolov

unread,
Nov 21, 2001, 8:12:24 AM11/21/01
to

Just a few (minor) remarks added to a very insightful analysis.

On Wed, 21 Nov 2001 02:45:42 GMT, Erik Naggum <er...@naggum.net> said:

[...]

EN> Even if the alternate branch is
EN> nil, specify it explicitly.

Precisely---if you omit the `else' part, you are not really
returning a value (even though the language is willing to make up
for it), so perhaps you want to use WHEN (or UNLESS).

EN> (This may be read to imply
EN> that I think it was a mistake to make the alternate branch
EN> optional, but it was probably made optional because if
EN> looks so much like programming languages that had a
EN> statement-only if.)

Maybe existing programs also had to be accommodated which had been
written before the introduction of WHEN and UNLESS and which
omitted the `else' part?

EN> While other programming languages may
EN> have an if statement, e.g., C, Common Lisp's if is much
EN> closer in meaning to C's conditional expression, ?:, which
EN> is usually not abused to chain a whole lot of them together

Or, if we include rarely used languages, isn't Common Lisp's IF in
fact closest to Algol's *if*? (As C's ?: cannot have the `else'
part omitted. Though I admit my memory fails me as to what happens
in e.g. ``i := if b then j''---a compile-time error?) In fact, off
the top of my head I should think that Algol 60 was the first
language where *if* names a conditional _expression_, a significant
difference from a conditional statement viewed essentially as an
abstraction hiding a couple of goto's. (I am primarily talking
about the use of the _name_ `if'; otherwise, I don't know if Algol
or Lisp was the first to have a conditional expression, as they
were developed roughly at the same time, but Lisp had only COND in
the beginning.)

One couldn't say, though, that Algol's *if* was not `abused in
chains' (if I may borrow the expression). By the way, there are
programmers who (in languages with C-like syntax) do not write
else-if chains, but rather stuff like

if (FOO1) BAR1;
if (FOO2) BAR2;

etc. where FOO1 and FOO2 will not be true at the same time. (Not
that I like this too much.)


---Vassil.

Vassil Nikolov

unread,
Nov 21, 2001, 8:12:35 AM11/21/01
to

Vassil Nikolov

unread,
Nov 21, 2001, 8:13:32 AM11/21/01
to

Espen Vestre

unread,
Nov 21, 2001, 8:35:14 AM11/21/01
to
Erik Naggum <er...@naggum.net> writes:

> made me think that this is not accurate. Lisp's if returns a value. The
> ifs of other programming languages are generally _statements_ that do not
> return a value. If they have a conditional that can return a value, it
> is usually very different from the usual if statement for one significant
> reason: It has to have a value for both the consequent and the alternate,
> while the traditional if forms have an optional alternate.

Is the latter true? I haven't used SIMULA for 16 years so I can't really
remember if the SIMULA "expression IF" worked that way, but certainly
the perl "expression if" does not work that way:

ev@wallace:~ % perl -we 'print "yes\n" if (1);'
yes

(perl's _unless_, which can't be mentioned often enough since some people
think lisp is the only language with such an animal, can of course also
be used as a "expression unless").

> One question is whether a form should be used for its value or not. The
> forms when and unless should clearly not be used for their value.

I strongly disagree. I think when and unless can be perfectly well used
for their value. In general I think the Common Lisp programmer should
be free to use any form for it's value whenever that value can be given
a meaningful interpretation.
--
(espen)

Janis Dzerins

unread,
Nov 21, 2001, 11:58:17 AM11/21/01
to
Espen Vestre <espen@*do-not-spam-me*.vestre.net> writes:

> Erik Naggum <er...@naggum.net> writes:
>
> > One question is whether a form should be used for its value or
> > not. The forms when and unless should clearly not be used for
> > their value.
>
> I strongly disagree. I think when and unless can be perfectly well
> used for their value. In general I think the Common Lisp programmer
> should be free to use any form for it's value whenever that value
> can be given a meaningful interpretation.

The point is not about legality or conformity, but about the
communication of intent. Lots of things in Common Lisp can be done in
many different ways and since the programs are written more for humans
than for computers, the programmer should choose the way that most
clearly communicates the intent (just like some people _do_ quote nil
and keywords).

If you use when or unless for value, you rely on the fact that if the
test fails they will return nil and you will use it as a meaningful
value. But this value does not appear anywhere and does not make this
explicit. Attention to detail at this level is what makes programs
beautiful and readable and approachable by non-experts in Common Lisp.

--
Janis Dzerins

Eat shit -- billions of flies can't be wrong.

Kent M Pitman

unread,
Nov 21, 2001, 1:16:45 PM11/21/01
to
Janis Dzerins <jo...@latnet.lv> writes:

> Espen Vestre <espen@*do-not-spam-me*.vestre.net> writes:
>
> > Erik Naggum <er...@naggum.net> writes:
> >
> > > One question is whether a form should be used for its value or
> > > not. The forms when and unless should clearly not be used for
> > > their value.
> >
> > I strongly disagree. I think when and unless can be perfectly well
> > used for their value. In general I think the Common Lisp programmer
> > should be free to use any form for it's value whenever that value
> > can be given a meaningful interpretation.
>
> The point is not about legality or conformity, but about the
> communication of intent. Lots of things in Common Lisp can be done in
> many different ways and since the programs are written more for humans
> than for computers, the programmer should choose the way that most
> clearly communicates the intent (just like some people _do_ quote nil
> and keywords).

But intent is the product of a set of style rules plus a set of actions
under those rules. We have no style rule for determining whether the
number 42 will be returned; that is done by using a construct from the
use of which it is ambiguous as to whether it returns 42 or not, plus
actually reading the code and determining what it will do. Yet such
code is not blocked from clearly communicating whether 42 is returned.

Nor is it the burden of every programmer to exhaust every possible cue
with an associative nuance, so that if two constructs compute the same
value, there must be a difference in nuance between the two. It is a
legitimate style decision to simply say "I use WHEN if there is no
alternative, and UNLESS if there is no consequent." It is also a
legitimate style decision to code otherwise. What matters more is to
know the convention than for us all to have the same convention,
because on the latter point we will not agree and we will war endlessly.

And certainly no one's style rules should keep him/her from seeing the
possibility that others use different rules. Style rules are merely a
cue to help manage the probability of various choices being made. If
one blindly infers that they assert actual meaning, one will find oneself
substantially and rightfully hampered in the ability to debug code.

> If you use when or unless for value, you rely on the fact that if the
> test fails they will return nil and you will use it as a meaningful
> value. But this value does not appear anywhere and does not make this
> explicit. Attention to detail at this level is what makes programs
> beautiful and readable and approachable by non-experts in Common Lisp.

I believe your case would be better made by asserting "I prefer the style
rule that says: ..." Because that leaves room for others to choose their
own path without argument. Asserting a style rule as if it were true,
or canonical, or right, or otherwise uniquely determined invites opposition
to what should be a common sense statement if presented properly. Style
rules assert a possible and useful axis of consistency from among many
that are available to freely suggest.

Personally, my preferred style rule says not to omit values when they
are possible to provide and when a value is required. So I might use
(IF x y) when an IF is not value-producing but (IF x y NIL) if the IF
is value producing. But that doesn't mean that when I use (WHEN x y)
I am saying there is no value. I choose between IF and WHEN on the
basis of whether I think there is a reasonable chance I might want to
add an alternative. If I do, I sometimes prefer IF, whether or nto I
am actually supplying an alternative at the time. When I use WHEN,
I usually either mean "this supplies no value" or "this supplies a value
which is either a meaningful true value, or a subordinate false value".
(Think of the vowel schwa in English.) So, for example, I might
commonly use:

(defun get-property (x y)
(when (symbolp x)
(get x y)))

In such a place, I intend this to be read "the value of GET-PROPERTY is
the result of (GET X Y) when X is a symbol, but it really has no properties
otherwise". This is computationally the same as, but connotationally
different than:

(defun get-property (x y)
(if (symbolp x)
(get x y)
nil))

which says "I mean to define that the value of the Y property of a
symbol X is stored on its plist when X is a symbol, and is NIL
otherwise." The latter gives, to me, a stronger sense that I have
thought through the consequences of yielding NIL and that I think this
is the right value to return, while the former gives the sense that I
am merely saying "there really is no property list for non-symbols,
and you'll have to assume a default". These are highly subtle
matters, but that's what style rules do: convey subtlety. And to
understand that subtlety, one does not consult a central table of
uniquely determined subtlety, one consults the programmer (or
programmer team, when programmers happen to be of pre-agreed or
pre-ordained like mind) and then the code.

And, personally, I would rather convey an abstract subtlely, irrelevant
to the computation per se, but very relevant to the programmer, such
as the one shown above ("non-symbols don't have plists" vs "it works for
the values of non-symbol properties to be assumed to be NIL, the former
being a statement about the symbol, the latter a statement about the use
of the symbol's properties) than a concrete cue such as "this will get
used for value" or "this will not get used for value", because it conveys
information about how I _think_ about the program, rather than merely
information about how I perform the rather mundane act of translating
my thoughts into code.

But I emphasize that this is merely a choice on my part, and that it
will not by any absolute metric be possible to show it better or worse
than your choice.

To understand a wise style choice, one must understand wisdom. Wisdom
is not a "what" question ("what do I do?", which almost precludes
choice) but a "why" question ("why would I do these various things?"
and then a willful selection among consequences in a space that is
most commonly not subject to linear ordering).

Dorai Sitaram

unread,
Nov 21, 2001, 2:12:59 PM11/21/01
to
In article <w6bshwj...@wallace.ws.nextra.no>,

Espen Vestre <espen@*do-not-spam-me*.vestre.net> wrote:
>Erik Naggum <er...@naggum.net> writes:
>
>> made me think that this is not accurate. Lisp's if returns a value. The
>> ifs of other programming languages are generally _statements_ that do not
>> return a value. If they have a conditional that can return a value, it
>> is usually very different from the usual if statement for one significant
>> reason: It has to have a value for both the consequent and the alternate,
>> while the traditional if forms have an optional alternate.
>...

>
>> One question is whether a form should be used for its value or not. The
>> forms when and unless should clearly not be used for their value.
>
>I strongly disagree. I think when and unless can be perfectly well used
>for their value. In general I think the Common Lisp programmer should
>be free to use any form for it's value whenever that value can be given
>a meaningful interpretation.

The rules are delightfully Scheme-y, with the
difference being that in Scheme these are not "style
rules". One has no recourse but to follow the rules,
as one cannot rely on an absent branch resolving
to #f, or even #t, or indeed any value that you can
trust.

Looks like the CL community is about to
rediscover the value (!) of the unspecified. :-)

--d

Espen Vestre

unread,
Nov 21, 2001, 2:13:19 PM11/21/01
to
Kent M Pitman <pit...@world.std.com> writes:

> (defun get-property (x y)
> (when (symbolp x)
> (get x y)))
>
> In such a place, I intend this to be read "the value of GET-PROPERTY is
> the result of (GET X Y) when X is a symbol, but it really has no properties
> otherwise".

good example, and quite representative for the kind of context in which
I use the value of when myself!

--
(espen)

Erik Naggum

unread,
Nov 21, 2001, 6:57:34 PM11/21/01
to
* Espen Vestre

| the perl "expression if" does not work that way:

Perl is not a language worth comparing anything to.

| (perl's _unless_, which can't be mentioned often enough since some people
| think lisp is the only language with such an animal, can of course also
| be used as a "expression unless").

Just being postfix does not make it an expression.

* Erik Naggum


> One question is whether a form should be used for its value or not. The
> forms when and unless should clearly not be used for their value.

* Espen Vestre


| I strongly disagree. I think when and unless can be perfectly well used
| for their value. In general I think the Common Lisp programmer should be
| free to use any form for it's value whenever that value can be given a
| meaningful interpretation.

Well, unlike what a Perl hacker will expect,

(setq foo (when bar zot))

actually does modify foo when bar is false. I think using the one-branch
conditionals when and unless for value is highly, highly misleading.

However, if they are used in a function body as the value-returning form
and it is defined to return nil when "nothing happens", I think it is
much more perspicuous to have an explicit (return nil) form under the
appropriate conditions than let when or unless fall through and return
nil by default, which can be quite invisible.

Erik Naggum

unread,
Nov 21, 2001, 7:32:49 PM11/21/01
to
* Kent M Pitman

> (defun get-property (x y)
> (when (symbolp x)
> (get x y)))

* Espen Vestre


| good example, and quite representative for the kind of context in which
| I use the value of when myself!

This is a sort of half-breed between a statement and an expression. I
hate examples, because people attach too much meaning to their specifics,
but I was trying to draw a line between statements and expressions, which
I honestly assumed would be understood as directly value-returning forms.
I assume from your responses that you would _not_ write

(setq foo (when bar zot))

but _would_ write

(setq foo (whatever))

in the presence of

(defun whatever ()
(when bar
zot))

the latter of which does communicate "enough" to be defensible. However,
I find it very, very strange that you think this is so representative of
using when as an expression that you strongly disagree that when and
unless should not be used for their value. To me, that says that you
want to use when in let bindings and for arguments to functions, etc,
which I think is just plain wrong. Please let me know if you want to use
when in the usual expression positions, and thus make a distinction
between whole function bodies inside when and unless and using them for
smaller expressions.

Erik Naggum

unread,
Nov 21, 2001, 7:36:36 PM11/21/01
to
* Dorai Sitaram

| Looks like the CL community is about to rediscover the value (!) of the
| unspecified. :-)

Scheme is all wrong. Making nil different from false is nuts, and
letting forms have an unspecified value is also just plain wrong.

It is important that style rules be breakable. Enforcing them is wrong.

Joe Schaefer

unread,
Nov 21, 2001, 8:10:03 PM11/21/01
to
Erik Naggum <er...@naggum.net> writes:

> Well, unlike what a Perl hacker will expect,
>
> (setq foo (when bar zot))
>
> actually does modify foo when bar is false.

Huh? That's exactly what a perl hacker would expect; in fact, s/he'd
also expect foo = zot whenever bar is true, and foo = bar otherwise.
*That* might be surprising to a lisp programmer, though :)

<ot>
Both conditionals and loop constructs usually have return values
in Perl; the conditional itself is returned whenever there is no
successful alternative. Perl's for/foreach are the exceptions here,
not the rule.
</ot>

--
Joe Schaefer

Kenny Tilton

unread,
Nov 21, 2001, 8:24:33 PM11/21/01
to
Jeez, I use when and unless for their values all the time. But then I am
an expert in lisp, I know what they return. :) I guess I am also an
expert because nil and '() look identical to me.

I think the big mistake in all this is thinking code should be readable.
It should not be. Not by non-experts, experts or even the author. it
should be understandable. anyone reading too fast to realize what when
does will not understand the code anyway.

JF's premise in that astonishing coding standards bit is that code is
read more often than it is written. Nah, the developer spends hours and
hours on code which may never be read by anyone. Even in large teams,
when code fails the pager of the author goes off. A few years later the
whole system gets rewritten from scratch.

me, i do not have to understand my code because if i have to look at it
I rewrite it anyway.

If I cannot use when for its value, why don't we just dump the whole
language? functional programming right out the window. We can make it an
error for the when conditional to evaluate to false.

And what's this about AND and OR returning the last evaluated form's
value? talk about something not being explicit. let's get that sorted
out immediately and return t or nil, period.

<g>

kenny
clinisys

Erik Naggum

unread,
Nov 21, 2001, 9:02:29 PM11/21/01
to
* Erik Naggum

> Well, unlike what a Perl hacker will expect,
>
> (setq foo (when bar zot))
>
> actually does modify foo when bar is false.

* Joe Schaefer


| Huh? That's exactly what a perl hacker would expect; in fact, s/he'd
| also expect foo = zot whenever bar is true, and foo = bar otherwise.
| *That* might be surprising to a lisp programmer, though :)

Heh, not at all, because if bar is false, foo will equal bar in Common
Lisp, too, although it is a slightly unusual way to look at it. Since
there is but one false value in Common Lisp, and Perl has a whole range
of them, I suppose there is Perlish sense in your version of this.

What I had in mind, however, was that Espen Vestre's example using a
postfix if would cause the statement preceding it _not_ to be evaluated
if the condition was false.

Erik Naggum

unread,
Nov 21, 2001, 9:15:52 PM11/21/01
to
* Kenny Tilton

| If I cannot use when for its value, why don't we just dump the whole
| language? functional programming right out the window. We can make it
| an error for the when conditional to evaluate to false.

"Should not" is different from "cannot". Grasp this and relax, please.

Espen Vestre

unread,
Nov 21, 2001, 9:40:14 PM11/21/01
to
Erik Naggum <er...@naggum.net> writes:

> I assume from your responses that you would _not_ write
>
> (setq foo (when bar zot))

I grepped through some thousand lines of code and found only one case
of that pattern (so maybe I actually intuitively do avoid it?)

But to me, 'when' has a very strong "silent" "otherwise nil" to it, so
I have absolutely no problems reading a statement like that. (And
since I read 'when' that way, '(if bar zot nil)' is somewhat "noisy"
to me).

I really don't see the big advantage of reserving 'when' and 'unless'
to side-effects-only cases.
--
(espen)

Dorai Sitaram

unread,
Nov 21, 2001, 9:55:17 PM11/21/01
to
In article <3BFC0E0B...@nyc.rr.com>,

Kenny Tilton <kti...@nyc.rr.com> wrote:
>Jeez, I use when and unless for their values all the time. But then I am
>an expert in lisp, I know what they return. :) I guess I am also an
>expert because nil and '() look identical to me.

Since "when" (and "unless") must return a value, why
not return a meaningful value? A return value of nil
currently does not imply that the "when" failed.
If we returned the value of the _test_, then the
result is meaningful and usable.

--d

Thomas F. Burdick

unread,
Nov 21, 2001, 10:05:36 PM11/21/01
to
Erik Naggum <er...@naggum.net> writes:

> * Dorai Sitaram
> | Looks like the CL community is about to rediscover the value (!) of the
> | unspecified. :-)
>
> Scheme is all wrong. Making nil different from false is nuts, and
> letting forms have an unspecified value is also just plain wrong.

I agree with the unspecified value part (which seems really weird for
a language with such funcitonal aspirations, too). I'm not so sure
about false, though. I don't like the pun that () is the same as
boolean false. I also don't like that the empty list is a symbol.
Don't get me wrong, it's easy enough to cope with, but it's
conceptually sloppy. I don't even see any good reason why NIL should
be false. It's a symbol; every other symbol is true. Of course, if
#f were a special false value, I don't know what BLOCK should return,
so that's maybe a practical argument against it. Or, maybe it should
just return #F. I hate the idea of someone doing something like:

(cons 'foo (dolist ...))

so () would be a bad choice. If NIL were just another symbol, that
would be a foolish choice. So the NIL that's returned now must be NIL
in the boolean sense.

So, I guess what I'm saying is that you ought to explain your
objection here (or point to a message where you've explained it
before, since I'm sure you have).

--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'

Marco Antoniotti

unread,
Nov 21, 2001, 10:10:59 PM11/21/01
to

ds...@goldshoe.gte.com (Dorai Sitaram) writes:

Ahem!

* (when 3 4)
4

* (when nil 5)
NIL

Cheers

--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
719 Broadway 12th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.

Kenny Tilton

unread,
Nov 21, 2001, 10:30:53 PM11/21/01
to

"Thomas F. Burdick" wrote:
> I don't even see any good reason why NIL should
> be false.

Understood, but in this case the proof is in the pudding for me. By
which I mean, programming with nil as false is so terrific it must be
Deeply Right.

isn't there a funny essay somewhere about the consequences of porting
something from Lisp to Scheme, specifically about the problem of having
to then differentiate between nil and false? I recall assoc figuring
prominently in the piece.

kenny
clinisys

Thomas F. Burdick

unread,
Nov 21, 2001, 10:56:57 PM11/21/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> "Thomas F. Burdick" wrote:
> > I don't even see any good reason why NIL should
> > be false.
>
> Understood, but in this case the proof is in the pudding for me. By
> which I mean, programming with nil as false is so terrific it must be
> Deeply Right.

But have you tried programming in a CL-like dialect where (), nil, and
boolean false were three different objects? Otherwise, that would be
somewhat like saying that lexical scoping was a bad idea because you
had so much more fun in Maclisp or Interlisp than in Scheme.

> isn't there a funny essay somewhere about the consequences of porting
> something from Lisp to Scheme, specifically about the problem of having
> to then differentiate between nil and false? I recall assoc figuring
> prominently in the piece.

Oh boy, how I hate when code depends on the pun between false and ().
Bleah. Would it really kill people to put a couple (not (null ..))s
here and there, and make their intentions more explicit?

Kenny Tilton

unread,
Nov 21, 2001, 10:43:23 PM11/21/01
to

Dorai Sitaram wrote:
> A return value of nil
> currently does not imply that the "when" failed.

Just to be sure I understand you, are you making the point that when
WHEN returns nil i do not know if the conditional or the consequent
returned nil? ie, it could be (when nil t) or (when t nil)?

To save an iteration at the risk of answering a straw man: that is an
interesting observation. But it should not matter; side-effects aside,
every form is a black box, the only thing a client cares about is the
result of evaluating the form, not its internals.

kenny
clinisys

Kent M Pitman

unread,
Nov 21, 2001, 11:02:22 PM11/21/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> "Thomas F. Burdick" wrote:
> > I don't even see any good reason why NIL should
> > be false.

As to the choice of the symbol, I somewhat agree. It's tradition, but
one I could have done without. On the other hand, in my 20+ year
career doing some fairly intensive Lisp, I've found it a minor
irritation once or twice, but basically have never found it got in the
way in any seriously material way ... so I guess I just don't buy any
argument that it matters.

As to the choice of the empty list being false, I also don't see a problem
there and actually see some virtue. I think all too much fuss has been
made over this.

> Understood, but in this case the proof is in the pudding for me. By
> which I mean, programming with nil as false is so terrific it must be
> Deeply Right.

In the MOO programming language, which (I think by design) has a very
Lispy feel, a bunch of objects are false, including 0 and "" and {}.
Errors are also false. They make the mistake of making their type OBJ
(sort of vaguely like our standard class) be false, and that causes
problems. But the other values being false don't cause any problem to
learn and it's quite handy to have these various degenerate cases all
count as false. MOO is a byte compiled language and not overly
obsessed with efficiency; there's probably something good about being
able to do a truth test in one instruction, so maybe it's not awful
that we have a single false value. But even so, I think that, if
anything, we lose out by not having more false values, not by failing
to jump on the Scheme bandwagon of "everything is bad but the
explicit".

> isn't there a funny essay somewhere about the consequences of porting
> something from Lisp to Scheme, specifically about the problem of having
> to then differentiate between nil and false? I recall assoc figuring
> prominently in the piece.

Well, people often do (cdr (assoc ...)) in LISP, and it's true that assoc
returns false when it fails, which you can't cdr. But you also can't cdr
the empty list in Scheme. So it would be a problem anyway.

Kenny Tilton

unread,
Nov 22, 2001, 5:50:20 AM11/22/01
to
OK, let's finish off this dead horse...

I agree '() being false being nil is confusing at first. I just
remembered what it was like when I was first learning Lisp. My feeling
was, OK, they're making this sh*t up as they go along. But now it feels
so natural I had no idea what you were going on about--until I
remembered my early experience.

Which takes me back to my pudding proof. If it was Truly Confused (like
some things I have worked with) it would never feel natural. But it
feels natural, so the problem up front must have been with me.

Scheme worked from first principles when they "improved" on this. That
is always dangerous. We are not as smart as we think. Who says we have
the first principles right? One of my design rules says good design
changes lead to less code; if I find myself adding code such as (not
(null ...)) all over the place I back out the change. Schemers should
have done the same when they saw the consequences of their change.

I believe it was David St. Hubbens (in collaboration with Nigel) who
said, It's a fine line between clever and stupid.

kenny
clinisys

Dmitri Ivanov

unread,
Nov 22, 2001, 8:26:27 AM11/22/01
to
Erik Naggum <er...@naggum.net> wrote in message
news:32153791...@naggum.net...
> Well, conflating "nothing" and "false" has long traditions in both
logic
> and programming languages. I think objection to it come only from a
> misguided sense of purity without a sense of history or continuity.

Someone may need to go beyond Boolean logic. Any three-valued or
multi-valued logic implementer would prefer to interpret NIL as
undefined or something else different form false.

Everyone who deals with database programming knows that AND, OR, and
other logical connectives has three-valued interpretation in SQL. I
consider this quite natural. Several lisp modules for relational
database access (SQL/ODBC and the like) makes database's NULL be
converted into/from Lisp's NIL. In this use, NIL would be considered as
an undefined value rather than the false value.
--
Sincerely,
Dmitri Ivanov
www.aha.ru/~divanov


Erik Naggum

unread,
Nov 21, 2001, 11:39:12 PM11/21/01
to
* Dorai Sitaram

| Since "when" (and "unless") must return a value, why not return a
| meaningful value? A return value of nil currently does not imply that
| the "when" failed. If we returned the value of the _test_, then the
| result is meaningful and usable.

This implies that the current return value is not meaningful, a premise
with which I simply disagree. Although it would be nice if when and
unless were defined that way, I think it should be possible to return a
value from these forms, just that it needs to be a judicious choice.

Kenny Tilton

unread,
Nov 21, 2001, 11:55:00 PM11/21/01
to

"Thomas F. Burdick" wrote:
> Oh boy, how I hate when code depends on the pun between false and ().
> Bleah. Would it really kill people to put a couple (not (null ..))s
> here and there, and make their intentions more explicit?

Omigod. You actually consider:

(when (find long-sought-thing input-stuff)
<stuff to do>)

hatefully inferior readability-wise to a double-negative? You can read
double-negatives?! Tell your programmers you just failed the Turing
Test.

Seriously, I think NIL as false is Deeply Correct. Consider FIND. Your
position is that (find x y) returns two possible values, x or nil. Too
literal. FIND either finds x or it does not.

kenny
clinisys

Erik Naggum

unread,
Nov 22, 2001, 12:11:22 AM11/22/01
to
* Thomas F. Burdick

| I'm not so sure about false, though. I don't like the pun that () is the
| same as boolean false. I also don't like that the empty list is a
| symbol. Don't get me wrong, it's easy enough to cope with, but it's
| conceptually sloppy.

I find it conceptually very clean. I find it equally conceptually clean
that 0 is false in C. Neither do I have any problems with Perl's false
values. I do have a problem with Scheme's anal-retentive false, because
it is so goddamn hard to obtain a false.

| I don't even see any good reason why NIL should be false.

There has to be at least one false value. Making the empty list false is
simply a very good choice for a language that gives you lists as a close
to primitive type. Linked lists have to be terminated by _something_,
and that something might as well be the answer to the question: "Are
there any more elements?" as a matter of pragmatics.

| So, I guess what I'm saying is that you ought to explain your objection
| here (or point to a message where you've explained it before, since I'm
| sure you have).

I have lost track of which objection you might be referring to here, but
I hazard a guess it is that I think making nil different from false is
nuts. It is nuts from a pragmatic point of view. Conceptualizations
that go against the pragmatic are even more wrong than Scheme in general,
but it is precisely because Scheme's conceptulization is impractical that
they have chosen to make their language impractical but conceptually
pure. I think Scheme is an excellent example of how you go wrong when
you decide that "practicality" is a worthless axis to find a reasonable
position on, or not even consider at all. Common Lisp is a practical
language and its conceptualization is one of trying to figure out what
the most elegant practical expression would be, not how impractical the
most elegant expression would be. This is just something Scheme freaks
will never accept as a point of serious difference between Common Lisp
and Scheme. I look at Scheme from a Common Lisp viewpoint, of course,
and that is not very productive, but Dorai Sitaram brought up this Scheme
nonsense as a reasonable way to talk about Common Lisp features. I think
I put it sufficiently clear when I started my reply with "Scheme is all
wrong". Those who do not think so are of course free to talk about
Scheme all they want, but the sheer _insistency_ that Scheme freaks come
to present their "views" about Common Lisp is really annoying. At least
they have their own community, so it is not as if they are fragmenting
the _Common_ Lisp community, but they also think they have a Lisp, and
that is at least as annoying.

Erik Naggum

unread,
Nov 22, 2001, 12:21:08 AM11/22/01
to
* Thomas F. Burdick

| Would it really kill people to put a couple (not (null ..))s here and
| there, and make their intentions more explicit?

Yes. Adding (not (null ...)) to previously obvious code would make
everything nearly unreadable. Besides, the intention _is_ to return the
empty list to those who look for a list and false to those who want a
boolean value. This is an important property of Common Lisp. Scheme
does not have this property, and consequently Scheme systems have a
gazillion small functions that are anal-retentively type-specific. One
of the reasons I like Common Lisp is that it has none of this nonsense.

Thomas F. Burdick

unread,
Nov 22, 2001, 12:29:43 AM11/22/01
to
Erik Naggum <er...@naggum.net> writes:

> * Thomas F. Burdick
> | I'm not so sure about false, though. I don't like the pun that () is the
> | same as boolean false. I also don't like that the empty list is a
> | symbol. Don't get me wrong, it's easy enough to cope with, but it's
> | conceptually sloppy.
>
> I find it conceptually very clean. I find it equally conceptually clean
> that 0 is false in C. Neither do I have any problems with Perl's false
> values. I do have a problem with Scheme's anal-retentive false, because
> it is so goddamn hard to obtain a false.

Bleah, I guess this is just a matter of taste, then. I personally
think that false should have a type of boolean, not integer nor
symbol. And, honestly, I don't see anything about #F as different
from () and NIL that would make it hard to get, per se. When I'm
testing for the end of a list, I write (cond ((null foo) ...)). When
I'm testing for not-the-end, I write (cond ((not (null foo)) ...>))
rather than (cond (foo ...)), because I want to be explicit about my
intentions. But I guess that shows that there's a lot of style issues
mixed in here.

[ As for Perl, you really don't mind the *string* "0" being false?!?! ]

> | I don't even see any good reason why NIL should be false.
>
> There has to be at least one false value. Making the empty list false is
> simply a very good choice for a language that gives you lists as a close
> to primitive type. Linked lists have to be terminated by _something_,
> and that something might as well be the answer to the question: "Are
> there any more elements?" as a matter of pragmatics.

Actually, I meant NIL qua symbol, not the empty list. Although, if I
had my druthers, () wouldn't be false either. I just don't see what's
so hard about writing (not (null ...)).

> | So, I guess what I'm saying is that you ought to explain your objection
> | here (or point to a message where you've explained it before, since I'm
> | sure you have).
>
> I have lost track of which objection you might be referring to here, but
> I hazard a guess it is that I think making nil different from false is
> nuts.

That would be it.

> It is nuts from a pragmatic point of view. Conceptualizations
> that go against the pragmatic are even more wrong than Scheme in
> general, but it is precisely because Scheme's conceptulization is
> impractical that they have chosen to make their language
> impractical but conceptually pure.

While I won't argue with that characterization of Scheme, I don't
think that seperating () and false is choosing purity over
practicality. I think it's easier to read code that checks for NIL
explicitly, and I don't think that checking with the NULL predicate is
a particular hinderance.

Thomas F. Burdick

unread,
Nov 22, 2001, 12:42:22 AM11/22/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> "Thomas F. Burdick" wrote:
> > Oh boy, how I hate when code depends on the pun between false and ().
> > Bleah. Would it really kill people to put a couple (not (null ..))s
> > here and there, and make their intentions more explicit?
>
> Omigod. You actually consider:
>
> (when (find long-sought-thing input-stuff)
> <stuff to do>)
>
> hatefully inferior readability-wise to a double-negative? You can read
> double-negatives?! Tell your programmers you just failed the Turing
> Test.

But (not (null ...)) is only a double negative when you're punning on
false and ()! NULL checks for end-of-list-ness. NOT negates. Do you
consider (not (zerop ...)) to be a double negative? I certainly hope
you don't write (null (symbolp foo)) to negate the boolean value
returned by SYMBOLP.

But, yes, my first reaction to your code above is that FIND returns a
boolean. Really, it returns a list. So the body of your WHEN is
being run when FIND returns a non-empty list, not when it returns
true. Imagine recasting it numerically:

(when (not (zerop (count long-sought-thing input-stuff)))
(do-stuff))

if that had been:

(when (count long-sought-thing input-stuff)
(do-stuff))

you would assume that COUNT was a predicate.

> Seriously, I think NIL as false is Deeply Correct. Consider FIND. Your
> position is that (find x y) returns two possible values, x or nil. Too
> literal. FIND either finds x or it does not.

No, my position is that there's a conceptual difference between the
empty list (), and the boolean false NIL. And that it's kinda weird
that false is a symbol.

None of this causes me much of a headache, though, and it's usually a
difference of a half a second or less to figure out that someone meant
false, not ().

And, so there's no misunderstanding, I don't mean to rehash this in
any sort of Common-Lisp-is-broken-because... or The Next Standard
Should Do... sort of way. I just don't think it's nutty to
distinguish NIL, (), and flase.

Joe Schaefer

unread,
Nov 22, 2001, 12:44:19 AM11/22/01
to
Erik Naggum <er...@naggum.net> writes:

> * Erik Naggum
> > Well, unlike what a Perl hacker will expect,
> >
> > (setq foo (when bar zot))
> >
> > actually does modify foo when bar is false.
>
> * Joe Schaefer
> | Huh? That's exactly what a perl hacker would expect; in fact, s/he'd
> | also expect foo = zot whenever bar is true, and foo = bar otherwise.
> | *That* might be surprising to a lisp programmer, though :)
>
> Heh, not at all, because if bar is false, foo will equal bar in Common
> Lisp, too, although it is a slightly unusual way to look at it. Since
> there is but one false value in Common Lisp, and Perl has a whole range
> of them, I suppose there is Perlish sense in your version of this.

Of course you're right; but I probably should point out that this
also applies to negated conditionals and loops as well (where the
returned conditional is something true):

% perl -wle '$a="cond"; sub f { unless ($a) {"cons"} }; print f'
cond
% perl -wle 'sub f { ($a="cond", "cons") until $a }; print f'
cond

> What I had in mind, however, was that Espen Vestre's example using a
> postfix if would cause the statement preceding it _not_ to be
> evaluated if the condition was false.

I know what you meant- I've just never seen anyone attempt
to write a "postfix if" in lisp before :). Now if you could
tell me whether or not a postfixed conditional declaration is
"legal" Perl ...

(please don't answer that- it's a rhetorical question :)

--
Joe Schaefer


Erik Naggum

unread,
Nov 22, 2001, 12:52:43 AM11/22/01
to
* Thomas F. Burdick

| Bleah, I guess this is just a matter of taste, then.

Nonono, you are just _wrong_. :)

| And, honestly, I don't see anything about #F as different from () and NIL
| that would make it hard to get, per se.

It would mean that functions need to know whether they should return an
empty list or a boolean. This is the reason that the pun is useful, just
as 0 being false in C is useful. I actually find s specific boolean type
to be incredibly painful -- to use it, you would always need multiple
values. It is not unlike asking real people "Do you know the time?".
"Yes" is not a good answer. Just the time will do nicely, thank you. If
you had me test for, say, find returning true before I could use its
return value, I would probably write macros to circumvent such nonsense.

| [ As for Perl, you really don't mind the *string* "0" being false?!?! ]

That Perl does type conversions east and west so you never actually know
what type of object you are dealing with is sometimes convenient par
excellence, but most of the time, it is just plain nuts. However, it is
actually useful in a number of languages. SQL, for instance, gets around
some of its syntax problems with this flexibility.

| Actually, I meant NIL qua symbol, not the empty list. Although, if I had
| my druthers, () wouldn't be false either. I just don't see what's so
| hard about writing (not (null ...)).

Well, it looks like really bad language design. Like Scheme. Failing to
have a function that turns something into a boolean directly is bad. If
you want to see if foo is a non-empty list, (not (null foo)) looks dumb,
but if you are expecting a list, (consp foo) is the right choice, in
which case you are well advised to look at typecase instead of cond.

| While I won't argue with that characterization of Scheme, I don't think
| that seperating () and false is choosing purity over practicality.

Well, conflating "nothing" and "false" has long traditions in both logic


and programming languages. I think objection to it come only from a
misguided sense of purity without a sense of history or continuity.

| I think it's easier to read code that checks for NIL explicitly, and I


| don't think that checking with the NULL predicate is a particular
| hinderance.

Well, if you used typecase and tested for null and cons and other types,
I would probably support you, but (not (null ...)) says "Scheme freak!"
to me, and in a horrible font, too. :)

Alain Picard

unread,
Nov 22, 2001, 8:52:05 AM11/22/01
to
Espen Vestre <espen@*do-not-spam-me*.vestre.net> writes:

> I strongly disagree. I think when and unless can be perfectly well used
> for their value. In general I think the Common Lisp programmer should
> be free to use any form for it's value whenever that value can be given
> a meaningful interpretation.

Well, Erik was talking about _style_. I know I couldn't keep my
lunch down if I saw something like

(setf foo (when (valid? bar) (blah))) ; Using implicit NIL as valid return

But I'd have no problems with

(setf foo (if (valid? bar)
(blah)
nil))

I only use WHEN and UNLESS in things like

(unless (valid? bar)
(error 'invalid-bar-error))


To each his own, I guess...

--
It would be difficult to construe Larry Wall, in article
this as a feature. <1995May29....@netlabs.com>

Alain Picard

unread,
Nov 22, 2001, 9:01:06 AM11/22/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> Jeez, I use when and unless for their values all the time. But then I am
> an expert in lisp, I know what they return. :) I guess I am also an
> expert because nil and '() look identical to me.
>

That's funny, NIL and '() look totally different to me.
The former says FALSE, the latter says EMPTY LIST.

I'm very careful about their use. Thus

(let ((bar '())
(baz nil))
;; Here I fully expect BAR to be used as a list,
;; and BAZ as an atom.
...)


What's more, I used NOT to make that distinction. It's only with
some years of practise (i.e. with _expertise_, to use your word)
that I've discovered that that distinction matters.

YMMV, of course.

Erik Naggum

unread,
Nov 22, 2001, 1:55:15 AM11/22/01
to
* Thomas F. Burdick

| Do you consider (not (zerop ...)) to be a double negative?

That depends on how you use it. I prefer (/= 0 ...) to duoble predicates.

| But, yes, my first reaction to your code above is that FIND returns a
| boolean. Really, it returns a list.

But find _does_ return nil or the object you asked it to find. It does
_not_ return a list, because it _cannot_ return a cons unless you have
asked it to find a cons, which is a statement about the specific call,
not about the function in general. (Functions like this that return nil
or cons are member and assoc.) The function position also returns nil or
the position where it found something, not a cons, so its notion of true
is simply "non-nil".

I maintain that it would not make sense to make nil or () not be false
without making every other object also not be true. If punning on false
is bad, punning on true is also bad. If we have a pure boolean type, we
would need to rethink this whole return value business and consider pure
predicates, not just for things like null to see if a list is empty, but
it would also be wrong to give it a non-list. So this is not a question
just of (not (null ...)), but of (and (listp ...) (not (null ...))),
which is again what (consp ...) does more efficiently, so the whole (not
(null ...)) thing is kind of moot. It works today _because_ of the pun
on true and false. It would not make sense to use null on non-lists in a
strict boolean-type universe, because boolean would not be the only type
to be treated anal-retentively.

| So the body of your WHEN is being run when FIND returns a non-empty list,
| not when it returns true.

I think you should look up what find does and returns, now...

| Imagine recasting it numerically:
|
| (when (not (zerop (count long-sought-thing input-stuff)))
| (do-stuff))
|
| if that had been:
|
| (when (count long-sought-thing input-stuff)
| (do-stuff))
|
| you would assume that COUNT was a predicate.

But this carefully elides the context in which nil = () = false makes
sense. In a language where you return pointers or indices into vectors,
0 = NULL = false makes sense. In such a language, you could not have a
function position that returned the position where it found something,
because 0 would

| No, my position is that there's a conceptual difference between the empty
| list (), and the boolean false NIL. And that it's kinda weird that false
| is a symbol.

Since there _is_ no "false" concept as such, but rather "nothing" vs
"thing" that supports a _generalized false_, I think the conclusion only
follows because you think the type boolean is defined differently than it
is. In fact, the boolean type is defined as the symbols t and nil.
(Please look it up in the standard.)

| None of this causes me much of a headache, though, and it's usually a
| difference of a half a second or less to figure out that someone meant
| false, not ().

I think this betrays a conceptual confusion. If you realized that they
are in fact exactly the same thing, you would not need to think about it,
but since you think they are something they are not, it takes think time
to undo the confusion. It is much smarter to fix the confusion at its
core and realize that you you cannot get what you want because what you
want is not within the tradition that produced Common Lisp.

Erik Naggum

unread,
Nov 22, 2001, 1:56:21 AM11/22/01
to
* Joe Schaefer <joe+u...@sunstarsys.com>

| (please don't answer that- it's a rhetorical question :)

Whew! You had me nervous there for a second.

Kenny Tilton

unread,
Nov 22, 2001, 2:59:24 AM11/22/01
to

"Thomas F. Burdick" wrote:
>
> But (not (null ...)) is only a double negative when you're punning on
> false and ()!

Touche! But this confirms you are composed of logic gates.

> Do you
> consider (not (zerop ...)) to be a double negative?

Zero is negative? :) Well I cannot understand even singly-negated tests.
The only time I use NOT is for:

(if (not <test>)
'no
<50 lines of code>)


> I certainly hope
> you don't write (null (symbolp foo)) to negate the boolean value
> returned by SYMBOLP.

If I have to choose between NULL and NOT I indeed use NOT against
predicates and NULL against existence, but this only happens because for
some reason I have for some reason been cornered into coding one or
another of those. But (not (null <test>)) not only obfuscates, it adds
two keywords where none were needed.

> No, my position is that there's a conceptual difference between the
> empty list (), and the boolean false NIL.

Buddha taught that in the beginning was the void, and the void became
nothing and something, and the something became the multitude. So
nothing, false, empty are all the same while true comes in many forms.

After we come to agreement on this let's go over to comp.lang.c and get
everyone agree on where to put {}s. :)

kenny
clinisys

Espen Vestre

unread,
Nov 22, 2001, 9:23:27 AM11/22/01
to
Espen Vestre <espen@*do-not-spam-me*.vestre.net> writes:

> > (setq foo (when bar zot))
>
> I grepped through some thousand lines of code and found only one case
> of that pattern (so maybe I actually intuitively do avoid it?)

After sleeping on it, I think the actual reason for the fact that such
forms are rare even if you're comfortable with using WHEN for its
value, is that in contexts where you SETF a variable which has NIL as
one of its possible values, that variable is very frequently already
_initialized_ with NIL. And that means that (when bar (setf foo zot))
is the right form... In fact I begin to suspect that the underlying
reason for this style rule may be that in good code, WHEN will
"naturally" have its most dominant usage for side effects. And this
statistical observation has then been simplified to a style rule which
disturbs me because it tries to introduce a classification of lisp
forms into two classes, a classification which I consider rather
unlispish (and I haven't touched scheme for the last 13 years, in case
you start to wonder ;-))

"All lisp forms are equalp and their values are all valuable" :-)
--
(espen)

Thomas F. Burdick

unread,
Nov 22, 2001, 3:37:57 AM11/22/01
to
Erik Naggum <er...@naggum.net> writes:

> Well, if you used typecase and tested for null and cons and other types,
> I would probably support you, but (not (null ...)) says "Scheme freak!"
> to me, and in a horrible font, too. :)

Well, it's not something I do often -- I'm actualy very prone to using
etypecase. I just grepped through several hundred lines of code (and
a Lisp compiler, no less, so it makes unusually heavy use of lists),
and found about .6 instances per hundred lines of "(not (null ", which
is about what I expected. The vast majority of the time, consp or
typecase is the right thing to do, and it looks like I usually use
(not (null ...)) when I'm expecting the value to be nil. As in:

(defun foo (list bar)
(if (not (null list))
(do-something #'foo list bar)
(let ((qux ...))
(do-the-rest-of-the-function))))

Maybe other people's coding style involves cases where this test would
come up more often? I don't know. Or, maybe it's because I learned
Scheme first. Ah, well, surviving habits from scheme, maybe, but not
freakiness.

Thomas F. Burdick

unread,
Nov 22, 2001, 3:58:03 AM11/22/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> "Thomas F. Burdick" wrote:
> >
> > But (not (null ...)) is only a double negative when you're punning on
> > false and ()!
>
> Touche! But this confirms you are composed of logic gates.

Crud, I thought those were neurons in there.

[...]


> If I have to choose between NULL and NOT I indeed use NOT against
> predicates and NULL against existence, but this only happens because for
> some reason I have for some reason been cornered into coding one or
> another of those. But (not (null <test>)) not only obfuscates, it adds
> two keywords where none were needed.

Shoot, I don't think I ever use find (I couldn't find any instances in
a big chunk of code -- plenty of "member"s, though), and I was
mistaken about what it does (I thought it returned a list of the
matching items, oops). Which makes this exchange heavy in the
talking-past-eachother area. Absolutely, (not (null (predicate))) is
confusing.
(not (null (returns-a-list))) is what I meant to be talking about. Of
course, I'm more likeley to check based on type, or to put (null ...)
higher in the cond, letting non-empty lists fall through for more
testing.

> > No, my position is that there's a conceptual difference between the
> > empty list (), and the boolean false NIL.
>
> Buddha taught that in the beginning was the void, and the void became
> nothing and something, and the something became the multitude. So
> nothing, false, empty are all the same while true comes in many forms.

Yeah, but he also taught that after I'm dead, I'm not gone.

> After we come to agreement on this let's go over to comp.lang.c and get
> everyone agree on where to put {}s. :)

They *still* haven't gotten that figured out? Maybe they could use
some help :-)

Takehiko Abe

unread,
Nov 22, 2001, 9:45:14 AM11/22/01
to
In article <86itc3c...@gondolin.local.net>, Alain Picard <api...@optushome.com.au> wrote:

> Espen Vestre <espen@*do-not-spam-me*.vestre.net> writes:
>
> > I strongly disagree. I think when and unless can be perfectly well used
> > for their value. In general I think the Common Lisp programmer should
> > be free to use any form for it's value whenever that value can be given
> > a meaningful interpretation.
>
> Well, Erik was talking about _style_. I know I couldn't keep my
> lunch down if I saw something like
>
> (setf foo (when (valid? bar) (blah))) ; Using implicit NIL as valid return

Why? You immediately know what it does when you see "(when ".

I sometimes write
(let ((foo (when bar ....)))
...

instead of (if bar (progn ....) nil)

>
> But I'd have no problems with
>
> (setf foo (if (valid? bar)
> (blah)
> nil))

With IF, my eyes look for else form [only to find NIL at the end
in this case.] That's slightly more work.

abe

--
<keke at mac com>

Kenny Tilton

unread,
Nov 22, 2001, 9:44:04 AM11/22/01
to

Alain Picard wrote:
>
> Kenny Tilton <kti...@nyc.rr.com> writes:
>
> > Jeez, I use when and unless for their values all the time. But then I am
> > an expert in lisp, I know what they return. :) I guess I am also an
> > expert because nil and '() look identical to me.
> >
>
> That's funny, NIL and '() look totally different to me.
> The former says FALSE, the latter says EMPTY LIST.

What does the compiler say? No Lisp implementation differentiates
between NIL and '()? So, as I see it, my mental processes should not.

Don't forget, folks, we are engaged in hand-to-hand combat with
compilers. Acknowledge their states of mind or perish. I remember
reading about SmallTalk that it had no pointers. Chya. So tell me (mr
author) is copy deep or shallow? Oops.

It would be great if some 3GL let us forget about assembly language, but
in fact every time I want to whack something from a list I must choose
between delete and remove. Explain to bubba that delete and remove from
lists are different...no way, you have to talk about implementation,
cons cells, pointers.

Now to be fair, by saying NIL and '() you are over-specifying, latching
onto conceptual differences at a finer granularity than the compiler, so
you are on solid ground. But to me that attitude is dangerous. It relies
on a fiction. Better to acknowledge the mindset of the compiler, who in
the end decides the behavior of our so-called high-level code.

kenny
clinisys

Christophe Rhodes

unread,
Nov 22, 2001, 11:14:20 AM11/22/01
to
Kent M Pitman <pit...@world.std.com> writes:

> Kenny Tilton <kti...@nyc.rr.com> writes:
>
> > "Thomas F. Burdick" wrote:
> > > I don't even see any good reason why NIL should
> > > be false.
>
> As to the choice of the symbol, I somewhat agree. It's tradition, but
> one I could have done without. On the other hand, in my 20+ year
> career doing some fairly intensive Lisp, I've found it a minor
> irritation once or twice, but basically have never found it got in the
> way in any seriously material way ... so I guess I just don't buy any
> argument that it matters.

It's not a serious material way, but it has caused irritation to me
that I can't use T as a variable. It's easily-get-roundable, of
course...

[(defun d2x/dt2 (x xdot y ydot time)
...)]

... but it has still once or twice gotten me to say "Aaargh" :-)

Cheers,

Christophe
--
Jesus College, Cambridge, CB5 8BL +44 1223 510 299
http://www-jcsu.jesus.cam.ac.uk/~csr21/ (defun pling-dollar
(str schar arg) (first (last +))) (make-dispatch-macro-character #\! t)
(set-dispatch-macro-character #\! #\$ #'pling-dollar)

Janis Dzerins

unread,
Nov 22, 2001, 11:18:45 AM11/22/01
to
t...@apocalypse.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> When I'm
> testing for the end of a list, I write (cond ((null foo) ...)).

Have you considered using function endp?

--
Janis Dzerins

Eat shit -- billions of flies can't be wrong.

Thomas F. Burdick

unread,
Nov 22, 2001, 11:47:16 AM11/22/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> OK, let's finish off this dead horse...

(Oh don't tempt me, a friend and I used to have this joke about dead
horses. See, there's this funny thing, where you keep beating them.
And, yeah, you've heard this before, but it's really funny. Anyways,
dead horse, yeah. So, I was beating it ... [you get the idea, I hope].)

> I agree '() being false being nil is confusing at first. I just
> remembered what it was like when I was first learning Lisp. My feeling
> was, OK, they're making this sh*t up as they go along. But now it feels
> so natural I had no idea what you were going on about--until I
> remembered my early experience.
>
> Which takes me back to my pudding proof. If it was Truly Confused (like
> some things I have worked with) it would never feel natural. But it
> feels natural, so the problem up front must have been with me.

I don't know that the problem is the inexperienced user. It certainly
feels natural to me anymore (despite the fact that I have
philosophical issues with it), but then, so do the wacky rules of
English and French grammar. And some of the "unintuitive" bits of
evolution science (I remember when they seemed weird, but it takes
effort). But our current conception of evolution could very well be
off, and I don't think it takes a genius to figure out that English is
a crazy (if practical) language.

Oy, I really didn't mean to draw this out into a long thread. I
*really* just wanted to refute the idea that it was nuts to separate
NIL and false. For all the arguments in that direction, the obvious
usability of Common Lisp means that it's also reasonable to conflate
them, despite any conceptual messiness that might (or might not)
entail. I kept responding because I felt like I needed to clarify
myself. And then, here we are with a long thread that should've been
3 messages long. (sigh). So, this is my last post to this thread,
and not just because I'm about to be away from home for a few days
:-). It should have died already, and I think it's my fault it
hasn't. On that note, here are some nice words from R. Kelly, having
nothing to do with Lisp, (), NIL, false, nor Scheme:

"I don't see nothing wrong
[...]
this is going on 'til the early morn'
and my word is bond."

Tim Bradshaw

unread,
Nov 22, 2001, 12:39:58 PM11/22/01
to
I'm not really following up here (I think I agree with Erik's article
insofar as it needs agreement, and it was certainly interesting). I
was prompted by some earlier discussion on this stuff to look at what
I tend to write - I don't have `style rules' but then I'm writing code
in a team of one so I don't have to formalise things fortunately. But
I definitely do have some informal rules on IF, WHEN, UNLESS which are
quite similar to those here (I don't think I use WHEN/UNLESS for
value).

But anyway, what was more interesting was to look at what I did with
NOT and NULL and conditionals. I have never thought about this until
I read through code, and I still don't understand why I write what I
do. For instance why this:

(when (not x) ...)

instead of

(unless x ...)

-- I use both, and they have different meanings to me (not to CL).
Not to mention (NOT (NULL ...)):

(when (not (null x)) ...)
(unless (null x) ...)

-- I have both these too, why? They have different connotations to
me, but I'm not sure why. Sometimes I can look back through CVS logs
and catch myself changing one into the other. And back again.

--tim

Pierre R. Mai

unread,
Nov 22, 2001, 1:18:37 PM11/22/01
to
ke...@ma.ccom (Takehiko Abe) writes:

> In article <86itc3c...@gondolin.local.net>, Alain Picard <api...@optushome.com.au> wrote:
>
> > Espen Vestre <espen@*do-not-spam-me*.vestre.net> writes:
> >
> > > I strongly disagree. I think when and unless can be perfectly well used
> > > for their value. In general I think the Common Lisp programmer should
> > > be free to use any form for it's value whenever that value can be given
> > > a meaningful interpretation.
> >
> > Well, Erik was talking about _style_. I know I couldn't keep my
> > lunch down if I saw something like
> >
> > (setf foo (when (valid? bar) (blah))) ; Using implicit NIL as valid return
>
> Why? You immediately know what it does when you see "(when ".
>
> I sometimes write
> (let ((foo (when bar ....)))
> ...
>
> instead of (if bar (progn ....) nil)

You could use (and bar ....) instead. That would make the value more
explicit to my eyes. But it's not something I worry about, I can read
the when form just fine, I'd just probably write the and version
myself.

Regs, Pierre.

--
Pierre R. Mai <pm...@acm.org> http://www.pmsf.de/pmai/
The most likely way for the world to be destroyed, most experts agree,
is by accident. That's where we come in; we're computer professionals.
We cause accidents. -- Nathaniel Borenstein

Erik Naggum

unread,
Nov 22, 2001, 2:27:31 PM11/22/01
to
* Kenny Tilton

| What does the compiler say? No Lisp implementation differentiates
| between NIL and '()? So, as I see it, my mental processes should not.

Is there no difference between (- x) and (1+ (lognot x)), either?
How about (first x) and (car x)? Or (ash x 3) and (* x 8)?

| Don't forget, folks, we are engaged in hand-to-hand combat with compilers.

I have never viewed compilers this way. Compilers are not the IRS.

| It would be great if some 3GL let us forget about assembly language, but
| in fact every time I want to whack something from a list I must choose
| between delete and remove. Explain to bubba that delete and remove from
| lists are different...no way, you have to talk about implementation, cons
| cells, pointers.

Huh? (let ((x '(1 2 3))) (delete 2 x) (equal x '(1 2 3))) => nil while
(let ((x '(1 2 3))) (remove 2 x) (equal x '(1 2 3))) => t.

| Now to be fair, by saying NIL and '() you are over-specifying, latching
| onto conceptual differences at a finer granularity than the compiler, so
| you are on solid ground. But to me that attitude is dangerous. It relies
| on a fiction. Better to acknowledge the mindset of the compiler, who in
| the end decides the behavior of our so-called high-level code.

Some of us think the specification for the compiler decides the behavior
of the compiler. That some things which produce the same effect but look
different should be treated differently can be exemplified by "its" and
"it's" and by "there" and "their" and "they're", both of which for some
reason do not appear to be distinct to a number of American spellers.

Takehiko Abe

unread,
Nov 22, 2001, 2:50:26 PM11/22/01
to
In article <878zcze...@orion.bln.pmsf.de>, "Pierre R. Mai" <pm...@acm.org> wrote:

> > Why? You immediately know what it does when you see "(when ".
> >
> > I sometimes write
> > (let ((foo (when bar ....)))
> > ...
> >
> > instead of (if bar (progn ....) nil)
>
> You could use (and bar ....) instead. That would make the value more
> explicit to my eyes.

Yes. I agree. I do use (and bar ...) too. I realized that I've been
inconsistent in this.

Thanks,

Kent M Pitman

unread,
Nov 22, 2001, 2:50:11 PM11/22/01
to
t...@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> It certainly feels natural to me anymore (despite the fact that I
> have philosophical issues with it), but then, so do the wacky rules
> of English and French grammar.

[You don't have to take this personally, Thomas. I'm starting from
your remark here because it was a good starting point, but the comments
are directed generally to anyone that "fits the bill"...]

But this is EXACTLY the point people are trying to make.

The Scheme community (and, I would say, the FP community in general)
wants to DEFINE what is natural and easy by a simplicity metric they
pulled out of a hat, as if the very meaning of natural/easy is
uniquely determined/predicted by that simplicity metric. It is not.
That's a possible theory of simplicity, but it is (a) not proven to in
fact make things simpler for most people and (b) not proven to be the
only way to make things simpler for most people.

The Scheme community then works to minimize the number of premises
they work from, as if minimizing this one axis in what is obviously a
multivariate system will yield a consequent minimization of the other
axes by magic. I don't buy that. First, I see language size and
isolated sentence size as inversely correlated. The bigger the
language, the less you have to say. THat is, a language that has has
all 64 crayola crayon colors as primitive concepts is at a marked
advantage for describing a sunset over one that has only the primary
colors plus the modifier words "saturated", "bright", "dark" and
adverbials like "not" and "very". So it may please some teacher of
this Esperanto-like "simple" language to to know he "empowered" people
generally to describe ANYTHING with his tools, but it won't
necessarily please the reader of a fine novel to see the sunset
described as a "very, very, light, unsaturated mix of blue and red" if
what is meant is "lavender". The reason "lavender" works, even though
it takes a long time to learn all the subtle color names, is that your
brain wetware learns to make a primitive connection from this word to
this color and doesn't have to waste compute time simulating things.
Moreover, it can be compared in more "satisfying" ways to other colors
like "orchid" than can "very, very, light ..." be compared to just
"very light..." Sure, you can make all the claims you want about the
extra word "very" being missing giving the same sense, but that still
requires you to remember the *input* string and deal with it as a
formal algebraic string because the human brain is not a precise
enough processor to actually carry the consequence of such thought
exercises primitively. I know my girlfriend often orders a medium
coffee extra extra extra light from Dunkin Donuts but I've seen them
sometimes give her a medium coffee extra extra light, which both
suggests that people receiving such data are bad at holding even that
long a string in their head and that she's unable to hold the precise
notion of that concept in her head.

Now, second, the Scheme community has another very unwarranted premise
underlying a great deal of its teaching, and it overflows sometimes
into design: that's that if they can find a simpler way to express
things (using their simplicity metric: smaller language) that this
will autmatically lead something to be easier to learn. This makes
unstated assumptions about how people think and how people learn. I
claim, without enumerated proof here, but with a belief that at least
I could dredge up proof if I had to because psychologists do research
these things all the time, that the human brain is not like an Intel
box, and that people do not operate on a RISC instruction set. I
think people have a highly parallel associative mechanism capable of
efficiently managing an enormous amount of special cases at the same
time. All naturally-designed human languages that I know of, not
counting the ones that were designed by professional logicians or
computer people, have tons of special cases, have context, etc. Of
course, human languages are all very different, each with their own
idiosyncracies. But what this tells you is that it's ok to have some
variation here. Humans will cope.

I think the fact is that the reason to keep programming languages
simple is not for the sake of humans, but for the sake of code. So
yes, for the sake of code, not making the language too difficult will
make programming easier. But on that we have a 25-or-so year history
during which both Scheme and CL have existed, and in no cases have I
ever seen or heard of someone tearing out their hair and leaving the
CL community saying "I just can't build complex programs because this
NOT/NULL [or false/empty-list] thing is making it too hard to write
metaprograms". It just doesn't happen. So no one ever points to that
as the reason for splitting false/empty-list. They point instead into
the murky depths of the human brain, citing simplicity without
defining their simplicity metric, citing how hard it is for students
to learn (which it is, in the abstract, but mostly because students
are often ill-trained to learn). I sometimes would go so far as to
think some students of Scheme are indoctrinated by some teachers to
actually reject, almost as a political action, the possibility of
receiving certain kinds of learning because they recognize it as not
simple enough. Yet they have somehow managed to recognize and adopt
this whole anti-complexity complexity when it would be simpler to just
learn things than to apply political philosophy to everything you
learn. The only other place I've ever seen that kind of resistance is
in recent converts to this or that church, who are never sure if they
should try to directly understand a truth you're trying to offer them
because they're not sure it's offered to them in a form that it would
be good for them to receive it in.

But to me, the issue of what makes a language easy/hard to use is the
dissonance between the mental representation of the user and the
manifest structure of the program. I have some theories about that,
but I acknowledge this as a hard problem. I'm not trying to argue CL
is an utterly simple language to learn and use. But people do often
claim that Scheme is simple to learn and use, and also that it is
simpler to learn and use than CL, and I'm arguing against accepting
such claims without better proof. If someone doesn't bring either
serious case studies or serious psychological evidence of mental
models into play in the discussion, I think it's worth questioning all
these unstated simplicity metrics that are advanced instead.

On learning and understanding, I think this: Years ago, I taught
myself Portuguese in anticipation of a couple of weeks vacation I was
going to spend in Brasil, it didn't occur to me that it was going to
be pronounced differently than Spanish. When I got to Rio, I found
some people who could understand me and some who couldn't. It wasn't
smart people who understood me and stupid people who didn't. It
crossed those lines. The line I eventually drew was that people who
wanted to understand me (i.e., those who stubbornly resisted
entertaining the implausible notion that what was coming from my mouth
might not be "an attempt at language") had no trouble understanding
me. But those who didn't want to understand me, or didn't mind not
understanding me, looked at me with blank stares. I'm convinced those
people actually had allowed themselves to think "perhaps this isn't
speech but just some kind of useless babble", and the believe that
this "simpler" answer could be true allowed them to rest confident
that not understanding me was the simplest answer to their
conversational dilemma. I really think the same of Lisp. Some people
see the NOT/NULL thing or the false/empty-list thing and decide "it
probably means the langauge is incapable of expressing anything
plainly". And voila, they find proof of their claim in the fact that
they cannot express themselves. Or else they decide that it's just an
artifact of the language that can/must be worked with, and, wonder of
wonders, it never becomes a problem. But the dividing line is not
that language feature.

Languages CAN accomodate ambiguity. (A huge percentage of all words in
all languages have multiple definitions, based on context.) Languages
cannot accomodate a closed mind.

Erik Naggum

unread,
Nov 22, 2001, 2:57:17 PM11/22/01
to
* Thomas F. Burdick

| I don't know that the problem is the inexperienced user.

I think it is. Some people insist on being inexperienced despite their
experience. I think this is a stupid kind of stubbornness, but we find
it in a number of people.

| But our current conception of evolution could very well be off, and I
| don't think it takes a genius to figure out that English is a crazy (if
| practical) language.

But it takes a really smart person to accept it for what it is and not
nurture a desire to change the grammar. The same is true for medicine.
It is pretty easy for anyone who is studying anatomy to figure out ways
that the human body could be improved. Fortunately, the ethical
standards of the medical discipline tend to discourage such desires.

| I *really* just wanted to refute the idea that it was nuts to separate
| NIL and false.

It _is_ nuts. False is defined as nil. Just as true is defined as t.

| For all the arguments in that direction, the obvious usability of Common
| Lisp means that it's also reasonable to conflate them, despite any
| conceptual messiness that might (or might not) entail.

They are not conflated. There is no conceptual messiness. False is
defined as nil. True is defined as t. That is how it is. If you cannot
deal with this, it is only your problem. Augustine's prayer may apply:
God grant me serenity to accept the things I cannot change, courage to
change the things I can, and wisdom to know the difference.

Janis Dzerins

unread,
Nov 22, 2001, 3:12:02 PM11/22/01
to
Erik Naggum <er...@naggum.net> writes:

> That some things which produce the same effect but look different
> should be treated differently can be exemplified by "its" and
> "it's" and by "there" and "their" and "they're", both of which for
> some reason do not appear to be distinct to a number of American
> spellers.

This is nothing new. There is even a paper written with exact rules of
what should be done. Here it is:

A Plan for the Improvement of English Spelling
by Mark Twain

For example, in Year 1 that useless letter "c" would be dropped
to be replased either by "k" or "s", and likewise "x" would no longer
be part of the alphabet. The only kase in which "c" would be retained
would be the "ch" formation, which will be dealt with later. Year 2
might reform "w" spelling, so that "which" and "one" would take the
same konsonant, wile Year 3 might well abolish "y" replasing it with
"i" and Iear 4 might fiks the "g/j" anomali wonse and for all.
Jenerally, then, the improvement would kontinue iear bai iear
with Iear 5 doing awai with useless double konsonants, and Iears 6-12
or so modifaiing vowlz and the rimeining voist and unvoist konsonants.
Bai Iear 15 or sou, it wud fainali bi posibl tu meik ius ov thi
ridandant letez "c", "y" and "x" -- bai now jast a memori in the maindz
ov ould doderez -- tu riplais "ch", "sh", and "th" rispektivli.
Fainali, xen, aafte sam 20 iers ov orxogrefkl riform, wi wud
hev a lojikl, kohirnt speling in ius xrewawt xe Ingliy-spiking werld.

Bruce Hoult

unread,
Nov 22, 2001, 4:42:33 PM11/22/01
to
In article <sfw8zcy...@shell01.TheWorld.com>, Kent M Pitman
<pit...@world.std.com> wrote:

> we have a 25-or-so year history
> during which both Scheme and CL have existed, and in no cases have I
> ever seen or heard of someone tearing out their hair and leaving the
> CL community saying "I just can't build complex programs because this
> NOT/NULL [or false/empty-list] thing is making it too hard to write
> metaprograms". It just doesn't happen. So no one ever points to that
> as the reason for splitting false/empty-list. They point instead into
> the murky depths of the human brain, citing simplicity without
> defining their simplicity metric

Here's what I don't get about CL confusing false and the empty list:
suppose you have a function (foo name) that returns a list of all the
classes being taken by a student. If the function returns NIL, does
that mean that the student is taking no classes at the moment, or does
it mean that the student doesn't exist?

It seems to me that *every* datatype deserves to potentially have a
"don't know" or "doesn't exist" value. Like NULL in SQL. An integer
field in a database can allow NULL, or can be declared to be NOT NULL
and this is an important distinction. In any complex program some code
needs to be written to cope with NULL values, and some code wants to
assume that there is always valid data.

It's bad to use a value of zero in an integer variable to mean NULL.
It's bad to use a value of -1 in an integer variable to mean NULL. It's
also bad, I think, to have a null pointer value in every pointer data
type. How often do C programs fail because some function gets passed a
null pointer that didn't expect it?

It seems to me that using an empty list to represent NULL is just as bad.

-- Bruce

Dr. Edmund Weitz

unread,
Nov 22, 2001, 4:56:10 PM11/22/01
to
Bruce Hoult <br...@hoult.org> writes:

> Here's what I don't get about CL confusing false and the empty list:
> suppose you have a function (foo name) that returns a list of all
> the classes being taken by a student. If the function returns NIL,
> does that mean that the student is taking no classes at the moment,
> or does it mean that the student doesn't exist?

That's what multiple values are for in CL, see the CLHS for GETHASH
for an example.

Edi

Frode Vatvedt Fjeld

unread,
Nov 22, 2001, 4:56:26 PM11/22/01
to
Bruce Hoult <br...@hoult.org> writes:

> Here's what I don't get about CL confusing false and the empty list:
> suppose you have a function (foo name) that returns a list of all
> the classes being taken by a student. If the function returns NIL,
> does that mean that the student is taking no classes at the moment,
> or does it mean that the student doesn't exist?

To me that would be (at least in principle) a poorly specified
function that performs two unrelated tasks: Checking whether a student
exists and listing a student's current classes. Those should be
separate functions, and calling the latter function on an unknown
student would be an error (exceptional situation). If for some reason
those two tasks must be smashed into a single function, good style
would be to return two values from that function. It would also be
possible to return a designated symbol like :no-such-student, although
I'd consider that an inferior option, stylewise.

> It seems to me that *every* datatype deserves to potentially have a
> "don't know" or "doesn't exist" value.

I disagree.

--
Frode Vatvedt Fjeld

Bruce Hoult

unread,
Nov 22, 2001, 5:25:41 PM11/22/01
to
In article <2hlmgy2...@dslab7.cs.uit.no>, Frode Vatvedt Fjeld
<fro...@acm.org> wrote:

> Bruce Hoult <br...@hoult.org> writes:
>
> > Here's what I don't get about CL confusing false and the empty list:
> > suppose you have a function (foo name) that returns a list of all
> > the classes being taken by a student. If the function returns NIL,
> > does that mean that the student is taking no classes at the moment,
> > or does it mean that the student doesn't exist?
>
> To me that would be (at least in principle) a poorly specified
> function that performs two unrelated tasks: Checking whether a student
> exists and listing a student's current classes. Those should be
> separate functions, and calling the latter function on an unknown
> student would be an error (exceptional situation).

Quite possibly, though an exception is a pretty heavy-weight mechanism.
You might also want to delay the exception until the client code
actually tries to use the value inappropriately.


> If for some reason those two tasks must be smashed into a single
> function, good style would be to return two values from that
> function.

That also seems pretty heavy-weight given that you're already taking a
hit for using a dynamically-typed language in which every value has a
general enough representation to be a number, string, symbol or anything
else.


> It would also be possible to return a designated symbol like
> :no-such-student, although I'd consider that an inferior option,
> stylewise.

I think that's a reasonable thing to do, and also that "false" is a
pretty good designated symbol to use.


> > It seems to me that *every* datatype deserves to potentially have a
> > "don't know" or "doesn't exist" value.
>
> I disagree.

So you want to have pairs of variables nearly everywhere, with one being
a boolean saying whether or not the other one is valid? And slots to be
in pairs? And functions to return two values?

Seems very strange when you only need one bit to represent that second
value, and the language you are using has *already* made provision to
incorporate that sort of information in every value. Every value, that
is, except for the empty list.

-- Bruce

Frode Vatvedt Fjeld

unread,
Nov 22, 2001, 5:46:32 PM11/22/01
to
Bruce Hoult <br...@hoult.org> writes:

>> To me that would be (at least in principle) a poorly specified
>> function that performs two unrelated tasks: Checking whether a student
>> exists and listing a student's current classes. Those should be
>> separate functions, and calling the latter function on an unknown
>> student would be an error (exceptional situation).
>
> Quite possibly, though an exception is a pretty heavy-weight
> mechanism. You might also want to delay the exception until the
> client code actually tries to use the value inappropriately.

An error is sort of a heavy-weight thing regardless of the costs
associated with signaling conditions. If signaling an error is the
right thing to do, then not doing so because it is or might be
"heavy-weight" is to me a rather absurd notion.

>> If for some reason those two tasks must be smashed into a single
>> function, good style would be to return two values from that
>> function.
>
> That also seems pretty heavy-weight given that you're already taking
> a hit for using a dynamically-typed language in which every value
> has a general enough representation to be a number, string, symbol
> or anything else.

I don't consider returning multiple values to be prohibitively
expensive except possibly in situations where extreme optimization is
required, in which case the rules of "good style" change
entirely. What good is having a rich language if you can't use it?

> So you want to have pairs of variables nearly everywhere, with one
> being a boolean saying whether or not the other one is valid? And
> slots to be in pairs? And functions to return two values?

I think Common Lisp is excellent evidence that this works out very
well in practice.

--
Frode Vatvedt Fjeld

Kenny Tilton

unread,
Nov 22, 2001, 5:59:00 PM11/22/01
to

Erik Naggum wrote:
> Or (ash x 3) and (* x 8)?

good point. ok, there is no rational basis for me not using '().

> Huh? (let ((x '(1 2 3))) (delete 2 x) (equal x '(1 2 3))) => nil while
> (let ((x '(1 2 3))) (remove 2 x) (equal x '(1 2 3))) => t.

I meant the man on the street would scoff at the idea that removing
something from a list was different from deleting something from a list.
Reminds me of the time (1978) I tried to explain the Basic "x = x + 1"
to a Math teacher. He got pretty upset about that.

kenny
clinisys

Erik Naggum

unread,
Nov 22, 2001, 6:39:13 PM11/22/01
to
* Bruce Hoult

| Here's what I don't get about CL confusing false and the empty list:

Please stop thinking of it as a "confusion", and you may get it.

| suppose you have a function (foo name) that returns a list of all the
| classes being taken by a student. If the function returns NIL, does that
| mean that the student is taking no classes at the moment, or does it mean
| that the student doesn't exist?

Well, read the documentation of the function to find out. What else can
there possibly be to say about this? This is a non-existing problem.

Since you think SQL's NULL is so great, do you get a NULL if the student
whose classes you ask for does not exist? Why would you ask for the
classes of a non-existing student? Not to mention, _how_? Is a student
somehow magically adressable? In other words, what did you give that
function as an argument to identify the student?

| It seems to me that using an empty list to represent NULL is just as bad.

If you need to distinguish the empty list from NULL (nil) in the same
function, your design sucks because you are confused, not the language.

Kent M Pitman

unread,
Nov 22, 2001, 7:24:31 PM11/22/01
to
Bruce Hoult <br...@hoult.org> writes:

> In article <sfw8zcy...@shell01.TheWorld.com>, Kent M Pitman
> <pit...@world.std.com> wrote:
>
> > we have a 25-or-so year history
> > during which both Scheme and CL have existed, and in no cases have I
> > ever seen or heard of someone tearing out their hair and leaving the
> > CL community saying "I just can't build complex programs because this
> > NOT/NULL [or false/empty-list] thing is making it too hard to write
> > metaprograms". It just doesn't happen. So no one ever points to that
> > as the reason for splitting false/empty-list. They point instead into
> > the murky depths of the human brain, citing simplicity without
> > defining their simplicity metric
>

> Here's what I don't get about CL confusing false and the empty list:

> suppose you have a function (foo name) that returns a list of all the
> classes being taken by a student. If the function returns NIL, does
> that mean that the student is taking no classes at the moment, or does
> it mean that the student doesn't exist?
>

> It seems to me that *every* datatype deserves to potentially have a

> "don't know" or "doesn't exist" value. Like NULL in SQL. An integer
> field in a database can allow NULL, or can be declared to be NOT NULL
> and this is an important distinction. In any complex program some code
> needs to be written to cope with NULL values, and some code wants to
> assume that there is always valid data.
>
> It's bad to use a value of zero in an integer variable to mean NULL.
> It's bad to use a value of -1 in an integer variable to mean NULL. It's
> also bad, I think, to have a null pointer value in every pointer data
> type. How often do C programs fail because some function gets passed a
> null pointer that didn't expect it?
>

> It seems to me that using an empty list to represent NULL is just as bad.

I've said I don't have an opposition to more degenerate values. But either
way, it's not a panacea. You're basically saying that for every type FOO
there should be a type (NULL-OF FOO) which is a subtype of FOO and is useful
because it's not one of the ordinary examplars of FOO. Well, first of all,
that's already not the empty list. The empty list is not a non-list, it's
a list that's empty. So the (NULL-OF LIST) would not be NULL but would be
a special non-list list, as opposed to an empty list. Or, at least, I think
it should be. You could probably make the case that the only "valid" lists
had elements, but I don't like that breakdown. You could say it required
the (NULL-OF CONS) for this, and then there'd be discussion about whether
(NULL-OF CONS) could be car'd and cdr'd, since NIL can be, and maybe we'd say
yes, it is secretly a special cons with car and cdr of NIL. But that all
sounds messy. And what about programs that return type (or foo bar). Is
there a type (NULL-OF (OR FOO BAR)) that is distinct from type (NULL-OF FOO)
and type (NULL-OF BAR)? If so, it sounds like a mess to represent and
recognize. But ok, maybe. I didn't think this through utterly but I feel
the phrase "set of all sets not contained in any set" is going to enter this
discussion really soon now... I do know that every time there has been a
serious discussion of solving this, such a bubble really does creep in.
No matter what set someone is returning, there's always a desire to squeeze
in just one extra element ... and often it defeats the whole point of having
picked the size of data storage one has chosen. Just look at NUL-terminated
strings in C vs the ability to hold all 256 characters, or look at the
opposite outcome in the utterly stupid Base64 MIME encoding, which requires
65(!) characters to correctly represent it, so never really compacts up
quite right.

Harald Hanche-Olsen

unread,
Nov 22, 2001, 8:30:07 PM11/22/01
to
+ Kent M Pitman <pit...@world.std.com>:

| No matter what set someone is returning, there's always a desire to squeeze
| in just one extra element ... and often it defeats the whole point of having

| picked the size of data storage one has chosen. Just [...] look at the

| opposite outcome in the utterly stupid Base64 MIME encoding, which requires
| 65(!) characters to correctly represent it, so never really compacts up
| quite right.

I don't quite understand the relevance of this example, since the
purpose of using 64 characters for the Base64 encoding is not, I
believe, compactness of representation, but simplicity of coding and
decoding. But it's true that the "=" padding character is not needed
for Base64 decoding: Just decode the input in groups of 4 characters
each producing 3 octets. Then, when all these groups are used up, you
will be left with 0, 2 or 3 characters which decode into 0, 1 or 2
octets respectively. So in this sense I can concur with your
characterization of Base64 as stupid. But compared to the use of NUL
to terminate C strings it seems to me a minor stupidity indeed.

--
* Harald Hanche-Olsen <URL:http://www.math.ntnu.no/~hanche/>
- Yes it works in practice - but does it work in theory?

Lieven Marchand

unread,
Nov 22, 2001, 5:37:27 PM11/22/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> isn't there a funny essay somewhere about the consequences of porting
> something from Lisp to Scheme, specifically about the problem of having
> to then differentiate between nil and false? I recall assoc figuring
> prominently in the piece.

http://www.lisp.org/humor/large-programs.html

--
Lieven Marchand <m...@wyrd.be>
She says, "Honey, you're a Bastard of great proportion."
He says, "Darling, I plead guilty to that sin."
Cowboy Junkies -- A few simple words

Pierre R. Mai

unread,
Nov 23, 2001, 1:02:41 AM11/23/01
to
Bruce Hoult <br...@hoult.org> writes:

> Here's what I don't get about CL confusing false and the empty list:
> suppose you have a function (foo name) that returns a list of all the
> classes being taken by a student. If the function returns NIL, does
> that mean that the student is taking no classes at the moment, or does
> it mean that the student doesn't exist?

How do you know that the function is going to return at all, if you
call it with the name of a non-student? That's right, you will look
at the specification of that function. And that's exactly where your
answer will be found. If the author of the function cosidered it
useful to conflate "student doesn't exist, and therefore doesn't take
any courses" and "student exists, but still doesn't take any courses"
(which can be very useful in quite a number of occasions), then it
will return the empty list in either case, and the documentation will
state that. Note that it would do this, even if NIL were unequal to
(). It is not trying to say don't know in the one case, and no
courses in the other, it is saying no courses in both cases, and that
is _exactly_ what it wants to say.

If the author thinks that those cases need to be distinguished, he has
any number of possible ways of communicating the difference. For
example he can use mulitple values, with the secondary value
indicating whether the student existed at all.

But mostly, if the difference between non-existing and
existing-but-course-less students is really relevant, I'd specify foo
to signal an error if passed the name of a non-student.

> It seems to me that *every* datatype deserves to potentially have a
> "don't know" or "doesn't exist" value. Like NULL in SQL. An integer

[...]

> type. How often do C programs fail because some function gets passed a
> null pointer that didn't expect it?

This is a direct contradiction to your previous statement. Either
every datatype deserves its own "don't know" or "doesn't exist" value,
which a null pointer in C arguably is, because it _can't_ clash with
any valid pointer value, or we forbid "don't know" values, because we
fear that receivers might not anticipate them and fail to handle them
correctly. Making a distinction between NIL and () isn't going to
solve the problem of functions blowing up if they get NIL instead of
something they expected (like a person object), in fact it is going to
_worsen_ the situation, because all list processing functions know how
to deal with empty lists, but now that NIL != () they are _more_
likely to blow up if handed NIL, when they aren't going to expect it.

> It seems to me that using an empty list to represent NULL is just as bad.

Well, a lot of things seem to me to be the case, when I sit in my
armchair and muse about the state of the world. Lucky for you I don't
share all of them with c.l.l.

Unless someone can demonstrate real problems when programming within
CL that are caused by (eq 'NIL '()), I consider it a worse problem
that so much time is wasted on discussing that non-issue, than any
problems that (eq 'NIL '()) could imaginably create, if it were indeed
a problem at all, which I don't see.

I think such issues should be decided based on some form of real-life
data, and not on armchair musing.

I have yet to see one bug that was caused by (eq 'NIL '()) tripping up
some minimally-competent programmer (i.e. one that didn't just start a
CL implementation by accident, when he really was expecting Scheme, or
some other language), or forcing someone to write noticably more
convoluted code because of it.

Kent M Pitman

unread,
Nov 23, 2001, 2:26:55 AM11/23/01
to
"Pierre R. Mai" <pm...@acm.org> writes:

> Bruce Hoult <br...@hoult.org> writes:
...
> > type. How often do C programs fail because some function gets passed a
> > null pointer that didn't expect it?
>
> This is a direct contradiction to your previous statement. Either
> every datatype deserves its own "don't know" or "doesn't exist" value,
> which a null pointer in C arguably is, because it _can't_ clash with
> any valid pointer value, or we forbid "don't know" values, because we
> fear that receivers might not anticipate them and fail to handle them
> correctly.

Yes, indeed. A *huge* number of Java programming errors that I've seen
people have great difficulty tracking down are due to the failure of
people to have to use a separated null type. In effect, every type is
secretly (or null the-type-i-thought-i-was-getting) and the syntax encourages
people to not remember the null, so they are continually baffled by the fact
that such a "typesafe"(R) language has lied to them. I had forgotten
about this horrifyingly common syndrome at the office where I found myself
watching this play out day after day after day, but that is certainly enough
all by itself to make me think I'm glad we don't have null objects PER SE
for all of our types. That doesn't mean at all that I mind having empty
lists or empty strings when they are properly degenerate cases of a more
general class and all the operators work on them in the expected way.

Pierre R. Mai

unread,
Nov 23, 2001, 1:46:23 AM11/23/01
to
Bruce Hoult <br...@hoult.org> writes:

> In article <2hlmgy2...@dslab7.cs.uit.no>, Frode Vatvedt Fjeld
> <fro...@acm.org> wrote:
>
> > Bruce Hoult <br...@hoult.org> writes:
> >
> > > Here's what I don't get about CL confusing false and the empty list:
> > > suppose you have a function (foo name) that returns a list of all
> > > the classes being taken by a student. If the function returns NIL,
> > > does that mean that the student is taking no classes at the moment,
> > > or does it mean that the student doesn't exist?
> >
> > To me that would be (at least in principle) a poorly specified
> > function that performs two unrelated tasks: Checking whether a student
> > exists and listing a student's current classes. Those should be
> > separate functions, and calling the latter function on an unknown
> > student would be an error (exceptional situation).
>
> Quite possibly, though an exception is a pretty heavy-weight mechanism.
> You might also want to delay the exception until the client code
> actually tries to use the value inappropriately.

Why would that be an appropriate thing to do? This seems like the C
philosophy of doing error-checking: "Never report errors at the place
where they actually occurred (calling a function that is specified to
take the name of an existing student with something else), but delay
it as long as necessary to destroy all relevant context; make it
maximally inconvenient to check for error situations; and above all
else, rather crash maximally fast, or produce wrong results, than
throwing away one instruction on detecting errors".

If that is your attitude about error checking, than I don't think that
(eq 'nil '()) is something you need to fret about, for a looong time.

Furthermore why care about the cost of exceptions in such a situation?
Unless your program is buggy as hell (i.e. calls foo with non-student
names all of the time, in-spite of foo's specification), that is. If
it is important to differentiate between non-students and students
with no courses, _you don't call foo with an unchecked name_. Period.

You write instead:

(defun bar (some-random-name)
(cond
((student-p name)
(let ((courses (foo name)))
;; Do something silly here...
))
(t
;; Do something differently silly here...
)))

The only thing that a non-nil "NULL" value would give you here, is the
ability to write instead

(defun bar (some-random-name)
(let ((courses-or-student-status (foo name)))
(cond
((not courses-or-student-status)
;; Do something differently silly here...
)
(t
;; Do something silly with courses-or-student-status here, but
;; we now know it actually is a list, not some overloaded
;; other return value-type...
))))

And that's the point where I'm thanking the powers that were, that we
don't see this kind of code all over the place. FOO should never have
been specified like this in the first place, if there really is a
difference between non-students and students with no courses. What
would be a descriptive name for foo? STUDENT-COURSES-AND-STUDENT-P?

> > If for some reason those two tasks must be smashed into a single
> > function, good style would be to return two values from that
> > function.
>
> That also seems pretty heavy-weight given that you're already taking a
> hit for using a dynamically-typed language in which every value has a
> general enough representation to be a number, string, symbol or anything
> else.

Multiple values are cheap in serious implementations. If I were prone
to armchair musing, I might conjecture that distinguishing between
'NIL and '() would have higher costs in terms of register and cache
pressure (as well as tag "pressure"), than pervasive usage of
two-value functions.

> > It would also be possible to return a designated symbol like
> > :no-such-student, although I'd consider that an inferior option,
> > stylewise.
>
> I think that's a reasonable thing to do, and also that "false" is a
> pretty good designated symbol to use.

Well you can already do this. You just have to write

(eq courses-or-student-status #f)

instead of

(not courses-or-student-status)

Not that I would consider code that did this to be well written code.
It actively encourages the same kind of lossage you get in C, where we
have all of those "failure" indicating values, that you have to
manually check, and if you don't (who does), work very nicely to
increase the time between error occurrance and error detection.

Regardless of any (eq 'NIL '()) issue, I can't see any justifiable
reason (senseless obsession about speed isn't one), for a function
student-courses that returns anything but a list (or other collection
datastructure). Either you define non-students names to be valid
arguments to that function, then you should just return the empty list
(collection, whatever) for non-students, or you say "student-courses
is actually not defined for non-students", in which case you signal an
error when called with a non-student name.

I'm even critical of a multiple-value version that _additionally_
indicates whether we're really talking about a student. But in cases
where this is justified, that additional value doesn't say "the
primary value is valid or not". The primary value is always valid,
and has the normal meaning. The secondary value just _adds_
additional information. Doing anything else just opens the door for
undetected error situations. We could then just as well be doing
errno in Common Lisp...

Doing anything else is just plain bad code in my book.

> > > It seems to me that *every* datatype deserves to potentially have a
> > > "don't know" or "doesn't exist" value.
> >
> > I disagree.
>
> So you want to have pairs of variables nearly everywhere, with one being
> a boolean saying whether or not the other one is valid? And slots to be
> in pairs? And functions to return two values?

I'm beginning to wonder if you have actually ever looked at real
Common Lisp code. How do you come up with such completely foolish
ideas? No one is suggesting such foolishness, because nothing of the
sort is necessary. If your code makes that kind of nonsense
necessary, by conflating validity information and data content in one
place all over the place, then it is bad code, for reasons that are
completely unrelated to the topic under discussion.

Bruce Hoult

unread,
Nov 23, 2001, 2:50:17 AM11/23/01
to
In article <sfwr8qq...@shell01.TheWorld.com>, Kent M Pitman
<pit...@world.std.com> wrote:

> I've said I don't have an opposition to more degenerate values. But
> either way, it's not a panacea. You're basically saying that for
> every type FOO there should be a type (NULL-OF FOO) which is a subtype
> of FOO and is useful because it's not one of the ordinary examplars
> of FOO.

Close, but not quite. I think it's more about bindings (and
declarations of them as in, for example, CLOS method arguments) than
about objects. And CL as it is is very nearly what I'm talking about,
with the single exception of the list type.

- you should be able to have a binding that you know has a valid value
of the appropriate type

- you should be able to have a binding that might contain a valid value,
or might contain the NULL value

- it's handy if the NULL value tests as false in conditional expressions

- I don't really care whether there is a different (NULL-OF FOO) for
each type, but I'd suggest that it's fine to have them all be the same,
e.g. #F. More efficient to test for, too.


> Well, first of all, that's already not the empty list. The empty list
> is not a non-list, it's a list that's empty. So the (NULL-OF LIST)
> would not be NULL but would be a special non-list list, as opposed to
> an empty list. Or, at least, I think it should be.

I agree.


> You could probably make the case that the only "valid" lists
> had elements, but I don't like that breakdown.

Sometimes that's useful, but not often. The Dylan <list> class has two
subclasses, <pair> and <empty-list>. <empty-list> has a single
instance, #(). So you can specialize a method on <list> and get either
an empty or a non-empty list, or you can specialize on <pair> and get a
guaranteed non-empty list.


> You could say it required the (NULL-OF CONS) for this, and then there'd
> be discussion about whether (NULL-OF CONS) could be car'd and cdr'd,
> since NIL can be, and maybe we'd say yes, it is secretly a special cons
> with car and cdr of NIL. But that all sounds messy.

Very. I'd think it should throw an exception.


> And what about programs that return type (or foo bar). Is there a type
> (NULL-OF (OR FOO BAR)) that is distinct from type (NULL-OF FOO)
> and type (NULL-OF BAR)? If so, it sounds like a mess to represent and
> recognize.

I agree. Easiest thing is to make (NULL-OF (OR FOO BAR)) be the same
object as (NULL-OF FOO) and (NULL-OFF BAR). I can't see any downside to
this, and NIL already plays this role in CL. That is to say, (NULL-OF
(OR FOO BAR)) can be NIL and the return type of a function that might
return a FOO or a BAR or NIL is (OR FOO BAR NULL).

This is all fine in CL already, *except* that a the list type is (OR
CONS NULL) and (NULL-OF (OR CONS NULL)) is NIL, which is a valid list.
That's why it would be better if there was a distinct "false" value
which wasn't the same as an empty list.


> No matter what set someone is returning, there's always a desire
> to squeeze in just one extra element ... and often it defeats the
> whole point of having picked the size of data storage one has
> chosen.

Sure. That's another good reason that you should be able to specify
that some particular binding or slot CAN'T be NULL.

-- Bruce

Erik Naggum

unread,
Nov 23, 2001, 5:10:16 AM11/23/01
to
* Bruce Hoult

| - I don't really care whether there is a different (NULL-OF FOO) for
| each type, but I'd suggest that it's fine to have them all be the same,
| e.g. #F. More efficient to test for, too.

The way you deal with these things for efficiency is to accept arguments
of any complex (or ...) type you want, but then you something like this

(typecase <arg>
(<type-1>
(locally (declare (type <type-1> <arg>))
...))
(<type-2
(locally (declare (type <type-2> <arg>))
...)))

This particular situation may actually be pre-optimized by your compiler
with appropriate locally forms and declarations inserted for you.

| This is all fine in CL already, *except* that a the list type is (OR
| CONS NULL) and (NULL-OF (OR CONS NULL)) is NIL, which is a valid list.
| That's why it would be better if there was a distinct "false" value
| which wasn't the same as an empty list.

"Better" in the absence of a context or a purpose renders the whole
statement completely meaningless. Most of the time, context-free
"better" simply means "better for me, regardless of consequences or what
other people need", and such statements should simply be ignored. I
would say they are arbitrary (which is even worse and more misleading
than if they were false) because of the absence of specific meaning.

I believe the only productive way to learn a new skill is to open one's
mind to the superior knowledge of those who already know it well and
really listen to their tales of what they went through to get where they
are today. If you come from somewhere else and have a different history
behind you, whatever you come to will look strange, but if you think what
you came from must always be more important than what you are going to,
and some people mysteriously believe this _unconditionally_, it will be
too hard for them to get into anything new, so they give up, and instead
go on and on about how wrong what they came to is. There are immigrants
in every culture who keep longing for their past and denouncing their new
living conditions for their entire life, but yet do not return. I do not
understand what is so special about what one accidentally met _first_
that makes everything one meets later on _productively_ judged by it.

Rahul Jain

unread,
Nov 23, 2001, 5:17:39 AM11/23/01
to
e...@agharta.de (Dr. Edmund Weitz) writes:

> That's what multiple values are for in CL, see the CLHS for GETHASH
> for an example.

Or conditions, if that's the way that's most natural to handle it in
your application. (Maybe seeing an unknown student means that either
the input is bogus or there's an inconsistency in the database or
something)

--
-> -/- - Rahul Jain - -\- <-
-> -\- http://linux.rice.edu/~rahul -=- mailto:rahul...@usa.net -/- <-
-> -/- "I never could get the hang of Thursdays." - HHGTTG by DNA -\- <-
|--|--------|--------------|----|-------------|------|---------|-----|-|
Version 11.423.999.220020101.23.50110101.042
(c)1996-2000, All rights reserved. Disclaimer available upon request.

Bruce Hoult

unread,
Nov 23, 2001, 5:30:05 AM11/23/01
to
In article <87vgg28...@orion.bln.pmsf.de>, "Pierre R. Mai"
<pm...@acm.org> wrote:

> Bruce Hoult <br...@hoult.org> writes:
>
> > It seems to me that *every* datatype deserves to potentially have a
> > "don't know" or "doesn't exist" value. Like NULL in SQL. An integer
>
> [...]
>
> > type. How often do C programs fail because some function gets passed a
> > null pointer that didn't expect it?
>
> This is a direct contradiction to your previous statement.

No, it's an illustration of the dangers of not having a proper
distinguished value for NULL.


> Either every datatype deserves its own "don't know" or "doesn't exist"
> value, which a null pointer in C arguably is, because it _can't_ clash
> with any valid pointer value, or we forbid "don't know" values, because
> we fear that receivers might not anticipate them and fail to handle them
> correctly.

There is a guarantee in C that no object has an address equal to the
null pointer, but there is no type that says "this pointer points to a
genuine object, and NOT to null". That's the problem. C++ tries to get
around this using references, but even they can be subverted with a bit
of hackery:

struct foo {int x};
foo *a = 0;
foo &b = *a;

b.x = 13; // oops!


This can't happen in, say, Dylan because there are no null pointers. If
you have something like...

define class foo(<object>)
slot x :: <integer>;
end;

let a :: <foo> = ...;

a.x := 13;

... then there is guaranteed to be no error in the assignment of 13 to
a.x.

If you actually *want* to have a null value then you do it explicitly:

let a :: type-union(singleton(#"null-value"), <foo>) = ...;

Conventionally the null value used is always #f -- the canonical "false"
-- and there is a standard function that makes it more convenient to
create these union types:

let a :: false-or(<foo>) = ....;

when (a)
a.x := 13
end


> Making a distinction between NIL and () isn't going to
> solve the problem of functions blowing up if they get NIL instead of
> something they expected (like a person object),

It has no effect in that case.

> in fact it is going to _worsen_ the situation, because all list
> processing functions know how to deal with empty lists, but now
> that NIL != () they are _more_ likely to blow up if handed NIL,
> when they aren't going to expect it.

No, that's an improvement, because such a situation is a programming
error, and you will now discover the error (and fix it) much sooner.


> > It seems to me that using an empty list to represent NULL is just as
> > bad.
>
> Well, a lot of things seem to me to be the case, when I sit in my
> armchair and muse about the state of the world. Lucky for you I don't
> share all of them with c.l.l.

I didn't start this thread.

Furthermore, I have a lot of experience in a language in which a false
value is not a list, so it's hardly armchair musing when I say that it's
a damn good idea to separate the two notions.


> I have yet to see one bug that was caused by (eq 'NIL '()) tripping up
> some minimally-competent programmer (i.e. one that didn't just start a
> CL implementation by accident, when he really was expecting Scheme, or
> some other language), or forcing someone to write noticably more
> convoluted code because of it.

That's a great stock answer that can be used to justify any "feature" in
any language or indeed application program. "If you were an expert in
this program then you wouldn't have any problems. How do we know if
you're an expert? Because you don't have any problems, of course!"

Cool.

Don't worry. CL is totally perfect just as it is. No other language,
past, future or present ever had any idea better than the ideas already
present in CL. Where CL is more flexible than other languages it's
because such complexity is necessary. Where CL is more restrictive than
othe languages it is because more generality is unnecessary.

I get it now.

-- Bruce

Bruce Hoult

unread,
Nov 23, 2001, 5:52:14 AM11/23/01
to
In article <32154810...@naggum.net>, Erik Naggum <er...@naggum.net>
wrote:

> * Bruce Hoult
> | - I don't really care whether there is a different (NULL-OF FOO) for
> | each type, but I'd suggest that it's fine to have them all be the same,
> | e.g. #F. More efficient to test for, too.
>
> The way you deal with these things for efficiency is to accept
> arguments
> of any complex (or ...) type you want, but then you something like this
>
> (typecase <arg>
> (<type-1>
> (locally (declare (type <type-1> <arg>))
> ...))
> (<type-2
> (locally (declare (type <type-2> <arg>))
> ...)))

That's right, except that you can't in CL distinguish between the empty
list and false.

Everything else is fine.


> I believe the only productive way to learn a new skill is to open one's
> mind to the superior knowledge of those who already know it well and
> really listen to their tales of what they went through to get where
> they are today. If you come from somewhere else and have a different
> history behind you, whatever you come to will look strange, but if you
> think what you came from must always be more important than what you
> are going to, and some people mysteriously believe this
> _unconditionally_, it will be too hard for them to get into anything
> new, so they give up, and instead go on and on about how wrong what
> they came to is.

That's a pretty much completely useless argument. How are we then to
distinguish me starting with Dylan and taking a look at CL from Erik
Naggum starting with CL and taking a look at Dylan? Are we doomed to
always disagree? I hope not.

Furthermore, it's not even a *correct* representation of the situation.
I learned Lisp 1.5 long before I learned Dylan. Contrary to your "baby
duck syndrome" supposition, I saw that very many things in Dylan are
done far better than in Lisp 1.5, separation of the concepts of false
and empty list being just one of them.

And that's not even counting the various other journeys. My first
programming language was FORTRAN IV. I saw that Pascal was bette, and
moved to that, and then later saw that Modula-2 was better and moved to
that. Then I learned C and saw that it was better than Pascal but worse
than Modula-2 and stayed with Modula-2. Then C++ came along and I saw
that it was better than Modula-2 and moved to it. Then Java came along
and I saw that it was worse than C++ + Boehm so I stayed with C++. Oh,
and I didn't mention the Data General machine I used in 1985 - 1986
which had only FORTRAN, COBOL and PL/1 available and so I choose to use
PL/1, that being the best of a bad lot. Or probably another dozen or
more languages along the way that I've learned, evaluated, and either
used or discarded.

-- Bruce

Kenny Tilton

unread,
Nov 23, 2001, 6:50:40 AM11/23/01
to

Bruce Hoult wrote:
>
> In article <32154810...@naggum.net>, Erik Naggum <er...@naggum.net>
> wrote:

.......


> > I believe the only productive way to learn a new skill is to open one's

> > mind to the superior knowledge of those who already know it well .....


>
> That's a pretty much completely useless argument. How are we then to
> distinguish me starting with Dylan and taking a look at CL from Erik
> Naggum starting with CL and taking a look at Dylan? Are we doomed to
> always disagree? I hope not.

You won't /always/ disagree because over time you get acquainted with
the different approach and your opinions will converge.

One of the things I sense about Lisp is that it has developed for a very
long time under the hands of folks who are insanely obsessed with doing
the Right Thing, and I think a large part of the determination of what
is the Right Thing comes from What Would A Reasonable Person Expect. And
so a Reasonable Person programs Lisp like a hot knife through warm
butter. But I digress.

A good example was my shift from MCL to ACL. My first reaction to ACL
was yechhh. But I figured it was just because I was used to MCL. Sure
enough, I now have no problems with ACL (and would probably have trouble
getting back into MCL).

So the point is, if you think the folks who created X gave it some
thought, take a few months to get into X before you dis it.

kenny
clinisys

Scott McKay

unread,
Nov 23, 2001, 1:36:44 PM11/23/01
to

"Bruce Hoult" <br...@hoult.org> wrote in message
news:bruce-9A9045....@news.paradise.net.nz...

>
> It seems to me that *every* datatype deserves to potentially have a
> "don't know" or "doesn't exist" value.

I thought this for a short while designing Dylan, but I changed my
mind pretty quickly. You can see where this leads with 'null' in
Java; Java's 'null' is, in some sense, typed, but the problem is that
'null' doesn't obey any of the protocols of the type.

Dylan has proper support for type unions, and we all realized that
'type-union(<integer>, singleton(#f))' -- or 'false-or(<integer>)',
since there's a standard extension macro -- is preferable. It allows
the possibility of a "null" without all the headaches, and it means that
in the usual case you can generate tighter code.

Pierre R. Mai

unread,
Nov 23, 2001, 1:58:58 PM11/23/01
to
Bruce Hoult <br...@hoult.org> writes:

> There is a guarantee in C that no object has an address equal to the
> null pointer, but there is no type that says "this pointer points to a
> genuine object, and NOT to null". That's the problem. C++ tries to get

That is a complaint about the weak type system that C has, which I can
sympathise with. If I wanted to program in a statically typed
language, I'd want a type system that is at least as powerful as that
most modern functional programming languages enjoy, with type-inference
thrown in.

> > in fact it is going to _worsen_ the situation, because all list
> > processing functions know how to deal with empty lists, but now
> > that NIL != () they are _more_ likely to blow up if handed NIL,
> > when they aren't going to expect it.
>
> No, that's an improvement, because such a situation is a programming
> error, and you will now discover the error (and fix it) much sooner.

It isn't a programming error. The callee is quite capable of handling
the empty list, and the caller has decided that it wants the NIL case
to be treated identically. The callee doesn't have to be written to
handle the NIL case.

What is the fix? Instead of

(defun foo (x)
(bar (list-or-nil-returner x)))

(defun bar (list)
(dolist (elem list) (print elem)))

you want to see either

(defun foo (x)
(let ((result (list-or-nil-returner x)))
(bar (if (valid-p result) ;; Could be only result if NIL != ()
result
'()))))

(defun bar (list)
(dolist (elem list) (print elem)))

or

(defun foo (x)
(bar (list-or-nil-returner x)))

(defun bar (list-or-nil)
(let ((list (if (valid-p list-or-nil) list-or-nil '())))
(dolist (elem list) (print elem))))

I think the first replacement is the better one, if bar can be
specified to just handle lists. But the fact of the matter is that
the original code is completely equivalent to that replacement, not
only in effect, but also in communicated intent.

> > > It seems to me that using an empty list to represent NULL is just as
> > > bad.
> >
> > Well, a lot of things seem to me to be the case, when I sit in my
> > armchair and muse about the state of the world. Lucky for you I don't
> > share all of them with c.l.l.
>
> I didn't start this thread.

So what?

> Furthermore, I have a lot of experience in a language in which a false
> value is not a list, so it's hardly armchair musing when I say that it's
> a damn good idea to separate the two notions.

But it is! The experience you have in Dylan counts as zero when
discussing the problems of Common Lisp. _They are different
languages_! Language features aren't orthogonal, they live in the
ecology of a whole language. Language feature A might be very
problematic in language 1, but pose no problems at all in language 2,
because it interacts very differently with other language features in
those languages, and with idiomatic programming in those languages.

So your experience with Dylan can support the claim "There is at least
one language where completely separating false and every other
datatype worked out great". Since I don't have enough experience with
Dylan, I can neither refute nor confirm that claim for Dylan, but I
have used a number of other programming languages that did this, and
didn't find any problems with this approach.

What your experience doesn't support is the claim "(eq NIL ()) is a
problem in Common Lisp", or the broader claim "Identifying the false
value and some value of another datatype is wrong or problematic in
any language".

What my experience with CL does support is that (eq NIL ()) is not a
problem I have ever encountered in serious use of Common Lisp:

> > I have yet to see one bug that was caused by (eq 'NIL '()) tripping up
> > some minimally-competent programmer (i.e. one that didn't just start a
> > CL implementation by accident, when he really was expecting Scheme, or
> > some other language), or forcing someone to write noticably more
> > convoluted code because of it.
>
> That's a great stock answer that can be used to justify any "feature" in
> any language or indeed application program. "If you were an expert in
> this program then you wouldn't have any problems. How do we know if
> you're an expert? Because you don't have any problems, of course!"

Who said anything about experts? I qualified my statement with
minimally competent, becaue we sadly get lots of people over here who
program in CL without having any knowledge of the language, assuming
they can just carry over their knowledge of Scheme, or some other
language. I don't think the problems they present are to be taken
seriously.

If I were to start programming in Dylan, and stumbled across the
"problem" that Dylan seals its GFs by default, since I, not having
read anything about Dylan and blissfully assuming that this works
just like in CL, ran into large numbers of errors. Now tell me, is my
having problems indicative of Dylan having a problem, or is it not
indicative of _me_ having a serious problem?

So we are not speaking about normal users having problems, we are
speaking about misguided individuals having problems.

> Don't worry. CL is totally perfect just as it is. No other language,

It isn't. There are a number of things that I find problematic. One
such problem is the fact that LOOP is specified not to allow the
intermixing of VARIABLE-CLAUSES and MAIN-CLAUSES:

<quote hyperspec>
loop [name-clause] {variable-clause}* {main-clause}*
</quote>

Since termination tests are part of the main-clauses, you can't write

(loop for x = (foo ...)
while x
for y = (do-something-with-non-null x)
for z = (bar y)
do
...)

This in itself causes one to write more convoluted code in such
situtions, especially if one can't fold the binding of y and z into a
LET construct, because one wants to use them in further loop clauses.

One of the better possibilities is

(loop for x = (foo ...)
for test = (unless x (loop-finish))
for y = (do-something-with-non-null x)
for z = (bar y)
do
...)

[Thanks Kent for reminding me about this possibility]

As I think you'll agree this is ugly, and non-obvious.

Furthermore this problem is aggravated by the fact that nearly all
LOOP implementations _do_ support this kind of intermingling, but
often without specifying the exact semantics of such a thing. This
leads many people astray, blissfully assuming that it is well
specified portable code they are writing, until some new LOOP
implementation coughs at their code, hopefully producing warnings, but
possibly producing false iteration code instead.

And it isn't a problem that only seriously misguided people
encounter. Even people well versed in the language make that slip
from time to time, as can be seen by the fact that Kent posted an
erroneous example only recently. Same thing happened to me lots of
times, until I have become paranoid enough that I check every loop
form I stumble across for that mistake. This is clearly an indication
that something is amiss here.

How to solve that problem is another question, of course. Reopening
the standard is out of the question for some time to come, so some
other solution will have to be found.

> past, future or present ever had any idea better than the ideas already
> present in CL. Where CL is more flexible than other languages it's
> because such complexity is necessary. Where CL is more restrictive than
> othe languages it is because more generality is unnecessary.

You seem to cling to the idea of a "perfect" language, and real
languages trying to approach that singularly-defined state of
perfection as a limit.

That is IMHO completely wrong. Many, many decisions of languages have
to be judged subjectively by that language's community.

For example, Dylan is more static than CL in a number of areas, and
defaults to the static choice in a number of places (e.g. sealing GFs
by default). So tell me, which is the better language, which made the
better choices? I don't think this is a sensible question. I think
CL made the correct choices with regards to the CL community, and
Dylan did so with regards to the Dylan community. Neither is a priori
better than the other, they are different, because the members of
their communities value things differently, and likely also write
different programs.

That doesn't mean that it isn't possible to criticize a language, it
just means that you have to do it from the point of view of someone
writing non-trivial programs in it.

What would you think of a German, who came to England, and started to
criticize the English language based on the little he knows about it,
and the many great ideas that German qua language embodies? The fact
that you can't just directly transplant language features from German
to English, and that things that would have been problems in German
aren't in English (and vice-versa), doesn't mean that one can't engage
in informed criticism of the language, it just means that one has to
inform oneself about the language, as used by the people, before one
can do so.

> I get it now.

I somehow doubt that very much...

Erik Naggum

unread,
Nov 23, 2001, 4:00:12 PM11/23/01
to
* Bruce Hoult

| That's right, except that you can't in CL distinguish between the empty
| list and false.

Geez, could you quit carping about this and start _listening_ some day
soon? That distinction is made in the protocol described in the
documentation of the function you are using. It is never a problem
because Common Lisp programmers do not _want_ to use false and the empty
list at the same time any more than C programmers want to put null bytes
in their strings or put any objects at the very beginning of memory.

It is the Sapir-Whorff hypothesis all over again. Because the language
does not do it, its (smarter) programmers do not want to do it. You want
to do something like this because you have yet to internalize the rules
of the language. The more you think it is "wrong", the less likely you
are to grasp what the rules of the language _are_.

| That's a pretty much completely useless argument.

Yeah, I figured you would not get it. I think you are a waste of time
this time, too. You are one of those guys who make up their mind what
the world should be like, and then blame the world for not conforming.
It is _not_ Common Lisp's fault you do not like some of its features.
There is consequently nothing that _Common_Lisp_ can do to fix this.

Scott McKay

unread,
Nov 23, 2001, 7:33:32 PM11/23/01
to

"Scott McKay" <s...@mediaone.net> wrote in message
news:MhsL7.1926$oV2.8...@typhoon.ne.mediaone.net...

>
> "Bruce Hoult" <br...@hoult.org> wrote in message
> news:bruce-9A9045....@news.paradise.net.nz...
> >
> > It seems to me that *every* datatype deserves to potentially have a
> > "don't know" or "doesn't exist" value.
>
> I thought this for a short while designing Dylan, but I changed my
> mind pretty quickly. You can see where this leads with 'null' in
> Java; Java's 'null' is, in some sense, typed, but the problem is that
> 'null' doesn't obey any of the protocols of the type.

Who is this prat "SWM" and did he design Dylan?

Sorry -- I didn't design Dylan. I meant "while Dylan was being
designed, I used to think this, too". I do not mean to take credit
for the design of very much of the Dylan language. Sorry.

Bruce Hoult

unread,
Nov 23, 2001, 11:47:02 PM11/23/01
to
In article <MhsL7.1926$oV2.8...@typhoon.ne.mediaone.net>, "Scott
McKay" <s...@mediaone.net> wrote:

> "Bruce Hoult" <br...@hoult.org> wrote in message
> news:bruce-9A9045....@news.paradise.net.nz...
> >
> > It seems to me that *every* datatype deserves to potentially have a
> > "don't know" or "doesn't exist" value.
>
> I thought this for a short while designing Dylan, but I changed my
> mind pretty quickly. You can see where this leads with 'null' in
> Java; Java's 'null' is, in some sense, typed, but the problem is that
> 'null' doesn't obey any of the protocols of the type.

You are mistaking my meaing. Or I wasn't clear enough, or something.
Null in Java is evil because there is no way to express the idea that
you have a variable that is known to *not* be null.

What I want intead is a "null" value that is not in fact a member of
*any* normal type, but which can be (OR ...)'d with any type to make a
new type-that-includes-null. The null value/type should not be a membe
of any normal type, which means it should not be, for example, a valid
list.


> Dylan has proper support for type unions, and we all realized that
> 'type-union(<integer>, singleton(#f))' -- or 'false-or(<integer>)',
> since there's a standard extension macro -- is preferable. It allows
> the possibility of a "null" without all the headaches, and it means that
> in the usual case you can generate tighter code.

Yes, this is a beautiful thing, and highly practical.

The only downside is that Dylan doesn't then have a proper <boolean>
type. type-union(<boolean>, singleton(#f)) is the same as <boolean>,
which is bad. But it's better than the false value being a valid list.

-- Bruce

Erik Naggum

unread,
Nov 24, 2001, 12:52:06 AM11/24/01
to
* Bruce Hoult

| You are mistaking my meaing. Or I wasn't clear enough, or something.
| Null in Java is evil because there is no way to express the idea that you
| have a variable that is known to *not* be null.

After a test for null, is that not precisely what you have?

| The null value/type should not be a membe of any normal type, which means
| it should not be, for example, a valid list.

Could you _please_ start to explain _why_ these random things you keep
carping about being "better" and "should" are just that? All we get from
you are random _conclusions_ and nothing at all to support them if one
happens to disagree with those conclusions. That _must_ mean there is
absolutely nothing to them.

Get over your personal hangup and just accept the language for what it
is. _Nothing_ will _ever_ happen to the language just because you keep
having these problems. Nobody is interested in your lack of will to
accept the language while you are learning it. It is fantastically
annoying to have ignorant spluts keep arguing about things they do not
like about the language. What do you nutballs expect to happen? Is this
how you cope with _unchangeable_ things in general? I do not expect you
to accept any other people's decisions any more than that if* guy did,
either, but it only makes you look _really_ stupid to those who manage to
live with the language. What do you _want_? If you have no other mission
here than to get "sympathy" for your personal problem of accepting what
you cannot change, I think the whole thing really reeks. Get over it and
move on, or back to perfect Dylan or whatever the fuck you really need.

Kenny Tilton

unread,
Nov 24, 2001, 7:17:39 AM11/24/01
to
Did someone say "relax"?

Erik Naggum wrote:
>
> Could you _please_ start to explain _why_ these random things you keep

> carping about being "better" and "should" are just that? ...
> Get over your personal hangup....Nobody is interested in your lack of
> will...It is fantastically annoying to have ignorant spluts keep arguing


> about things they do not

> like...What do you nutballs expect to happen?...it only makes you look
> _really_ stupid.....your personal problem of accepting what


> you cannot change, I think the whole thing really reeks. Get over it and
> move on, or back to perfect Dylan or whatever the fuck you really need.

What justifies this bilious spew? Aside from it being great fun to write
and read.

Here is something I have practicing lately in professional email and NG
postings. After I write something I go back over and eliminate
everything in the second person from sensitive material. Programmers are
sensitive; our asses are always on the line. When code breaks, the
author gets beeped. Sometimes fired.

So where I have originally written "in convert-date-to-inches you use
the metric conversion..." I go back and change that to
"...convert-date-to-inches uses a metric conversion. maybe we should use
english...".

The article to which I respond uses the second person 23 times in
fourteen sentences (counting the third person bit about ignorant spluts
as 5). Ouch. Now excuse we while I go look up "splut".

kenny
clinisys

Erik Naggum

unread,
Nov 24, 2001, 5:15:42 PM11/24/01
to
* Kenny Tilton
| [...] this bilious spew? [...]

Now your article looks much better, does it not? Context be damned! Let
us all only select the individual words we do not like and respond to each.

But to answer your stupid question: The text you elided in order to post
your venomous response, of course.

Learn to recognize a troll who is not after solving any problems, but
only seeks _sympathy_ for his problems. My guess is he only needs
someone to say they agree with him that it is bad design to "confuse" the
empty list and nil, and he will feel much better about himself. What
would actually _solve_ his problem, would, of course, be to _understand_
the issue, but sympathy-seekers are prevented from understanding because
there is no sympathy in understanding. Understanding yields joy, not
shared suffering -- that is the result of its opposite.

Thomas F. Burdick

unread,
Nov 24, 2001, 7:27:12 PM11/24/01
to
Bruce Hoult <br...@hoult.org> writes:

> In article <sfw8zcy...@shell01.TheWorld.com>, Kent M Pitman

> <pit...@world.std.com> wrote:
>
> > we have a 25-or-so year history
> > during which both Scheme and CL have existed, and in no cases have I
> > ever seen or heard of someone tearing out their hair and leaving the
> > CL community saying "I just can't build complex programs because this
> > NOT/NULL [or false/empty-list] thing is making it too hard to write
> > metaprograms". It just doesn't happen. So no one ever points to that
> > as the reason for splitting false/empty-list. They point instead into
> > the murky depths of the human brain, citing simplicity without
> > defining their simplicity metric
>

> Here's what I don't get about CL confusing false and the empty list:

> suppose you have a function (foo name) that returns a list of all the
> classes being taken by a student. If the function returns NIL, does
> that mean that the student is taking no classes at the moment, or does
> it mean that the student doesn't exist?

Well, that's a lousy interface (to the function foo). I can see two
good ways to fix it:

1. FOO returns two values, the first being the list, the second
being a boolean, true if the student was found, as with GETHASH.

2. FOO returns the list, and signals an error if the student is not
found. If the caller is expecting there to be a high proportion
of unknown students, the cost of this situation can be reduced
somewhat by having the keyword arugments :error-p and
:error-value, as with READ.

One thing that's very nice about having a Really Big language is that
(iff it's well-designed, as CL is) the language itself offers good
design examples. If you're having a problem expressing something,
first see if CL deals with similar situations, and see how it deals
with them. (AMOP is also quite good for this).

As I said before, the NIL-the-symbol/NIL-the-boolean/NIL-the-empty-list
thing causes occasional philisophical angst for me, but no practical
problems that good design couldn't solve.

> It seems to me that using an empty list to represent NULL is just as bad.

Er, I hope you meant "to represent false", because null-ness is a
property of lists (or sets, or ...), not booleans.

--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'

Thomas F. Burdick

unread,
Nov 24, 2001, 7:43:40 PM11/24/01
to
"Pierre R. Mai" <pm...@acm.org> writes:

This is a very good analogue. I started this strand of this thread,
not as a criticism of CL's design choice (which, in practice, works
just fine in CL, and has yet to cause me a practical problem), but
rather as a defense of another choice as reasonable. I still think a
reasonable language, similar to CL, but differing in its goals, could
make the other choice without pain.

French has some very cool things that are missing from English.
Borrowing cool things where you can works out pretty well, in practice
(cf. the English language). Trying to force the fundemental,
incompatible ideas of one language onto another just makes a mess (eg,
when people try to make English a Romance language), even if those
ideas were perfectly wonderful in the original language (cf. French).
Design choices cannot be made independently of one another, which
means there will never be a perfect language, any more than there will
be a perfect organism -- the best one can hope for is a perfect fit
for its environment/user-base.

Boris Schaefer

unread,
Nov 24, 2001, 10:36:28 PM11/24/01
to
* Bruce Hoult <br...@hoult.org> wrote:
|
| Here's what I don't get about CL confusing false and the empty list:
| suppose you have a function (foo name) that returns a list of all
| the classes being taken by a student. If the function returns NIL,
| does that mean that the student is taking no classes at the moment,
| or does it mean that the student doesn't exist?

I don't think your problem is with CL "confusing" false and the empty
list.

Suppose you have a function (takes-class-p name class), that checks
whether a student takes a specific class at the moment. If the
function returns NIL, does that mean that the student is not taking
that class at the moment, or does it mean that the student doesn't
exist?

I think your problem is with bad documentation.

Boris

--
bo...@uncommon-sense.net - <http://www.uncommon-sense.net/>

Laugh and the world thinks you're an idiot.

Nicolas Neuss

unread,
Nov 25, 2001, 5:01:53 PM11/25/01
to

During an earlier thread on the NIL/false issue, Kent Pitman pointed
to a website with a very interesting discussion of this issue (if I
remember correctly, it was within the ANSI committee). Unfortunately,
I can't find that link anymore. Could someone help me?

Thank you, Nicolas.

P.S.: Sorry, if it was mentioned already in this thread. I couldn't
bear reading this never-ending story in whole length again...

Kent M Pitman

unread,
Nov 25, 2001, 5:50:00 PM11/25/01
to
Nicolas Neuss <ne...@ortler.iwr.uni-heidelberg.de> writes:

The ANSI group didn't have a web site, so this isn't enough
information to jog my memory. Maybe someone else will remember
another clue.

Nicolas Neuss

unread,
Nov 26, 2001, 10:00:20 AM11/26/01
to

I'm sorry, I messed this up. The reference I had in mind was about
another "hot" topic, namely the single namespace vs. double namespace
issue. Of course, when adjusting my memory, I found the reference
immediately. It is your report (together with Gabriel)

http://world.std.com/~pitman/Papers/Technical-Issues.html

A pity, that there is nothing similar for the nil/false issue.

Anyway, I'm sorry for my confusion.

Yours, Nicolas.

Tim Bradshaw

unread,
Nov 26, 2001, 1:07:46 PM11/26/01
to
Kent M Pitman <pit...@world.std.com> wrote in message news:<sfwr8qq...@shell01.TheWorld.com>...

> And what about programs that return type (or foo bar). Is
> there a type (NULL-OF (OR FOO BAR)) that is distinct from type (NULL-OF FOO)
> and type (NULL-OF BAR)? If so, it sounds like a mess to represent and

> recognize. But ok, maybe. I didn't think this through utterly but I feel
> the phrase "set of all sets not contained in any set" is going to enter this
> discussion really soon now... I do know that every time there has been a
> serious discussion of solving this, such a bubble really does creep in.

> No matter what set someone is returning, there's always a desire to squeeze
> in just one extra element ... and often it defeats the whole point of having
> picked the size of data storage one has chosen.

I think it's at least some exponential blowup thing. If you have n
basic types, then I think you have 2^n possible types like (or ...),
and you want each of these to have a distinct NULL-OF, so you need 2^n
distinct values.
And we have satisfies as a type descriptor too (oops, lots and *lots*
of NULL-OFs now), and what about (null-of (or foo (member (null-of
foo)))), or even better (null-of (not (member (null-of foo))))?

--tim

Kenny Tilton

unread,
Nov 27, 2001, 4:23:14 AM11/27/01
to

Erik Naggum wrote:
>
> * Kenny Tilton
> | [...] this bilious spew? [...]

That's a great compression algorithm, is it not? A little lossy in that
it tosses all civil discourse and keeps only the fighting words, but
there's the benefit, we don't have to wade thru the tedious material
stuff to get to the fireworks. Glad to see the 98% compression achieved
on my post.

>
> But to answer your stupid question: The text you elided in order to post
> your venomous response, of course.
>

Turn about is fair play, but FWIW my intent was pacifistic and
compassionate. And as a faithful reader of such threads I was honestly
puzzled as to how we got from zero to sixty in one article. Most folks
earn their incinerations by pursuing the threads beyond reason,
something not evident in this case.

> Learn to recognize a troll...

Fine, but missing from the above digest is my implication that a master
of relaxation would take such common NG conduct in stride.

[aside: the 2nd-Person scoring was off last time; it was the use
injunctions such as "Learn to..." that should count as five YOUs.]

It's a shame to see such incredible energy, devotion, and intellect
tilting at trolls, if*, and dictionary entries. I'd rather see a sit-in
staged at the most prestigious university not teaching Lisp. Students
would go crazy over a trash-talking, "bad boy" of computer science, John
McEnroe meets Sean Penn, high-intellect act.

You're the rock star of Common Lisp. Get your head out of c.l.l. and go
win us some converts.

kenny
clinisys

Janis Dzerins

unread,
Nov 27, 2001, 10:16:05 AM11/27/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> You're the rock star of Common Lisp. Get your head out of c.l.l. and
> go win us some converts.

I don't understand why some people are obsessed by the idea that
Common Lisp needs converts. I even think that converts that have to be
won should better stay away from Common Lisp.

--
Janis Dzerins

Eat shit -- billions of flies can't be wrong.

Vebjorn Ljosa

unread,
Nov 27, 2001, 10:49:01 AM11/27/01
to
* Janis Dzerins <jo...@latnet.lv>

| Kenny Tilton <kti...@nyc.rr.com> writes:
|
| > You're the rock star of Common Lisp. Get your head out of c.l.l. and
| > go win us some converts.
|
| I don't understand why some people are obsessed by the idea that
| Common Lisp needs converts. I even think that converts that have to be
| won should better stay away from Common Lisp.

Hrmf. Heretic. :)

--
Vebjorn Ljosa

Kenny Tilton

unread,
Nov 27, 2001, 10:53:50 AM11/27/01
to

Janis Dzerins wrote:
>
> Kenny Tilton <kti...@nyc.rr.com> writes:
>
> > You're the rock star of Common Lisp. Get your head out of c.l.l. and
> > go win us some converts.
>
> I don't understand why some people are obsessed by the idea that
> Common Lisp needs converts. I even think that converts that have to be
> won should better stay away from Common Lisp.

I agree, actually. The unmentioned alternative to a university sit-in
would be simply to do great things with CL and not worry about what
other people think.

If CL had as many users as Java, Python, or Perl I think we would all
benefit, but I do not see that ever happening. I /do/ see other
languages continuing to pick up on CL features such as GC,
introspection, anonymous functions, GFs, macros so that if CL finally
dies it will have already been reborn in other HLLs.

kenny
clinisys

Janis Dzerins

unread,
Nov 27, 2001, 11:23:02 AM11/27/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> Janis Dzerins wrote:
> >
> > Kenny Tilton <kti...@nyc.rr.com> writes:
> >
> > > You're the rock star of Common Lisp. Get your head out of
> > > c.l.l. and go win us some converts.
> >
> > I don't understand why some people are obsessed by the idea that
> > Common Lisp needs converts. I even think that converts that have
> > to be won should better stay away from Common Lisp.
>
> I agree, actually. The unmentioned alternative to a university
> sit-in would be simply to do great things with CL and not worry
> about what other people think.

Oh, I see you're trying to be funny. But we don't have to dismiss
_all_ others. I just came up with a first criterion that people who I
would listen to would have to satisfy: they must have read at least
one standard (be it a programming language or community accepted
protocol, like most internet protocols) and don't complain about how
stupid one thing or another in it is (without having a better
solution).

> If CL had as many users as Java, Python, or Perl I think we would
> all benefit, but I do not see that ever happening. I /do/ see other
> languages continuing to pick up on CL features such as GC,
> introspection, anonymous functions, GFs, macros so that if CL
> finally dies it will have already been reborn in other HLLs.

And we especially don't need people talking about the death of Common

Erik Naggum

unread,
Nov 27, 2001, 1:23:37 PM11/27/01
to
* Kenny Tilton <kti...@nyc.rr.com>

| Turn about is fair play, but FWIW my intent was pacifistic and
| compassionate.

Yes, intent is all that counts.

| And as a faithful reader of such threads I was honestly puzzled as to how
| we got from zero to sixty in one article. Most folks earn their
| incinerations by pursuing the threads beyond reason, something not
| evident in this case.

Huh? Bruce Hoult has been carping on the same stupid "confusion" for
years. Nothing ever happens. No understanding. Just pauses between
reiterations and regurgitations of the same stale arguments.

| You're the rock star of Common Lisp. Get your head out of c.l.l. and go
| win us some converts.

As most rock stars, I think I should go despair about my popularity.

///
--
The past is not more important than the future, despite what your culture
has taught you. Your future observations, conclusions, and beliefs are
more important to you than those in your past ever will be. The world is
changing so fast the balance between the past and the future has shifted.

Kenny Tilton

unread,
Nov 27, 2001, 1:56:48 PM11/27/01
to

Janis Dzerins wrote:
>
> Oh, I see you're trying to be funny.

No, implicit in my suggestion was the energy I saw being misdirected at
defending CL, I gathered in the hope someday of greater use. Given that
goal apparently sought by others, I recommended more aggressive action
crucially outside c.l.l.

I am on the fence. I would love to see CL take over the world, but I am
not going to worry about it, I am just trying to do good work with CL.

And I definitely agree with the immediate point to which I responded:
too aggressive a netting might snare the wrong fish. CL would be wasted
on anyone who does not get it. But the only way to choose the few is to
call the many, perhaps with a bullhorn at some prestigious university.

>
> And we especially don't need people talking about the death of Common
> Lisp.

CL is too good to be threatened by things like NG articles, and it is
too good to die. To die something better must come along, and that is
impossible because CL could become that better thing and do so better
than does the thing itself. Look at OO and CLOS. This is why Arc may be
a wrong turn.

kenny
clinisys

Kenny Tilton

unread,
Nov 27, 2001, 2:25:39 PM11/27/01
to

Erik Naggum wrote:
>
> Huh? Bruce Hoult has been carping on the same stupid "confusion" for
> years.

Oh, OK. Sometimes the existence of a certain amount of history is
apparent in these threads, this time I did not pick that up.

kenny
clinisys

Andreas Bogk

unread,
Nov 27, 2001, 2:31:01 PM11/27/01
to
Erik Naggum <er...@naggum.net> writes:

> Get over your personal hangup and just accept the language for what it
> is. _Nothing_ will _ever_ happen to the language just because you keep
> having these problems. Nobody is interested in your lack of will to
> accept the language while you are learning it. It is fantastically

Can anybody explain to me why some people regard the Common Lisp
standard as gospel? What happened to the spirit of continuous
improvement that has led Lisp through the decades?

Andreas

--
"In my eyes it is never a crime to steal knowledge. It is a good
theft. The pirate of knowledge is a good pirate."
(Michel Serres)

Andreas Bogk

unread,
Nov 27, 2001, 2:55:37 PM11/27/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> One of the things I sense about Lisp is that it has developed for a very
> long time under the hands of folks who are insanely obsessed with doing
> the Right Thing, and I think a large part of the determination of what
> is the Right Thing comes from What Would A Reasonable Person Expect. And

I hoped that it would be like this.

But I'm seeing a lot of "Common Lisp does it that way and you need to
swallow it", and a lot of people who seem to have forgotten that
Common Lisp is man-made (and even designed by a committee and full of
bad compromises and legacy crap).

We folks from the Dylan community see ourselves as part of the Lisp
community. That's not only because most of the Dylan designers were
also involved in the Common Lisp standardization process, but also
because the heritage shows in a lot of places, ranging from the object
system (modelled after CLOS), the optimzation theory (type
annotations), first class functions, to the UI framework (CLIM
vs. DUIM), the general compiler theory etc. We're interested in an
honest discussion on what the Right Thing is (and yes, Dylan has it's
shortcomings too).

Andreas Bogk

unread,
Nov 27, 2001, 3:02:46 PM11/27/01
to
Erik Naggum <er...@naggum.net> writes:

> It is _not_ Common Lisp's fault you do not like some of its features.
> There is consequently nothing that _Common_Lisp_ can do to fix this.

Yes, but Lisp can fix it.

Wade Humeniuk

unread,
Nov 27, 2001, 3:32:02 PM11/27/01
to
> > It is _not_ Common Lisp's fault you do not like some of its features.
> > There is consequently nothing that _Common_Lisp_ can do to fix this.
>
> Yes, but Lisp can fix it.
>

It is not broken. It is a feature not a mistake. If some people are not
happy with CL then they can write a new Lisp in CL (as a new shadowed
package, or would people rather write it in C?). Nothing is stopping them,
create a language that has false.

Wade


Erik Naggum

unread,
Nov 27, 2001, 3:34:23 PM11/27/01
to
* Kenny Tilton
| No, implicit in my suggestion was the energy I saw being misdirected at
| defending CL, I gathered in the hope someday of greater use.

Please let each person determine what is the "greater use" of their own
energy, as long as it is not harmful.

| Given that goal apparently sought by others, I recommended more
| aggressive action crucially outside c.l.l.

How do you know about happens outside c.l.l? How would you discover that
whatever it is you would recommend is actually done?

| I am on the fence. I would love to see CL take over the world, but I am
| not going to worry about it, I am just trying to do good work with CL.

I would not like CL take over the world, because that which takes over
the world, is taken over by the world. Considering what the world does
to other things it has taken over, it would be terrible, terrible fate.

| This is why Arc may be a wrong turn.

I have briefly looked at Arc. It is yet another demonstration of the
problem of too strong an ego that cannot live with what somebody else has
made. Be it the standard conditionals, nil versus false versus the empty
list, or whatever else this purportedly strong ego is too weak to accept,
it is nothing more than proof of the core problem of the IT world -- the
hardness of its pillars makes them brittle, not strong, so they cannot be
used to build upon. What was it that stood so much in the way that Paul
Graham could not have accomplished it without creating a new language?
Why was creating a new language and starting from scratch better than
building on what had come before? Why is the IT world defined by people
who are unable to deal with the concepts of continuity, longevity, and
design for long-term stability? Why do they believe they are so much
smarter than everything that has gone before them, when they clearly are
not and repeat mistakes that take years to undo, if not replaced by
another stupid "revolution" that itself starts from scratch?

If people built societies the way computer people build communities, we
would still live have small warring tribes and no concept of a law that
binds all people and absolutely no concept of a constitution that binds
lawmakers. For all the talk about the Internet changing the world, we
lag the real world by about 40,000 years when it comes to how we make
lots of people who do _not_ agree to everything live and work together.

Suddenly, I feel old and tired.

///
--
The past is not more important than the future, despite what your culture
has taught you. Your future observations, conclusions, and beliefs are
more important to you than those in your past ever will be. The world is
changing so fast the balance between the past and the future has shifted.

Erik Naggum

unread,
Nov 27, 2001, 3:56:10 PM11/27/01
to
* Erik Naggum
> Get over your personal hangup and just accept the language for what it
> is. _Nothing_ will _ever_ happen to the language just because you keep
> having these problems. Nobody is interested in your lack of will to
> accept the language while you are learning it.

* Andreas Bogk
| Can anybody explain to me why some people regard the Common Lisp standard
| as gospel?

Well, why do you regard it as gospel? Why do _you_ think in such terms?
Explain this, and you will be much closer to the wisdom you seek.

| What happened to the spirit of continuous improvement that has led Lisp
| through the decades?

The keyword here is "continuous". At some point, some people decided
that the only way to achieve improvement would be through discontinuity
and revolution, through many meaningless changes they could achieve some
small meaningful one. These people have only succeeded in one thing: To
instill this meme in so many people that they do not even _try_ to make
continuous improvements, anymore. Whey they fail again and again to
achieve improvement with their revolutions, they argue that stronger and
more powerful revolutions are necessary, when in fact it was the idea
that revolutions are necessary that caused them to fail. Smaller egoes
and more purpose would have made them succeed, because what they need to
succeed with is not to build a whole new world from scratch, but to make
those who already live in one to accept their improvements. If they do
not, accept that, too, and try again. Accepting defeat is perhaps the
only true evidence of personal strength. Refusing to accept defeat and
believing that if you only try the exact same thing again over and over
you will some day get a different result, is simply the insanity of weak
minds that refuse to let go of their one chance at success and greatness.

Every bit of progress has cost thouands of setbacks, but each did in fact
not set the whole industry back because one did _not_ start from scratch
with every "invention". Because of the continuity, one built upon what
already existed and found an acceptable way to achieve one's goal until
the underlying changes were being made by those who were motivated by the
success of the visible changes.

Erik Naggum

unread,
Nov 27, 2001, 4:10:44 PM11/27/01
to
* Andreas Bogk
| But I'm seeing a lot of "Common Lisp does it that way and you need to
| swallow it", and a lot of people who seem to have forgotten that
| Common Lisp is man-made (and even designed by a committee and full of
| bad compromises and legacy crap).

So are the laws of any given country. You do not break them because you
object to them, you enter politics and obey the laws while you change
them. If you are the fucking clueless moron who breaks laws you do not
like, you are nothing but a retarded criminal. Why the criminal mind is
so important to hold up as a role model for social change is beyond me.

| We folks from the Dylan community see ourselves as part of the Lisp
| community.

You seem to be quite alone in this regard, especially considering your
hang to insult other Lisp communites and waltz in with stupid concerns
that simply are _not_ concerns except to outsiders. As convicted felons
protest their innocence, but would not improve unless they accepted that
they are guilty and the fate of the guilty, any random outsider who does
not accept that complaining about non-issues is stupid or the negative
consequences of such actions, will never be part of that community.

| We're interested in an honest discussion on what the Right Thing is (and
| yes, Dylan has it's shortcomings too).

A good start would be to accept the choices people have made. Coming
into a new community and accusing people of regarding their standards as
"gospel" because you want to be a criminal in that community is not a
good start. Strive not to be an outsider. Do _not_ see yourself as an
outsider. (There are no "insiders", but people who choose to regard
themselves as if they are always doomed to stand outside and look in,
have no hope of ever gaining any useful information about what they keep
looking at and not understanding. Part of relinquishing the "outsider"
status is to accept that other people have accepted certain things, and
that they are _not_wrong_ in doing so even if you think it is not right.
In time, you will see the wisdom that there are more than one right, that
the idea that there is "one right" is wrong, but that this does not mean
that one cannot determine that something will always be wrong no matter
what is right.)

Wade Humeniuk

unread,
Nov 27, 2001, 4:34:32 PM11/27/01
to
>
> | This is why Arc may be a wrong turn.
>
> I have briefly looked at Arc. It is yet another demonstration of the
> problem of too strong an ego that cannot live with what somebody else
has
> made. Be it the standard conditionals, nil versus false versus the
empty
> list, or whatever else this purportedly strong ego is too weak to
accept,
> it is nothing more than proof of the core problem of the IT world -- the
> hardness of its pillars makes them brittle, not strong, so they cannot
be
> used to build upon. What was it that stood so much in the way that Paul
> Graham could not have accomplished it without creating a new language?
> Why was creating a new language and starting from scratch better than
> building on what had come before? Why is the IT world defined by people
> who are unable to deal with the concepts of continuity, longevity, and
> design for long-term stability? Why do they believe they are so much
> smarter than everything that has gone before them, when they clearly are
> not and repeat mistakes that take years to undo, if not replaced by
> another stupid "revolution" that itself starts from scratch?
>

I went to an OO conference in Santa Clara,1991. At lunch time I sat down
with this older gentleman, maybe in his fifties. The first thing he asked
me was, "We are a Cobol shop, have been for a long time, I am here to see if
we have to change. Things seem to be working fine for us. Do you think we
have to change?". Now, not knowing Cobol, and thinking for literally 2
seconds I said "No." He seemed immensely relieved and I am sure that he
went back and continued in Cobol.

There is alot to be said for sticking with an approach and not giving into
the calls to change everything. Computing seems to have really hard hit by
this reinvention syndrome, maybe because its largest group of developers are
young competitive men. Trying to kill the older males off I suppose,
primevel instincts coupled with above average intelligence. Driving them
off the "kill" (so to speak). Maybe Microsoft is successful since Gate's
personality is strong enough to subdue the rabble at the gates (eheh, images
of Frankenstein come to mind). Perhaps the young males energies should be
harnessed into much more difficult projects until they mellow out a bit.

Wade

Kent M Pitman

unread,
Nov 27, 2001, 5:46:21 PM11/27/01
to
Erik Naggum <er...@naggum.net> writes:

> * Erik Naggum
> > Get over your personal hangup and just accept the language for what it
> > is. _Nothing_ will _ever_ happen to the language just because you keep
> > having these problems. Nobody is interested in your lack of will to
> > accept the language while you are learning it.
>
> * Andreas Bogk
> | Can anybody explain to me why some people regard the Common Lisp standard
> | as gospel?
>
> Well, why do you regard it as gospel? Why do _you_ think in such terms?
> Explain this, and you will be much closer to the wisdom you seek.
>
> | What happened to the spirit of continuous improvement that has led Lisp
> | through the decades?
>

> The keyword here is "continuous". [...]

I'll put the same thought another way. I'd say the keyword was
"improvement".

CL provides a base from which to move *forward*. Re-analyzing the base is
not moving forward but *laterally*.

No one denies that there can be hill-climbing problems in any field,
requiring some backup before moving forward. But the cost of backing out
of assumptions is generally higher than the cost of not doing so, so to
not be causing people gratuitous extra cost, one would want to justify the
need to back up.

Of course, not everyone ever moved forward to use all of what ANSI CL
has in the first place. Such people don't feel the cost of backing up
in the same way as people who did. That leads to people talking at
crossed purposes about what the "big deal" is. To those who have an
investment in a certain way of doing things, it is a major big deal
and the cost is not just "belief" (those who are not invested probably
think it's all a matter of "saving face" or "people being stuck in
their thoughts" as if reading a new paper could change them out of it)
but "action" (this translates quickly to "dollars" in translation,
quality assurance, etc. and steals precious budget form "finishing
product", "marketing", "new features", etc.).

So to Andreas my question back would be...

"Can anybody explain to me why some people regard musical standards as
a good use of anyone's time?" Even just discussing it seems unproductive.

I don't mean discussing technical flaws--that makes sense. But discussing
the conceptual gestalt and trying to get community consensus that "the
standard should be deviated from" seems pointless. People have the ability
to answer this question each individually for themselves; no group consensus
is required. And one reason it's important to have a standard is that
standards are convergent. Those of adhering have a community of common
knowledge to share. Not adhering is divergent; non-adherents don't always
have something to share since they may diverge in different ways. In that
sense, a discussion of Python or Dylan as a specific alternative is better
than a mere bitch session on why people don't like what they have.

Jochen Schmidt

unread,
Nov 27, 2001, 7:51:53 PM11/27/01
to

# Kenny Tilton <kti...@nyc.rr.com> wrote to Bruce Hoult:
| One of the things I sense about Lisp is that it has developed for a very
| long time under the hands of folks who are insanely obsessed with doing
| the Right Thing, and I think a large part of the determination of what
| is the Right Thing comes from What Would A Reasonable Person Expect. And

# Andreas Bogk answered to Kenny Tilton:
| I hoped that it would be like this.


|
| But I'm seeing a lot of "Common Lisp does it that way and you need to
| swallow it", and a lot of people who seem to have forgotten that
| Common Lisp is man-made (and even designed by a committee and full of
| bad compromises and legacy crap).

No you don't have to swallow it. You can decide to use CL or not but
bitching around on things that _you_ as a non-CL user don't like is not
particularily fair.

The points critizized here in this thread (nil/false/'()...) seem to be no
"bug" or "design-error" to the _users_ of the language but instead of that
- a _feature_ . It is simply not enough to conclude that it is a
design-error in Common Lisp if it could be counted as a design-error in a
completely other language (like Dylan - if you count that as lisp or not).

Do you think it is a good idea for a basketball player to go to a football
club and criticizing them for using the feet to hit the ball because this
is a particular bad idea in contrast to the higher agility they would have
using their hands?

Another claim you mindlessly reuse here as a fact is that nonsense that a
language designed by a commitee is bad from it's beginnings. Compromises do
not _need_ to be bad - sometimes a compromise is (seen at a whole) _much_
better than any of the possible extremes. The good thing of design by a
(good) commitee (like in any good democraty) is that it is seldom that
_critical_ flaws end up in the result.

# Andreas Bogk continues to answer to Kenny Tilton:


| We folks from the Dylan community see ourselves as part of the Lisp

| community. That's not only because most of the Dylan designers were
| also involved in the Common Lisp standardization process, but also
| because the heritage shows in a lot of places, ranging from the object
| system (modelled after CLOS), the optimzation theory (type
| annotations), first class functions, to the UI framework (CLIM
| vs. DUIM), the general compiler theory etc. We're interested in an


| honest discussion on what the Right Thing is (and yes, Dylan has it's
| shortcomings too).

I personally see it as a bad point that Dylan omitted s-expressions since
they are an important part of the "magic" behind lisp. But I don't think
that Dylan is broken because of this fact - it simply changed it's audience
to people that do not see or do not want the benefits of s-expression
notation. The bad thing is that some Dylan users tend to claim to new users
interested in lisp that Dylan is unconditionally better for them because it
does not have "this many ugly parens". This claims imply that it is a
bug to have s-expressions and even worse - it omits that it is maybe a
_loss_ for Dylan not having them!!!

The bad thing when discussing about "The Right Thing" is that it simply
does not exist out of context. A particular language, a community and even
an implementation all define contexts that have to be taken into account
when searching for "the Right Thing". Even if the context is well defined
it happens from time to time that "the Right Thing" is ambiguous.

I'm too very interested in discussing language issues - but I think it is
not a _honest_ discussion if on participant claims that the others are
wrong because _oneself_ did it the other way!

Ask yourself what the real reasons are behind that particular wish of
discussion - is it _really_ for finding the "Right Thing"? (which would
imply to be _open_ for solutions that are different to your own!) Or is it
maybe more like pushing of the own way to others?
Is this _really_ about investigating if CL is good or what could be done
better in Dylan? To me it looks more like marketing and advertising Dylan
here in c.l.l - and not like "honest discussion".

ciao,
Jochen

--
http://www.dataheaven.de

Lieven Marchand

unread,
Nov 27, 2001, 4:36:33 PM11/27/01
to
Andreas Bogk <and...@andreas.org> writes:

> But I'm seeing a lot of "Common Lisp does it that way and you need to
> swallow it", and a lot of people who seem to have forgotten that
> Common Lisp is man-made (and even designed by a committee and full of
> bad compromises and legacy crap).

I'm not sure where you see this, but perhaps I'm too close to it. One
argument that is less important to the Dylan community then to the CL
community is the cost of change. There is a larger amount of CL code
around, more CL books and tutorials and more CL implementations, so
any proposed change not only has to prove its use, but also its cost
effectiveness. For a lot of the minor things where people argue about,
changing them wouldn't be worth it even if you could convince
everyone.

Even perfect updates to the standard have a cost. Consider the
changes between Ada 83 and Ada 95. There is a large consensus in the
Ada community that Ada 95 is a far better language then Ada 83. But
the real or perceived cost and difficulty of complying to the new
standard has made a number of commercial implementors decide to drop
their Ada offerings, which has caused problems where platforms no
longer had a commercially available Ada compiler.

--
Lieven Marchand <m...@wyrd.be>
She says, "Honey, you're a Bastard of great proportion."
He says, "Darling, I plead guilty to that sin."
Cowboy Junkies -- A few simple words

Andreas Bogk

unread,
Nov 27, 2001, 5:30:38 PM11/27/01
to
"Wade Humeniuk" <hume...@cadvision.com> writes:

> > Yes, but Lisp can fix it.
> It is not broken.

People's opinion about this one varies, as well as about other
features. The argument "It's not broken because CL says so" doesn't
count. I'm interested in arguments that sound like "CL does the Right
Thing because..." or "CL does the Wrong Thing because...".

I'm sure you can think of CL features that bother you enough that you
would change them if given the chance, but not enough to keep you from
using CL.

> It is a feature not a mistake.

This sounds like a Microsoft argument. There are such things as
misfeatures.

> If some people are not
> happy with CL then they can write a new Lisp in CL (as a new shadowed

Now this sounds like the typical argument of defenders of C: "I can
show you that my language is Turing-complete, so I can solve any
problem you can."

I can write my new Lisp in itself, as it is expected from any serious
language.

> package, or would people rather write it in C?). Nothing is stopping them,
> create a language that has false.

Been there, done that, trying to share the experience. Well,
actually, I just help maintaining the Gwydion Dylan system, and was
neither involved in the design of the language nor it's
implementation, people smarter than me from the Lisp community have.

Andreas

--
"In my eyes it is never a crime to steal knowledge. It is a good
theft. The pirate of knowledge is a good pirate."
(Michel Serres)

Andreas Bogk

unread,
Nov 27, 2001, 6:10:56 PM11/27/01
to
Erik Naggum <er...@naggum.net> writes:

> | Can anybody explain to me why some people regard the Common Lisp standard
> | as gospel?
> Well, why do you regard it as gospel? Why do _you_ think in such terms?

I don't. I suggested that you do, based on your "it is the way it is,
get over with it" argument.

Dylan was designed based on the experience with other Lisp
designs. When I see a difference between the way CL does something,
and the way Dylan does it, I ask myself if this is by design or by
accident, and whether the modification is the Right Thing or the Wrong
Thing. It is interesting to get the opinions of seasoned CLers on
these features, even if I have a bias from my prior experience and
might not agee with them. After all, everyone is biased.

> Explain this, and you will be much closer to the wisdom you seek.

Ho-hum. I guess I'll have to wait for your answer before
enlightenment sets in.

> | What happened to the spirit of continuous improvement that has led Lisp
> | through the decades?
> The keyword here is "continuous". At some point, some people decided
> that the only way to achieve improvement would be through discontinuity
> and revolution, through many meaningless changes they could achieve some
> small meaningful one. These people have only succeeded in one thing: To
> instill this meme in so many people that they do not even _try_ to make
> continuous improvements, anymore. Whey they fail again and again to
> achieve improvement with their revolutions, they argue that stronger and
> more powerful revolutions are necessary, when in fact it was the idea
> that revolutions are necessary that caused them to fail. Smaller egoes

I'm from East Germany, and have been there when the Berlin Wall came
down. Don't tell me revolutions don't happen, I have been part of
one.

But I think your general insight is correct, there ought to be a
balance of change. Both lack of change and too much change are
dangerous to the stability of a system.

What I am perceiving (and this is as subjective as it gets) is a lack
of change.

> and more purpose would have made them succeed, because what they need to
> succeed with is not to build a whole new world from scratch, but to make
> those who already live in one to accept their improvements. If they do

Again an interesting observation. Let me know, what change would you
accept?

> not, accept that, too, and try again. Accepting defeat is perhaps the
> only true evidence of personal strength. Refusing to accept defeat and
> believing that if you only try the exact same thing again over and over
> you will some day get a different result, is simply the insanity of weak
> minds that refuse to let go of their one chance at success and greatness.

It is only insanity if you don't learn from your failures, and don't
get a different result next time. Maybe you won't succeed, because
the challenge is bigger than a lifetime, but that doesn't mean trying
is futile. Unless, of course, you hide your results from the world.

I'd even go as far as saying that *only* failures lead to genuine
insight, whereas a success is just a validation of your current model
of the world, and not an improvement.

> Every bit of progress has cost thouands of setbacks, but each did in fact
> not set the whole industry back because one did _not_ start from scratch
> with every "invention". Because of the continuity, one built upon what
> already existed and found an acceptable way to achieve one's goal until
> the underlying changes were being made by those who were motivated by the
> success of the visible changes.

I agree. But I think we currently disagree on what part of the model
to keep, and what to change.

Andreas Bogk

unread,
Nov 27, 2001, 7:04:10 PM11/27/01
to
Erik Naggum <er...@naggum.net> writes:

> | Common Lisp is man-made (and even designed by a committee and full of
> | bad compromises and legacy crap).
> So are the laws of any given country. You do not break them because you
> object to them, you enter politics and obey the laws while you change
> them. If you are the fucking clueless moron who breaks laws you do not
> like, you are nothing but a retarded criminal. Why the criminal mind is
> so important to hold up as a role model for social change is beyond me.

Gandhi made the concept of "civil disobedience" popular, and showed
that it works.

I do tend to break laws I consider immoral or meaningless. Maybe this
has to do with the fact that I was raised in a dictatorship.

And changing a law works differently in practice: you throw a lot of
money at lobbyists. I'm actively involved in fighting against new
surveillance laws, DMCA-like copyright regulations, and related civil
liberty issues. Believe me, I know the mechanisms, and I'm depressed
at how the so-called democracies are run on this planet.

One of my research areas is cryptography, and I've been involved in
the GSM authentication attack and the DeCSS decryption software. Laws
are on it's way that will outlaw this kind of research, driven by
nothing more than a handfull of intellectual property lawyers from the
recording and movie industry with an unlimited budget.

But this is starting to get severely off-topic, so I stop ranting
here. For the purposes of this discussion, the summary is: I don't
buy that metaphor, please use another one.

> | We folks from the Dylan community see ourselves as part of the Lisp
> | community.
> You seem to be quite alone in this regard, especially considering your
> hang to insult other Lisp communites and waltz in with stupid concerns
> that simply are _not_ concerns except to outsiders. As convicted felons

And what way do you suppose people shall learn something deep about
CL, except by discussing their concerns with those who know? That
way, you keep outsiders to be outsiders.

> protest their innocence, but would not improve unless they accepted that
> they are guilty and the fate of the guilty, any random outsider who does
> not accept that complaining about non-issues is stupid or the negative
> consequences of such actions, will never be part of that community.

Then consider yourself something like a secret conspiracy.

> | We're interested in an honest discussion on what the Right Thing is (and
> | yes, Dylan has it's shortcomings too).
> A good start would be to accept the choices people have made. Coming

I do accept the choices, but I want to understand the reasoning behind
it. This allows me to make a better decision for myself.

Just delivering the results without sharing the insights is keeping
out people.

> into a new community and accusing people of regarding their standards as
> "gospel" because you want to be a criminal in that community is not a
> good start. Strive not to be an outsider. Do _not_ see yourself as an

I reject the notion of the Lisp community being identical to the
Common Lisp community, and I especially reject the notion of CL being
used as a guide to define who's a criminal in the Lisp community.

I feel I have a lot of common ground with many people here, basic
things like believing that automatic memory management, dynamic
typing, general function dispatch and interactive development are good
ideas.

> looking at and not understanding. Part of relinquishing the "outsider"
> status is to accept that other people have accepted certain things, and
> that they are _not_wrong_ in doing so even if you think it is not right.

If I find a feature that strikes me as odd, there could be different
things going on:

1) It's indeed a bit odd, but people get used to it soon, so it won't
be a problem, but losing it wouldn't hurt either.

2) It's a powerful feature I hadn't discovered before that leads me to
new ways to express my ideas, and it's incredibly valuable.

3) I am the first one to notice how to do much better.

Number 3 probably happens twice a lifetime, and is infinitely
valuable. But already being able to tell the difference between 1 and
2 is important to gain real understanding.

> In time, you will see the wisdom that there are more than one right, that
> the idea that there is "one right" is wrong, but that this does not mean
> that one cannot determine that something will always be wrong no matter
> what is right.)

I fail to see how something can always be wrong, when something can't
always be right. Successful dialog depends on understanding the
common set of prerequisites, and trying to share the workload for
reaching new insights based on these prerequisites.

Andreas Bogk

unread,
Nov 27, 2001, 7:50:00 PM11/27/01
to
Kent M Pitman <pit...@world.std.com> writes:

> CL provides a base from which to move *forward*. Re-analyzing the base is
> not moving forward but *laterally*.

I'd dispute that. Re-analyzing the the Axiom of Parallels in geometry
resulted in the development of non-Euclidean geometry, which was a
tremendous success.

> No one denies that there can be hill-climbing problems in any field,
> requiring some backup before moving forward. But the cost of backing out
> of assumptions is generally higher than the cost of not doing so, so to
> not be causing people gratuitous extra cost, one would want to justify the
> need to back up.

An obvious process. One must not forget to account the savings
reached against the costs, and the possibility of reducing the cost by
analyzing it's nature.

> crossed purposes about what the "big deal" is. To those who have an
> investment in a certain way of doing things, it is a major big deal
> and the cost is not just "belief" (those who are not invested probably
> think it's all a matter of "saving face" or "people being stuck in
> their thoughts" as if reading a new paper could change them out of it)
> but "action" (this translates quickly to "dollars" in translation,
> quality assurance, etc. and steals precious budget form "finishing
> product", "marketing", "new features", etc.).

I think I want to understand what these issues are.

> "Can anybody explain to me why some people regard musical standards as
> a good use of anyone's time?" Even just discussing it seems unproductive.

Musicians who only play by the standards might be technically
excellent, but boring. Interesting music is the one violating the
standards in a way that doesn't sound unpleasant to the listener
regardless. Bad music violates the standards and sounds bad.

> I don't mean discussing technical flaws--that makes sense. But discussing
> the conceptual gestalt and trying to get community consensus that "the
> standard should be deviated from" seems pointless. People have the ability

No. It's called progress. Even if such a discussion process doesn't
actually result in a change of consensus, it is still vital for
teaching the deeper ideas.

Not doing that leads to loss of adaptibility, which could become a
problem when prerequisits change.

> have something to share since they may diverge in different ways. In that
> sense, a discussion of Python or Dylan as a specific alternative is better
> than a mere bitch session on why people don't like what they have.

But it doesn't answer the question what choices to make given the
chance of starting from scratch.

Andreas Bogk

unread,
Nov 27, 2001, 8:27:49 PM11/27/01
to
Lieven Marchand <m...@wyrd.be> writes:

> I'm not sure where you see this, but perhaps I'm too close to it. One
> argument that is less important to the Dylan community then to the CL
> community is the cost of change. There is a larger amount of CL code
> around, more CL books and tutorials and more CL implementations, so
> any proposed change not only has to prove its use, but also its cost
> effectiveness. For a lot of the minor things where people argue about,
> changing them wouldn't be worth it even if you could convince
> everyone.

This is of course totally reasonable behaviour. Nevertheless, there
might be people who don't have these constraints, or the cost might be
lower than people think. So the discussion is not worthless.

Let me give you an example. There seems to be a common consensus that
Emacs Lisp is broken. However, the cost of change appears high:
there's lots of legacy code out there.

The biggest obstacle in automatic translation from elisp to, say,
scheme, is that elisp has dynamic scoping, whereas scheme (or CL for
that matter) employs lexical scoping. Well, you could make all local
bindings dynamic bindings, but the code would be a mess.

On the ICFP2001 conference, there was a paper that described how to
employ data flow analysis to figure out which bindings could be
replaced by lexical bindings without changing the semantics of the
code. A test with a representative file from Gnus showed that only 4
out of 150 bindings were actually used in a dynamic fashion. These
can be refactored manually.

A scientific result changed what seemed to be like a heroic task into
something manageable.

It also works the other way around: the scientific community is always
looking for challenging problems of practical importance.

Andreas Bogk

unread,
Nov 27, 2001, 9:20:16 PM11/27/01
to
Jochen Schmidt <j...@dataheaven.de> writes:

> No you don't have to swallow it. You can decide to use CL or not but
> bitching around on things that _you_ as a non-CL user don't like is not
> particularily fair.

Just that I am a non-CL user (yet, I wish I would get clg working...),
doesn't mean I cannot imagine what it would be like to work with a
Lisp where nil equals '(). Especially since I have enjoyed working
with languages that differentiate, and appreciate the coherency
resulting from following stricter design criteria.

> The points critizized here in this thread (nil/false/'()...) seem to be no
> "bug" or "design-error" to the _users_ of the language but instead of that
> - a _feature_ . It is simply not enough to conclude that it is a
> design-error in Common Lisp if it could be counted as a design-error in a
> completely other language (like Dylan - if you count that as lisp or not).

As a feature, it feels like a convenience hack so you can write
(if foo) instead of (unless (empty? foo)).

That's not much of a gain, given that you have just violated the
design rule of having a way to differentiate between a valid and an
invalid result. So you're having a potential pitfall here that you
need to be aware of when writing code. This might feel natural after
having developed awareness for the phenomenon and trained avoiding it.
Still, it adds to the learning curve for newcomers, and potentially
uses up cycles in your brain that you could use to solve the actual
problem instead.

> Do you think it is a good idea for a basketball player to go to a football
> club and criticizing them for using the feet to hit the ball because this
> is a particular bad idea in contrast to the higher agility they would have
> using their hands?

No. The rules are fixed and simple. I could see different basketball
teams having an argument about a basketball rule, however. I could
also see an argument about training methods for underlying basic
primitives of movements and physical abilities.

> Another claim you mindlessly reuse here as a fact is that nonsense that a
> language designed by a commitee is bad from it's beginnings. Compromises do
> not _need_ to be bad - sometimes a compromise is (seen at a whole) _much_
> better than any of the possible extremes. The good thing of design by a
> (good) commitee (like in any good democraty) is that it is seldom that
> _critical_ flaws end up in the result.

As with laws, it's hard to see afterwards what the compromises
involved were. Judging from what I've read in several documents about
the history of Lisp, CL was a rather hairy compromise.

Of course, not all committee results are bad. I just sometimes have
that imagination of a painting designed by a committee of Rembrandt,
Van Gogh and Dali.

> I personally see it as a bad point that Dylan omitted s-expressions since
> they are an important part of the "magic" behind lisp. But I don't think

How would you feel about reviving the prefix Dylan syntax?

> that Dylan is broken because of this fact - it simply changed it's audience
> to people that do not see or do not want the benefits of s-expression
> notation. The bad thing is that some Dylan users tend to claim to new users

One of the things on my list is finding out whether this benefit is
really there or if it could be achieved by other means.

> interested in lisp that Dylan is unconditionally better for them because it
> does not have "this many ugly parens". This claims imply that it is a
> bug to have s-expressions and even worse - it omits that it is maybe a
> _loss_ for Dylan not having them!!!

That's just to lure in the newbies, in whose eyes this *is* a bug. In
my view, it's a minor inconvenience that I don't actually mind
anymore, and probably just a cultural thing. For me, the Dylan syntax
is better readable, because it provides more context to my eye. I can
spot assignments in infix Dylan immediately, whereas it takes me
several seconds to locate an assignment in prefix code. Same goes for
grokking arithmetic expressions and array access.

The s-expression argument comes up quite often. Why not, as an
experiment, start telling the newbies that, even though you think
s-expressions are superior, they can try Dylan to learn the basic
concepts, and then come back later to learn about advanced concepts.

> The bad thing when discussing about "The Right Thing" is that it simply
> does not exist out of context. A particular language, a community and even
> an implementation all define contexts that have to be taken into account
> when searching for "the Right Thing". Even if the context is well defined
> it happens from time to time that "the Right Thing" is ambiguous.

Discussing the Right Thing naturally boils down to discussing the
context, and that's productive.

> I'm too very interested in discussing language issues - but I think it is
> not a _honest_ discussion if on participant claims that the others are
> wrong because _oneself_ did it the other way!

I promise not to do that. But I might claim that someone is wrong if
he presents an argument that contradicts a common context we've
established before. If in his model there is no contradiction, he
must be using different axioms than me, and isolating these
differences can be a rewarding insight to both participants of the
discussion. That would perfectly refute my claim of wrongness.

> Ask yourself what the real reasons are behind that particular wish of
> discussion - is it _really_ for finding the "Right Thing"? (which would
> imply to be _open_ for solutions that are different to your own!) Or is it
> maybe more like pushing of the own way to others?

It's Yin and Yang. I can only establish facts about how important an
argument is to someone by trying to push them. It is polite to keep
that push as small as possible, and a strong reaction to a small push
indicates a big force not originating from me. I am fully aware that
this might push me around too, and I don't insist on not moving. I
just believe that we all might end up in a constellation much more
beneficial for all.

> Is this _really_ about investigating if CL is good or what could be done
> better in Dylan? To me it looks more like marketing and advertising Dylan
> here in c.l.l - and not like "honest discussion".

If you consider it advertising when I'm saying that Dylan was a good
idea, then yes, I am advertising. But it's honest, since that's my
opinion that I can back with arguments, and I can be convinced
otherwise with better arguments.

I do not mean to flame, troll, or insult people. I'm coming here with
an open mind, and a story to tell. I hope I'm finding people here of
likewise ilk.

Bradford W. Miller

unread,
Nov 27, 2001, 10:22:02 PM11/27/01
to
For a summary of the NIL/False dichotomy (and why to overload them) see

"A Short Ballad Dedicated to the Growth of Programs" by Ashwin Ram

http://www.lisp.org/humor/large-programs.html

Best,

Bruce Hoult

unread,
Nov 28, 2001, 12:08:16 AM11/28/01
to
In article <B8296E2A.11AC%Bradford...@motorola.com>, "Bradford W.
Miller" <Bradford...@motorola.com> wrote:

(cdr (assq key a-list))

vs

(let ((val (assq key a-list)))
(cond ((not (null? val)) (cdr val))
(else nil)))


What would be wrong with:

(element a-list key :default nil)

??

-- Bruce

Kenny Tilton

unread,
Nov 28, 2001, 12:30:03 AM11/28/01
to

Bruce Hoult wrote:
>
> In article <B8296E2A.11AC%Bradford...@motorola.com>, "Bradford W.
> Miller" <Bradford...@motorola.com> wrote:
>
> > For a summary of the NIL/False dichotomy (and why to overload them) see
> >
> > "A Short Ballad Dedicated to the Growth of Programs" by Ashwin Ram
> >
> > http://www.lisp.org/humor/large-programs.html

Ah, that's the piece I was thinking of quite a few dead horses back.
Priceless.

>
> (cdr (assq key a-list))
>
> vs
>
> (let ((val (assq key a-list)))
> (cond ((not (null? val)) (cdr val))
> (else nil)))
>
> What would be wrong with:
>
> (element a-list key :default nil)

I do not know either language and take your word for it that your
offering is the same as the lisp version, but I think that misses the
point of the spoof, viz, what happens /in general/ when NIL and false
are different. ie, CMIIW one cannot always avoid horrors such as:

(not (null? <x>))

and:

(else nil)

..with some language feature such as (element...).


kenny
clinisys

Andreas Bogk

unread,
Nov 28, 2001, 12:10:13 AM11/28/01
to
"Bradford W. Miller" <Bradford...@motorola.com> writes:

> "A Short Ballad Dedicated to the Growth of Programs" by Ashwin Ram
> http://www.lisp.org/humor/large-programs.html

Nice read. For comparison, here's the idiom the author seeked in
Dylan:

element(a-list, key, default: #f)

which even works regardless of the type of the collection like lists,
hashtables and vectors, and which allows for an alternative default
value in case #f is a legal element of a-list.

Thomas F. Burdick

unread,
Nov 28, 2001, 1:33:38 AM11/28/01
to
Janis Dzerins <jo...@latnet.lv> writes:

> Kenny Tilton <kti...@nyc.rr.com> writes:
>
> > You're the rock star of Common Lisp. Get your head out of c.l.l. and
> > go win us some converts.
>
> I don't understand why some people are obsessed by the idea that
> Common Lisp needs converts. I even think that converts that have to be
> won should better stay away from Common Lisp.

That's unnecessarily elitist. I don't think that Lisp needs everyone
who can write a line of code, but there are a lot of people who,
without effort from others, wouldn't even know that Lisp exists (in
its modern form). And, even if they do, there are a *lot* of cool
things to learn, and if they don't have any idea how good CL is, how
will they know to prioritize learning it? I don't want every
halfway-stupid Perl hacker working in Lisp. I do want a lot of people
who are very intelligent, concentrating on other things, and fighting
against their language, without realizing the extent to which they can
do something about that, to learn Lisp. How did you learn that Lisp
was worth learning (instead of doing whatever else you could have used
the same time for)? Being at the right place at the right time?
Concerted evangelism? Both? If it hadn't been for a stroke of luck,
I'd be working on C++ compilers now, because I wouldn't have realized
the extent to which a language could work with me.

--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'

Andreas Bogk

unread,
Nov 28, 2001, 1:33:56 AM11/28/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> are different. ie, CMIIW one cannot always avoid horrors such as:
>
> (not (null? <x>))
>
> and:
>
> (else nil)

A idiom one commonly sees in a number of Lisps is

(and x (some-operation-that-fails-on-false x))

which would read

x & x.some-operation-that-fails-on-false

in infix Dylan. If the compiler[0] knows that the type of x is
false-or(<x>), it can even prove that x will never be false for
some-operation, and optimize away type checks, function dispatch and
the like.

Note that if the result of some-operation is <y>, the type of the
complete expression above would be false-or(<y>).

Andreas

[0] A smart enough compiler. Functional Developer is, Gwydion Dylan
isn't.

Bruce Hoult

unread,
Nov 28, 2001, 3:22:41 AM11/28/01
to
In article <87elmje...@teonanacatl.andreas.org>, Andreas Bogk
<and...@andreas.org> wrote:

> x & x.some-operation-that-fails-on-false
>
> in infix Dylan. If the compiler[0] knows that the type of x is
> false-or(<x>), it can even prove that x will never be false for
> some-operation, and optimize away type checks, function dispatch and
> the like.

Gwydion handles this just fine if x is a simple binding. What it
doesn't do (and bug reports have been submitted about) is optimize:

foo(x) & foo(x).some-operation-that-fails-on-false

or (equivilently)

x.foo & x.foo.some-operation-that-fails-on-false


Of course in general you can't optimize this because foo() might have
side effects, but in the special case of foo() being a
compiler-generated slot getter (which is what the bug reports were
about) the compiler can safely assume that there are no side effects and
CSE it. Gwydion doesn't (yet) do this.

At one time I thought that it was correct to not CSE slot access because
the value of the slot could be changed by another thread (which can't
happen with a local binding), but then some of the folks who originally
designed Dylan said that there was no intention to enforce thread-safety
at that granularity.

-- Bruce

Erik Naggum

unread,
Nov 28, 2001, 4:25:21 AM11/28/01
to
* Andreas Bogk

| Can anybody explain to me why some people regard the Common Lisp standard
| as gospel?

* Erik Naggum


> Well, why do you regard it as gospel? Why do _you_ think in such terms?

* Andreas Bogk


| I don't. I suggested that you do, based on your "it is the way it is,
| get over with it" argument.

I repeat: Why do you think in such terms? Your suggestion is nothing but
a way to tell the world that you conceptualize in terms of "gospel" and
other religious terms. _Why_ do you do this? What purpose does such a
conceptualization serve? What kind of short-circuiting of your thinking
processes are you satisfied with once you can label someone "religious"?
I am interested in _why_ you have this conceptualization. If you do not
even recognize that in order to accuse somebody else of something when
lacking evidence of it _from_ those you accuse, i.e., you must recognize
that the "pattern" you see is your own mental creation, you have to think
in the terms you accuse them of, please let me know that you do not even
consider _yourself_ worth listening to, and I shall comply with that.

There are a few things that are never true of "me", only of "you", in the
words and opinions and thinking patterns of some people. Those who make
that mistake, provide the world with evidence that they cannot consider
what it would mean for someone for their accusations to be true, hence
they are worthless nonsense published only to pester and annoy people,
because they, too, _know_ that it is untrue.

Erik Naggum

unread,
Nov 28, 2001, 5:02:44 AM11/28/01
to
* Andreas Bogk

| I do tend to break laws I consider immoral or meaningless. Maybe this
| has to do with the fact that I was raised in a dictatorship.

It probably explains why it remained a dictatorship for so long if that
is what it did to its people's concept of obeying laws while _not_ trying
to change them. However, I have no sympathy for those who cannot get
over their hardships when these hardships go away. Barring actual mental
illness, there is simply no excuse for a thinking person _not_ to change
his mind when he world changes around him. And in fact, Common Lisp is
_not_ a dictatorship. It is a voluntary standard, but if you purport to
conform to it, you can conform to it and be an honest person, or you can
fail to conform to it while you say you and be a manipulating liar. It
seems to me that suffering dictatorships tells people that it is _right_
to manipulate and lie, because if you do not engage in these tactics, you
suffer and die. That frame of mind may take a lot of work to get out of,
but it is worth it.

| For the purposes of this discussion, the summary is: I don't buy that
| metaphor, please use another one.

Then I will consider you a criminal in our little society, one who is
fighting "laws he consider immoral or meaningless" simply because he has
failed to think things through.

| That way, you keep outsiders to be outsiders.

Being an outsider is a personal, voluntary choice of attitude, it is not
something that others can impose on you.

| Then consider yourself something like a secret conspiracy.

Again, why do _you_ think in such terms? _This_ is your core problem.

| Just delivering the results without sharing the insights is keeping out
| people.

There is no such active purpose or intent. You are not in an oppressive
dictatorship, anymore. Adjust accordingly.

| I reject the notion of the Lisp community being identical to the
| Common Lisp community, and I especially reject the notion of CL being
| used as a guide to define who's a criminal in the Lisp community.

Of course you do. You are a criminal in this community, and you want
Dylan to be a Lisp. This is no different from a Scheme freak who has
made up his mind that Scheme is a Lisp, such that he can capitalize on
the value of being a Lisp, but can still blame "Lisp" for shortcomings
while keeping everything good to be associated with "Scheme".

| I feel I have a lot of common ground with many people here, basic things
| like believing that automatic memory management, dynamic typing, general
| function dispatch and interactive development are good ideas.

Intelligent people tend to find people with whom they have common
disagreements, not common agreements. It is not what people think is
right that unite smart people, it is what they think is wrong. This is
also what keeps reasonable societies and communities together. Since you
have experience with dictatorships, you may recognize that what makes a
society a dictatorship is that its people are forced to agree on what is
right, and that has _horrible_ results.

| If I find a feature that strikes me as odd, there could be different
| things going on:
|
| 1) It's indeed a bit odd, but people get used to it soon, so it won't
| be a problem, but losing it wouldn't hurt either.

Getting rid of it would hurt all those who are already used to it.

* Erik Naggum


> In time, you will see the wisdom that there are more than one right, that
> the idea that there is "one right" is wrong, but that this does not mean
> that one cannot determine that something will always be wrong no matter
> what is right.

| I fail to see how something can always be wrong, when something can't
| always be right.

That is because you warped the statement into meaninglessness. Please
think about it some more. Many people spend _years_ coming to grips with
this inequality of the determinability of right and wrong and of making
the mistake of believing that _a_ right answer is _the_ right answer.
Wars have been fought over this, and many lives lost in bad cultures.

E.g., you can determine that something cannot be right concurrently with
something else (that is right) because they exclude eachother completely.
This is eminently possible without knowing what is _actually_ right.
Most of how we build (good) societies is based on this principle.

Some people tend to think that because they find evidence of something,
they can conclude that they have that something. This is false. It is
only if you do not find evidence of _not_ being something that you can
say that. Until you have looked for and not found counter-evidence,
_you_ have contributed the conclusion from evidence that could point in
any direction. Remember, from a single data point, you can extrapolate
in any direction. Counterinformation is more important than information
in determining what you have really found, because it helps exclude that
which _could_ be right, but actually are not.

Erik Naggum

unread,
Nov 28, 2001, 6:59:56 AM11/28/01
to
* Andreas Bogk <and...@andreas.org>

| Just that I am a non-CL user (yet, I wish I would get clg working...),
| doesn't mean I cannot imagine what it would be like to work with a
| Lisp where nil equals '().

People who imagine things that are not so, have a very strange tendency
to believe that other things remain unchanged which would be _very_
different if their simple "change" were indeed made. It takes a very,
very smart person to lie consistently about something for a long time
without being exposed, because all things interconnect and two things
that would normally exclude eachother seem to be true at the same time.
The unusual ability of liars to explain apparent contradictions is one of
the things that give them away. The knowledge of the world possessed by
honest people is limited in strange and unpredictable ways, and sooner or
later, you run into something they cannot explain, but this is _normal_.
A person who has constructed a make-believe world has had to make up so
much that the boundaries of their knowledge tend to be more predictable
and they exceed other people in their detailed knowledge of their world,
because of their fear that the unexplainable will give them away. Even
knowing this, it is extremely hard to lie convincingly -- those who are
best at it write long novels, which differ from other elaborate lies in
that they do not even _intend_ to be true.

In other words, I strongly doubt that you can.

| As a feature, it feels like a convenience hack so you can write
| (if foo) instead of (unless (empty? foo)).

Is this the extent of your imagination?

| That's not much of a gain, given that you have just violated the design
| rule of having a way to differentiate between a valid and an invalid
| result.

Where the hell did this rule come from? I thought you had rejected laws
that were immoral or meaningless because your upbrining in dictatorships.
What makes you even _believe_ that you can dictate such rules and _not_
have people object to the nonsense?

| Still, it adds to the learning curve for newcomers, and potentially uses
| up cycles in your brain that you could use to solve the actual problem
| instead.

As a matter of fact, (when foo ...) has a _much_ lower cognitive load
than (unless (empty? foo) ...). If you at _least_ had rewritten it as
(when (pair? foo) ...), you might have a fighting chance, but the two are
not quite similar -- foo could be a non-list, in which case empty? might
provide the wrong answer. An empty string or vector or hashtable or
package or whatever is true in Common Lisp, but empty? should be true of
all of these. You would in fact have to be

(unless (or (not (list? foo)) (not (pair? foo))) ...)

to be an accurate "translation", or you could of course write

(unless (not (eql foo <false>)) ...)

which just proves that (when foo ...) is the _correct_ choice!

| As with laws, it's hard to see afterwards what the compromises involved
| were. Judging from what I've read in several documents about the history
| of Lisp, CL was a rather hairy compromise.

That _should_ tell you something about people, _not_ about languages.

| I just sometimes have that imagination of a painting designed by a
| committee of Rembrandt, Van Gogh and Dali.

When I see people denounce the work of several people who work together,
I see a person who thinks _much_ too highly of his own abilities. Out of
all the millions, if not billions, of painters in the history of the
world, the handful of geniuses who _did_ paint better than a committee
would have done actually prove that committees do a better job than the
(- total-world-population number-of-geniuses) people would. However, if
you think of _yourself_ as the Rembrandt of programming language design,
this may be hard to understand. However, since irrationally exaggerated
egos tend to cause few problems until they are challenged (at which point
such people implode and/or become physically violent), staying away from
people who put a bullet through inflated egos is a good survival tactic,
as is trying to intimidate anyone who can expose them, and one may in
fact keep believing that one's ego is the correct size for quite a while.
E.g., I know a lot of people who are better than me at many of the things
I want to be good at, but I know far, far more people who only _think_
they are and who have yet to wake up and smell the coffee and realize
their "ranking". These latter people tend to hate me for not allowing
them to keep thinking they are far better than they are.

| One of the things on my list is finding out whether this benefit is
| really there or if it could be achieved by other means.

Whether it could or not is irrelevant unless you are designing a new
language from scratch -- and you do not do that in a newsgroup for an
established language, at least not under such pretenses as you do.

The question is whether it should even be attempted. Smart people can
figure out better ways to make democracy work, but when people who are
too smart for their own good get brilliant ideas, they tend to set up
dictatorships, instead, because the royal mess that is democracy in
action is actually _much_ worse than _any_ isolated theory could be --
until implemented. And that is what makes them _better_, because the
crucial element of a democracy is that people agree only on what _not_ to
do, not on what to _do_. Basically, what they end up doing is a fall-out
of what they have agreed to _exclude_ from the possibility of being done.
Given the resources of modern countries, _anything_ could be achieved.
It is what we give high enough priority that it excludes a lot of stuff
that actually gets done. In the budgeting and prioritizing process of
politics, the actual agreements are over what _not_ to do with all that
money, what _not_ to bring up again during the budget period. Budget
debates are not about the money, but about killing political ideas.

| That's just to lure in the newbies, in whose eyes this *is* a bug.

So you admit to fraudulent marketing. Well, good luck with Dylan.

| In my view, it's a minor inconvenience that I don't actually mind
| anymore, and probably just a cultural thing.

"Just a cultural thing"? That is precisely what the super-tolerant
idiots say about the molestation of young females in backward cultures
that claim it is their "religion" that defends this criminal act against
at least half of humanity. Cultures are tremendously important, and some
of them are just plain _bad_.

_Culture_ is at the very core of why people choose language communities.

| The s-expression argument comes up quite often. Why not, as an
| experiment, start telling the newbies that, even though you think
| s-expressions are superior, they can try Dylan to learn the basic
| concepts, and then come back later to learn about advanced concepts.

Why the hell would Common Lisp users want to do that? I think you, the
proposer of this idiotic manipulation attempt, suggest to your Dylan
users to try out Common Lisp before they tire of Dylan's shortcomings.
Man, you are so incredibly short-sighted you insult your own intelligence
with such a stupid, stupid suggestion. You really _are_ a marketing and
advertising person, are you not? Zero technical skills compensated for
by lots of smooth talking could produce such an incredibly _dumb_ attempt
to pull the wool over so many people's eyes, but not honesty and smarts.

| Discussing the Right Thing naturally boils down to discussing the
| context, and that's productive.

That "context" is a large framework of what has been excluded from the
discussion. In essence, The Right Thing is whatever is left when you
have agreed not to pursue a very large number of paths. It is the same
way when people say they have chosen their new car through a careful
process of weighing positive and negative sides, cost and efficiency, and
can make a perfect explanation for why this car is _the_ best choice.
What they usually omit from this story is how they "decided" to not even
consider 99% of the car market before they started weighing anything at
all and probably were left with a handful of models, if not actual cars,
based on unexpressed and emotionally determined desiderata, among which
some _actually_ irrelevant factor was "weighed" and found sufficient.

To trace the history of how we ended up with our conclusions, ignore all
the explicit arguments and premises and logic and focus on what went down
the drain before you even _started_ to think about it. _That_ is where
you will find the history. It is not as accidental as you might think.
What we do _automatically_ is what defines our sense of culture. If you
come from a different culture, you will fail to find the reasons in the
_explicit_ history of the new culture. (This is why history is such a
hard discipline and requires people who are able to put themselves in the
context of their discoveries.)

It is fundamentally unproductive to "discuss" the context. Either you
grasp it more or less automatically, or you fail to. If you do not, you
can find particular reasons why it failed, but if you persist, you will
only be an outsider looking in at something you do not understand. If,
on the other hand, you accept that whatever this new thing is, you should
let it influence you before you try to influence it, you will slowly grow
into its frame of mind in ways that are incredibly hard to explain
because it happens just as implicitly as how two people grow together
when they live together, how pets and their owners communicate without
any signs that outsiders can observe, how we attribute this to intuition
when in fact it is nothing more than the ability to discern signals that
other people overlook.

Discussing underlying premises of the tacitly accepted and rejected
requires specially trained people. Philosophers and psychologists are
sometimes able to pick up those underlying premises, but the Heisenberg
uncertainty principle applies to people, too: just by asking and _making_
people think about something, you have influenced their thinking and in
minute ways changed them. The amount of intellectual attention and
dedication to detail necessary to prevent errors and both false positives
and negatives in this process is _frightening_ to the untrained.

Consequently, I completely fail to see how you can even assume that you
would be able to conduct and complete this procedure fruitfully without
massive loss of accuracy even if you did it face to face with people. In
fact, I expect that such a procedure would be a total wash on USENET.
Therefore, discussing the context here _must_ be counter-productive.

| But I might claim that someone is wrong if he presents an argument that
| contradicts a common context we've established before.

But because you are an outsider by choice, you would not be able to
determine this. Someone who decides to learn something fully, has to
_immerse_ themselves in it before he starts to think too much, or the
process of immersion and learning and understanding will _fail_. If you
start to think too early in the process, you will use your previous
contexts to validate what you are learning, and that is wrong. By so
doing, you will block your ability to validate using a different context,
unless you are very, very smart and self-aware. Very few people are.

| If in his model there is no contradiction, he must be using different
| axioms than me, and isolating these differences can be a rewarding
| insight to both participants of the discussion. That would perfectly
| refute my claim of wrongness.

Your belief in a logic you have demonstrated a serious lack of ability to
handle productively is downright charming, but it is so much hard work
and so painful a process that it must be a matter of _habit_, not a
matter of studiously conscious procedures done in your sunday clothes
only when called upon. If you are sloppy and confused and do not look
carefully at your observations and conclusions _regularly_, you are not a
person with whom this process can be expected to produces good results.

I am looking forward to how well you understand these premises of a
discussion at the level you seem to seek. I think it is just as much
pretense and hogwash as claims to live in a world of "proofs", which is
also only for show to people who do not think it through.

| It's Yin and Yang. I can only establish facts about how important an
| argument is to someone by trying to push them. It is polite to keep
| that push as small as possible, and a strong reaction to a small push
| indicates a big force not originating from me.

This presupposes that there is a priori and universal agreement on the
amount of push -- that I cannot think your push was bigger than you think
it was. Since this is obviously ridiculous to base an argument on, what
such a reaction _really_ indicates is most probably that you have failed
to assess the amount of push you exerted correctly, and particularly so
because you failed to understand that you relied on an agreement that
simply _could_ not exist, for your argument to be true. Such sloppiness
in thinking that pretends to be logical is actually quite alarming, as it
indicates that you have never been challenged on its fundementals and
have been allowed to walk through life thinking much too highly of your
logical abilities and the guaranteed results of applied logic. This is
almost like watching old Star Trek episodes with the ridiculous role of
Spock, who is "logical" based on a bunch of ludicrous premises.

The lack of precision and willingness to think through what you are
saying is downright annoying. You think too little and talk too much.
Nice words, looks good to the careless observer, but is just bullshit.
You simply fail to understand that people do not just disagree on some
surface issue -- they may disagree all the way down. Even if you seem to
agree on _some_ aspects of something, that is absolutely no guarantee
that this is accidental. E.g., a realist and an idealist may agree on
the fruitlessness of homeopathic "medicine" for reasons that look the
same for a while, but than radically depart on some core principle.
People can likewise agree on some "Lispness" of their pet languages, but
strongly disagree that a language that lacks s-expressions in its syntax
should even pretend to be "a Lisp".

| If you consider it advertising when I'm saying that Dylan was a good
| idea, then yes, I am advertising. But it's honest, since that's my
| opinion that I can back with arguments, and I can be convinced otherwise
| with better arguments.

What utter nonsense. You decided on what made you choose Dylan long
before you ever heard any "argument" either way. You will not be swayed
on any but the most superficial points by arguments. You will, instead,
protect yourself from such swaying. How can I say this so certainly?
Because you show an amazing lack of insight into how people choose and
value things. Of course, now that I have said this, you may think about
it and you may decide to surprise me. That would be kind of fun.

| I do not mean to flame, troll, or insult people. I'm coming here with an
| open mind, and a story to tell.

You would like to believe so, but it is in fact false.

If you react _defensively_ to the last line, your mind is _not_ open.

I think I dislike that trolls that come in nice suits more than the
stinking homeless bum trolls.

Erik Naggum

unread,
Nov 28, 2001, 7:09:38 AM11/28/01
to
* Andreas Bogk

| The biggest obstacle in automatic translation from elisp to, say,
| scheme, is that elisp has dynamic scoping, whereas scheme (or CL for
| that matter) employs lexical scoping. Well, you could make all local
| bindings dynamic bindings, but the code would be a mess.

Nonsense. The biggest obstacle is that any usable Emacs would have to
implement an Emacs Lisp so faithful to the original that it would never
see any users switch to the new and improved Emacs Lisp who could find
even a smidgeon of old Emacs Lisp code to get useful things done, and
since the new Emacs would not supplant the old Emacs unless people were
confident that their old Emacs Lisp stuff worked in the new, it would one
giant project to prove that Emacs Lisp can be hosted on something other
than the old C engine, which has approximately as much value to any Lisp
community as a Dylan advocate wasting their time with design discussions.

_People_ is the main impediment to human progress. I wonder what kind of
extraterrestial influences those who do not understand this are under.

| A scientific result changed what seemed to be like a heroic task into
| something manageable.

I fear that you actually believe this, which is pretty tragic.

Erik Naggum

unread,
Nov 28, 2001, 7:19:57 AM11/28/01
to
* Andreas Bogk

| People's opinion about this one varies, as well as about other features.
| The argument "It's not broken because CL says so" doesn't count.

"It is not illegal just because the law says so", said the criminal, ...

| I'm interested in arguments that sound like "CL does the Right
| Thing because..." or "CL does the Wrong Thing because...".

... "I am only interested in arguments that sound like <whatever>".

I think we have ourselves another specimen of that immature humanoid who
has yet to figure out that _people_ actually count.

Let me be nasty for a second. How old are you, Andreas? 18? 16?

That people can agree to things without proof of excellence is a good
thing. But I guess Dylan is just as anal-retentive as Scheme and that
the reason we have a current influx of Dylanites is that nothing happens
in the Dylan community.

The biggest problem with all these "logical" types is that they have no
clue how to choose the premises from which they draw their conclusions,
they just take them for granted, unquestioned, received by revelation,
and cannot fathom that anyone would disagree with their premises, only
with their conclusions. E.g., the premise that technical debates in a
community who has already agreed on a large standard are based in logic
from _their_ choice of technical premises. That is simply _wrong_.

Kaz Kylheku

unread,
Nov 28, 2001, 7:37:17 AM11/28/01
to
In article <87adx7g...@teonanacatl.andreas.org>, Andreas Bogk wrote:
>As a feature, it feels like a convenience hack so you can write
>(if foo) instead of (unless (empty? foo)).
>
>That's not much of a gain, given that you have just violated the
>design rule of having a way to differentiate between a valid and an
>invalid result.

In places where the Scheme language report says that the result of an
expression is unspecified, or that an evaluation order is unspecified,
what design rule is being followed?

Erik Naggum

unread,
Nov 28, 2001, 7:39:54 AM11/28/01
to
* Andreas Bogk

| I'd dispute that. Re-analyzing the the Axiom of Parallels in geometry
| resulted in the development of non-Euclidean geometry, which was a
| tremendous success.

Did anything happen to Euclidean geometry because of this re-evaluation?

Or did the development of non-Euclidean geometries prove useful in ways
that did not impact the remainder of Euclid's The Elements _at_all_? Was
it not one of the amazingly interesting features of non-Euclidean
geometry that it did _not_ contradict or have a stupid quarrel with the
rest of his work?

So why are you still here when you should be in comp.lang.dylan extolling
the features of non-<whatever> Lisps? Who do you think cares? Invite
Lisp people to your own very low-traffic forum to discuss this with you,
rather than annoy people with your repetitive nonsense, OK? Or are you,
as I now strongly suspect, only posting in comp.lang.lisp because you
think Lisp people should be "converted" to Dylan because nobody else are?

By the way, what you call "axiom" is called "postulate" in Euclid because
of the distinction that Aristotle drew between the two concepts. But I
suppose you do not recognize Euclid's The Elements as authoritative on
what Euclid said, either. "It is so because Euclid said so" seems to be
an invalid argument to you, but I am afraid that I have no "logical"
answer that I expect will sate your desire for pathological nonsense.

Ray Blaak

unread,
Nov 28, 2001, 8:38:32 AM11/28/01
to
Erik Naggum <er...@naggum.net> writes:
> | For the purposes of this discussion, the summary is: I don't buy that
> | metaphor, please use another one.
>
> Then I will consider you a criminal in our little society, one who is
> fighting "laws he consider immoral or meaningless" simply because he has
> failed to think things through.

So who are you? Judge, jury and jailer?

How could criticism of Lisp in general and CL in particular be possibly
considered criminal? That is ridiculous. Criticism and discussion is hardly the
violation of any "law".

The only possible crime that could occur in the context of CL is to implement a
language that does not conform to the standard and then call it Common
Lisp. There are no other "laws" that could be violated.

When debating the merits of a language, however, anything goes, especially in a
usenet group.

Ideally, smart people who disagree about important issues offer criticisms.
Rebuttals are returned. In the ensuing debate the various tradeoffs are
realized and understood, and everyone is that much wiser, even if their
positions are not necessarily changed.

> * Erik Naggum
> > In time, you will see the wisdom that there are more than one right, that
> > the idea that there is "one right" is wrong, but that this does not mean
> > that one cannot determine that something will always be wrong no matter
> > what is right.

Even if you determine to your satisfaction that something is always wrong,
smart people can still disagree with you. If they are indeed incorrect, the
resulting discussion ideally should still be rewardingly illuminating to
all. If you get bored with repeating the same old arguments, you can point
people to a FAQ, let someone else carry the "fight", or else simply ignore
them.

Andreas's real crime here seems to be 1) that he is into Dylan, 2) thinks it's
in the Lisp family, and 3) has the audacity to criticize your favourite
language.

Where *else* can he discuss Lisp's shortcomings in a meaningful manner? The
people who can most intelligently correct the error of his ways hang out here.

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

Alain Picard

unread,
Nov 28, 2001, 9:27:37 AM11/28/01
to
Andreas Bogk <and...@andreas.org> writes:

>
> As a feature, it feels like a convenience hack so you can write
> (if foo) instead of (unless (empty? foo)).
>
> That's not much of a gain, given that you have just violated the
> design rule of having a way to differentiate between a valid and an
> invalid result.

Please, pay attention.

People have already explained that

1) There is already a large community who think it's a feature, not
what you condescendingly call a "design rule violation"

2) A lot of these people are very smart

3) They've already given you examples of the idioms which are natural
in CL to "differentiate between valid and invalid results".

So what remains? It still looks like, to me, that it's a different way
of doing things than you're used to, so you immediately conclude it's bad.

One thing you'll learn, if you persevere with CL, is that some of the
brightest minds ever to touch a keyboard have contributed to its design,
directly or indirectly (i.e. via historical accidents).

I've learned that, when I read CLtL2, if I don't understand something,
or think I disagree with something, I need to look harder, because it
is almost certainly _I_ who is missing something.

I suggest you adopt that attitude for a couple of years, write lots of
code, and _THEN_ come tell this newsgroup why nil == () is bad in
real day-to-day CL usage, AND what you propose is better.

Who knows? You just _might_ be a genius, come up with a great innovation,
and get the language changed.


--
It would be difficult to construe Larry Wall, in article
this as a feature. <1995May29....@netlabs.com>

Bruce Hoult

unread,
Nov 28, 2001, 9:36:50 AM11/28/01
to
In article <861yijw...@gondolin.local.net>, Alain Picard
<api...@optushome.com.au> wrote:

> So what remains? It still looks like, to me, that it's a different way
> of doing things than you're used to, so you immediately conclude it's bad.
>
> One thing you'll learn, if you persevere with CL, is that some of the
> brightest minds ever to touch a keyboard have contributed to its design,
> directly or indirectly (i.e. via historical accidents).

What *you* have missed, is that some of those exact same brightest minds
to ever touch a keyboard went from Common Lisp to design a new language
and did a few things differently the second time around.

Are you saying that you're brighter than Moon?

-- Bruce

Janis Dzerins

unread,
Nov 28, 2001, 10:42:56 AM11/28/01
to
Ray Blaak <bl...@telus.net> writes:

> Erik Naggum <er...@naggum.net> writes:
> > | For the purposes of this discussion, the summary is: I don't buy that
> > | metaphor, please use another one.
> >
> > Then I will consider you a criminal in our little society, one who is
> > fighting "laws he consider immoral or meaningless" simply because he has
> > failed to think things through.
>
> So who are you? Judge, jury and jailer?

Look at yourself.

> How could criticism of Lisp in general and CL in particular be
> possibly considered criminal? That is ridiculous. Criticism and
> discussion is hardly the violation of any "law".

Smart people (as you like to call them) are concerned only about
constructive criticism. Criticism of things one does not understand is
not a constructive criticism.

--
Janis Dzerins

Eat shit -- billions of flies can't be wrong.

Kent M Pitman

unread,
Nov 28, 2001, 11:06:54 AM11/28/01
to
Bruce Hoult <br...@hoult.org> writes:

It's not obvious how anything Alain has said neglects this.

Also, Steele, for example, designed Scheme first and then CL. Was CL a
rejection of Scheme for him? Was his later work with C++ a rejection of CL?
Was his later work with Java a rejection of C++? I suspect some of the
answers here are "yes" and some "no", but I wouldn't know without asking him.
I point it out to say that the single-bit of information represented in
the yes/no answer to the question "used to work with X now works for Y?"
is not the same as the single-bit of information represented in the statement
"has rejected all aspects of X for Y". I quote (or is it paraphrase, since
I'm not sure I have an exact wording that I think is best)
Pitman's Two-Bit Rule: when representing two bits of information,
use two bits to do it.

Further, as I have pointed out many times before, there is no "good/bad"
distinction in the abstract. Good and bad are dictated by context. When
you make a new language, you make a new ecology. What is good and bad
in that new ecology is what makes sense there in context.

That's the reason that the apparent kludge of ()/#f being the same works in
CL. Tons of other decisions are of similar kind. NIL's are padded out for
return values where not supplied. NIL can be car/cdr'd. We use type
"designators" all over where other languages would use raw types only.
There is a certain design consistency here that is underappreciated, and that
I hoped to highlight in the spec when I invented the designator concept
where previously there had been only "a lot of special cases". Just because
people are bad at articulating it doesn't mean they are stupid.

And saying
(when foo ...)
is not the same as saying
(when (not (null foo)) ...)
at the intention level. It carries a subtlely different connotation for
some of us. The former, to me, asks "if there is a foo" and the latter asks
"if there foo is not empty". These are represented the same in CL, but I
prefer the expressional sense of the former. In my mind, when a list goes to
empty, I like to think of it as not existing. I don't think of it as existing
but empty. It works out programmatically nicely to have the two be the same.
It's fine for people to think otherwise, but it's not fine for them to pretend
that the language doesn't intend to support my way of thinking.

If you really want a language with no ability to pun on types, I
really do suggest Scheme. Not just because it makes this decision
differently (or "right", if you prefer to say that) but because its
community will reinforce in you the notion that this is the only
possible legitimate point of view, and give you a generally warm sense
of fuzzy that you have come home. Its leaders will also make it a
priority to ruthlessly seek out lurking places where anyone is punning
for convenience and to callously shun such people, and that will
probably make you feel good about your leaders and the community they
have created. And that's WHY we have separate political parties, er,
languages. Because people want different things. In this political party,
we tolerate diverse points of view. You can write (not (null x))
and I can write x. We both know what each other means. And our code
interacts. If you don't like that, and prefer to interact with people
who agree with you that only one point of view is possible, then this is
not the language for you. It will not just frustrate you on this point.
It will frustrate you on a whole host of issues where the design style
has been of similar character.

> Are you saying that you're brighter than Moon?

I'll save Alain from having to point out that this kind of remark is
not a useful debate tactic. Also, you imply by this that Moon thinks
nil/false thing was done wrong in CL. I personally doubt you'll get him
to make such a claim, but in any case it's unfair of either your or me
to associate him with a position without asking him to state it for himself.

Andreas Bogk

unread,
Nov 28, 2001, 11:23:55 AM11/28/01
to
k...@ashi.footprints.net (Kaz Kylheku) writes:

> In places where the Scheme language report says that the result of an
> expression is unspecified, or that an evaluation order is unspecified,
> what design rule is being followed?

"Leave some freedom to the poor implementors."

I'll refrain from judging this.

Janis Dzerins

unread,
Nov 28, 2001, 11:37:56 AM11/28/01
to
t...@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> Janis Dzerins <jo...@latnet.lv> writes:
>
> > Kenny Tilton <kti...@nyc.rr.com> writes:
> >
> > > You're the rock star of Common Lisp. Get your head out of c.l.l. and
> > > go win us some converts.
> >
> > I don't understand why some people are obsessed by the idea that
> > Common Lisp needs converts. I even think that converts that have to be
> > won should better stay away from Common Lisp.
>

> ...

> I do want a lot of people who are very intelligent, concentrating on
> other things, and fighting against their language, without realizing
> the extent to which they can do something about that, to learn Lisp.

This is how I _finally_ decided to switch to Common Lisp. But this is
not a "winning coverts" thing. It is a "there must be a better way"
thing that people must come to themselves.

> How did you learn that Lisp was worth learning (instead of doing
> whatever else you could have used the same time for)?

The enlightenment does not come in one day. That's the reason that
people who switch to Lisp because someone told it's "way cool" won't
work.

> If it hadn't been for a stroke of luck, I'd be working on C++
> compilers now, because I wouldn't have realized the extent to which
> a language could work with me.

The best thing that can be done about this is to make people aware of
Common Lisp. If they are at least a bit intelligent they will look
into it and find for themselves whether it is worth learning.

Bruce Hoult

unread,
Nov 28, 2001, 11:54:05 AM11/28/01
to
In article <sfw7ksb...@shell01.TheWorld.com>, Kent M Pitman
<pit...@world.std.com> wrote:

> Bruce Hoult <br...@hoult.org> writes:
>
> > In article <861yijw...@gondolin.local.net>, Alain Picard
> > <api...@optushome.com.au> wrote:
> >
> > > So what remains? It still looks like, to me, that it's a different
> > > way
> > > of doing things than you're used to, so you immediately conclude it's
> > > bad.
> > >
> > > One thing you'll learn, if you persevere with CL, is that some of the
> > > brightest minds ever to touch a keyboard have contributed to its
> > > design,
> > > directly or indirectly (i.e. via historical accidents).
> >
> > What *you* have missed, is that some of those exact same brightest
> > minds
> > to ever touch a keyboard went from Common Lisp to design a new language
> > and did a few things differently the second time around.
>
> It's not obvious how anything Alain has said neglects this.
>
> Also, Steele, for example, designed Scheme first and then CL. Was CL a
> rejection of Scheme for him? Was his later work with C++ a rejection of
> CL? Was his later work with Java a rejection of C++?

Of course you'd hav to ask him to find out, but I suspect that he's been
seeking a wider audience for his ideas, as first developed in the
various "lambda the ultimate ..." papers and no doubt refined since.


> Just because people are bad at articulating it doesn't mean they
> are stupid.

That applies in both directions, though you wouldn't know it to read
many of the replies to myself and Andreas here.


> And saying
> (when foo ...)
> is not the same as saying
> (when (not (null foo)) ...)
> at the intention level. It carries a subtlely different connotation for
> some of us.

And Andreas and I have much the same subtly different connotation. The
only real difference is that we think that perpetuating the old "the
list is the fundamental datastructure in Lisps" myth is doing the Lisp
community (of which we are a part) a disservice.

We want to be able to use the *same* subtle connotation for data types
other than lists without somehow bringing in an implicit assumption that
a list is a valid value where you want to convey the idea that something
is either a string or doesn't exist, or is either a number or doesn't
exist, or is either a hash table or doesn't exist.


> If you really want a language with no ability to pun on types, I
> really do suggest Scheme.

Scheme is way too limiting. We've got far more in common with CL than
we have with Scheme. Scheme isn't even an option any more than Jensen &
Wirth Pascal is an option.


> If you don't like that, and prefer to interact with people
> who agree with you that only one point of view is possible, then this is
> not the language for you. It will not just frustrate you on this point.
> It will frustrate you on a whole host of issues where the design style
> has been of similar character.

False premise, false conclusions.


> > Are you saying that you're brighter than Moon?
>
> I'll save Alain from having to point out that this kind of remark is
> not a useful debate tactic.

Funnily enough I know this. The point of my making this remark is that
this is *exactly* the tactic that has been used against myself for some
time, and is now being used against Andreas in, for example, Alain's
message.

It is an invalid debating tactic and I totally reject implications based
upon it.

Whether particular things are good or bad should be decided on the basis
of logic, not on the basis of argument from authority. Of course that
becomes difficult when you explicitly reject logic, as Erik just did. I
don't know what that leaves, other than tradition and accident.

-- Bruce

Kent M Pitman

unread,
Nov 28, 2001, 12:13:03 PM11/28/01
to
Andreas Bogk <and...@andreas.org> writes:

> k...@ashi.footprints.net (Kaz Kylheku) writes:
>
> > In places where the Scheme language report says that the result of an
> > expression is unspecified, or that an evaluation order is unspecified,
> > what design rule is being followed?
>
> "Leave some freedom to the poor implementors."
>
> I'll refrain from judging this.

Why are the implementors more deserving of freedom than the users?
Certainly there are more users. And they do the activity of using much
more often than the implementors do the activity of implementing.

Implementation doesn't need to be easy, just possible.

Indeed, the whole point of an implementation is to centralize hard things
so that they are done only once. Easy things don't need centralization.

I am one of the "authors" (such as we are) of the Revised Report on
Scheme. I've participated in the meetings. The "freedom" is not left
there for implementors, as far as I've ever been able to tell. The
Scheme designers rarely discussed implementation beyond "is it
possible". The freedom is there because the designers, as a group at
least, though there are individual exceptions and I like to claim I'm
one of them, have a phobia about the spec being too long, regardless
of whether that makes the spec "more useful". As to "more useful", we
once had a discussion in the design committee in which some people
hinted that if the spec were more useful, the issue of usefulness
might cause control of the language to be taken from the committee and
put in the hands of users, who had a vested stake in the outcome.
That is, that the usefulness of something causes design principles to
be sacrificed and is the road to disaster. Further, the committee
has, when it has spoken at all, which isn't much recently, expressed
considerably more interest in the issue of book compatibility than
implementation compatibility. To put that in the bluntest of terms,
individuals on the committee have sometimes even gone so far as to say
that their focus has been on preserving the right of people who
disagree about how to write Scheme textbooks to assert what they like
without trampling one another.

I think CLTL was a similar stage of language evolution to Scheme. It
was an attempt to make the words span the gap between differing
implementations, hoping that by leaving enough things unspecified, you
could make a lot of disparate behaviors conforming. The CL community,
at any rate, decided this was not acceptable, and demanded that things
be made more compatible, that things left unspecified be made possible
to test for, etc. We could have left things like evaluation order, or
the order of certain class precedence lists in classes created by
DEFCLASS, unspecified. But that would have just hurt users in the
name of "implementation flexibility".

Language design is not about pleasing implementors. (Just as "raising
kids" is not about "pleasing parents".) There is a primary task to be
accomplished which drives, or ought to drive, the goodness of the
result. Users of a language are not, or ought not be, secondary to
the process. They are why we have languages.

Whatever one thinks of the NIL/false pun, one can hardly accuse it of
being there for "implementor convenience". It was put there because some
users wanted it. Some of us wish there were more such, not fewer such.
I really like the way it works in MOO, with "", #(), and errors being false,
too. I definitely regard that the language would be poorer for my needs
if we moved away from such overlap instead of toward it.

I also did not start out thinking this. I used to rant at people
about not doing (NOT (NULL ...)) because various people thought I
should or because it just seemed fun to do. But someone once pointed
out to me that it's easier to learn to "like" something than it is to
learn to "unlike" something. I don't know if that's true, but one can
certainly find anecdotal evidence to suggest it might be. And anyway,
I've come to like what CL does. I doubt I could as easily come to
unlike it without some major problem coming up with it. And I've been
programming Lisp relatively intensely for 20+ years without such a
major problem coming up, so I'm starting to doubt that it will.

Kent M Pitman

unread,
Nov 28, 2001, 12:26:14 PM11/28/01
to
Bruce Hoult <br...@hoult.org> writes:

> > If you really want a language with no ability to pun on types, I
> > really do suggest Scheme.
>
> Scheme is way too limiting. We've got far more in common with CL than
> we have with Scheme. Scheme isn't even an option any more than Jensen &
> Wirth Pascal is an option.

I think this is not coincidence. I think the cause of Scheme being
what you perceive as limiting and cause of Scheme making what you see
as the "right" choice on this issue are the forces of the same or similar
kind. That is, you have a certain style of design and it leads to some
consequences you like and some you don't like.

> > If you don't like that, and prefer to interact with people
> > who agree with you that only one point of view is possible, then this is
> > not the language for you. It will not just frustrate you on this point.
> > It will frustrate you on a whole host of issues where the design style
> > has been of similar character.
>
> False premise, false conclusions.

I wasn't really meaning to make the statement for the purpose of
advancing its logic. It was making it to be honest-to-goodness
helpful. I didn't want to say "If you don't like it, go elsewhere"
because this would sound like I was just trying to shun you, which
would not be a fair assessment. I'm just saying that languages are
political parties and people should associate with one that supports
their view. Moreover, as to this political party, its core membership
(that is, as embodied in J13) apparently agrees that the cost of
opening the existing standard for tinkering is prohibitively high. It
is not up for debate. I have to say "apparently agrees" and can't say
"agrees" since I'm not its spokesperson (no one is), but its actions
in having declined the chance to open itself for change do, I think,
more or less speak for themselves. You're welcome to disagree with
whatever you like, and to stick around fuming over this, but the issue
is really not up for debate in any practical sense. And I believe you
are just spinning your wheels and wasting valuable time (mine, yours,
and other people's) over something that isn't important enough.

Look, life is short. We're all getting older. The move to CL was
about putting Maclisp to bed and saying "it's time to argue over a new
set of things". This discussion is very "maclisp" and is just done.
I don't expect to look back when I'm on my deathbed and say "I wish
I'd spent more time looking into Bruce's assertion I was wrong on
this". And I don't want either of our tombstones to read "they almost
reached agreement about the empty-list/false thing". I'm much more likely
to say "damn, I wish I could have back all those minutes I wasted
in that stupid, pointless discussion". This has been talked to death.
There are no more points to be made.

Takehiko Abe

unread,
Nov 28, 2001, 1:42:57 PM11/28/01
to
In article <bruce-79ABC1....@news.paradise.net.nz>, Bruce Hoult <br...@hoult.org> wrote:

>
> What *you* have missed, is that some of those exact same brightest minds
> to ever touch a keyboard went from Common Lisp to design a new language
> and did a few things differently the second time around.

Certainly Dylan was not intended to be a next Common Lisp. Its original
goal was different from CL's. I dug up info-mcl mailing list's archive
and located this:

From Steve Strassmann
Date: 1992-06-25
Subject: RE: MCL Framework & Directions
[...]

MCL and Dylan are two very different products, and are expected to fill
the different needs of two very different communities. [...]
[...]

Dylan, however, is not aimed at the Lisp market. It's aimed at the
current market for static languages. We would definitely consider Dylan
a failure if it only stole support from the lisp community and had no
impact on the rest of the world. We think there are compelling reasons
for a static programmer to seriously consider switching to Dylan, and
we'll do everything we can to get them to do so!

[Note the last line.]

abe

--
<keke at mac com>

Andreas Bogk

unread,
Nov 28, 2001, 1:55:17 PM11/28/01
to
Kent M Pitman <pit...@world.std.com> writes:

> > "Leave some freedom to the poor implementors."
> > I'll refrain from judging this.
> Why are the implementors more deserving of freedom than the users?

I'm not implying they do. But they are deserving the freedom to
actually be able to implement, and to reach a consensus about the
standard if their implementation differ in some detail which would be
hard to change.

I think in a way a designer is a potential implementor, so he's often
in the same position.

> Implementation doesn't need to be easy, just possible.

I agree. This seems to have been one of the design principles of
Dylan as well.

[lots of stuff I completely agree to snipped]

> Whatever one thinks of the NIL/false pun, one can hardly accuse it of
> being there for "implementor convenience". It was put there because some

Nobody said that.

> users wanted it. Some of us wish there were more such, not fewer such.
> I really like the way it works in MOO, with "", #(), and errors being false,
> too. I definitely regard that the language would be poorer for my needs
> if we moved away from such overlap instead of toward it.

How do you feel about the false-or(<type>) mechanism? Wouldn't that
just be the generalization of that overlap in a cleaner way?

Marco Antoniotti

unread,
Nov 28, 2001, 3:02:23 PM11/28/01
to

Andreas Bogk <and...@andreas.org> writes:

> "Bradford W. Miller" <Bradford...@motorola.com> writes:
>
> > "A Short Ballad Dedicated to the Growth of Programs" by Ashwin Ram
> > http://www.lisp.org/humor/large-programs.html
>
> Nice read. For comparison, here's the idiom the author seeked in
> Dylan:
>
> element(a-list, key, default: #f)
>
> which even works regardless of the type of the collection like lists,
> hashtables and vectors, and which allows for an alternative default
> value in case #f is a legal element of a-list.

This argument can be turned on its head. As an example, the *ML* crowd
(Haskell included), would argue that either you'd have to program a
special failure value into the alist data type, or that an exception
should be raised if no value were to be found.

ASSOC, FIND and friends are annoying, as (agreeing with Paul Graham)
it is somewhat annoying to have separate abstractions for table
lookups.

This is somewhat strange and an oversight in view of the fact that
GETHASH does the right thing. It accepts a default and returns two
values.

Cheers

--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
719 Broadway 12th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.

Kent M Pitman

unread,
Nov 28, 2001, 3:54:59 PM11/28/01
to
Andreas Bogk <and...@andreas.org> writes:

> > ... I definitely regard that the language would be poorer for my needs


> > if we moved away from such overlap instead of toward it.
>
> How do you feel about the false-or(<type>) mechanism? Wouldn't that
> just be the generalization of that overlap in a cleaner way?

(I reject your implicit suggestion that the word "clean" applies to
one of these approaches and not to the other. There is nothing "unclean"
about correctly applying any well-defined semantics. What feels "unclean"
to you, as nearly as I can tell, is that you don't want the definition
to be what the definition is. But the language is defined as it is,
and since it's in no danger of changing, there is nothing unclean
about the use.)

But in answer to your question, no, the (FALSE-OR type) thing moves
in the wrong direction. It IS a useful technology for places where it
was not possible to find a degenerate element within the set.

For example, had () and NIL and #f been all separate to start, I could
imagine arguing to make () false, just as I have noted that I'd be
happy if "" was false and #() was false. However, I can't imagine
that a priori, I'd argue that (intern "NIL") should result in a false
value. Absent history, I can't make a huge case that any given symbol
should be false. So in a world where those were split, and where I
had no memory of this world, I think I'd argue that (FALSE-OR SYMBOL)
was the right way to talk about the union of boolean false and the
symbols, since the choice of any one symbol as a degenerate case
(absent a historical basis, as with Lisp) would be unfair in
Internationalization terms, if nothing else. And certainly if I were
telling you to merge a faluse value with some random number seed, I
wouldn't try to figure out what a degenerate seed was so that I could
argue it should be false. I'd just say (FALSE-OR RANDOM-STATE).

But there are places where there are natural nulls, and lists and
arrays (including, of course, strings) are among them. I don't feel a
need for an extra type in a great many situations. This is evident in
the number of applications that do (PUSH X (GETHASH A B)) where they
don't check to see if (GETHASH A B) returns NIL, NIL or NIL, T because
it doesn't matter to them. Good language design is not done by
randomly changing a feature but by doing feature changes in
coordinated sets. So if we could declare a hash table of integers,
there might be cases where people usefully did (INCF (GETHASH A B))
without having to initialize (GETHASH A B) because they would know
that (GETHASH A B) would return 0, NIL when there was no element or 0,
T when an element had been set to 0.

Also, in languages where you have more than one false, you can choose
to do (EQ value 'particular-false-value) and to treat the other values
differently. So you might want the type (AND (MEMBER NIL) type)
even though (FALSE-OR type) might mean the same thing. It wouldn't
capture the intent I'm looking for.

Keep in mind that in mixed data, the pun problem exists ANYWAY because
a lot of the time I'm making FOO's and representing them somehow. e.g.,
maybe as a standard class. In that case, NIL can mean absence of FOO.
I can always safely do (gethash 'x *foo-table*) and test the result for
truth because I know there is no false-value in that table. But suppose,
you say, a FOO is represented as a list. Yes, then I have to worry the
list might be NIL, and a probelm might result. SO I say back, suppose
a FOO is represented as a boolean. (That would mean I only ever have
two of them. Or maybe I have some special reason that booleans are enough.
Streams are like this, with terminal I/O and standard-input/standard-output
getting booleans that "represent" them as designators in Lisp.) Confusion
CAN still result and having the datatypes laid out a certain way doesn't
make the world "clean", it just makes it "less error-prone". It is all
just a matter of degree, not a binary matter of "good" and "bad".
And even as to degree, moving it in the direction of separation means
more typing for people, and some people seem to regard that as "good"
while others don't, so even the directionality is up for grabs.


Lieven Marchand

unread,
Nov 27, 2001, 9:15:15 PM11/27/01
to
Andreas Bogk <and...@andreas.org> writes:

> Of course, not all committee results are bad. I just sometimes have


> that imagination of a painting designed by a committee of Rembrandt,
> Van Gogh and Dali.

In more artisanal times, like Rubens and probably Rembrandt still, a
painting was a committee work, where the master did the composition,
the foreground and other import stuff and one of his students might
fill in a tree or clouds in the background.

--
Lieven Marchand <m...@wyrd.be>
She says, "Honey, you're a Bastard of great proportion."
He says, "Darling, I plead guilty to that sin."
Cowboy Junkies -- A few simple words

Erik Naggum

unread,
Nov 28, 2001, 4:53:49 PM11/28/01
to
* Ray Blaak

| So who are you? Judge, jury and jailer?

It is a metaphor, intended to show a particular attitude that has an
exact parallel in the real world. Grow a clue, now.

| Andreas's real crime here seems to be 1) that he is into Dylan, 2) thinks
| it's in the Lisp family, and 3) has the audacity to criticize your
| favourite language.

Nonsense. He speaks of what he does not know. He also criticizes with
no intention of resolving anything. Common Lisp is not being designed at
this time, and these things are so fundamental that there is no way his
criticism can possibly stop, because they are not going to change. There
is no way this person is going to cease his complaints, because he will
never be satisfied. Why do you defend such people and activities?

| Where *else* can he discuss Lisp's shortcomings in a meaningful manner?
| The people who can most intelligently correct the error of his ways hang
| out here.

No, the error of his ways is that he thinks that a newcomer to town
should be _respected_ for disagreeing with the prevailing customs for no
better reason than that they are different where he came from. This is
fantastically stupid in real life, too, and has a name: "an obnoxious
tourist". There is no confusion or error that anybody else can fix.

Erik Naggum

unread,
Nov 28, 2001, 5:00:03 PM11/28/01
to
* Bruce Hoult

| What *you* have missed, is that some of those exact same brightest minds
| to ever touch a keyboard went from Common Lisp to design a new language
| and did a few things differently the second time around.

But they designed a new language and set up a new community for it! They
did _not_ hang around in the Common Lisp community and whine about it.

| Are you saying that you're brighter than Moon?

Please think about what you are _actually_ saying.

Erik Naggum

unread,
Nov 28, 2001, 5:36:37 PM11/28/01
to
* Bruce Hoult

| Of course you'd hav to ask him to find out, but I suspect that he's been
| seeking a wider audience for his ideas, as first developed in the
| various "lambda the ultimate ..." papers and no doubt refined since.

_I_ assume that Guy L. Steele is a very smart _professional_ and is not
married to any of the languages on which he has worked. Actually, I do
not expect a _personal_ attachment from any seriously good Common Lisp
programmer. There are personal _values_, but they can and should be
approached professionally, because one cannot always get what one wants,
and it is incredibly stupid to whine for decades about something you did
not get that was personal to you.

The distinction between personal and professional seems to be lost on
some people. They tend to get into problems when they are required to be
professional and detach personally.

| That applies in both directions, though you wouldn't know it to read
| many of the replies to myself and Andreas here.

Of course you are the judge of this, because you have already made up
your mind and you also get personal about it, so you are prevented from
seeing the _professionalism_ in the replies you get.

| And Andreas and I have much the same subtly different connotation. The
| only real difference is that we think that perpetuating the old "the
| list is the fundamental datastructure in Lisps" myth is doing the Lisp
| community (of which we are a part) a disservice.

Why have you decided to find converts in comp.lang.lisp? This looks more
and more like a personal mission. Invite those who want to discuss this
stupid shit with you to comp.lang.dylan. It does not look like anybody
would disturb anyone.

| We want to be able to use the *same* subtle connotation for data types
| other than lists without somehow bringing in an implicit assumption that
| a list is a valid value where you want to convey the idea that something
| is either a string or doesn't exist, or is either a number or doesn't
| exist, or is either a hash table or doesn't exist.

Why do you want to do this in Common Lisp when you have your perfect
little toy language Dylan that gets it right? Is this how you idiots
think that people will choose Dylan? Insult the best language on earth,
take criticism personally, be obnoxiously obtuse and do not get the
point, then give them Dylan in shining armor as the answer. Good luck.

| Scheme is way too limiting. We've got far more in common with CL than
| we have with Scheme. Scheme isn't even an option any more than Jensen &
| Wirth Pascal is an option.

Why do you have this desire to have things in common with other people?
That looks like personal insecurity to me. Is not Dylan enough for you?
Do you need to reach out and find people to disagree strongly with just
to feel you have something in "common" with them that you do not focus
on? If you have so much in common with somebody, why spend your time
carping about differences?

None of this makes any _sense_. I believe you are just trolls from a
community that has no future and then you attack the closest competitor
you think you can annoy into supporting you.

| Funnily enough I know this. The point of my making this remark is that
| this is *exactly* the tactic that has been used against myself for some
| time, and is now being used against Andreas in, for example, Alain's
| message.

You still have not figured out that there is a difference between people
who made up their mind to be outsiders and those who have not. Please do.

| Whether particular things are good or bad should be decided on the basis
| of logic, not on the basis of argument from authority.

What kind of idiot _are_ you? Geez, do you even _believe_ this crap?
Good and bad _are_ arguments from authority, you annoying little shit.
If you think logic helps, consider this: The premises on which you base
your "logic" eventually turn into arguments from authority, no matter
where you start. Why is this? Good and bad do not exist in nature.
There is no absolute test for goodness or badness out there that is
independent of people. Do you think there is, Bruce Hoult? Do you think
if you research long enough, you will find elemental particles of good
and bad that can form the basis of a logic that all people can agree on?

Good and bad are the results of people who want to live together. This
means they _have_ an authority higher than themselves which they accept.
It can be some funny deity or it can be the fuzzy "community" or it can
be a set of law and lots of strange things, but people happen to agree on
what good and bad should be considered in _reference_ to. A standard of
ethics, in the non-technical meaning of "standard" _is_ an authority.
Those who reject it are considered _bad_guys_ in that community. We have
a standard for a language that we accept and those who keep quibbling
over it and when there is no possible way it could ever stop, because
there is no possible way to change what they keep carping about for no
good reason are _bad_guys_ to this community.

| Of course that becomes difficult when you explicitly reject logic, as
| Erik just did. I don't know what that leaves, other than tradition and
| accident.

I just rejected logic? I reject logic as the proper means to resolve
ethical problems. Does that mean I reject _logic_? You really _are_
quite insane. If someone says I should use classical mechanics to learn
to drive a car, and I think this is inappropriate even though there are
many elements of mechanics (including the pun) in driving cars, do I
reject classical mechanics? Or do I reject its _application_?

For someone who thinks logic is so great a univeral problem-solver, you
sure have a funny way of arriving at _your_ conclusions.

Marco Antoniotti

unread,
Nov 28, 2001, 5:42:53 PM11/28/01
to

This discussion made me wonder about the status of ASSOC and FIND, and
what would mean to "change the standard".

CLHS reports:

find item sequence &key from-end test test-not start end key => element
assoc item alist &key key test test-not => entry
gethash key hash-table &optional default => value, present-p

Do you think it would be too much of a change to request the
vendors/implementors to change the behavior of the implementation in
such a way that

find item sequence &key from-end test test-not start end key default => element, present-p
assoc item alist &key key test test-not default => entry, present-p

(Of course a better writeup is necessary).

Also, what could be an "agreed upon and simple" machinery such that
all the implementations could check for this "extension"?

Ray Blaak

unread,
Nov 28, 2001, 5:54:05 PM11/28/01
to
Erik Naggum <er...@naggum.net> writes:
> Why do you defend such people and activities?

I object only to his being called a criminal. The metaphor is not applicable
since there are no laws being violated. "Obnoxious tourist" would be much more
accurate, and while despicable, is not a crime in any part of the world that I
know of.

He is only talking for Christ's sake. Debunk him or ignore him.

Kaz Kylheku

unread,
Nov 28, 2001, 5:57:35 PM11/28/01
to
In article <87y9krc...@teonanacatl.andreas.org>, Andreas Bogk wrote:
>k...@ashi.footprints.net (Kaz Kylheku) writes:
>
>> In places where the Scheme language report says that the result of an
>> expression is unspecified, or that an evaluation order is unspecified,
>> what design rule is being followed?
>
>"Leave some freedom to the poor implementors."
>
>I'll refrain from judging this.

But not from judging the role of NIL in Lisp.

Erik Naggum

unread,
Nov 28, 2001, 6:04:19 PM11/28/01
to
* Marco Antoniotti

| Also, what could be an "agreed upon and simple" machinery such that
| all the implementations could check for this "extension"?

I think a new package named COMMON-LISP-2002, say, which implements the
new symbols and semantics, would be the way to go.

Erik Naggum

unread,
Nov 28, 2001, 6:21:43 PM11/28/01
to
* Ray Blaak

| I object only to his being called a criminal. The metaphor is not applicable
| since there are no laws being violated.

The metaphor does not concern _what_ one disregards, considers oneself
above, disrespects, etc, but _that_ one knows better than the community
and that if there is ever some disagreement, the community is wrong for
making its choices.

| "Obnoxious tourist" would be much more accurate, and while despicable, is
| not a crime in any part of the world that I know of.

Ok, so you have a personal hangup about "criminal" and only think it
concerns "crime", and not the personal attitude towards authority. I
shall make a small note of this, and that you refuse to get the point.
Fine with me.

Coby Beck

unread,
Nov 28, 2001, 6:31:35 PM11/28/01
to

"Erik Naggum" <er...@naggum.net> wrote in message
news:32159219...@naggum.net...

> * Andreas Bogk
> | I'd dispute that. Re-analyzing the the Axiom of Parallels in geometry
> | resulted in the development of non-Euclidean geometry, which was a
> | tremendous success.
>
> Did anything happen to Euclidean geometry because of this re-evaluation?
>
> Or did the development of non-Euclidean geometries prove useful in ways
> that did not impact the remainder of Euclid's The Elements _at_all_? Was
> it not one of the amazingly interesting features of non-Euclidean
> geometry that it did _not_ contradict or have a stupid quarrel with the
> rest of his work?
>
> So why are you still here when you should be in comp.lang.dylan extolling
> the features of non-<whatever> Lisps? Who do you think cares? Invite
> Lisp people to your own very low-traffic forum to discuss this with you,
> rather than annoy people with your repetitive nonsense, OK? Or are you,
> as I now strongly suspect, only posting in comp.lang.lisp because you
> think Lisp people should be "converted" to Dylan because nobody else are?
>

FWIW I find these cross language disscussions for the most part educational.
Perhaps it is just because I am not as familiar with all the arguments and
criticisms as Erik is and he is obviously fed up with it.

That said, I have not yet seen anything brought up that makes me less satisfied
with the solutions common lisp provides. I looked over Paul Grahams Arc page
and while I find all of the goals he expresses fine, the examples he has so far
of things he wants different from CL strike me as very trivial and very
personal. The points raised so far in this thread about #f vs nil and '() etc
are interesting and I believe support the idea that there is another approach.
But Common Lisp has not taken that approach and I see no problem as it is. If
things were broken enough that you had to start from scratch, these are
interesting issues, but with such a fine and established base as we have now,
these are moot points.

Common Lisp doesn't have if*; in Common Lisp nil == '() == false; Common Lisp
has too many parens in its cond form; Common Lisp has a loop macro that is very
un-lispy......so what? *Nothing* there is even _remotely_ unuseable or
unsupportable. And the flexibility is built in to the language to to modify so
much to your own personal tastes. All the energy spent trying to sugar coat
lisp for the masses would be so much better spent developing all those huge
libraries Java and Perl people miss so much.

I do not beleive popularity is a bad thing and I would honestly like to see
lisp grow its user base. But it is not worth _any_ sacrifice in the integrity
of its design. Jan Derzen said something along the lines of "if they have to
be converted, who wants them". While I can't agree with that as stated, I do
feel that if you show someone the light and they don't see it, that is there
problem. Too many parens is *not* what keeps people from appreciating lisp.

--
Coby
(remove #\space "coby . beck @ opentechgroup . com")


Kent M Pitman

unread,
Nov 28, 2001, 6:29:44 PM11/28/01
to
Erik Naggum <er...@naggum.net> writes:

> * Marco Antoniotti
> | Also, what could be an "agreed upon and simple" machinery such that
> | all the implementations could check for this "extension"?
>
> I think a new package named COMMON-LISP-2002, say, which implements the
> new symbols and semantics, would be the way to go.

Right. Don't underestimate the number of possible places where an
extra value would fall through and not be wanted. Changes like this
are "less likely" to break things, but not "unable" to break things.

Andreas Bogk

unread,
Nov 28, 2001, 2:57:19 PM11/28/01
to
Erik Naggum <er...@naggum.net> writes:

> > Well, why do you regard it as gospel? Why do _you_ think in such terms?
> | I don't. I suggested that you do, based on your "it is the way it is,
> | get over with it" argument.
> I repeat: Why do you think in such terms? Your suggestion is nothing but
> a way to tell the world that you conceptualize in terms of "gospel" and
> other religious terms. _Why_ do you do this? What purpose does such a

Because that's the association I have when reading your arguments.
The "you must believe in it, because it was written by God^Wpeople
much smarter than you" argument. The "it's not Lisp unless it is
Common Lisp, and everybody deviating from Common Lisp is a heretic,
even if he doesn't claim

> conceptualization serve? What kind of short-circuiting of your thinking
> processes are you satisfied with once you can label someone "religious"?

I can stop trying to have a rational argument with them about the
subject of their belief. I might try to start a religious argument,
but that's an entirely different game.

> I am interested in _why_ you have this conceptualization. If you do not
> even recognize that in order to accuse somebody else of something when
> lacking evidence of it _from_ those you accuse, i.e., you must recognize
> that the "pattern" you see is your own mental creation, you have to think
> in the terms you accuse them of, please let me know that you do not even
> consider _yourself_ worth listening to, and I shall comply with that.

I'm not lacking evidence, there's enough in your postings. If I sound
like a religious zealot to you (which of course is just a pattern in
*your* brain), and if you think religious discussions are pointless,
stop listening to me. All else would be a waste of time and bandwidth.

> There are a few things that are never true of "me", only of "you", in the
> words and opinions and thinking patterns of some people. Those who make
> that mistake, provide the world with evidence that they cannot consider
> what it would mean for someone for their accusations to be true, hence
> they are worthless nonsense published only to pester and annoy people,
> because they, too, _know_ that it is untrue.

I'm only reporting my impressions, honestly and faithfully. If this
annoys you, maybe you should search the reason on your side.

Andreas Bogk

unread,
Nov 28, 2001, 3:19:27 PM11/28/01
to
Erik Naggum <er...@naggum.net> writes:

> | I do tend to break laws I consider immoral or meaningless. Maybe this
> | has to do with the fact that I was raised in a dictatorship.
> It probably explains why it remained a dictatorship for so long if that
> is what it did to its people's concept of obeying laws while _not_ trying
> to change them.

The real reason has probably more to do with the fact that the limited
freedom resulted in a greatly improved personal and social security:
nobody was homeless or out of work, women's liberation was not just a
promise but fact, and the material difference between the rich and the
poor was almost inivisible by today's standards.

Have *you* ever tried to change a law?

> his mind when he world changes around him. And in fact, Common Lisp is
> _not_ a dictatorship. It is a voluntary standard, but if you purport to
> conform to it, you can conform to it and be an honest person, or you can
> fail to conform to it while you say you and be a manipulating liar. It

You must confuse me with somebody else. All I'm saying is that if I
fail to conform to Common Lisp, it is still Lisp.

> Then I will consider you a criminal in our little society, one who is
> fighting "laws he consider immoral or meaningless" simply because he has
> failed to think things through.

Usually considering something immoral and meaningless involves thinking.

> | Then consider yourself something like a secret conspiracy.
> Again, why do _you_ think in such terms? _This_ is your core problem.

Because *you* treat me that way, and I suggest this is *your* problem.
Seems to be hard for you to understand.

> | Just delivering the results without sharing the insights is keeping out
> | people.
> There is no such active purpose or intent. You are not in an oppressive
> dictatorship, anymore. Adjust accordingly.

I am not suggesting purpose or intent, I'm observing effects.

> Of course you do. You are a criminal in this community,

... by your dubious definition of criminal.

> and you want Dylan to be a Lisp.

Well, it is. It's not Common Lisp, though.

> This is no different from a Scheme freak who has
> made up his mind that Scheme is a Lisp, such that he can capitalize on
> the value of being a Lisp, but can still blame "Lisp" for shortcomings
> while keeping everything good to be associated with "Scheme".

If he says Scheme is a Lisp, and that Lisp has shortcomings, he's
saying that Scheme has shortcomings. So there's no point.

What I want to captialize on is sharing experience with other Lisp
people about the common foundations. You can hardly blame me for
that.

> > In time, you will see the wisdom that there are more than one right, that
> > the idea that there is "one right" is wrong, but that this does not mean
> > that one cannot determine that something will always be wrong no matter
> > what is right.
> | I fail to see how something can always be wrong, when something can't
> | always be right.
> That is because you warped the statement into meaninglessness. Please

Could be that the statement was meaningless to begin with.

> think about it some more. Many people spend _years_ coming to grips with
> this inequality of the determinability of right and wrong and of making
> the mistake of believing that _a_ right answer is _the_ right answer.

I don't believe that *a* right answer is *the* right answer. It's
hard to find out how you read that from my above comment.

It's just that I don't think that *a* wrong answer is *the* wrong
answer, for precisely the same reason. That's what I have written
above, and it would suit you well to address this argument, instead of
handwaving.

Andreas Bogk

unread,
Nov 28, 2001, 6:46:16 PM11/28/01
to
Erik Naggum <er...@naggum.net> writes:

> People who imagine things that are not so, have a very strange tendency
> to believe that other things remain unchanged which would be _very_
> different if their simple "change" were indeed made. It takes a very,

Well, that's the reason we're discussing this issue here with people
having the experience, instead of blindly believing our gedanken
experiment.

> | As a feature, it feels like a convenience hack so you can write
> | (if foo) instead of (unless (empty? foo)).
> Is this the extent of your imagination?

Well, it extends to a general dislike against any use of inband
signalling in a lot of other contexts.

By the way, the URL of the poem on the topic did a lot more to
enlighten me on the subject: it showed me a typical construct where
nil == '() is useful, and that I need not worry about Dylan doing it
in a way I consider more consistent, because the concerns don't apply.

All I've seen from you, on the other hand, is hundreds of lines of
insult against my person and intelligence, sprinkled with a couple of
interesting, but unrelated insights.

> | That's not much of a gain, given that you have just violated the design
> | rule of having a way to differentiate between a valid and an invalid
> | result.
> Where the hell did this rule come from?

It's a specialization of the rule of not using inband signalling,
because there might be data that looks like a signal.

> I thought you had rejected laws
> that were immoral or meaningless because your upbrining in dictatorships.

I don't consider this rule meaningless. But not because it is written
down in some text I consider authoritative in what is right or wrong,
but because of a conscious decision that the rule makes sense.

This is based on observation of the problems (especially security
problems) of software that violates these rules. Prominent examples
are Blueboxing (the ability to make fraudulent calls in C5 PBX systems
by generating tones) and denial of service against modems by sending ICMP
Echo packets with +++ATH0 in them.

I even think there was a security problem in X11 that was based on
sending 2^32-1 bytes of data to the server. That made some counter
reach -1, which was treated special. The poor C program promptly
mangled the return pointer on the stack, and an attacker could inject
exploit code.

> What makes you even _believe_ that you can dictate such rules and _not_
> have people object to the nonsense?

I do not believe I can dictate such rules. But I believe this rule is
meaningful, and that a lot of people share it.

So anybody who thinks that CL is better off violating this rule either
doesn't believe in it, or believes that there are more important
rules. In both cases, I am curious to know why.

> As a matter of fact, (when foo ...) has a _much_ lower cognitive load
> than (unless (empty? foo) ...).

Only if you have interned this particular feature so much that you
also see the latter meaning if you see the former in code.

Using the former when meaning the latter fails to communicate the
intent.

> If you at _least_ had rewritten it as
> (when (pair? foo) ...), you might have a fighting chance, but the two are
> not quite similar -- foo could be a non-list, in which case empty? might
> provide the wrong answer. An empty string or vector or hashtable or
> package or whatever is true in Common Lisp, but empty? should be true of
> all of these.

The intent when writing such code is indeed testing for an empty
container, so the fact that it works correctly for non-list container
is a good thing.

Too bad this isn't true for the (when foo) case, it only works for
lists.

By the way, please forgive the use of the Dylanesque empty?. I'm so
used to working in a language where I can express operations on
collections independent of their implementation that I completely
missed the fact that there is no empty? in Common Lisp, and that it
can't be implemented in a way that would have equal performance to
(when foo).

> | I just sometimes have that imagination of a painting designed by a
> | committee of Rembrandt, Van Gogh and Dali.

> When I see people denounce the work of several people who work together,
> I see a person who thinks _much_ too highly of his own abilities. Out of

I've been to some meetings of standardization groups, and have seen
how they work, thank you. Their compromises are often not mine, and
their documents below the standard of the individual members.

Quite often, what they produce makes the world a better place. Common
Lisp certainly has served it's purpose. The citation above is just a
nightmare haunting me :)

> all the millions, if not billions, of painters in the history of the
> world, the handful of geniuses who _did_ paint better than a committee
> would have done actually prove that committees do a better job than the
> (- total-world-population number-of-geniuses) people would.

Not if it would increase the marketshare of vendor X not to do so.
I'm speaking from experience here (and no, the genius, if he was one,
was not me).

> However, if you think of _yourself_ as the Rembrandt of
> programming language design, this may be hard to understand.

I've only been using programming languages for the last 14 years, and
I've only been studying programming language design for the last 5
years, so I'm certainly neither the most experienced language designer
nor the best.

But I think I'm able to judge other people's designs up to a certain
degree.

> E.g., I know a lot of people who are better than me at many of the things
> I want to be good at, but I know far, far more people who only _think_
> they are and who have yet to wake up and smell the coffee and realize
> their "ranking".

So your participation in this newsgroup has the purpose of
establishing some smartness ranking?

> These latter people tend to hate me for not allowing
> them to keep thinking they are far better than they are.

I think most people tend to hate you because of your attitude. I have
met people smarter *and* more humble than you.

> | One of the things on my list is finding out whether this benefit is
> | really there or if it could be achieved by other means.
> Whether it could or not is irrelevant unless you are designing a new
> language from scratch

It's not irrelevant, it's called "learning". It might even be of some
use if I ever decide it would be nice to design a new language from
scratch.

But I think slightly improving existing languages is a more realistic
target.

> until implemented. And that is what makes them _better_, because the
> crucial element of a democracy is that people agree only on what _not_ to
> do, not on what to _do_.

Do you pay taxes?

> | That's just to lure in the newbies, in whose eyes this *is* a bug.
> So you admit to fraudulent marketing. Well, good luck with Dylan.

Imagine a smiley at the end of the line. A neutral formulation would
be: it reduces the learning curve for newbies that already have used a
language with infix syntax, so we can teach them about more relevant
concepts, like closures, GF dispatch, dynamic types etc. So the
likelihood is higher that they won't want to go back to languages that
don't offer these features.

> | In my view, it's a minor inconvenience that I don't actually mind
> | anymore, and probably just a cultural thing.
> "Just a cultural thing"? That is precisely what the super-tolerant
> idiots say about the molestation of young females in backward cultures
> that claim it is their "religion" that defends this criminal act against
> at least half of humanity. Cultures are tremendously important, and some
> of them are just plain _bad_.

Have you just compared infix syntax to child molestation, or is this
just my imagination?

> | The s-expression argument comes up quite often. Why not, as an
> | experiment, start telling the newbies that, even though you think
> | s-expressions are superior, they can try Dylan to learn the basic
> | concepts, and then come back later to learn about advanced concepts.
> Why the hell would Common Lisp users want to do that? I think you, the

Because this was one of the original intents of Dylan, and it works.
Everybody who understands Dylan is a potential user of CL.

> proposer of this idiotic manipulation attempt, suggest to your Dylan
> users to try out Common Lisp before they tire of Dylan's shortcomings.

Don't laugh, but I do.

> Man, you are so incredibly short-sighted you insult your own intelligence
> with such a stupid, stupid suggestion. You really _are_ a marketing and
> advertising person, are you not? Zero technical skills compensated for
> by lots of smooth talking could produce such an incredibly _dumb_ attempt
> to pull the wool over so many people's eyes, but not honesty and smarts.

You're insulting your intelligence with flames and rude behaviour.

I've had several opportunities to demonstrate my technical skills, for
instance leading a development effort for digital TV software with a
team of 40 developers (and my design worked), and recently as a member
of the team winning the second prize at the ICFP2001 contest.

> To trace the history of how we ended up with our conclusions, ignore all
> the explicit arguments and premises and logic and focus on what went down
> the drain before you even _started_ to think about it. _That_ is where

I think that would be a bad approach. Logic has it's limits, but it
cannot be plainly rejected as irrelevant.

> It is fundamentally unproductive to "discuss" the context. Either you

If you think so, stop discussing with me. I'm interested, and other
people are too.

> Discussing underlying premises of the tacitly accepted and rejected
> requires specially trained people. Philosophers and psychologists are
> sometimes able to pick up those underlying premises, but the Heisenberg

That are no skills that can not be learned and made use of in our
field. Look into any good book on user interface design for examples.
Or look into this newsgroup for that matter: the argument of intent is
of psychological nature, and many of your arguments are philosophical.
Some are rhetorical, for that matter.

> Consequently, I completely fail to see how you can even assume that you
> would be able to conduct and complete this procedure fruitfully without
> massive loss of accuracy even if you did it face to face with people. In

It's called discussion, and is the prominent purpose of USENET.

> But because you are an outsider by choice, you would not be able to
> determine this. Someone who decides to learn something fully, has to
> _immerse_ themselves in it before he starts to think too much, or the
> process of immersion and learning and understanding will _fail_. If you
> start to think too early in the process, you will use your previous
> contexts to validate what you are learning, and that is wrong. By so
> doing, you will block your ability to validate using a different context,
> unless you are very, very smart and self-aware. Very few people are.

Do you consider yourself to be that smart? How deeply have you looked
into Dylan, for instance, to be able to say that it doesn't have the
Lisp nature?

> Your belief in a logic you have demonstrated a serious lack of ability to
> handle productively is downright charming, but it is so much hard work

You still have to show a serious flaw in my logic.

> and so painful a process that it must be a matter of _habit_, not a
> matter of studiously conscious procedures done in your sunday clothes
> only when called upon. If you are sloppy and confused and do not look
> carefully at your observations and conclusions _regularly_, you are not a
> person with whom this process can be expected to produces good results.

Who tells you I'm not practicing it on a daily basis?

> I am looking forward to how well you understand these premises of a
> discussion at the level you seem to seek. I think it is just as much

I hope I'm not doing too bad.

> pretense and hogwash as claims to live in a world of "proofs", which is
> also only for show to people who do not think it through.

One has to recognize that a lot of our daily activities consists of
building models and executing "proofs" in the model by constantly
verifying it against the real world.

I currently enjoy seeing my two year old son grow and learn. It takes
kids awhile until they figure out the concept of object permanence:
objects are still there even if you close your eyes. Then they have a
lot of fun executing some proofs in the form of dad hiding and
reappearing behind a curtain.

I bet the higher thought processes of animals are alot like that.
What separates us from animals is that we have consciousness, and are
able to use it in order to recognize that a model is a model and act
appropriately.

There are some things we cannot understand using the model-building
process, consciousness itself is an instance. This is where the world
of models, rules and proofs fails, and where psychology, philosophy
and religion come into play. That does not make these things
irrelevant.

> | It's Yin and Yang. I can only establish facts about how important an
> | argument is to someone by trying to push them. It is polite to keep
> | that push as small as possible, and a strong reaction to a small push
> | indicates a big force not originating from me.
> This presupposes that there is a priori and universal agreement on the
> amount of push -- that I cannot think your push was bigger than you think
> it was.

I can only tell you about my intention. I didn't consider discussion
of language features a major flame bait, but as a good opportunity to
either learn or teach (and I am open for both directions).

Of course, we both can only see the combined result of our forces.
Judging by the size of the thread and the number of words written, it
was a big force. Maybe we can do something useful with it, if we can
cooperate to direct it.

> Since this is obviously ridiculous to base an argument on, what
> such a reaction _really_ indicates is most probably that you have failed
> to assess the amount of push you exerted correctly, and particularly so
> because you failed to understand that you relied on an agreement that
> simply _could_ not exist, for your argument to be true. Such sloppiness

My assertion might have failed because I didn't have the knowledge
that I was here to seek. And an agreement might not exist (yet)
personally with you, but I have reason, based on my experience with
selected members of this community (personal, and reading their source
code and documents), to believe that I would find people who agree
here.

> in thinking that pretends to be logical is actually quite alarming, as it
> indicates that you have never been challenged on its fundementals and
> have been allowed to walk through life thinking much too highly of your
> logical abilities and the guaranteed results of applied logic. This is
> almost like watching old Star Trek episodes with the ridiculous role of
> Spock, who is "logical" based on a bunch of ludicrous premises.

Your irrational behaviour is a living proof that logic has it's limits.

> The lack of precision and willingness to think through what you are
> saying is downright annoying. You think too little and talk too much.
> Nice words, looks good to the careless observer, but is just bullshit.

You're welcome to actually show where my logic is flawed, instead of
just claiming it's bullshit. Maybe I learn something. Maybe you
learn something. Are you prepared for both?

> You simply fail to understand that people do not just disagree on some
> surface issue -- they may disagree all the way down. Even if you seem to

I do not fail to understand this, although two persons who disagree on
*anything* are rather unlikely. What you fail to understand is that
this isn't the case between the Lisp and the Dylan folks, for they
have common roots.

> People can likewise agree on some "Lispness" of their pet languages, but
> strongly disagree that a language that lacks s-expressions in its syntax
> should even pretend to be "a Lisp".

That probably depends on the angle of view. For me, adding an
s-expression parser to the Gwydion Dylan compiler looks like a project
I could pull off if I dedicate a month or two, whereas removing
dynamic typing from Dylan is something I'd consider impossible for
myself, and changing the heart of the language.

So on the worktime-for-Andreas-metric, Dylan is two months away from
anything that can pretend to be a Lisp in your metric.

Wether that's still a Lisp on your metric is of course up to your
call, but I'd argue that it's close, the roots are common, and a
discussion here fruitful.

> | If you consider it advertising when I'm saying that Dylan was a good
> | idea, then yes, I am advertising. But it's honest, since that's my
> | opinion that I can back with arguments, and I can be convinced otherwise
> | with better arguments.
>
> What utter nonsense. You decided on what made you choose Dylan long
> before you ever heard any "argument" either way. You will not be swayed
> on any but the most superficial points by arguments. You will, instead,
> protect yourself from such swaying. How can I say this so certainly?
> Because you show an amazing lack of insight into how people choose and
> value things. Of course, now that I have said this, you may think about
> it and you may decide to surprise me. That would be kind of fun.

I am observing how people choose languages. Rest assured that
s-expressions are the number one reason why people shun Common Lisp,
regardless of whether they are good, bad or meaningless.

Since you seem to have bigger insight into how people choose and value
things, you might want to share it with us, instead of calling people
names.

Anyways, even if your assertion about my lack of insight were true, it
still wouldn't say anything about the result of arguments on my
points.

> | I do not mean to flame, troll, or insult people. I'm coming here with an
> | open mind, and a story to tell.
> You would like to believe so, but it is in fact false.
>
> If you react _defensively_ to the last line, your mind is _not_ open.

Why should I react offensively? Although I cannot be sure of the
causes of my actions, as they depend on my environment, I am the
ultimate authority on my intentions. You have no chance of
questioning that without at least trying to support it with evidence.

So your line is obviously offensive, attacking my integrity without
backing it up. By not being offensive, your attack runs into
nothingness, and you lose balance.

Coby Beck

unread,
Nov 28, 2001, 7:13:44 PM11/28/01
to

"Bruce Hoult" <br...@hoult.org> wrote in message
news:bruce-F1C168....@news.paradise.net.nz...

To be fair, this usually gets used only after all of the arguments are
presented and there is still no consensus.

> It is an invalid debating tactic and I totally reject implications based
> upon it.
>
> Whether particular things are good or bad should be decided on the basis
> of logic, not on the basis of argument from authority. Of course that
> becomes difficult when you explicitly reject logic, as Erik just did. I
> don't know what that leaves, other than tradition and accident.

Logic is important but it really is not the only basis for deciding anything,
even a computer language design. There is also intuition, consensus of
personal opinions and practicality as well as tradition and accident. Those
are not all bad things by nature and they are all legitimate circumstances.

And sometimes agreeing to disagree is the only reasonable outcome.

Tim Bradshaw

unread,
Nov 28, 2001, 7:26:32 PM11/28/01
to
Andreas Bogk <and...@andreas.org> wrote in message news:<87elmke...@teonanacatl.andreas.org>...
> Lieven Marchand <m...@wyrd.be> writes:
>
> > I'm not sure where you see this, but perhaps I'm too close to it. One
> > argument that is less important to the Dylan community then to the CL
> > community is the cost of change. There is a larger amount of CL code
> > around, more CL books and tutorials and more CL implementations, so
> > any proposed change not only has to prove its use, but also its cost
> > effectiveness. For a lot of the minor things where people argue about,
> > changing them wouldn't be worth it even if you could convince
> > everyone.
>
> This is of course totally reasonable behaviour. Nevertheless, there
> might be people who don't have these constraints, or the cost might be
> lower than people think. So the discussion is not worthless.

It is worthless in the context of CL. There are clearly decisions that
CL made which are either fairly arbitrary (like NIL/false, perhaps) or
arguably wrong (some aspects of inheritance in CLOS). The Lisp
community has already been through several sets of such changes - the
changes involved in moving from pre-CL lisp systems to CL, and the
changes in moving from CLtL1 systems to ANSI CL systems. I've been
involved in both of these (and I still occasionally have to fix CLtL1
issues in code), and I can tell you they are *bloody painful*, and
*bloody expensive*.

I don't pretend to speak for the Lisp community, but for myself I
don't ever want to have the language change out from under me in
incompatible ways again. I have thousands and thousands of lines of
CL code which I use *all the time*, and I want to get on and live my
life and not ever have to worry about whether I've made some
possibly-now-invalid assumption in code I wrote at 4am, barely
understood at the time and definitely do not understand now. There is
simply nothing that is wrong enough with CL that I want, ever, to see
incompatible changes. And the amount of code I use is pretty small by
many standards.

You have to remember that many people have been through this process,
moving code from MACLISP to Zetalisp to CL to ANSI CL or from
InterLisp to CL to ANSI CL, and doing it all over again just is not
attractive *especially* when the kinds of changes people are
suggesting are fixes to things that many do not regard as broken in
the first place. There was a compelling reason to move things to CL,
there really is no compelling reason to make random small incompatible
tweaks to the language now.

It's like the side of the road you drive on: I mean it's just obvious
that driving on the wrong side is this stupid, dangerous idea. It's
not like there's disagreement like there is with NIL/false - everyone
knows driving on the left is just *better*. But it's really an
incompatible change, and it would be quite expensive to make, so it's
not generally considered worth it. Indeed people who spend a lot of
time worrying about it are generally regarded in the driving community
as fools, especially when they insist on posting in
comp.driving.right.

Another thing people don't want to happen is fragmentation, and again,
that's because people have *seen* this happen before and they don't
want it to happen again. CL was this heroic, hugely expensive (how
many millions of dollars I wonder? less than 1000?) effort to unite a
fragmented community which ultimately succeeded but in the process
just destroyed great areas of stuff. What happened to all the
InterLisp stuff? - it's all largely just vanished, because porting it
to CL was too hard. I'm really too young to remember this, but I was
there when the InterLisp machines were going away and it was painful
to see how much stuff got lost, even in one fairly small project. I
*still* don't have some of the tools I had then. And, althogh you are
probably too young, a lot of people remember the bad taste left by
Dylan, which was seen as an attempt to fragment the community for no
very good reason: that was really a nasty experience. So people don't
react too well to suggestions that involve incompatible new dialects,
and it's not really surprising. And especially they do not react well
to suggestions of incompatible dialects based on something that many
people do not see as broken.

> On the ICFP2001 conference, there was a paper that described how to
> employ data flow analysis to figure out which bindings could be
> replaced by lexical bindings without changing the semantics of the
> code. A test with a representative file from Gnus showed that only 4
> out of 150 bindings were actually used in a dynamic fashion. These
> can be refactored manually.
>
> A scientific result changed what seemed to be like a heroic task into
> something manageable.

I'm sorry, this is just laughable - this is everything which is wrong
about this kind of argument. They loooked at *one file*! Well, I
have maybe 100 files of random personal elisp code, lots of it written
in a real hurry and/or hacked from other stuff which I barely
understood. Lots of this stuff is probably marginal, already, but I
use it all the time. There are nearly 1600 files, and a million
lines, of elisp in the xemacs distribution, *many* of which I use. I
rely on this stuff *completely* and if someone suggests that I should
fix my code because they want to change the way scoping works in elisp
then I'll stop upgrading. Sure scoping in elisp is broken, but it's
just *not broken enough* that it is worth fixing. I already find it
*significantly* painful to do emacs upgrades, and a change like this
is just not worth it. I have better things to do with my time than
worry about incompatible changes to something like this. It's not
like there's a performance problem or anything any more.

Here's another example: SunOS 4 to 5. Again, you may not remember
what this was like, but many do (especially a lot of people at Sun I
bet). SunOS 4 was really a mess, 4.0 was hopeless at the user level,
4.1 was kind of OK for users but internally horrible (there were,
seriously, things in the kernel like `x=x;' with a comment saying
`this makes it work'). SPARC support was wedged into it, and there
was basically no real chance of getting decent multiprocessor
performance because the architecture was so broken. And lots of
commerical people wanted SysV, so there was hacked-in SysV stuff both
at user and kernel level. It must have been horrible for Sun. But
SunOS 5 took *years* to be accepted, because lots of people had all
sorts of stuff which really depended on SunOS 4 and *really* did not
want to change things, because from the user level 4.1.3 / 4.1.4
worked really OK, and early SunOS 5 was buggy and slow. I remember the
horror when Sun came out with machines (ultras? or was it before that)
which *would not run* SunOS 4, and the relief when we found that you
could, in fact, get SunOS 4 for them if you asked the right people.
This must have cost Sun *enormous* amounts of money. You can see how
bad it was by the fact that they've now renumbered things so no one
ever worries that there might be a SunOS 6 some day. And that was a
change which - even though I'm a BSD person and it hurts to say this -
needed to be made.

Finally, the question is *why*? Why are people obessing away about
NIL/false or other incompatible changes which have little benefit and
much cost, when instead you could be working in *compatible
enhancements*, which would have little cost and huge benefit. I mean
there must be *millions* of things you could add to CL which would not
break a single line of existing conforming CL code and would provide
cool new stuff. Tie down the MOP, for instance. Design and get
agreement on a MP interface. URIs. Standard sockets. FFI.
Defsystem. I can just keep typing these things in for ever. *Why*
are you worrying about some trivial little design issue when you could
be doing something cool and new? Come on, get *over* it, this is just
*STUPID*.

--tim

Erik Naggum

unread,
Nov 28, 2001, 7:52:03 PM11/28/01
to
* Andreas Bogk

| Because that's the association I have when reading your arguments.

Precisely. This is your problem, and you should just go fix it. Nobody
is so fucking stupid as to regard a standard as "gospel". Grow a clue.

| The "you must believe in it, because it was written by God^Wpeople much
| smarter than you" argument.

Where is the "believe in" part outside or your mind? Just because you
have a personal problem with your incredibly low reading comprehension
and an overactive imagination that fills in the blanks when you do not
understand what you read, does not give you the right to assume that you
reach valid conclusions. In fact, it is typical of inferior thinking
skills that you _do_ think you can fill in the blanks and reach any
goddamn conclusion you want. Rational people do not lie about their
observations in order to arrive at their pre-conceived conclusions.

| The "it's not Lisp unless it is Common Lisp, and everybody deviating from
| Common Lisp is a heretic, even if he doesn't claim

Nobody says this, either, you dimwit. Notice how you introduce all the
religious terms -- because that is _your_ language.

> What kind of short-circuiting of your thinking processes are you
> satisfied with once you can label someone "religious"?

| I can stop trying to have a rational argument with them about the subject
| of their belief.

But because _you_ make up your mind that somebody is religious, and you
are the first to relinquish rational argument, _you_ are in fact the only
irrational and religious person around. You will never understand this,
any more than most criminals accept that they are guilty.

| I'm not lacking evidence, there's enough in your postings.

Only for the association in _your_ mind. That has nothing at all to do
with me. For all your fascination with logic, you sure do not know how
to arrive at valid premises. When you accuse me of something when in
fact you are only accusing me of causing associations in a deranged and
religious mind, it is important to point out that every monster you see
is your own creation. Religious people, especially those who have turned
their back to religion for the wrong reasons and who have a huge personal
authority problem as a result, tend to assume that _all_ authorities are
religious in nature, or want to be. This happens only to stupid people
who are too goddamn slowwitted to figure out what they really object to.
Because they can label everything they do not like "religious" after this,
they will also never mature or develop beyond this infantile rejection of
authority. In short, mentally underdeveloped and rebellious children.

| If I sound like a religious zealot to you (which of course is just a
| pattern in *your* brain), and if you think religious discussions are
| pointless, stop listening to me.

A person who talks about "gospel" is ipso facto a religious zealot.

| I'm only reporting my impressions, honestly and faithfully.

My _impression_ of you is that you are probably the stupidest person to
come visit us in several months. What value does this impression have?
Should I share it with anyone? I am trying to cause you, the stupidest
person around, to revv up your dysfunctional brain and stop accusing
people of your own mental problems that cause you to think anybody but
you think in terms of religion and gospel. This is _your_ problem, and
only _you_ can solve it. Here is how: Figure out that people who look
religious to _you_, are in fact _not_. Then read my signature and be
enlightened, or at least start to think.

| If this annoys you, maybe you should search the reason on your side.

Of course, it is also Common Lisp's fault that you have problems with it.

Dylan seems to breed clueless idiots faster than applications.

Erik Naggum

unread,
Nov 28, 2001, 8:27:19 PM11/28/01
to
* Andreas Bogk

| Have *you* ever tried to change a law?

Yes. I also succeeded. Next moronic question, please.

| All I'm saying is that if I fail to conform to Common Lisp, it is still
| Lisp.

This is sheer idiocy. Implying that you believe something so
fantastically moronic is not a very smart move on your part.

> Then I will consider you a criminal in our little society, one who is
> fighting "laws he consider immoral or meaningless" simply because he has
> failed to think things through.

| Usually considering something immoral and meaningless involves thinking.

A typical moron response. "Fail to think things _through_" cannot be
countered simply by arguing that something "usually involves thinking".
In fact, you _support_ my argument that yo do not think things _through_.

| Because *you* treat me that way, and I suggest this is *your* problem.
| Seems to be hard for you to understand.

When a criminal gets caught, it is always whoever catches him who is to
blame for his predicament. That you react this way supports my image of
you as someone who has not learned to subordinate his desires to that of
an authority. Usually, this is due to massive immaturity or arrested
development, but sometimes, it is a kind of arrogance that actually has
concluded that society can go to hell. How do you make people change
their mind once you have given them this "impression"? You _THINK_ and
provide them with counter-evidence. Of course, trying to give you any
counter-evidence to your religious lunacy has made you even _more_
certain that you are right. This indicates that you retarded or have
never actually _observed_ that you have been wrong at any time in your
whole life. This goes with the arrogance and maturity problems you have
so far made a point out of underlining.

  If you do not like this "personal touch", quit accusing people of being
religious simply because you are too stupid to argue against them.

> and you want Dylan to be a Lisp.

| Well, it is. It's not Common Lisp, though.

Dylan is a Lisp the day Perl is a Lisp. For the same reason.

| If he says Scheme is a Lisp, and that Lisp has shortcomings, he's saying
| that Scheme has shortcomings. So there's no point.

Sigh. You probably even believe this. I feel sorry for you the day when
you figure out what marketing is made of, indeed human communication.

| What I want to captialize on is sharing experience with other Lisp people
| about the common foundations. You can hardly blame me for that.

I can blame you for not inviting people into your little pond to discuss
them there, and that is what I do. Go back to comp.lang.dylan and talk
about your favorite Dylan things there. Invite Lisp people to your forum.
Obviously, you know that this will fail to have any desired impact, and
still you have not figured out why Scheme people talk negatively about
"Lisp" and positively about "Scheme". Pretty amazing, really.

| I don't believe that *a* right answer is *the* right answer. It's
| hard to find out how you read that from my above comment.

Really? A moron who finds evidence of religion at the drop of a hat has
problems figuring out how his own arguments look to others. Dude, how
have you managed to stay alive so long?

| It's just that I don't think that *a* wrong answer is *the* wrong answer,
| for precisely the same reason. That's what I have written above, and it
| would suit you well to address this argument, instead of handwaving.

If _a_ wrong answer was _the_ wrong answer, it would mean that every
_other_ answer would be right. Such is the implication of "_the_ right
answer", but I am not surprised that you do not get this. I think I have
had enough of your idiocy, now. You clearly cannot think under pressure,
much less logically, so I asusme that your brain actually only functions
when your ego is massaged sufficiently, so it can only be used when you
feel safe and secure. That is pretty useless -- thinking hard should be
most available because it is most _useful_ when you are under pressure.
You are not even smart enough to hold back from posting until you can
start to think clearly.

Dylan seems to breed idiots faster than it breeds applications.

Lieven Marchand

unread,
Nov 28, 2001, 4:27:27 PM11/28/01
to
Kent M Pitman <pit...@world.std.com> writes:

> So if we could declare a hash table of integers, there might be
> cases where people usefully did (INCF (GETHASH A B)) without having
> to initialize (GETHASH A B) because they would know that (GETHASH A
> B) would return 0, NIL when there was no element or 0, T when an
> element had been set to 0.

I've been using (INCF (GETHASH A B 0)) for that.

Bruce Hoult

unread,
Nov 28, 2001, 10:22:55 PM11/28/01
to
In article <32159556...@naggum.net>, Erik Naggum <er...@naggum.net>
wrote:

> * Bruce Hoult
> | What *you* have missed, is that some of those exact same brightest
> | minds
> | to ever touch a keyboard went from Common Lisp to design a new language
> | and did a few things differently the second time around.
>
> But they designed a new language and set up a new community for
> it! They did _not_ hang around in the Common Lisp community and
> whine about it.

Who's whining here?

I'm interested in learning the facts of what the differences are between
CL and Dylan, and what the reasoning is behind those differences (from
both sides), and to then make my own judgements about whether anything
of value has been lost in creating Dylan from CL.

Please note that I'm posting in the generic "Lisp" newsgroup, not a
specialized one for Common Lisp such as c.l.clos.


> | Are you saying that you're brighter than Moon?
>
> Please think about what you are _actually_ saying.

What I'm _actually_ saying is that the argument "CL was designed by
genuises, you're not one, so shut up" is not useful.

-- Bruce

Bruce Hoult

unread,
Nov 28, 2001, 10:30:00 PM11/28/01
to
In article <keke-28110...@solg4.keke.org>, ke...@ma.ccom
(Takehiko Abe) wrote:

That's right, and it has bearing on certain design choices such as
Generic Functions being "sealed" by default and a lot of langauge
efficiency being acheived through compiler optomizations that rely on
sealing and a closed-world assumption. So Dylan tries pretty hard to be
as efficient as a static language, while still enabling most of the
dynamic features of CL when you want them. And some things that can be
done in CL on the fly are done in Dylan by changing source code and
recompiling -- you can't change the class of an exisiting object, for
example, or add slots to existing objects.

This has no bearing on the question here being discussed, of "nil qua
false".

-- Bruce

Bruce Hoult

unread,
Nov 28, 2001, 10:56:01 PM11/28/01
to
In article <fbc0f5d1.01112...@posting.google.com>,
tfb+g...@tfeb.org (Tim Bradshaw) wrote:

> I don't pretend to speak for the Lisp community, but for myself I
> don't ever want to have the language change out from under me in
> incompatible ways again. I have thousands and thousands of lines of
> CL code which I use *all the time*, and I want to get on and live my
> life and not ever have to worry about whether I've made some
> possibly-now-invalid assumption in code I wrote at 4am, barely
> understood at the time and definitely do not understand now. There is
> simply nothing that is wrong enough with CL that I want, ever, to see
> incompatible changes. And the amount of code I use is pretty small by
> many standards.

So *this* is where all the defensiveness here is coming from!!

Every time I or Andreas or someone else is interested in learning about
and comparing the way CL does something with the way that other
langauges do similar things, you for some reason I don't fathom
immediately think that they want to *change* CL.

Quite apart from being false, it is a preposterous idea to imagine that
I have the *power* to bend the CL standard to my will even if for some
strange reason I *wanted* to. I would never have thought of it as a
possibility. I'm astounded that you seem to think it's a possiblity.

Astounded.

-- Bruce

Pierre R. Mai

unread,
Nov 28, 2001, 11:05:21 PM11/28/01
to
Bruce Hoult <br...@hoult.org> writes:

> I'm interested in learning the facts of what the differences are between
> CL and Dylan, and what the reasoning is behind those differences (from
> both sides), and to then make my own judgements about whether anything
> of value has been lost in creating Dylan from CL.

This appears to me to be not an unbiased stance. You seem to have
made up your mind quite some time ago that nothing "of value" has been
lost, and you are now seeking confirmation on this point. Since you
will be the arbitrator of what is of value and what isn't, there will
be little surprise about the final outcome, will there?

Furthermore you don't seem to acknowledge the fact that value is
always relative to people. Things aren't of value in themselves.
They are of value, because they are valued by someone. People often
don't agree on what they value.

Some people have stated here that they do value that (eq 'NIL '()) in
CL. You obviously don't value such a thing. So, lucky you that Dylan
does what you value [leaving aside the question that it isn't the
other way around (for all of us)]. CL provides what I value. Now
that we are aware of the fact that we value different things, can we
move on?

Ah, but we can't, because you need support for your view that Dylan
didn't leave out anything of value from CL. Maybe we could get the
current NCITS/J13 to publically declare "Dylan has everything that was
good and great about (Common) Lisp, left out all the crap.
Furthermore it wasn't designed by some steenking Committee, so
therefore we declare the whole Common Lisp standard superceded by
[insert Dylan "standard" here]".

Maybe this would get the world to finally see that Dylan is the way
forward, and everything else is just the delusional ranting of people
who just have the _wrong_ values.

Regs, Pierre.

--
Pierre R. Mai <pm...@acm.org> http://www.pmsf.de/pmai/
The most likely way for the world to be destroyed, most experts agree,
is by accident. That's where we come in; we're computer professionals.
We cause accidents. -- Nathaniel Borenstein

Bruce Hoult

unread,
Nov 28, 2001, 11:35:14 PM11/28/01
to
In article <sfwhere...@shell01.TheWorld.com>, Kent M Pitman
<pit...@world.std.com> wrote:

> So if we could declare a hash table of integers,
> there might be cases where people usefully did (INCF (GETHASH A B))
> without having to initialize (GETHASH A B) because they would know
> that (GETHASH A B) would return 0, NIL when there was no element

> or 0,T when an element had been set to 0.

This is certainly handy in keeping many Perl programs short, but I feel
that it's not a good thing in a language in which you can implement
powerful abstractions efficiently.

Your hash of integers is presumably the concrete implementation of some
abstraction. This implementation might some day change as you realize
that another implementation technique has better characteristics. So
you don't want to have client code explicitly depending on the
representation.

There is also no reason to suppose that 0 is always the appropriate
default value for a numeric value -- that depends on the abstraction
being modelled, and perhaps on considerations such as minimizing storage
usage by avoiding explicitly storing data for the most common case.


What I would do is to write a getter and setter that do the right thing
for the domain being modelled, and get them hooked into the
GET-SETF-EXPANSION mechanism. The getter might be as simple as
element(a, b, default: 0).

-- Bruce

Bruce Hoult

unread,
Nov 29, 2001, 12:43:06 AM11/29/01
to
In article <87snayj...@orion.bln.pmsf.de>, "Pierre R. Mai"
<pm...@acm.org> wrote:

> Bruce Hoult <br...@hoult.org> writes:
>
> > I'm interested in learning the facts of what the differences are
> > between CL and Dylan, and what the reasoning is behind those
> > differences (from both sides), and to then make my own judgements
> > about whether anything of value has been lost in creating Dylan
> > from CL.
>
> This appears to me to be not an unbiased stance. You seem to have
> made up your mind quite some time ago that nothing "of value" has been
> lost

How could I possibly have already made up my mind about such a thing
when I am not yet an expert in CL?


> and you are now seeking confirmation on this point. Since you
> will be the arbitrator of what is of value and what isn't, there will
> be little surprise about the final outcome, will there?

You will therefore no doubt express your "little suprise" when I tell
you that off the top of my head, at least the following things of value
(to me) have been lost:

- "collect" clause in the loop macro ("for" macro in Dylan)

- incf/decf. The Dylan ":=" is equivalent to the CL "setf", but Dylan
lacks incf/decf in particular and the C'ish modification operators ++,
--, +=, -=, &=, |= etc in general. I miss this.

[rest snipped as flowing from an incorrect premise]

-- Bruce

Jochen Schmidt

unread,
Nov 29, 2001, 1:40:26 AM11/29/01
to
Bruce Hoult wrote:

> In article <fbc0f5d1.01112...@posting.google.com>,
> tfb+g...@tfeb.org (Tim Bradshaw) wrote:
>
>> I don't pretend to speak for the Lisp community, but for myself I
>> don't ever want to have the language change out from under me in
>> incompatible ways again. I have thousands and thousands of lines of
>> CL code which I use *all the time*, and I want to get on and live my
>> life and not ever have to worry about whether I've made some
>> possibly-now-invalid assumption in code I wrote at 4am, barely
>> understood at the time and definitely do not understand now. There is
>> simply nothing that is wrong enough with CL that I want, ever, to see
>> incompatible changes. And the amount of code I use is pretty small by
>> many standards.
>
> So *this* is where all the defensiveness here is coming from!!

huh?



> Every time I or Andreas or someone else is interested in learning about
> and comparing the way CL does something with the way that other
> langauges do similar things, you for some reason I don't fathom
> immediately think that they want to *change* CL.

No - the annoying fact is that the way you both argue shows that you are
not interested in finding what could be done better in Dylan but more
finding arguments were CL is worse than Dylan.

You came here and proclaimed that CL seems to have a problem because it does
not distinguish nil/false/'() and Dylan has done this better. You then *got*
your answer that no lisper here ever had any problem with this issue and
that it is even counted as a feature in some contexts. But instead of
learning from that, you annoy people by insisting that lispers should have
a problem if they think so or not only because you think it fits your bill
and CL is wrong and Dylan is right completely forgetting the fact that only
the community itself is able what is counted right or wrong.

You criticize that this facility is restricted to lists while Dylan has all
this generic container stuff - completely forgeting the fact that lists are
of *much* higher value in a language that got not crippled by omitting
s-expressions.

One thing you both seem to completely forget is that your silly little
language-war is really a disservice to Dylan. Many lispers may try out
Dylan from themselves but if they get insulted and annoyed by some language
fanatics I think the chance for that is quickly decreasing against zero.
(This is at least the effect this discussions had to me so far...)

Jochen Schmidt

--
http://www.dataheaven.de

Bruce Hoult

unread,
Nov 29, 2001, 12:59:06 AM11/29/01
to
In article <sfw7ksb...@shell01.TheWorld.com>, Kent M Pitman
<pit...@world.std.com> wrote:

> Moreover, as to this political party, its core membership
> (that is, as embodied in J13) apparently agrees that the cost of
> opening the existing standard for tinkering is prohibitively high. It
> is not up for debate.

Once again we have this defensiveness, based on a false premise.

I don't want to change CL. I certainly don't have the power to change
CL, even if I wanted to. It is, as you say, "done". Fine. Can we
please move on from this false premise?

What I want to do is to *understand* CL, just for my own pure
intellectual curiosity. I want to know not only what *is* in CL, but
*why* it is. If there's a logical reason then I'd like to know it. If
there are special advantages conferred by something that make certain
things easier to do then I want to learn about that too. And if
something is just historical accident and it hasn't been judged worth
the pain of changing then that answers my question too.

Far from wanting to change CL, what I want to do is to see if there is
anything that should be changed in Dylan. And *that* I believe I have a
strong chance of doing. I can implement new things in CMU Gwydion
Dylan, try them out, and if they work well there is an excellent chance
of them being propogated to the other implementations.

-- Bruce

Andreas Bogk

unread,
Nov 28, 2001, 8:41:27 PM11/28/01
to
Lieven Marchand <m...@wyrd.be> writes:

> In more artisanal times, like Rubens and probably Rembrandt still, a
> painting was a committee work, where the master did the composition,
> the foreground and other import stuff and one of his students might
> fill in a tree or clouds in the background.

Committees work different.

Bruce Hoult

unread,
Nov 29, 2001, 2:44:03 AM11/29/01
to
In article <9u4051$h1j$1...@rznews2.rrze.uni-erlangen.de>, Jochen Schmidt
<j...@dataheaven.de> wrote:

> No - the annoying fact is that the way you both argue shows that you are
> not interested in finding what could be done better in Dylan but more
> finding arguments were CL is worse than Dylan.

If that is the impression you get then it is an incorrect one.


> You came here and proclaimed that CL seems to have a problem
> because it does not distinguish nil/false/'() and Dylan has done
> this better.

That is factually incorrect.

Thomas F. Burdick made that claim, purely about CL with no reference to
Dylan, in <xcvpu6b...@conquest.OCF.Berkeley.EDU>. I later came
into the thread to offer my experiences and thoughts.


> One thing you both seem to completely forget is that your silly little
> language-war is really a disservice to Dylan.

There is no language war from my side. I think both CL and Dylan are
valuable languages to have in your toolkit, and I would welcome the
chance to work professionally in either.


> Many lispers may try out Dylan from themselves but if they get
> insulted and annoyed by some language fanatics I think the chance
> for that is quickly decreasing against zero.

CL of course has no language fanatics.

-- Bruce

Brian Palmer

unread,
Nov 29, 2001, 3:45:55 AM11/29/01
to
tfb+g...@tfeb.org (Tim Bradshaw) writes:

> It's like the side of the road you drive on: I mean it's just obvious
> that driving on the wrong side is this stupid, dangerous idea. It's
> not like there's disagreement like there is with NIL/false - everyone
> knows driving on the left is just *better*. But it's really an
> incompatible change, and it would be quite expensive to make, so it's
> not generally considered worth it. Indeed people who spend a lot of
> time worrying about it are generally regarded in the driving community
> as fools, especially when they insist on posting in
> comp.driving.right.

? I'm not familiar with this argument.


> *still* don't have some of the tools I had then. And, althogh you are
> probably too young, a lot of people remember the bad taste left by
> Dylan, which was seen as an attempt to fragment the community for no
> very good reason: that was really a nasty experience. So people don't
> react too well to suggestions that involve incompatible new dialects,
> and it's not really surprising. And especially they do not react well
> to suggestions of incompatible dialects based on something that many
> people do not see as broken.

Right. That may explain things, but it doesn't entirely justify
matters. My perspective, as someone just starting out and learning
lisp (in particular, emacslisp more than common lisp), and who has
been lurking in the group for less than a year, is that the "Common
Lisp community" as represented on the newsgroup is very brittle. The
progression of some discussions have definitely left a very bad taste
in my mouth, even as uninvolved as I am in the group.

--
Brian Palmer
"Whoever fights monsters should see to it that in the process he does
not become a monster. And when you look long into an abyss, the abyss
also looks into you" - Nietzsche

Erik Naggum

unread,
Nov 29, 2001, 3:53:02 AM11/29/01
to
[ I have made an effort to answer with a one-liner to each paragraph, with
further elaboration following it. You may skip the elaboration unless
you want to respond to this. ]

* Andreas Bogk


| Well, it extends to a general dislike against any use of inband
| signalling in a lot of other contexts.

Where did this "dislike" come from? When does your "dislike" begin?

I would have assumed that you dislike everything that computers do with
that attitude, since they practically _embody_ the principle of inband
signalling these days. Digital transmissions practically _forbid_ real
out-of-band signalling -- it is all done by in-stream encapsulations and
encapsulation these days, precisely what "in-band" refers to. Sheesh.

| This is based on observation of the problems (especially security
| problems) of software that violates these rules.

Ah, the good old argument from "my experiences of fear and pain", again!

The best solution to some people's severe personal problems with all
things painful is simply to ask them to increase their pain threshold --
nothing else will actually help. Wimps and whiners will never amount to
anything in a world where the expectation that everything be painless is
routinely disproved. An experience of pain means that _you_ do something
wrong. If you are the arrogant type, you will blame somebody else for it
or the universe in general if you are _real_ idiot, but arguments based
on "it hurts, so I won't do it" are actually _wrong_. It was _not_ what
you did that made it hurt, except in such trivial cases that you never
talk about it.

If you design crappy software and something dies on you, the cause is not
because the language violated some stupid rule of in-band signalling --
it your own, personal ineptitude that was the cause and your own goddamn
fault for not being able to deal with it when you implied to yourself and
the computer and your superiors that you could.

| So anybody who thinks that CL is better off violating this rule either
| doesn't believe in it, or believes that there are more important rules.
| In both cases, I am curious to know why.

Or they do not actually violate it, because you are simply _wrong_.

Your failure to grasp what you want to accuse others of is repeated with
an alarmingly high frequency, and it seems to be increasing rapidly when
you are chastised for it. The world is not at fault for not obeying your
rules. You _really_ need to grasp this. Rebellious idiot students could
perhaps get away with such cluelessness in the late 1960's, but rebelling
against the authority of a programming language standard is simply _nuts_.

> As a matter of fact, (when foo ...) has a _much_ lower cognitive load
> than (unless (empty? foo) ...).

| Only if you have interned this particular feature so much that you also
| see the latter meaning if you see the former in code.

You _know_ this kind of thing? You show no evidence of doing so.

This is stuff that is _measurable_ and which has been studied over and
over. "Cognitive load" is actually a well-known phenomenon, and it is
one of those things for which ignorant newbies are _not_ the standard by
which everything is measured. When I said "as a matter of fact", I did
not mean your kind of fact, I meant _fact_. Do you understand this?

I also demonstrated that (empty? foo) is the _wrong_ replacement, that
empty? must be true of much more than lists, but that none of these are
false. In other words, you are just _wrong_.

People who are psychologically prevented from accepting anything that
other people tell them is the rules they have to follow, will get upset
for no reason about _their_ "rules" being violated. This is _curable_,
but not by changing the rules in long established standards.

| Using the former when meaning the latter fails to communicate the intent.

The former means that one is testing for a non-nil value.

You are testing for "a non-empty something". You have misunderstood the
intent and this causes you to communicate something else. Most of your
conclusions come from making similar mistakes and not listening when
people tell you to pause and think. This makes you look _tremendously_
retarded to those who _do_ know.

> If you at _least_ had rewritten it as (when (pair? foo) ...), you might
> have a fighting chance, but the two are not quite similar -- foo could be
> a non-list, in which case empty? might provide the wrong answer. An
> empty string or vector or hashtable or package or whatever is true in
> Common Lisp, but empty? should be true of all of these.

| The intent when writing such code is indeed testing for an empty
| container, so the fact that it works correctly for non-list container is
| a good thing.

This is actually wrong in Common Lisp.

It might be right in Dylan, but it goes to show how Dylan is _not_ a
Lisp, that you are not discussing this in the proper forum, and that you
are not listening when people talk to you. If nothing else, this alone
makes you stand out like a prize moron.

| Too bad this isn't true for the (when foo) case, it only works for lists.

You demonstrate only your arrogance from ignorance

I am a little amazed at your lack of will or ability to introspect. You
are reacting in a way that demonstrates that you do not listen at all,
but react only to what your "impressions" tell you is happening. This is
the modus operandi of prejudicial _idiots_.

| By the way, please forgive the use of the Dylanesque empty?. I'm so used
| to working in a language where I can express operations on collections
| independent of their implementation that I completely missed the fact
| that there is no empty? in Common Lisp, and that it can't be implemented
| in a way that would have equal performance to (when foo).

Yes, paying attention is evidently too high a price for your arguments.

Maybe you will pay more attention in the future? That would really help.

> I see a person who thinks _much_ too highly of his own abilities.

| I've been to some meetings of standardization groups, and have seen how


| they work, thank you. Their compromises are often not mine, and their
| documents below the standard of the individual members.

Why go to such lengths to confirm what I just said about you?

Why do you think your extraordinary ability to generalize from painful
experiences produces _true_ or _useful_ results? You do not even seem
able to recognize that having been to "some meetings" does not give you a
right to conclude _anything_. This implies that you think the painful is
the normal, and that there is nothing you can or should do about it. And
that explains why you dig yourself in deeper all the time, too.

Part of the ability to generalize correctly is the ability to weed out
exceptional situations and not confuse noise and signal. If you think
what you have observed gives you grounds to believe it is the _normal_
situations, you are as mistaken as you are about this forum. You simply
do not get normal reactions when you poke people in the eye, and you
_should_ be able to understand this. However, I doubt that you are.

| I've only been using programming languages for the last 14 years, and
| I've only been studying programming language design for the last 5 years,
| so I'm certainly neither the most experienced language designer nor the
| best.

Yet such incredible immaturity after so much experience is _alarming_.

> E.g., I know a lot of people who are better than me at many of the things
> I want to be good at, but I know far, far more people who only _think_
> they are and who have yet to wake up and smell the coffee and realize
> their "ranking".

| So your participation in this newsgroup has the purpose of establishing
| some smartness ranking?

No. Reading comprehension is not your strong suit, is it?

Does your dysfunctional brain realize that as you go wrong with such a
mindless accusation, you need to try something else, or will you just
think you have proved your argument _because_ I deny it? Really stupid
people tend to consider their prejudices proved the stronger their victim
objects, proved when the victim does not object, and proved when they
agree. That is what stupid prejudice is all about. You sound like one
who suffers from this particular problem and post your stupid prejudice
because you think this will win a debate for you, when what _would_ have
helped is simply using your goddamn brain to _THINK_.

Smart people recognize other smart people. Stupid people do not. This
means that failing to understand one's "ranking" is an indication that
one is stupid below an important threshold. Your persistent failure to
read what people write accurately, however, is a pretty good sign you are
a very unobservant person in general.

> These latter people tend to hate me for not allowing
> them to keep thinking they are far better than they are.

| I think most people tend to hate you because of your attitude.

You are not most people, nor do "most people" hate me, you dipshit.

That you are not most poeple _should_ be an important realization for
you. You cannot extrapolate your experiences to other people, not in
normal situations, and especially not in abnormal situations. Every
argument that appeals to statistics about what other people think are
ipso facto _invalid_ and merely tells others that you are immensely
stupid. But you will not understand this, either, will you?

You reject arguments that appeal to authority, but you appeal to your own
unverifiable experiences, to fear and pain, and to popularity, all of
which are incredibly stupid compared to appeals to accept an _actual_
authority in a particular field. If you have never been castigated for
your stupidity before, and if you are in fact as stupid as I think you
are, you will not understand or accept that you are wrong in any way, and
you will cocoon yourself in self-preserving delusions that you are not
acting like a moron here. My attitude is simply that I despise stupidity
in all its shapes and forms. If you want to be stupid, you will hate me.
If you can figure out that you need to pull yourself together and stop
making stupid mistakes and arguments, you will _not_ take it personally,
but _understand_ what the fuss is all about. I use this as a means of
determining whether people ar worth listening to after they had a chance.

| I have met people smarter *and* more humble than you.

I actually doubt that, or you would have recognized that you are being
castigated for your serious _lack_ of humility in this forum. Your
ignorant arrogance and your lack of willingness to listen when people
reject your premises and tell you that you need to _acknowledge_ the new
community you have just walked into have all caused you to become more
and more arrogant -- those are not smart reactions. And just because you
think you have "a Lisp" and thus a "right" to post bullshit here does not
mean anyone has to agree with you. You have comp.lang.dylan, but it is
not possible for you to invite people over to your forum to talk with you
there, is it? My guess -- nobody _wants_ to. So you have to trespass on
their grounds and annoy them on home turf, instead. Goddamn stalker!

That you do not at _all_ understand that you are not welcome to post
bullshit, and that is not just my reaction, means that you are here on a
mission, where ignoring other people's concerns are perfectly acceptable.
This is evident in much of what you post. Such arrogance does not make
people likely to think you are here to be constructive or learn something.

Considering that you appeal to logic, but demonstrate no skills in using
it even to save yourself, I consider the rest of your attempts to look
friendly and polite be deceptive as well.

| It's not irrelevant, it's called "learning". It might even be of some
| use if I ever decide it would be nice to design a new language from
| scratch.

Learning? Learning _what_?

That being an obnoxious idiot tourist in a new community makes people
pissed because you are too goddamn stupid to look around you and wait
until you grasp what is going on before you start to make "suggestions"
for that community to adopt?

That some people do _not_ consider what you are unable to deal with
errors, and would in fact do the exactly same thing all over again?

That some people _like_ what you have such a personal problem with?

That nobody cares what a goddamn Dylan freak has problems with?

| But I think slightly improving existing languages is a more realistic
| target.

It does not happen the way you think.

Waltzing into a community to tell people how to improve _must_ fail,
especially when you come from a community that walked out on Lisp in the
first place to do their stupid thing.

That you already think standards committees do poor work and that you
"know" how they work (thank you), must mean that you are here to make
people _abandon_ their standard and adopt Bogk Lisp, instead, which would
of course be an improvement over absolutely anything, right? Now, we
just had another case here with a guy who just could _not_ accept that
Common Lisp has a large set of perfectly fine conditionals -- he just
_had_ to use his own, and anyone who uses the standard ones around him
gets chastised for it and have their code mutilated. He, too, has a very
strong disdain for "committee work". He, too, knows best himself. There
is a commonality here that you may not notice right away, so let me make
it clear to you: The reason people who have "special ideas" do not get
them accepted is that most of the time, it is because they are _nuts_,
and that their "special ideas" are old ideas that have already been
discarded or are known to lead into major messes. Failure to listen to
the community in this situation means that one is not contributing to the
community, but regards the community as one's private ego massage team.
People generally reject every attempt to put them into this role.

Languages are not slightly improved.

| Do you pay taxes?

Next moronic question, please! Geez, just how retarded _are_ you?

| In my view, it's a minor inconvenience that I don't actually mind
| anymore, and probably just a cultural thing.

> "Just a cultural thing"? That is precisely what the super-tolerant
> idiots say about the molestation of young females in backward cultures
> that claim it is their "religion" that defends this criminal act against
> at least half of humanity. Cultures are tremendously important, and some
> of them are just plain _bad_.

| Have you just compared infix syntax to child molestation, or is this just
| my imagination?

Just your hyperactive and free-wheeling imagination, again.

I also think you missed the reference to female circumcision and thought
it was about "child molestation" because, again, you had to fill in the
blanks where you did not understand something fully. You are _really_
quite fascinating to watch. Actually being bothered to be accurate or
pay attention to your level of comprehension it clearly too much to ask
of you. That you have not met people who have told you to go to hell
previously must be because they have been too polite to tell you the
truth, and now you are all hysterical because I am "rude" to you. Get a
grip on yourself and figure out that only _you_ can change all this.

| I've had several opportunities to demonstrate my technical skills, [...]

Why are you defending yourself with something so utterly irrelevant?

Who "you" are is of absolutely no interest to me. Your arguments and
opinions are, and only your arguments and opinions. They are the subject
of my criticism, not you, but they have a person and a will to act behind
them, and it is in the capacity that "you" are chastised. Do something
else, and I will respond to that, instead. If you persist in defending
yourself, I must have been correct in my assessment and made it hurt real
bad. You should not expose yourself that much in public. This is not a
personal chat forum.

If you post mostly stupid arguments and nonsense, that is what you are,
here. If you never do any better, then it must be because you _cannot_
do better. When it hurts to post some moronic bullshit, try something
different -- do not just _be_ a moron and keep posting moronic bullshit
because you think you have a "right" to do it.

> To trace the history of how we ended up with our conclusions, ignore all
> the explicit arguments and premises and logic and focus on what went down
> the drain before you even _started_ to think about it. _That_ is where

| I think that would be a bad approach. Logic has it's limits, but it
| cannot be plainly rejected as irrelevant.

Your reading comprehension problem is showing again.

Can you at least make an _effort_ to think about what you read and
perhaps fail to make so many stupid mistakes? Dude, you are a random
number generator. How can anyone talk to such a moron as yourself when
you grasp _nothing_ of what you are being told?

Logic was not rejected as irrelevant, you moron, you were told to ignore
it if you wanted to trace the _history_ of your conclusions. It is your
tacitly accepted premises that guided everything -- logic made it simply
follow from those premises. Your amazing lack of thinking skills is
beginning to be such a curiosity that I am tempted to reply to you only
to see if you do any other hilariously funny mental tricks.

| How deeply have you looked into Dylan, for instance, to be able to say
| that it doesn't have the Lisp nature?

It has rejected s-expressions.

How deeply would I have had to look into Dylan to satisfy you? There is
clear evidence that you would not accept _anything_ as satisfactory.

You show us that you have not understood what Lisp nature is, because the
only "Lisp" you _actually_ know well is Dylan. To you, Common Lisp has
Dylan nature, but that does not mean that Dylan has Lisp nature. You do
not know the first thing about Lisp nature, except for what some other
Dylan freak has told you about it. Right?

| You still have to show a serious flaw in my logic.

Blasting your premises to pieces does not count?

Must I _accept_ your premises in order to show a weakness in your logic?
Sorry, but that is not how _real_ logic works. _Real_ logic ensures that
conclusions follow from their premises, and that is all. The best that
can be done with logic is to show that _if_ the premises are correct,
_then_ the conclusions also are. If the premises are false, _anything_
can follow. So if you are hung up in logic, which is fairly trivial and
mechanistic, you need a way to ascertain that your _premises_ are good.
You do not seem to grasp this at _all_.

It is utterly amazing to me how anyone can talk so loudly about logic and
not understand the importance of the premises for his reasoning, and it
is even more amazing that you _dismiss_ those who reject your premises
when they are simply _untrue_. What the hell kind of logic is it that
you want, Andreas Bogk?

| Who tells you I'm not practicing it on a daily basis?

Your news articles, you dimwit. Grow a clue, now.

| I hope I'm not doing too bad.

No, you are doing a lousy job.

| One has to recognize that a lot of our daily activities consists of
| building models and executing "proofs" in the model by constantly
| verifying it against the real world.

Really? And if one does not "recognize" this?

People who believe in the model bullshit are wrong.

| Then they have a lot of fun executing some proofs in the form of dad
| hiding and reappearing behind a curtain.

Yeah, I am sure they execute proofs when they figure these things out.

This means that "proof" to you has a pedestrian meaning and not a formal
meaning at all. This is quite informative. Poor children, by the way.

| I bet the higher thought processes of animals are alot like that.

Yes, my cat also executes proofs. Cool, I always thought she was smart.

| There are some things we cannot understand using the model-building
| process, consciousness itself is an instance. This is where the world of
| models, rules and proofs fails, and where psychology, philosophy and
| religion come into play.

And just _how_ do you know these things?

This looks more and more like the same old problem of premises taken for
granted and which cannot be questioned. The fact that you reject every
attempt to question your premises rhymes with your belief that others
have no rational basis for their conclusions, either, and hence you make
those stupid accusations about "gospel". Logic from "postulates" and
"axioms" and otherwise _unquestioned_ premises is a fool's business --
damn near _anybody_ can do it, it is a simple matter of following a bunch
of fairly straightforward rules to the letter. Figuring out whether the
core premises are good, however, requires serious skill and deep thought,
sometimes the work of geniuses. This is where people usually fail, and
miserably. This is where philosphy becomes _interesting_. Your reaction
to this is as follows, however.

| That does not make these things irrelevant.

Your "logic" appears to be based on unquestioned beliefs that have no
rational basis whatsoever.

| Your irrational behaviour is a living proof that logic has it's limits.

Do you even read what you are writing? Do _you_ laugh, too?

But please let me watch your learning ability in practice. "It's" is a
contraction of "it is" or "it has". "Its" is a possessive pronoun. Can
you figure out which to use at what time and consistently avoid making
more silly mistakes? That would be appreciated. I assume, however, that
you have developed your English, Dyneng or something, in which you have
your own rules of grammar that are much better than all those stupid ones
that a very large community of people much less smart than you have made
the mistake of using for hundreds of years. You would of course still
claim it is "an English" because it has "English nature", even though it
fails to conform to accepted standars for English. "It's" is clearly the
best way to express the possessive form of "it". Of course, consistency
be damned, so it s not "he's" and "she's" and "they's" and "us's", etc,
it is only "it's". The rest of the possisive pronouns are just fine.
But for someone who confuses these two to carp about the confusion caused
by nil and false and the empty list is hilariously funny. To make such a
stink about disliking in-band signalling and then to abuse the apostrophe
to destroy whatever information is already there is very, very amusing.

If it were not for your terribly stuck-up attitude problem and arrogance
towards communities you are not a member of, I would let your mistakes
pass -- this is not an English class -- but you are so certain of your
own perfection that pointing out that you make a grade-schooler's mistake
in English and are too arrogant to recognize it, becomes important. You
do not pay attention to details. You make mistakes that you _ignore_.
Then you go all huffing and puffing about lots of things you fail to
grasp fully. You are an idiot, Andreas Bogk. And so are your stupid
concerns about Common Lisp and Dylan's pretense of being "a Lisp".

| You're welcome to actually show where my logic is flawed, instead of
| just claiming it's bullshit.

The premises you do not question and want people to agree to, are wrong.

You do not listen to this at all, but want people to accept them and then
show you "logical flaws" in your reasoning from them. This is not how
logic works. Logic works only if the premises are known to be true. If
your premises are false, logic alone does not produce useful results. A
lot of Star Trek fans seem to believe in Spock-style logic.

| I do not fail to understand this, although two persons who disagree on
| *anything* are rather unlikely.

Did you mean "everything" here or what?

| What you fail to understand is that this isn't the case between the Lisp
| and the Dylan folks, for they have common roots.

This is one of the premises that you do not want to hear otherwise about.

No, they do not have common roots, they have _some_ common roots, and so
do almost all programming languages. Just as Scheme has more Algol in it
than Lisp, Dylan chose a syntax that is anything _but_ common with Lisp.
In other words, Dylan has at least one root that is not common with Lisp.
So your whole goddamn _premise_ is wrong. The Dylan community rejected
the Lisp community, and now you need to get back into the warmth because
it gets cold and lonely over there in miserably failed Dylan land. Guess
what? You are not welcome back if you want to keep your arrogance and
your rejection and your stupid little language. Eat enough crow, make
enough amends, understand that your language is sufficiently different
from Lisp that you should really go to Python or Ruby or something if you
want something that looks and feels the same, and _maybe_ you would not
be such a goddamn obnoxious tourist.

| For me, adding an s-expression parser to the Gwydion Dylan compiler looks
| like a project I could pull off if I dedicate a month or two, whereas
| removing dynamic typing from Dylan is something I'd consider impossible
| for myself, and changing the heart of the language.

If you can write your code in the s-expression syntax, that would count.
If you cannot, then it does not count. Do you grasp the difference?

| Rest assured that s-expressions are the number one reason why people shun
| Common Lisp, regardless of whether they are good, bad or meaningless.

Well, gee. How do you know these things?

How many real people did you poll to find out, as opposed to imaginary
duplicates of yourself? People shun Common Lisp because it does not have
any of the common names for anything that the C community has chosen.
What you stupidly and misguidedly call the "learning curve", which is
really the amount of stuff learned over time, is _accused_ of being
"steep", which would actuall mean that one can learn a lot of stuff in a
very short amount of time, which would be _good_ for a language. What we
have, instead is that the cost of learning Common Lisp is one of getting
rid of a _lot_ of old baggage. The parentheses only symbolize this.
Only real idiots are _really_ put off by the parentheses, but since it is
accepted, and it is not accepted to be a moron who cannot learn new
languages because he simply does not have the brain capacity to learn
them in time, especially in a culture where people are taught a lot of
lies about programming languages, such as them all being the same with
only a little new syntax, people will do a lot of irrational things to
avoid feeling stupid -- look at yourself and how you react to my pointing
out that you are doing a lot of stupid things: you get _defensive_ and
all snotty about "rude behavior", but you do _not_ fix the problem. This
means that you would rather be stupid and please, nobody say you are,
than _not_ be stupid. People who are unable to come to grips with Lisp
are the same kind of people as you -- they carp about something that is
_completely_ irrelevant which gives them a stupid _excuse_ to fail, so
they do not look so stupid in their own eyes.

However, only people who are unafraid of making mistakes and failing will
ever succeed in anything. Learning anything new means you will make some
stupid mistakes early that may be hard to fix if people around you are so
"polite" as not to point them out to you, and if you are unintelligent
and unobservant, you will not even notice that things no longer make a
whole lot of sense. This is the time when smart people stop to think,
and stupid people start to blame the language.

| Since you seem to have bigger insight into how people choose and value
| things, you might want to share it with us, instead of calling people
| names.

If you start to focus on what _you_ want, you would see I do _both_.

Since you _are_ behaving incredibly stupidly with your constant whining,
and it is the cause of what you do not like, just stop whining. It is as
simple as that. You see, unlike you, I do not criticize something just
to criticize it. I do not harrass you about something that you are
unable to change the way you harrass this community about your perfect
Dylan that made some other choices. I _expect_ you to grasp what you are
being criticized for, and _also_ critize you for it if you do not.

| Anyways, even if your assertion about my lack of insight were true, it
| still wouldn't say anything about the result of arguments on my points.

OK, if this were literally true, it would mean that you pull your
arguments out of thin air. I quite concur with this assessment.

> If you react _defensively_ to the last line, your mind is _not_ open.

| Why should I react offensively?

Again, reading comprehension is not your strong suit, is it?

But well, you _did_ react defensively, so I have seen what I need to see
from you. Next time, try actually responding to what people _write_, not
what you read out of your own mind. Or look up the difference between
"offense" and "defense" in your favorite dictionary.

Just stop making so many stupid mistakes. THINK!

Erik Naggum

unread,
Nov 29, 2001, 4:06:58 AM11/29/01
to
* Bruce Hoult

| What I want to do is to *understand* CL, just for my own pure
| intellectual curiosity. I want to know not only what *is* in CL, but
| *why* it is.

But you seem to reject the answers you get! You keep asking even when
you get the perfectly honest and full answer. That is the insanity.
Despite what you say, you do not appear to be satisfied with the truth.
In other words, you communicate that you think people are guilty of
hiding something from you, and that is actually _very_ offensive.

| If there's a logical reason then I'd like to know it.

You, too, seem to think that you can have logic without premises, or at
least different premises from what _you_ have. Why is that?

| Far from wanting to change CL, what I want to do is to see if there is
| anything that should be changed in Dylan.

Then why are you not discussing this in comp.lang.dylan? And why are you
talking about how Dylan does things all the time if you want to change
Dylan? Sorry, this does not compute.

Erik Naggum

unread,
Nov 29, 2001, 4:11:00 AM11/29/01
to
* Bruce Hoult

| Please note that I'm posting in the generic "Lisp" newsgroup, not a
| specialized one for Common Lisp such as c.l.clos.

But why are not posting in the specialized comp.lang.dylan?

| > | Are you saying that you're brighter than Moon?
| >
| > Please think about what you are _actually_ saying.
|
| What I'm _actually_ saying is that the argument "CL was designed by
| genuises, you're not one, so shut up" is not useful.

Nobody has ever said anything even remotely similar to that, and it is
offensive to attribute such rampant idiocy to people just because _you_
have a hard time coming up with intelligent arguments. That you see the
world in such terms is something you just have to discuss with someone
who cares.

And if that _idiotic_ line of yours was not whining, nothing is.

Erik Naggum

unread,
Nov 29, 2001, 4:14:25 AM11/29/01
to
* Bruce Hoult

| How could I possibly have already made up my mind about such a thing
| when I am not yet an expert in CL?

Easy. Just be a moron. You do a good job of this so far, toghether with
that other Dylan lunatic, so it is not particularly unlikely that you
actually are illogical farts who have come here only to annoy people.

Erik Naggum

unread,
Nov 29, 2001, 4:23:22 AM11/29/01
to
* Andreas Bogk
| Committees work different.

I think you meant to say that you know for certain that all committees
are _exactly_ alike, because you have been to at least one meeting of at
least one committee. You should make clear to those of us who have been
members of many committees and have not seen this incredibly simple truth
or indeed discovered your Grand Unifying Theory of Committees, that we
are mistaken and have been deluded. There is actually only one committee
in the whole world, and it is run by telepathic extraterrestial aliens
who want to remove individual freedom, and they were also behind the 9/11
attack and now George W. Bush is turning the U.S.A. into a dictatorship
where Chinese legal practices against "national security" is becoming
increasingly popular with that Ashcroft figure. The Committee was also
behind the Common Lisp standard. Dylan somehow escaped the death grip of
The Committee and is the last bastion of individual freedom on earth, our
last hope against alien take-over. Therefore, the only remaining hope
for mankind is that Dylan take over the world.

"Committees work different." Really. Dude, are you fucking _nuts_?

Dylan, being a rebellious child of Lisp, is attacking the parens.

Erik Naggum

unread,
Nov 29, 2001, 4:35:30 AM11/29/01
to
* Tim Bradshaw
| Here's another example: SunOS 4 to 5. [...] It must have been horrible

| for Sun. But SunOS 5 took *years* to be accepted, because lots of people
| had all sorts of stuff which really depended on SunOS 4 and *really* did
| not want to change things, because from the user level 4.1.3 / 4.1.4
| worked really OK, and early SunOS 5 was buggy and slow.

While we are telling stories: Some bigwhig from Sun made a bet at a
conference that there would be no more SunOS 4 versions after 4.1.3.
Then a new version came out, so he lost his bet. Lots of people never
figured out the joke in its version designation, so allow me to repeat
this even though lots of people _did_ get it. It was called 4.1.3_U1.
Get it? (Pronounce it. Get it now? :)

| Finally, the question is *why*? [...] I mean there must be *millions*


| of things you could add to CL which would not break a single line of
| existing conforming CL code and would provide cool new stuff. Tie down
| the MOP, for instance. Design and get agreement on a MP interface.
| URIs. Standard sockets. FFI. Defsystem. I can just keep typing these
| things in for ever. *Why* are you worrying about some trivial little
| design issue when you could be doing something cool and new? Come on,
| get *over* it, this is just *STUPID*.

Because it is the only contribution these feebleminded morons can make.
It is based on some theoretical foundation that is just plain _wrong_,
and that means it violates an artificial "pattern of design" that some
people are so unbelievably anal about adherence to that they simply go
nuts if somebody does something else.

Erik Naggum

unread,
Nov 29, 2001, 5:06:10 AM11/29/01
to
* Bruce Hoult

| Every time I or Andreas or someone else is interested in learning about
| and comparing the way CL does something with the way that other
| langauges do similar things, you for some reason I don't fathom
| immediately think that they want to *change* CL.

NO, you imbecile. It is that you want to make people feel their teeth
with their tongue. Normal people walk through their entire life not
feeling their teeth with their tongue. But, if something goes wrong,
they keep feeling them all the time, and then they pay someone to fix it.
What you are doing is to tell people that their teeth are wrong, when in
fact they are not. You run around like a headless chicken in this
community and tell people that should feel their teeth because they have
flaws that only you were smart enough to notice. And so many people feel
their teeth with their tongues, and make funny faces. Then they have to
explain to others why they are feeling their teeth with their tongue, and
so lots of people get insecure about their teeth who were perfectly happy
with them up until then. This would raise "awareness" of something that
really needs to be the subject of no awareness whatsoever, because it
uses resources and concentration that should have had productive use.

This would actually be a great thing to do for a _really_ devious dentist.

But then you are so incredibly, insufferably annoying to tell people that
"no, no, no, I do not want you to _change_ your teeth, there is nothing
to fix, really, but just keep feeling your teeth, because I think it is
so amusing to watch all you people make funny faces". Then you do not
grasp the first thing about people's reaction to your idiotic behavior.

| Astounded.

Really? Your ability to reason about what you do seems thinner than the
homeopathic soup made by boiling the shadow of a pigeon starved to death.

Dylan freaks seem so obsessed with their language they would kill their
own mothers just so they could use the skin to make a drum to beat their
own praises.

That _widely_ used language seems utterly unspoilt by failure, and if its
proponents should occasionally have stumbled across the truth, they have
hastily picked themselves up and hurried on as if nothing had happened.

Erik Naggum

unread,
Nov 29, 2001, 5:55:21 AM11/29/01
to
* Brian Palmer
| My perspective [...] is that the "Common Lisp community" as represented

| on the newsgroup is very brittle. The progression of some discussions
| have definitely left a very bad taste in my mouth, even as uninvolved as
| I am in the group.

It is indeed the case that the community is brittle. We suffer morons
from other communities all the time, we have traitors in our own camp,
and we have "popularity problems" and all sorts of irrelevant issues that
people who need an excuse _not_ to use (Common) Lisp need to feel good
about themselves instead of feeling like idiots who do not just go and do
what they want to do. There have been such people in this newsgroup for
the past 5 years at least. I have argued that this dissatisfaction with
a great language is actually causing all the lack of popularity, because
whoever wants to do something great for a bunch of sourpusses who will
whine and bitch about trivial idiotic things because they have a mental
problem accepting the authority of the standard, or generally just have
so big egos that they cannot deal with the rejection of their bad ideas?

This is just like some refugees from lands of poverty and war and famine
and pain and illness who spend their entire lives cursing the country
that has given them everything, but never "enough", mainly because they
have no idea how to go about getting what they want on their own. There
are some people who think the universe _owes_ them something. For some
reason, these people tend to come to Common Lisp, most probably because
Common Lisp has also given people so much for free that they could never
create on their own that they feel helpless if they need something they
have not got. Common Lisp is also kind of a _relief_ from all the
moronic languages out there, and finding that the relief was not perfect
may cause some people to feel a little betrayed and to want more for free.
We see this in people who whine endlessly about various things that are
not in the standard, so they cannot use whatever their implementation
offers them. Similarly nutty arguments are extremely exhausting.

I have also argued that any random luser off the Net (it used to be the
street, but the lusers are too fat to walk these days) can find something
to improve on in any of those new toy languages, while it almost takes a
genius to make _actual_ improvements to Common Lisp. This means that
among the million idiot ideas that get implemented and discussed in the
new toy languages, one or two good ideas may survive the "masses", while
we need about one good idea for every five failing ones in Common Lisp.

In most other language communities, having your ideas rejected is no big
deal, because you can come up with another one at little extra cost, but
if you spent a year designing something super-clever that you really like
and which you have used for a long time seeing it trashed viciously
(because you refuse to back down and get increasingly hostile to those
who simply did not like your idea to begin with) may be too much for some
brittle egos. However, as every successful person knows, you have to
learn from but otherwise forget your failures -- harbor no regrets, just
do better next time. Several contributors to the Common Lisp community
have actually expressed extreme hostility to the failure to accept their
undoubtedly brilliant ideas in some other universe, but while the Scheme
community encourages people to go off and implement their _own_ Scheme,
the Common Lisp standard is so big and mature that those who want to
reinvent the wheel, or at least a portion of the wheel (like an Arc :),
usually fail miserably. (Just look at Guile, an attempt to approach
Common Lisp asymptotically, but which took off with just short of the
escape velocity of Scheme.) In short, there is much more self-screening
and "perfectionism" in the Common Lisp community than other communities.

What this is driving at is the unprofessionalism of the "lone programmer"
-- and Lisp is so powerful that it does not _need_ large teams -- who
very unfortunately takes his software development _personally_. People
fall in love with (Common) Lisp in strange ways and few seem to have that
important ability to get up and walk away from their creations, to throw
it away if it turns out to have outlived its usefulness, etc. This hang
to get personal about their profession is tremendously annoying, because
it creates another barrier to acceptance of good ideas: the inability to
reject someone's ideas without their feeling personally offended. We
also have some amazing nutballs in this forum who post for no other
reason than to "exact some measure of revenge" (to quote at least one
mass-murdering anti-government nationalist) against whoever they think is
responsible for their rejection. This _unprofessionalism_ is dangerous.

What would help make the community less brittle? Professional detachment
from one's professional opinions. Fewer people who take comments about
their professional opinions personally. Fewer people who post personal
opinions in the guise of professional opinions.

Bruce Hoult

unread,
Nov 29, 2001, 6:21:02 AM11/29/01
to
In article <32159956...@naggum.net>, Erik Naggum <er...@naggum.net>
wrote:

> * Bruce Hoult


> | What I want to do is to *understand* CL, just for my own pure
> | intellectual curiosity. I want to know not only what *is* in CL, but
> | *why* it is.
>
> But you seem to reject the answers you get! You keep asking even when
> you get the perfectly honest and full answer. That is the insanity.

On the contrary, I really appreciate the thoughtful answers I get from
Kent Pitman, Pierre Mai and others who while I sometimes fail to
communicate what I mean clearly enough always remain polite.


> | Far from wanting to change CL, what I want to do is to see if there is
> | anything that should be changed in Dylan.
>
> Then why are you not discussing this in comp.lang.dylan?

Because I am in the process of learning CL and this seems to be where
the CL people are.


> And why are you talking about how Dylan does things all the time
> if you want to change Dylan? Sorry, this does not compute.

Because it is easier to read unfamilar code than to write it. If I
express some point in Dylan then I can do that quickly an precisely
without errors and probably everyone can understand it, wheras if I try
to put it into CL -- especially if it's a corner of the language I'm in
the process of learning about -- then I'm likely to make mistakes which
obscure the point.

-- Bruce

Ian Wild

unread,
Nov 29, 2001, 8:57:16 AM11/29/01
to
Bruce Hoult wrote:
>
> - incf/decf. The Dylan ":=" is equivalent to the CL "setf", but Dylan
> lacks incf/decf in particular and the C'ish modification operators ++,
> --, +=, -=, &=, |= etc in general. I miss this.


Can you not just macro them in?

Alain Picard

unread,
Nov 29, 2001, 9:28:45 AM11/29/01
to
Erik Naggum <er...@naggum.net> writes:

>
> NO, you imbecile. It is that you want to make people feel their teeth

> with their tongue. [SNIP!]

Is it just me, or was that the most _HILARIOUS_ thing _EVER_ posted
to this newsgroup? I'm verging on tears... Hee heee, oof.

Well, they say laughter is good for your health. Thanks, Erik!


p.s. of course, now I'm gonna "feel" my teeth all evening... but it
was worth it. :-)

--
It would be difficult to construe Larry Wall, in article
this as a feature. <1995May29....@netlabs.com>

Alain Picard

unread,
Nov 29, 2001, 10:00:03 AM11/29/01
to
Bruce Hoult <br...@hoult.org> writes:

>
> What *you* have missed, is that some of those exact same brightest minds
> to ever touch a keyboard went from Common Lisp to design a new language
> and did a few things differently the second time around.
>

> Are you saying that you're brighter than Moon?
>

I tell you what. You go re-read my post, my _entire_ post,
and try to _understand_ what I _actually_ wrote.

If you're smart enough to
1) realize that I didn't insult anyone
2) realize that YOU just insulted ME
3) apologize to me for your honest mistake (see, I'm giving
you the benefit of the doubt here)

THEN I'll consider that it may be worth my while to reply to
you in the future. This one is a freebie. :-)

Have a nice day.

--
Against stupidity, the Gods themselves contend in vain.

lars_lundback

unread,
Nov 29, 2001, 10:52:07 AM11/29/01
to
On 29 Nov 2001 20:28:45 +1100, Alain Picard <api...@optushome.com.au>
wrote:

>Erik Naggum <er...@naggum.net> writes:
>
>>
>> NO, you imbecile. It is that you want to make people feel their teeth
>> with their tongue. [SNIP!]
>
>Is it just me, or was that the most _HILARIOUS_ thing _EVER_ posted
>to this newsgroup? I'm verging on tears... Hee heee, oof.
>
>Well, they say laughter is good for your health. Thanks, Erik!
>

Not only you, I too stand up. Pure sarcasm is the best blade.
Applaudes and cheers.

Lars

Tim Bradshaw

unread,
Nov 29, 2001, 11:08:58 AM11/29/01
to
Bruce Hoult <br...@hoult.org> wrote in message news:<bruce-BDED06....@news.paradise.net.nz>...

>
> Every time I or Andreas or someone else is interested in learning about
> and comparing the way CL does something with the way that other
> langauges do similar things, you for some reason I don't fathom
> immediately think that they want to *change* CL.

No, I don't think that. Obviously I've either expressed myself badly
or you are not undertanding what I'm trying to say.

What I'm trying to say is that whether NIL and false are different is
this *tiny bit of linguistic trivia* which it is a *complete waste of
time* to discuss. I don't know if Dylan or Scheme are `better' than
CL, or if Java is `better' than C++, but if they are it absolutely *is
not* to do with whether they equate NIL, or 0, with falsehood. There
are much bigger issues here.

And further, what I'm trying to say is that it *might* have been
interesting to discuss NIL/false when this part of the language was
being designed, but now it's done it is not interesting any more
because that stage of design is all done now.

It seems to be a fairly common tendency to stress away about these
trivial issues in cll (and elsewhere, I guess), and it's just a huge
waste of time. As far as I can see it's partly to do with people who
haven't been able to get over losing what they saw as some battle, and
obsess endlessly about it, and it's partly to do with being a
convenient way of not thinking about actual real problems. Finally
it's a classic cult thing - since no change can happen it's safe to
discuss how things would be different/better if the change did happen.

I think we need to stop looking backwards and re-fighting old battles,
won or lost, and look at the future. We can't change the past, all
that stuff is sunk cost now. If we have to look backwards, we should
look at *important* bits of history, not trivial ones, even though
it's easier to look at the trivial ones. An important bit of history
might be `why did Symbolics lose to Sun?' If the answer has anything
to do with Lisp at all, it *certainly* does not have to do with
NIL/false, inheritance issues, or even Lisp1/Lispn for that matter:
those things are just in the noise, even though they are much easier
to have opinions about than the real issues.

We need to be forward-looking, and discussing unchangable linguistic
trivia is not forward-looking, even though it may be more confortable
for many.

--tim

Tim Bradshaw

unread,
Nov 29, 2001, 11:28:45 AM11/29/01
to
Bruce Hoult <br...@hoult.org> wrote in message news:<bruce-DDFADF....@news.paradise.net.nz>...

>
> What I want to do is to *understand* CL, just for my own pure
> intellectual curiosity. I want to know not only what *is* in CL, but
> *why* it is. If there's a logical reason then I'd like to know it. If
> there are special advantages conferred by something that make certain
> things easier to do then I want to learn about that too. And if
> something is just historical accident and it hasn't been judged worth
> the pain of changing then that answers my question too.

Well, here's how you understand CL: write large programs in it. No
amount of discussion of the language is a substitute for this, because
CL is a language which is *about* being able to write large programs,
if it's about anything. Until you've written thousands of lines of
code you just won't understand why it is the way it is (and I don't
mean NIL/false here, I mean the language). I've been writing CL for
13 years or something, and I *still* have moments of insight into
things. There simply is no substitute for experience.

--tim

Tim Bradshaw

unread,
Nov 29, 2001, 11:43:42 AM11/29/01
to
Erik Naggum <er...@naggum.net> wrote in message news:<32159973...@naggum.net>...

> While we are telling stories: Some bigwhig from Sun made a bet at a
> conference that there would be no more SunOS 4 versions after 4.1.3.
> Then a new version came out, so he lost his bet. Lots of people never
> figured out the joke in its version designation, so allow me to repeat
> this even though lots of people _did_ get it. It was called 4.1.3_U1.
> Get it? (Pronounce it. Get it now? :)

(:-). Wasn't there a 4.1.4 later on? I forget. Anyway the thing I
heard was that weird things happened with numbering (kind of akin to
the 5.6/7 saga, but mure amusing I think) about 4.1. Some post 4.1
release - maybe 4.1.3 but I'm not sure - suffered a change where
essentially everything got shunted down a level, so it really was a
single-dot release not a double-dot release. In fact it was really
4.2, but Sun didn't want to call their OS <anything>-4.2 because of a
certain historically significant Unix version...

--tim

Bruce Hoult

unread,
Nov 29, 2001, 11:45:01 AM11/29/01
to
In article <3C05F96A...@cfmu.eurocontrol.int>, Ian Wild
<i...@cfmu.eurocontrol.int> wrote:

incf & decf, yes, easily. The others can't be done without changing the
compiler's parser to accept them as infix operators. Which is a matter
of minutes to do for any particular compiler, of course, but whether
anyone else wants it I don't know.

-- Bruce

Bruce Hoult

unread,
Nov 29, 2001, 11:54:49 AM11/29/01
to
In article <86pu61v...@gondolin.local.net>, Alain Picard
<api...@optushome.com.au> wrote:

> Bruce Hoult <br...@hoult.org> writes:
>
> >
> > What *you* have missed, is that some of those exact same brightest
> > minds
> > to ever touch a keyboard went from Common Lisp to design a new language
> > and did a few things differently the second time around.
> >
> > Are you saying that you're brighter than Moon?
> >
>
> I tell you what. You go re-read my post, my _entire_ post,
> and try to _understand_ what I _actually_ wrote.
>
> If you're smart enough to
> 1) realize that I didn't insult anyone

No, you insulted Andreas by effectively accusing him of acting in bad
faith.


> 2) realize that YOU just insulted ME

Did that *really* need a "smiley"? I'm sorry. I should probably not
reply to other people in the same session in which I have to deal with
Erik.


> 3) apologize to me for your honest mistake (see, I'm giving
> you the benefit of the doubt here)

No offense to you was intended.


> THEN I'll consider that it may be worth my while to reply to
> you in the future.

THAT is entirely up to you.

-- Bruce

Tim Bradshaw

unread,
Nov 29, 2001, 12:41:46 PM11/29/01
to
"Coby Beck" <cb...@mercury.bc.ca> wrote in message news:<b4aN7.131476$Yb.34...@typhoon.tampabay.rr.com>...
>
> I do not beleive popularity is a bad thing and I would honestly like to see
> lisp grow its user base. But it is not worth _any_ sacrifice in the integrity
> of its design. Jan Derzen said something along the lines of "if they have to
> be converted, who wants them". While I can't agree with that as stated, I do
> feel that if you show someone the light and they don't see it, that is there
> problem. Too many parens is *not* what keeps people from appreciating lisp.

And since we're here there are some other quite popular languages that
have NIL/false-equivalent equations. Like, erm, C and C++ (0 is
false), Python (which makes all sorts of things false like ""), and
Perl (similar rules to Python maybe, certainly "" and 0, and
disturbingly enough also "0").

--tim

Nils Goesche

unread,
Nov 29, 2001, 11:49:58 AM11/29/01
to
Bruce Hoult <br...@hoult.org> writes:

> In article <32159956...@naggum.net>, Erik Naggum <er...@naggum.net>
> wrote:
>
> > * Bruce Hoult
> > | What I want to do is to *understand* CL, just for my own pure
> > | intellectual curiosity. I want to know not only what *is* in CL, but
> > | *why* it is.
> >
> > But you seem to reject the answers you get! You keep asking even when
> > you get the perfectly honest and full answer. That is the insanity.
>
> On the contrary, I really appreciate the thoughtful answers I get from
> Kent Pitman, Pierre Mai and others who while I sometimes fail to
> communicate what I mean clearly enough always remain polite.

Actually, Erik's first postings on the subject, the ones where he
clearly explained the issue several times, were perfectly polite,
too; see for instance

http://groups.google.com/groups?q=naggum+false+nil+qua&hl=en&rnum=1&selm=3215382911849059%40naggum.net

But for some strange reason, none of those postings of his were
answered by the ``other side''. That's why I, too, got the impression
that you people weren't actually interested in learning about the
issue but rather in teaching everyone how necessary it is to introduce
an additional value for boolean `false', like Dylan or Scheme, without
giving a single reason why that would be better, BTW.

Regards,
--
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9

Daniel Barlow

unread,
Nov 29, 2001, 1:59:54 PM11/29/01
to
tfb+g...@tfeb.org (Tim Bradshaw) writes:

> Perl (similar rules to Python maybe, certainly "" and 0, and
> disturbingly enough also "0").

Also ``undef'' - but note _not_ "0e0"

The hazier reaches of my memory tell me that this "zero-but-true"
value has actually been used for that purpose in some Perl module.
Don't remember what, though. Could have been DBI-related or something
to do with Oraperl.

OK, so this is offtopic for the group (seems mostly ontopic for the
thread, though). I'm procrastinating about putting together this
month's FTX13; I wouldn't even be reading this otherwise.


-dan

--

http://ww.telent.net/cliki/ - Link farm for free CL-on-Unix resources

Wade Humeniuk

unread,
Nov 29, 2001, 3:20:58 PM11/29/01
to
> > And why are you talking about how Dylan does things all the time
> > if you want to change Dylan? Sorry, this does not compute.
>
> Because it is easier to read unfamilar code than to write it. If I
> express some point in Dylan then I can do that quickly an precisely
> without errors and probably everyone can understand it, wheras if I try
> to put it into CL -- especially if it's a corner of the language I'm in
> the process of learning about -- then I'm likely to make mistakes which
> obscure the point.

If you need some help learning CL maybe you could post a substative (a
non-trivial real program) amount of code in Dylan and people could write the
equivalent solution in CL. Then both sides could learn something.

Wade


Lieven Marchand

unread,
Nov 28, 2001, 8:35:29 PM11/28/01
to
tfb+g...@tfeb.org (Tim Bradshaw) writes:

[ lots of stuff I agree with. These are a few snippings ]

> Sure scoping in elisp is broken, but it's just *not broken enough*
> that it is worth fixing.

If I could get magically one thing done to the elisp interpreter, it
wouldn't be scoping, it would be threading. I don't mind the dialect
all that much since I don't write in it all that much. But that when
gnus has a spot of network trouble it causes all other frames to go
blank is painful.

> Here's another example: SunOS 4 to 5. Again, you may not remember
> what this was like, but many do (especially a lot of people at Sun I
> bet).

Ask Larry McVoy about it. He left Sun and hasn't gotten over it yet.

> Finally, the question is *why*? Why are people obessing away about
> NIL/false or other incompatible changes which have little benefit and
> much cost, when instead you could be working in *compatible
> enhancements*, which would have little cost and huge benefit. I mean


> there must be *millions* of things you could add to CL which would not
> break a single line of existing conforming CL code and would provide
> cool new stuff. Tie down the MOP, for instance. Design and get
> agreement on a MP interface. URIs. Standard sockets. FFI.
> Defsystem. I can just keep typing these things in for ever. *Why*
> are you worrying about some trivial little design issue when you could
> be doing something cool and new? Come on, get *over* it, this is just
> *STUPID*.

Amen.

--
Lieven Marchand <m...@wyrd.be>
She says, "Honey, you're a Bastard of great proportion."
He says, "Darling, I plead guilty to that sin."
Cowboy Junkies -- A few simple words

Lieven Marchand

unread,
Nov 28, 2001, 8:41:20 PM11/28/01
to
Andreas Bogk <and...@andreas.org> writes:

> By the way, please forgive the use of the Dylanesque empty?. I'm so
> used to working in a language where I can express operations on
> collections independent of their implementation that I completely
> missed the fact that there is no empty? in Common Lisp, and that it
> can't be implemented in a way that would have equal performance to
> (when foo).

It probably can within a small constant amount and worrying about such
trivia isn't productive. Please do not set up such strawmen.

> Do you consider yourself to be that smart? How deeply have you looked


> into Dylan, for instance, to be able to say that it doesn't have the
> Lisp nature?

You come to argue Dylan in c.l.l. and ask people here to prove their
Dylan credentials? (For the record, I have the Apple infix Dylan book
floating somewhere about but lost intrest when the Dylan designers
introduced misfix. You're paying the price now with your overcomplex
and underpowered macro system)

Xah Lee

unread,
Nov 29, 2001, 5:00:49 PM11/29/01
to

> From: Erik Naggum <er...@naggum.net>
> Organization: Naggum Software, Oslo, Norway
> Newsgroups: comp.lang.lisp
> Date: Thu, 29 Nov 2001 05:06:10 GMT
> Subject: Re: On nil qua false [was: Re: On conditionals]


>
> * Bruce Hoult
> | Every time I or Andreas or someone else is interested in learning about
> | and comparing the way CL does something with the way that other
> | langauges do similar things, you for some reason I don't fathom
> | immediately think that they want to *change* CL.
>
> NO, you imbecile. It is that you want to make people feel their teeth
> with their tongue. Normal people walk through their entire life not
> feeling their teeth with their tongue. But, if something goes wrong,
> they keep feeling them all the time, and then they pay someone to fix it.
> What you are doing is to tell people that their teeth are wrong, when in
> fact they are not. You run around like a headless chicken in this
> community and tell people that should feel their teeth because they have
> flaws that only you were smart enough to notice. And so many people feel
> their teeth with their tongues, and make funny faces. Then they have to
> explain to others why they are feeling their teeth with their tongue, and
> so lots of people get insecure about their teeth who were perfectly happy
> with them up until then. This would raise "awareness" of something that
> really needs to be the subject of no awareness whatsoever, because it
> uses resources and concentration that should have had productive use.


That's very funny and apropos. Superbly done. It had me laughing.

--

Dear Dylan lovers, i'd suggest you guys leave Common Lispers alone. It's an
old language obsesses by old people who will be dead anytime soon. In
Chinese there's a saying "The new waves pushes the old waves in Yangtze
River". It means that younger generation takes over old generation with
respect to progress. This is nature's way as a dictatorship and mass
murderer. Old people are preordained to die. They hold power, but not for
long. They guide and inspire the younger generation then they drop dead.
Unpleasant thought, to be sure, but divine order.

In computer languages, there's Common Lisp, then there's Scheme and Dylan
and Haskell et al. Sure, lisp evolves and hangs on. Let's hope it live long
and prosper. Still, there are hungry generations awaiting its death, so that
more resources are available for the young.

I advise you younger generation to leave the lispers alone. Don't bother
study lisp, but instead master your Dylan or Haskell or Mathematica. Write
an application or two. If you have extra time, master one or two
mathematics. A theory of graphs, a course of symbolic logic, an
understanding of an algebra, a look at denotational semantics for examples.
If you must get into science history, then nose about history of
mathematics. There you'll learn how humanity's most significant intellectual
ideas evolve. This will give you far more insights to computer language
linguistics than the petty history of lisp. To appreciate math history, you
do need proportional understanding of mathematics. (you pretty much need to
be familiar with subject X to appreciate the history of X.) If you have no
hankering for math history, then you might venture into the history of
humanity. There you will learn how trivial are the debates of Common Lisp vs
Scheme vs Dylan, or C vs C++ vs Java that you see daily in newsgroups and
websites by living zombies who oftentimes never thought of the context of
their discussion, nor what they are talking about. If you dig deep, you'll
see how insignificant are even sciences. (what good is knowledge of sciences
when your wife is fucked by hypocrites and your daughters made into feminism
asses and your sons political asses and your parents drugged by religion and
your siblings blind firebrands and your government and community chaotic and
helpless?) How it will benefit you by learning the history of humanity is
really dependant on each person. You will at the very least not sounding
like a moron among elites. With luck, i wish you young to become the next
great philosophers and social leaders, if not the best scientists.

Knowledge and Love; Goody and goody.

Xah
x...@xahlee.org
http://xahlee.org/PageTwo_dir/more.html


Andreas Bogk

unread,
Nov 29, 2001, 5:09:40 PM11/29/01
to
tfb+g...@tfeb.org (Tim Bradshaw) writes:

> What I'm trying to say is that whether NIL and false are different is
> this *tiny bit of linguistic trivia* which it is a *complete waste of
> time* to discuss.

Is it a complete waste of time for a teacher to teach, because he
already knows what he's teaching?

If it is a complete waste of time for you, don't discuss.

*I* have learned a lot during the discussion, and most points have
been made. Thanks to the polite and smart people in this newsgroup
who are actually interested in teaching what they know.

> And further, what I'm trying to say is that it *might* have been
> interesting to discuss NIL/false when this part of the language was
> being designed, but now it's done it is not interesting any more
> because that stage of design is all done now.

Please understand that we are trying to gain a deeper insight. We're
not just users of CL who need to get a job done, so we need not only
to understand what results from CL, but also what led to CL.

> that stuff is sunk cost now. If we have to look backwards, we should
> look at *important* bits of history, not trivial ones, even though
> it's easier to look at the trivial ones. An important bit of history
> might be `why did Symbolics lose to Sun?' If the answer has anything

That's an interesting one. I did some reading ("UNIX-HATERS
Handbook", "The Architecture of Symbolic Computing"), and their
explanations are:

- SUNs were cheaper
- SUNs were faster
- SUNs booted faster (although that one's probably tongue-in-cheek)
- Advance in compiler technology made special-purpose hardware superfluous
- Students were brainwashed at universities

The price tag is probably reason #1. OpenGenera is still $5000 (if
anybody of you has a license of OpenGenera lying around that he could
lend, donate or sell cheaply to a student of Lisp and its history,
I'd be very happy).

> We need to be forward-looking, and discussing unchangable linguistic
> trivia is not forward-looking, even though it may be more confortable
> for many.

"Unchangable" depends on the point of view. I completely understand
people's constraints, but they do not apply to all people. And
discussing trivia has the potential to increase understanding, which
is what we are seeking.

Andreas

--
"In my eyes it is never a crime to steal knowledge. It is a good
theft. The pirate of knowledge is a good pirate."
(Michel Serres)

Brian Palmer

unread,
Nov 29, 2001, 7:10:10 PM11/29/01
to
Daniel Barlow <d...@telent.net> writes:

> tfb+g...@tfeb.org (Tim Bradshaw) writes:
>
> > Perl (similar rules to Python maybe, certainly "" and 0, and
> > disturbingly enough also "0").
>
> Also ``undef'' - but note _not_ "0e0"
>
> The hazier reaches of my memory tell me that this "zero-but-true"
> value has actually been used for that purpose in some Perl module.
> Don't remember what, though. Could have been DBI-related or something
> to do with Oraperl.

Even more fun, the value "0 but true" evaluates to 0 in numeric
contexts, but is considered true in boolean expressions. Plus it's a
little clearer what's going on than "0e0".

--
Brian Palmer
"Whoever fights monsters should see to it that in the process he does
not become a monster. And when you look long into an abyss, the abyss
also looks into you" - Nietzsche

Jochen Schmidt

unread,
Nov 29, 2001, 9:04:10 PM11/29/01
to
Bruce Hoult wrote:

> In article <9u4051$h1j$1...@rznews2.rrze.uni-erlangen.de>, Jochen Schmidt
> <j...@dataheaven.de> wrote:
>
>> No - the annoying fact is that the way you both argue shows that you are
>> not interested in finding what could be done better in Dylan but more
>> finding arguments were CL is worse than Dylan.
>
> If that is the impression you get then it is an incorrect one.

Some smart guy told me one day that what gets communicated is not what one
says but what the other side understands. So if you want to transmit
information it is _your_ responsibility to make clear what you mean - not
mine.

>> You came here and proclaimed that CL seems to have a problem
>> because it does not distinguish nil/false/'() and Dylan has done
>> this better.
>
> That is factually incorrect.
>
> Thomas F. Burdick made thatkdi claim, purely about CL with no reference to
> Dylan, in <xcvpu6b...@conquest.OCF.Berkeley.EDU>. I later came
> into the thread to offer my experiences and thoughts.

No it is not factually incorrect. I said that you "proclaimed that CL seems
to have a problem...". This does not imply that you was the one who started
this discussion.

>> One thing you both seem to completely forget is that your silly little
>> language-war is really a disservice to Dylan.
>
> There is no language war from my side. I think both CL and Dylan are
> valuable languages to have in your toolkit, and I would welcome the
> chance to work professionally in either.

Then I still cannot understand why you have to insist on the claim that CL
is wrong and Dylan is right completely ignoring any comments from people
that actually _use_ CL.
What is holding you off opening your little book of Dylan-lacks and write
into it

"- nil/false/'() issue no problem for either Dylan or CL"

and be satisfied that neither CL nor Dylan has to be changed to be right in
each others way.

>> Many lispers may try out Dylan from themselves but if they get
>> insulted and annoyed by some language fanatics I think the chance
>> for that is quickly decreasing against zero.
>
> CL of course has no language fanatics.

Why do you try reading between the lines when there is nothing there?
In my experience every community of significant size has fanatics.
It is simply wrong to draw from that the conclusion that it is ok to behave
like a language fanatic.

ciao,
Jochen

--
http://www.dataheaven.de

Thomas F. Burdick

unread,
Nov 29, 2001, 8:24:21 PM11/29/01
to
tfb+g...@tfeb.org (Tim Bradshaw) writes:

> And since we're here there are some other quite popular languages that
> have NIL/false-equivalent equations. Like, erm, C and C++ (0 is
> false), Python (which makes all sorts of things false like ""), and
> Perl (similar rules to Python maybe, certainly "" and 0, and
> disturbingly enough also "0").

Yeah, well just wait for Perl 12, when they'll make "naught" false :-P

--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'

Bruce Hoult

unread,
Nov 29, 2001, 9:14:54 PM11/29/01
to
In article <9u5joh$jl7$1...@news3.cadvision.com>, "Wade Humeniuk"
<hume...@cadvision.com> wrote:

> If you need some help learning CL maybe you could post a substative
> (a non-trivial real program) amount of code in Dylan and people could
> write the equivalent solution in CL. Then both sides could learn
> something.

That certainly might be interesting, but I wouldn't dream of asking
anyone here to do that much work.

Also, although I do have a couple of reasonably substantive Dylan
programs in the public domain (e.g. an ICFP2000 contest ray tracer and
an ICFP2001 contest markup language optimizer, both available from cvs
at www.gwydiondylan.org) the translation of the vast majority of that
code to CL is a simple syntactic transformation which won't teach anyone
anything. It's the dusty little corners of the language which are more
interesting, and the more likely to surprise.

-- Bruce

Bruce Hoult

unread,
Nov 29, 2001, 9:24:29 PM11/29/01
to
In article <fbc0f5d1.01112...@posting.google.com>,
tfb+g...@tfeb.org (Tim Bradshaw) wrote:

> And since we're here there are some other quite popular languages that
> have NIL/false-equivalent equations. Like, erm, C and C++ (0 is
> false), Python (which makes all sorts of things false like ""), and
> Perl (similar rules to Python maybe, certainly "" and 0, and
> disturbingly enough also "0").

I am heartened to see that you find that disturbing. The risks in Perl
of real data looking like "false" are immense. I know, because I write
a lot of Perl. Most of it is supposed to be "throw away", but we all
know what happens to throw-away code ... it comes back to bite your bum
a couple of decades later.

-- Bruce

Wade Humeniuk

unread,
Nov 29, 2001, 9:54:25 PM11/29/01
to
> > If you need some help learning CL maybe you could post a substative
> > (a non-trivial real program) amount of code in Dylan and people could
> > write the equivalent solution in CL. Then both sides could learn
> > something.
>
> That certainly might be interesting, but I wouldn't dream of asking
> anyone here to do that much work.
>
> Also, although I do have a couple of reasonably substantive Dylan
> programs in the public domain (e.g. an ICFP2000 contest ray tracer and
> an ICFP2001 contest markup language optimizer, both available from cvs
> at www.gwydiondylan.org) the translation of the vast majority of that
> code to CL is a simple syntactic transformation which won't teach anyone
> anything. It's the dusty little corners of the language which are more
> interesting, and the more likely to surprise.

I looked at some of your ICFP2001 code. Your are right (though I do not
know dylan well) that it seems to be a simple syntatic translation. The
lesson for me in this is that CL has all of the functionality of Dylan and
is very similar. My questions back are:

Did any of those dusty litle corners make any difference in your program?
The answer probably is that you did not use any of the little dusty little
corners.

Would you say when Dylan was created that its model was CL and those dusty
little corners from CL where not included in Dylan?

Are you asking if some of those dusty corners left behind would be useful to
be included into Dylan?

Is this what you are trying to determine. That would be a more interesting
question.

Perhaps you can make a list of issues (differences, not the nil/()/false
issue) you consider useful looking into? Maybe then you can get some input
if they would be good to put into Dylan.

Wade


Bruce Hoult

unread,
Nov 29, 2001, 10:05:19 PM11/29/01
to
In article <lkr8qhn...@pc022.bln.elmeg.de>, Nils Goesche
<car...@cartan.de> wrote:

> > On the contrary, I really appreciate the thoughtful answers I get from
> > Kent Pitman, Pierre Mai and others who while I sometimes fail to
> > communicate what I mean clearly enough always remain polite.
>
> Actually, Erik's first postings on the subject, the ones where he
> clearly explained the issue several times, were perfectly polite,
> too; see for instance
>
> http://groups.google.com/groups?q=naggum+false+nil+qua&hl=en&rnum=1&selm=3
> 215382911849059%40naggum.net
>
> But for some strange reason, none of those postings of his were
> answered by the ``other side''. That's why I, too, got the impression
> that you people weren't actually interested in learning about the
> issue but rather in teaching everyone how necessary it is to introduce
> an additional value for boolean `false', like Dylan or Scheme, without
> giving a single reason why that would be better, BTW.

Well, yes, that post is reasonable and calm and in fact I don't disagree
with anything in it, as far as it goes. And I don't want to restart
this whole thread either.

The only issue I have, as I said when I joined the thread half a dozen
messages later, is how you tell whether a function searching for a list
and returning it found it and it was empty, or whether it was not found
at all.

This question doesn't apply to either "member" or "assoc" used as
examples in Erik's post. Or, at least, if it does apply the answer is
something like "the people who designed these functions were aware of
the problem you mention and side-stepped the problem by returning not
the value being sought, but a data structure containing the value e.g.
assoc returns the entire cons containing both the key and the value, not
just the value".

Is this technique used by everyone else when they write functions that
return lists in their own CL code? I don't know. Certainly no one even
*mentioned* it or said "yes, it's a problem, but we get around it by
using this idiom". They just said "it's not a problem".

-- Bruce

Tim Moore

unread,
Nov 29, 2001, 10:32:23 PM11/29/01
to
In article <bruce-5A5398....@news.paradise.net.nz>, "Bruce
Hoult" <br...@hoult.org> wrote:


>
> This question doesn't apply to either "member" or "assoc" used as
> examples in Erik's post. Or, at least, if it does apply the answer is
> something like "the people who designed these functions were aware of
> the problem you mention and side-stepped the problem by returning not
> the value being sought, but a data structure containing the value e.g.
> assoc returns the entire cons containing both the key and the value, not
> just the value".
> Is this technique used by everyone else when they write functions that
> return lists in their own CL code? I don't know. Certainly no one even
> *mentioned* it or said "yes, it's a problem, but we get around it by
> using this idiom". They just said "it's not a problem". -- Bruce

There are a few techniques. The one mentioned above is common.
One can also supply a default argument to the getter which is returned if
nothing is found; see "getf". Still another way is to return an additional
value indicating if anything was found. See "gethash".

Tim

Andreas Bogk

unread,
Nov 29, 2001, 10:19:14 PM11/29/01
to
Erik Naggum <er...@naggum.net> writes:

> "Committees work different." Really. Dude, are you fucking _nuts_?

You're still as offensive as before...

> Dylan, being a rebellious child of Lisp, is attacking the parens.

... but funnier.

I guess I delay killfiling you for a few more days.

Thomas F. Burdick

unread,
Nov 29, 2001, 10:44:19 PM11/29/01
to
Bruce Hoult <br...@hoult.org> writes:

> In article <lkr8qhn...@pc022.bln.elmeg.de>, Nils Goesche
> <car...@cartan.de> wrote:
>
> > > On the contrary, I really appreciate the thoughtful answers I get from
> > > Kent Pitman, Pierre Mai and others who while I sometimes fail to
> > > communicate what I mean clearly enough always remain polite.
> >
> > Actually, Erik's first postings on the subject, the ones where he
> > clearly explained the issue several times, were perfectly polite,
> > too; see for instance
> >
> > http://groups.google.com/groups?q=naggum+false+nil+qua&hl=en&rnum=1&selm=3
> > 215382911849059%40naggum.net
> >
> > But for some strange reason, none of those postings of his were
> > answered by the ``other side''. That's why I, too, got the impression
> > that you people weren't actually interested in learning about the
> > issue but rather in teaching everyone how necessary it is to introduce
> > an additional value for boolean `false', like Dylan or Scheme, without
> > giving a single reason why that would be better, BTW.
>
> Well, yes, that post is reasonable and calm and in fact I don't disagree
> with anything in it, as far as it goes. And I don't want to restart
> this whole thread either.
>

> The only issue I have, as I said when I joined the thread half a dozen
> messages later, is how you tell whether a function searching for a list
> and returning it found it and it was empty, or whether it was not found
> at all.

I could have sworn this was answered (in fact, I'm pretty sure I
addressed this myself). Do like the other functions in CL do (not
assoc) -- return two values, or have :error-p and :default keyword
arguments.

(my-association-finder (gensym) some-data-structure)
=> NIL;
NIL
or
(my-association-finder (gensym) some-data-structure)
Error in function MY-ASSOCIATION-FINDER: Item not found ...
or
(my-association-finder (gensym) some-data-structure
:error-p nil :default :not-found)
=> :NOT-FOUND

> This question doesn't apply to either "member" or "assoc" used as
> examples in Erik's post. Or, at least, if it does apply the answer is
> something like "the people who designed these functions were aware of
> the problem you mention and side-stepped the problem by returning not
> the value being sought, but a data structure containing the value e.g.
> assoc returns the entire cons containing both the key and the value, not
> just the value".

I don't think this is side-stepping the problem. If getting the cons
cell were only useful for determining whether or not the item was
found, then I'd agree, but it can be useful to have the cons cell for
other reasons (such as changing the value associated, and having this
change propogate to anything currently holding onto that cons cell).

> Is this technique used by everyone else when they write functions that
> return lists in their own CL code? I don't know. Certainly no one even
> *mentioned* it or said "yes, it's a problem, but we get around it by
> using this idiom". They just said "it's not a problem".

It's not a problem because we have multiple-values and keyword arguments.

Erik Naggum

unread,
Nov 29, 2001, 11:22:10 PM11/29/01
to
* Bruce Hoult

| I should probably not reply to other people in the same session in which
| I have to deal with Erik.

You imply that you are _personally_ affected by my articles. _This_ is
your core problem. _This_ is how these things develop badly. Quit it!
Become a _professional_, and just _quit_ the stupid personal reactions.
It is the sheer stupidity of your _professional_ opinion as posted to a
professional forum that is attacked here. You do _not_ have a personal
opinion on nil vs false, or on language design. (If you have, keep it
yourself.) When you post professional bullshit, you should _expect_ to
be treated harshly. If you do not understand this, suppose you are in a
meeting where the object to design something, and you bring up your
idiocy again and again and refuse to get the point. Do you think people
will tolerate you? If you persist in being an idiot in a professional
setting, you _will_ be beaten up and thrown out of the forum. Do you
think anyone will care how _you_ feel, when you have ignored the whole
reason for the forum's existence? People have a _purpose_ when they come
to a forum like this. The fundamental premise is that you are here to
share information and knowledge and professional opinions in order to
further a clearly constructive interest. When you violate that premise,
you are what is known on USENET as a troll. Much less favorable terms
are applied in real life to people who violate the premises for a forum.

You have a moral obligation to be intelligent when you post to a forum
for professional discussions, which you have not understood and do not
appreciate. If you take these things personally, you are making a very
serious mistake. Yet, if you are unprofessional, there is something
wrong with _your_ attitude, not just your arguments and opinions, and
_you_ need to fix it. Since you are in a professional forum, critique of
your (personal) behavior is _not_ about _you_, it is about your _role_ in
this forum. If you do not understand this, you will miss most of what is
going on, here. If you are taking things so personally that you lose
your mental balance, you should spend time with someone who cares about
you, even if paid to do so, and talk it out. Newsgroups are not therapy
sessions.

The above quoted line was obviously intended on your part to blame me for
your mental instability, because you think this is a forum where anyone
cares how you feel and why. It is not. (People may care, but that is a
personal choice, not the purpose of the newsgroup.) It is increasingly
evident that you Dylan guys are here to get personal affirmation of your
misguided _professional_ choices, which is highly inappropriate for a
professional forum. If you have that kind of personal needs, imposing
them on other people is the pinnacle of inconsiderateness and rudeness,
but people who think their personal feelings should be on CNN every day,
do use USENET for this. Now, sharing personal stories is one thing, but
demanding that other people satisfy one's personal needs is just plain
bad behavior. Those who think they have a "right" to push their personal
concerns on other people never consider any other person or concerns, and
hence do not tolerate that anybody else reprimand them for their behavior
because those others do not have the "right" to do so in their view.
This whole "rights" thing is very strange, and basically just nonsense.
It is as if someone has been watching too many crime-fighting TV shows
and think that anyone who criticizes them for anything has to follow the
strict rules of a government agency and violate their "rights" if not.

///
--
The past is not more important than the future, despite what your culture
has taught you. Your future observations, conclusions, and beliefs are
more important to you than those in your past ever will be. The world is
changing so fast the balance between the past and the future has shifted.

Kenny Tilton

unread,
Nov 29, 2001, 11:29:15 PM11/29/01
to

Bruce Hoult wrote:
> The only issue I have, as I said when I joined the thread half a dozen
> messages later, is how you tell whether a function searching for a list
> and returning it found it and it was empty, or whether it was not found
> at all.

This may not be a good example. Not there is not a good one out there.
But in this case we are asking a function to answer two questions with
one value. Never a good idea.

Specifically, by your definition of the issue the function is being
asked to return:

1> Some value associated with the input value, if any

2> Whether any value is associated with the input value

Programmers have played cute tricks like that for centuries, but it is
wrong. Makes code confusing. And it is unnecessary, expecially when you
can return multiple values.

I was just reminded of how CL handles optional arguments, where the
function is curious if its client supplied nil or did not supply the
argument. In our app we have:

(defmethod initialize-instance :before ((self PSClass)
&rest iArgs
&key (logical-unit-of-work nil
luw-specified)
&allow-other-initargs)
(assert luw-specified)
...)

The idea being that it is OK to do I/O outside an LUW, just let us know
that you know what you are doing and have not simply forgotten to supply
the luw control block when actually intending an LUW-managed I/O.

But again, that is two diff questions: what luw if any are we using? and
are you thinking clearly in re luws? So CL offers two diff answers, it
does not try to jam two answers into one.

kenny
clinisys

Bruce Hoult

unread,
Nov 30, 2001, 12:04:59 AM11/30/01
to
In article <3C06C58F...@nyc.rr.com>, Kenny Tilton
<kti...@nyc.rr.com> wrote:

> Bruce Hoult wrote:
> > The only issue I have, as I said when I joined the thread half a dozen
> > messages later, is how you tell whether a function searching for a list
> > and returning it found it and it was empty, or whether it was not found
> > at all.
>
> This may not be a good example. Not there is not a good one out there.

I agree, my example was not the best. I think it was posted around 0400
local time...

-- Bruce

Bruce Hoult

unread,
Nov 30, 2001, 12:07:56 AM11/30/01
to
In article <xcvd721...@blizzard.OCF.Berkeley.EDU>,

Yes it was, but we now appear to be into meta-discussion mode.

It's done as far as I'm concerned, and has been for a long time.

-- Bruce

Bruce Hoult

unread,
Nov 30, 2001, 12:54:55 AM11/30/01
to
In article <9u6aq8$r5g$1...@news3.cadvision.com>, "Wade Humeniuk"
<hume...@cadvision.com> wrote:

> I looked at some of your ICFP2001 code. Your are right (though I do not
> know dylan well) that it seems to be a simple syntatic translation. The
> lesson for me in this is that CL has all of the functionality of Dylan
> and is very similar.

Very similar: yes. *All* the functionality: no, that isn't true, in
either direction.


Dylan is CLOS-all-the-way-down, more like Smalltalk than CL. Dylan
allows the user to trade-off dynamism at runtime for (hopefully) better
optimization and speed, but even at its most dynamic is less flexible at
runtime than CL. There is no eval so you can't do a REP loop. Dylan is
intended to be a compiled language in which compile time is clearly
separated from runtime, both so the compiler can make more assumptions
about the code and optimize harder, but also so that programs *don't*
expect to have the compiler there at runtime so they can run on smalle
machines and/or have smaller image sizes. That's becoming less and less
important every year, of course, but full CL is still hard to fit onto a
PDA. Then there are the syntactic differences. I can and do program
happily in C, Perl, Dylan, Scheme, PostScript, OCaml so I can cope
easily with any number of different syntax styles, but I find that I
*do* prefer what Lisp calls "special forms" to be written using either
keywords or punctuation different from that used for expressions. Not
that the actual syntax choosen by the designers of Dylan thrills me all
that much. But I can certainly live with it, and for me it's better
than S-expressions.


> My questions back are:
>
> Did any of those dusty litle corners make any difference in your program?
> The answer probably is that you did not use any of the little dusty
> little corners.

That's going to depend on the exact definition of "dusty little
corners". There is certainly some use of that sort of thing in, for
example, the way I hid some very low level efficient bit banging behind
a high level interface.


> Would you say when Dylan was created that its model was CL and those
> dusty little corners from CL where not included in Dylan?

CL was certainly a major influence (as was Smalltalk and C++ (or Simula,
if you prefer)), and I understand that trying to improve on some of the
decisions and historical accidents in CL was a definite goal.


> Are you asking if some of those dusty corners left behind would be useful
> to be included into Dylan?

Yes. New ideas aren't always better than old ones and improvements
aren't always. Only experience can tell you that. After using it for a
few years I know a number of things that I think could be done better in
Dylan. I don't know whether or not CL does those things any better,
because I don't yet know CL that well. But I suspect that it *is* the
dusty corners that I don't know well, rather than the normal stuff. I
mean, if someone asks "how can I prevent my class from being
instantiated", I can say to myself "well maybe you could use the C++
technique of declaring a virtual function and put '= 0' on the end
instead of implementing it, or else maybe you could use the Dylan
technique of adding a method to the make() or initialize() GFs that
throws an error". On any given question, the chances are 99% that the
Dylan technique is also applicable to CL, and I just need to find the
correct name for it e.g. make-instance instead of make.

Now this probably *would* be a dusty corner of CL to a C++ programmer,
but it's obvious to a Dylan programmer.


> Is this what you are trying to determine. That would be a more
> interesting question.
>
> Perhaps you can make a list of issues (differences, not the
> nil/()/false issue) you consider useful looking into? Maybe then
> you can get some input if they would be good to put into Dylan.

I've been working on assembling such a list for some time.

-- Bruce

Pierre R. Mai

unread,
Nov 30, 2001, 12:56:12 AM11/30/01
to
Bruce Hoult <br...@hoult.org> writes:

> The only issue I have, as I said when I joined the thread half a dozen
> messages later, is how you tell whether a function searching for a list
> and returning it found it and it was empty, or whether it was not found
> at all.

GETHASH is a function that can be employed in situations where an
empty list, and "didn't find anything" are distinct situations. Its
approach is one, that should make Andreas very happy, in that it uses
true out-of-band signalling to signal the presence or absence of an
entry, via its second return value.[1]

Now, if we had a false value #f, which was distinct from NIL/(), then
would returning #f be an acceptable substitute to real out-of-band
signalling?

No, because how is a function that is searching for a boolean value
going to indicate the difference between finding #f and not finding an
entry at all?

Unless you can create a completely distinct "false" value for _all_
values, including that "false" value itself[2], you are not going
to be able to avoid conflating some of them. And that will pose
problems if you insist on in-band signalling (note that in-band- and
out-of-band signalling are usually defined w.r.t. to communication
channels, not w.r.t. distinct alphabets).

So, if you really have to distinguish between "false" and "not found",
or between "empty list" and "not found", use out-of-band signalling,
i.e. use a separate return value for the "found/not found" flag.

That said[3], you will have noticed that empirically, situations where it
is necessary to distinguish between "false" and "not found" don't
arise that often, because false is a common fall-back for "not found"
entries.[4]

The same is in my not-so-very-limited experience true of the empty
list. It is far more often the case that I _want_ a not-found
situation to degenerate into a "nothing found" <=> "empty list found"
situation. In a fairly representative sample of 100KLoC of code that
I've written, there are less than 10 occurrences of gethash with a
multiple-value-bind within 2 lines of context (from a total of 373
occurrences of gethash). And most of those are in an implementation
of weak hash-tables, based on weak references.

Ditto for a random sample of open source CL code, that includes:

- OpenMusic 4.0.3 GPL Release
- cl-http 70.23
- current CMU CL source code, including PCL-derived CLOS, and some
MIT/Symbolics code

That's a total of around 650KLoC, of very different origins, with
1107 occurrences of gethash. Of those, there are only 22 occurrences
of m-v-bind within two lines of context, of which probably less than
half are actually uses of m-v-bind on the return value of gethash.

Now, this doesn't necessarily capture all uses of the second return
value of gethash: it could get passed-through a function return, or
people could use m-v-list, or some other m-v primitive to access the
second value. Of those only the first case seems to be a common
thing, and even then I'd estimate it not to exceed the direct m-v-bind
scenario.

So even if we round this figure up excessively, we find that this is a
thing that is rarely occurring. Either people are continuously
writing incorrect code by omitting "required" checks for the second
return value, or, far more likely, they are making good use of the
default value nil/().

Or in other words, CL made certain quite common usage patterns easier
to write and more concise. It achieved that by making a certain
number of other, less frequent usage patterns more expensive to write.
That seems like a valid trade-off to me.

Of course this doesn't address the issue of the influence of that
design decision on usage patterns. That said, given that Dylan's
element GF signals an error to indicate "not-found" in its out-of-band
mode, it seems that the designers of Dylan concurred that this is not
a frequent usage pattern, making Dylan an unsuitable target for
further investigation of that issue.

Now that we have thought very hard about this, what are the
conclusions we can draw? Let's see:

a) CL isn't broken, it made an IMHO valid design trade-off (though it
probably did so unconsciously).

b) Dylan isn't necessarily broken, it has just made another trade-off,
and it is for the Dylan community to check whether that trade-off
paid off in their day-to-day usage.

c) That said, those issues are purely intellectual exercises, because
neither language community is in any position to revise that
decision now.

d) When we ever have to design yet another language (i.e. waste
everybodies time and resources for little gain, instead of
improving one of the extensible programming languages), it won't be
because of either choice. Furthermore, we can't extrapolate from
either language, because this trade-off will have to be based on
the interplay with a number of other design decisions, related to
frequency of use of certain data-structures and constructs.

Regs, Pierre.

Footnotes:
[1] It also allows the user to supply another default/not-found value
instead of NIL/(), which is again a good design decision.

[2] Which is somewhat problematic to achieve on current day
computers.

[3] I.e. having established that your question/problem hasn't really
been about (eq 'NIL '()) at all.

[4] This is further mitigated by the fact of footnote [1].

--
Pierre R. Mai <pm...@acm.org> http://www.pmsf.de/pmai/
The most likely way for the world to be destroyed, most experts agree,
is by accident. That's where we come in; we're computer professionals.
We cause accidents. -- Nathaniel Borenstein

Andreas Bogk

unread,
Nov 30, 2001, 1:13:55 AM11/30/01
to
Kent M Pitman <pit...@world.std.com> writes:

> > How do you feel about the false-or(<type>) mechanism? Wouldn't that
> > just be the generalization of that overlap in a cleaner way?
> (I reject your implicit suggestion that the word "clean" applies to
> one of these approaches and not to the other. There is nothing "unclean"
> about correctly applying any well-defined semantics. What feels "unclean"
> to you, as nearly as I can tell, is that you don't want the definition
> to be what the definition is. But the language is defined as it is,
> and since it's in no danger of changing, there is nothing unclean
> about the use.)

I think that the point that Common Lisp cannot be changed and would be
worse with that change is well taken. I can also see nothing unclean
in making use of this feature, given that it is in the design.

As you have correctly asserted, my question was directed at finding
out what approach would appeal to you more, given you were involved in
designing some Lisp-like language without any constraints like
existing code that needs to be ported.

> But in answer to your question, no, the (FALSE-OR type) thing moves
> in the wrong direction. It IS a useful technology for places where it
> was not possible to find a degenerate element within the set.

Can I understand this answer as saying that making natural nulls false
and using false-or are two techniques addressing the same issue, where
the former applies to less cases, but is better suited to them?

The two approaches seem mutually exclusive to me, though. Once your
type has an instance that is false, (FALSE-OR type) becomes useless in
that it doesn't behave like a naive user would expect.

> For example, had () and NIL and #f been all separate to start, I could
> imagine arguing to make () false, just as I have noted that I'd be
> happy if "" was false and #() was false. However, I can't imagine

If I understand it correctly, people argue that the equality of NIL
and the empty list is elegant, because any function returning false
for whatever reason still returns a valid list. Wouldn't introducing
multiple falses bear the risk of getting a false of the wrong type
where you don't expect it? For the records, while I haven't written
anything bigger than ten lines in MOO, I never experienced a problem
of that nature.

/When/ introducing multiple falses, I'd argue for introducing a
canonical false as well.

> Internationalization terms, if nothing else. And certainly if I were
> telling you to merge a faluse value with some random number seed, I
> wouldn't try to figure out what a degenerate seed was so that I could
> argue it should be false. I'd just say (FALSE-OR RANDOM-STATE).

I think we can safely say that we agree on this one.

> But there are places where there are natural nulls, and lists and
> arrays (including, of course, strings) are among them. I don't feel a

From your example below, I conclude this should also be true for
integers.

> need for an extra type in a great many situations. This is evident in
> the number of applications that do (PUSH X (GETHASH A B)) where they
> don't check to see if (GETHASH A B) returns NIL, NIL or NIL, T because
> it doesn't matter to them.

The price to pay for not having it would be having to write:

(PUSH X (GETHASH A B :DEFAULT NIL))

although one could argue that this makes the intent "I know what to do
when I don't find the element" better visible to the reader.

> Good language design is not done by randomly changing a feature but
> by doing feature changes in coordinated sets.

I agree. The poem mentioned in this thread shows nicely how a random
feature change that looks innocent enough results in an unusable
language.

Before this discussion, I was also unaware of the fact that separating
false and the empty list in Dylan wouldn't work so smoothly if it
hadn't been for type unions and the default keyword in the ELEMENT
function.

> So if we could declare a hash table of integers,
> there might be cases where people usefully did (INCF (GETHASH A B))
> without having to initialize (GETHASH A B) because they would know
> that (GETHASH A B) would return 0, NIL when there was no element or 0,
> T when an element had been set to 0.

Again,

(INCF (GETHASH A B :DEFAULT 0))

would have the same effect, with the same consequences on
communicating the intent.

> Also, in languages where you have more than one false, you can choose
> to do (EQ value 'particular-false-value) and to treat the other values
> differently.

That's true. It's probably the same overhead as having to write
(NULL? value) in languages where the null values aren't false.

This probably reduces the question of which is "better" to the
question of "what case arises more often", and this is so dependent on
style and personal preferences that no answer can be given.

> list might be NIL, and a probelm might result. SO I say back, suppose
> a FOO is represented as a boolean. (That would mean I only ever have

Yes, in case FOO can be a boolean all is lost, and you have to find
another trick. In Dylan code, one often finds idioms like this:

define constant $not-supplied = pair(#f, #f);

define method foo(bar, #key baz = $not-supplied)
...
end;

Unsupplied keyword arguments default to #f. The purpose of this idiom
is to differentiate between an unsupplied argument, and #f being
supplied to the function. When not supplying and supplying #f are
semantically the same, the trick is not needed.

$not-supplied is some random object on the heap that's only equal to
itself, and not exported from the module. So there's no way that
outside code can call this function and pass $not-supplied.

> And even as to degree, moving it in the direction of separation means
> more typing for people, and some people seem to regard that as "good"
> while others don't, so even the directionality is up for grabs.

Requiring more typing is not a a good thing per se. Separating
semantically what is separate conceptually is a good thing. Making
life easy for a programmer is a good thing too. The two often move in
different directions, and the right balance is certainly a matter of
personal taste.

Andreas Bogk

unread,
Nov 30, 2001, 2:11:02 AM11/30/01
to
Lieven Marchand <m...@wyrd.be> writes:

> > By the way, please forgive the use of the Dylanesque empty?. I'm so
> > used to working in a language where I can express operations on
> > collections independent of their implementation that I completely
> > missed the fact that there is no empty? in Common Lisp, and that it
> > can't be implemented in a way that would have equal performance to
> > (when foo).
> It probably can within a small constant amount and worrying about such
> trivia isn't productive. Please do not set up such strawmen.

I am sorry, I guess I have been discussing with Erik too long and
stared adopting his style of discussion.

> > Do you consider yourself to be that smart? How deeply have you looked
> > into Dylan, for instance, to be able to say that it doesn't have the
> > Lisp nature?
> You come to argue Dylan in c.l.l. and ask people here to prove their
> Dylan credentials?

No, I was specifically addressing Erik, because on one hand he claimed
one cannot say anything about a programming language without having
studied it for several years, and on the other hand he's pretty
certain in his claims about that language.

> (For the record, I have the Apple infix Dylan book
> floating somewhere about but lost intrest when the Dylan designers
> introduced misfix. You're paying the price now with your overcomplex
> and underpowered macro system)

It doesn't feel any more complex than the CL macro system to me. The
only aspect of "underpoweredness" that I am aware of are procedural
macros, and they are certainly implementable. If you know more,
please let me know.

Bruce Hoult

unread,
Nov 30, 2001, 2:31:30 AM11/30/01
to
Arrrgghh. I *said* I didn't want to repoen this, and the message to
which you are replying is part of a meta-discussion.

That said, thank you for your very good summary. I see little to
disagree with.


In article <871yihx...@orion.bln.pmsf.de>, "Pierre R. Mai"
<pm...@acm.org> wrote:

> Bruce Hoult <br...@hoult.org> writes:
>
> > The only issue I have, as I said when I joined the thread half a dozen
> > messages later, is how you tell whether a function searching for a list
> > and returning it found it and it was empty, or whether it was not found
> > at all.
>
> GETHASH is a function that can be employed in situations where an
> empty list, and "didn't find anything" are distinct situations. Its
> approach is one, that should make Andreas very happy, in that it uses
> true out-of-band signalling to signal the presence or absence of an
> entry, via its second return value.[1]

Yep, GETHASH is perfectly fine.


> Now, if we had a false value #f, which was distinct from NIL/(), then
> would returning #f be an acceptable substitute to real out-of-band
> signalling?
>
> No, because how is a function that is searching for a boolean value
> going to indicate the difference between finding #f and not finding an
> entry at all?

I agree, and I said so in one of my early posts in this thread. I think
#f is better than '() for this purpose but it's still not ideal. It
should really be a true "bottom" value as used in the likes of ML &
Haskell. This I think does solve the conflation problem.

I'll just note that as a matter of usage, it's common in Dylan programs
to create a custom boolean type using, say, one-of(#"FOO", #"NOT-FOO")
-- i.e. type-union(singleton(#"FOO"), singleton(#"NOT-FOO")). It's a
little more typing than using #t and #f but more self-documenting and
the efficiency is actually identical, since the <boolean> type is
defined as one-of(#f, #t) so it's all pointer comparisons anyway. And
packed data structures can represent one type-union of two symbols in a
single bit just as easily as they can represent any other type-union of
two symbols.


> Or in other words, CL made certain quite common usage patterns easier
> to write and more concise. It achieved that by making a certain
> number of other, less frequent usage patterns more expensive to write.
> That seems like a valid trade-off to me.

I agree with the principle.


> Of course this doesn't address the issue of the influence of that
> design decision on usage patterns. That said, given that Dylan's
> element GF signals an error to indicate "not-found" in its out-of-band
> mode, it seems that the designers of Dylan concurred that this is not
> a frequent usage pattern

And the "element" GF also allows you to specify any default value that
you want, as does CL GETHASH.


> Now that we have thought very hard about this, what are the
> conclusions we can draw? Let's see:
>
> a) CL isn't broken, it made an IMHO valid design trade-off (though it
> probably did so unconsciously).

Sure.


> b) Dylan isn't necessarily broken, it has just made another trade-off,
> and it is for the Dylan community to check whether that trade-off
> paid off in their day-to-day usage.

Uh huh.


> c) That said, those issues are purely intellectual exercises, because
> neither language community is in any position to revise that
> decision now.

Maybe, maybe not. Dylan is a little more likely to be still malleable
than CL, and there are also new languages popping up that might beneft
from things learned in both languages. Curl, for example. Or Arc,
which appears to be repeating a *lot* of the design decisions in Dylan,
while also doing a lot differently. We haven't seen much of the non
S-expression grammar yet, but it appears to be going for extreme
terseness, which the Dylan designers sure didn't do. There are
certainly times when "[+ _ 7]" might be more convenient and perhaps
clearer than either "method(a) a + 7 end" or "(lambda (a) (+ a 7))".
That's 7 vs 19 vs 20 characters, btw. Not that brevity is the be all
and end all. Dylan is pretty close to my personal lack of brevity limit
in terms of number of characters, but is perhaps saved because it's not
that many *tokens*, and also because programs don't require very many
lines. COBOL and HyperTalk, on the other hand, are *way* over my lack
of brevity limit...

-- Bruce

Kent M Pitman

unread,
Nov 30, 2001, 2:56:37 AM11/30/01
to
Andreas Bogk <and...@andreas.org> writes:

> > But in answer to your question, no, the (FALSE-OR type) thing moves
> > in the wrong direction. It IS a useful technology for places where it
> > was not possible to find a degenerate element within the set.
>
> Can I understand this answer as saying that making natural nulls false
> and using false-or are two techniques addressing the same issue, where
> the former applies to less cases, but is better suited to them?

("fewer" cases). Yes, probably. [I'm not positive that's the statistic,
but propbably it is and it's not worth fussing about. The essence of
your remark sounds right.]



> The two approaches seem mutually exclusive to me, though. Once your
> type has an instance that is false, (FALSE-OR type) becomes useless in
> that it doesn't behave like a naive user would expect.

I don't think that's always got to be true. It might just expose that
FALSE-OR was the wrong name for that type-operation in a Lisp that
subscribed to the other theory. You'd probably call it NIL-OR or
something like that, to empahsize which FALSE you were using. If you
didn't just use or(singleton(#f),othertype).



> > For example, had () and NIL and #f been all separate to start, I could
> > imagine arguing to make () false, just as I have noted that I'd be
> > happy if "" was false and #() was false. However, I can't imagine
>
> If I understand it correctly, people argue that the equality of NIL
> and the empty list is elegant, because any function returning false
> for whatever reason still returns a valid list. Wouldn't introducing
> multiple falses bear the risk of getting a false of the wrong type
> where you don't expect it? For the records, while I haven't written
> anything bigger than ten lines in MOO, I never experienced a problem
> of that nature.

You just have to know which kind of false you're supposed to return
(if the client is dictating terms) or which type of false someone
says they are returning (if the user is). Today I had to write
room.tell_contents($set_utils:set_difference(others,seen||{}));
to paper over just this problem. It's rare that this is needed,
but it does happen. It's also very easy to work around, and a reasonable
price to pay for the cases where it works. As with all things, any
well-defined spec does not leave any confusion on this point.
It's easy to think you'd be confused if you think that the return
value is left to chance. (And, frankly, some moos are very anarchic
with no one spec'ing anything. But I can assure you that this kind of
problem is the LEAST of the troubles that results from anarchy. :-)

> /When/ introducing multiple falses, I'd argue for introducing a
> canonical false as well.

Then you could again call false-or by the name you wanted. :-)
Again, this is why I say context matters so much when doing language
design.

However, I don't see the value of a canonical false. It would only
make people feel bad about using some equally legit value. The truth
has to be that the canonicality, such as it is, is context-dependent,
and more precisely, spec-dependent. You could, of course, make
something like (BOOLEAN-UTILS:CANONICAL-FALSE 0) => NIL, but then
that doesn't keep you from having (NUMBER-UTILS:CANONICAL-FALSE NIL) => 0.
As they say, "the nice thing about standards is that there are so
many of them". (Ok, so it's kind of out of context, but it seemed to
sort of apply...)

> > Internationalization terms, if nothing else. And certainly if I were
> > telling you to merge a faluse value with some random number seed, I
> > wouldn't try to figure out what a degenerate seed was so that I could
> > argue it should be false. I'd just say (FALSE-OR RANDOM-STATE).
>
> I think we can safely say that we agree on this one.
>
> > But there are places where there are natural nulls, and lists and
> > arrays (including, of course, strings) are among them. I don't feel a
>
> From your example below, I conclude this should also be true for
> integers.

Well, your language has to speak to what values are true and what are false
and whether any are in between. There's a second question of canonical
truth. Lisp speaks to both. But i"m not sure how this matters.



> > need for an extra type in a great many situations. This is evident in
> > the number of applications that do (PUSH X (GETHASH A B)) where they
> > don't check to see if (GETHASH A B) returns NIL, NIL or NIL, T because
> > it doesn't matter to them.
>
> The price to pay for not having it would be having to write:
>
> (PUSH X (GETHASH A B :DEFAULT NIL))
>
> although one could argue that this makes the intent "I know what to do
> when I don't find the element" better visible to the reader.

You could. Then again, even defaults should have default values.
There are reasons not all args are required. Don't confuse "what would
suffice" with "what someone might want to say". Plainly the default
arg to gethash (which is optional, not keyword, btw) is more powerful.
I probably should have used a diffeernt function that didn't have this arg.

> > Also, in languages where you have more than one false, you can choose
> > to do (EQ value 'particular-false-value) and to treat the other values
> > differently.
>
> That's true. It's probably the same overhead as having to write
> (NULL? value) in languages where the null values aren't false.

Well, I was also thinking of cases where I sometimes have switch
values that are VERBOSE = NIL, T, or :ALWAYS, where I do
(EQ VERBOSE 'T)
in some cases and just
VERBOSE
in others.



> This probably reduces the question of which is "better" to the
> question of "what case arises more often", and this is so dependent on
> style and personal preferences that no answer can be given.
>
> > list might be NIL, and a probelm might result. SO I say back, suppose
> > a FOO is represented as a boolean. (That would mean I only ever have
>
> Yes, in case FOO can be a boolean all is lost, and you have to find
> another trick. In Dylan code, one often finds idioms like this:
>
> define constant $not-supplied = pair(#f, #f);
>
> define method foo(bar, #key baz = $not-supplied)
> ...
> end;
>
> Unsupplied keyword arguments default to #f. The purpose of this idiom
> is to differentiate between an unsupplied argument, and #f being
> supplied to the function. When not supplying and supplying #f are
> semantically the same, the trick is not needed.

As long as you don't call the function recursively, or as long as you
don't call some other function that uses the same constant.

The right way to handle this is with supplied-p args of CL.
If you think supplied-p is a good concept, which I'm somewhat mixed on.
I use it. But I always hate it when I do because compositional
algebra for "pass-through functions" is painful.

> $not-supplied is some random object on the heap that's only equal to
> itself, and not exported from the module. So there's no way that
> outside code can call this function and pass $not-supplied.
>
> > And even as to degree, moving it in the direction of separation means
> > more typing for people, and some people seem to regard that as "good"
> > while others don't, so even the directionality is up for grabs.
>
> Requiring more typing is not a a good thing per se. Separating
> semantically what is separate conceptually is a good thing.

No, that's a value judgment. It's only a bad thing when a confusion will
certainly result. In most cases, it's in a gray area between those two.
This entire discussion is made up of words taht are blurry. Separating
our individual thoughts into things that have no type overlap would make
it huger than either of us would want to imagine. And the result would
not be necessarily any better since then none of us would read the other's
words at all.

> Making
> life easy for a programmer is a good thing too. The two often move in
> different directions, and the right balance is certainly a matter of
> personal taste.

Making life easy for the programmer is, imo, the only goal here.
The only place where making a programmer write more words is better
is when it makes his life easier in the long run.

Erik Naggum

unread,
Nov 30, 2001, 3:15:25 AM11/30/01
to
* Andreas Bogk

| I am sorry, I guess I have been discussing with Erik too long and stared
| adopting his style of discussion.

No, you are just being yourself, but you are starting to lose control,
and this need to blame someone else for your problems is quite typical.
If it really is so easy to make you do thing which you will later claim
is against your conscious will, I think you should now return to whoever
told you to come to comp.lang.lisp to post your idiotic drivel, and ask
for more money or whatever. It is time for you Dylan retards to quit the
game-playing you engage in. Dylan is the language of choice for retards,
as has been demonstrated beyond all possible doubt. You have done your
job, so go home, now.

| No, I was specifically addressing Erik, because on one hand he claimed
| one cannot say anything about a programming language without having
| studied it for several years, and on the other hand he's pretty certain
| in his claims about that language.

Your reading comprehension has been questioned several times, already, so
why do you need to prove that you are so amazingly unintelligent? Note
that this is no longer a question about your stupidity, which is a choice
not to think. You really are retarded. It is impossible to want to fake
your behavior if you had the intelligence to do anything better.

Bruce Hoult

unread,
Nov 30, 2001, 3:15:29 AM11/30/01
to
In article <87herd9...@teonanacatl.andreas.org>, Andreas Bogk
<and...@andreas.org> wrote:

> Before this discussion, I was also unaware of the fact that separating
> false and the empty list in Dylan wouldn't work so smoothly if it
> hadn't been for type unions and the default keyword in the ELEMENT
> function.

I think type unions are an *extremely* important language feature, and
one I miss greatly in C++ & Java. They allow you to do OO kinda stuff
without requiring things to have a common base class. In fact, if I
understand it properly, the ML languages effectively use type-union
*instead* of inheritance. In ML you pick them apart with pattern
matching, but I think instead combining them with Generic Functions is
just as good, or better.

-- Bruce

Thomas F. Burdick

unread,
Nov 30, 2001, 3:15:50 AM11/30/01
to
Bruce Hoult <br...@hoult.org> writes:

What the hell are you talking about? If you *knew* it had been
answered (I figured you'd missed it somehow), why on earth did you
post this?

Is this technique used by everyone else when they write functions
that return lists in their own CL code? I don't know. Certainly
no one even *mentioned* it or said "yes, it's a problem, but we
get around it by using this idiom". They just said "it's not a
problem".

Just to be a troll? Because I can't think of any other reason. I try
to give people the benefit of the doubt, but shit like this makes it
difficult.

Bruce Hoult

unread,
Nov 30, 2001, 3:33:18 AM11/30/01
to
In article <xcv7ks9...@conquest.OCF.Berkeley.EDU>,
t...@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) wrote:

> Bruce Hoult <br...@hoult.org> writes:
>
> > In article <xcvd721...@blizzard.OCF.Berkeley.EDU>,
> > t...@blizzard.OCF.Berkeley.EDU (Thomas F. Burdick) wrote:
> >
> > > I could have sworn this was answered (in fact, I'm pretty sure I
> > > addressed this myself).
> >
> > Yes it was, but we now appear to be into meta-discussion mode.
> >
> > It's done as far as I'm concerned, and has been for a long time.
>
> What the hell are you talking about? If you *knew* it had been
> answered (I figured you'd missed it somehow), why on earth did you
> post this?
>
> Is this technique used by everyone else when they write functions
> that return lists in their own CL code? I don't know. Certainly
> no one even *mentioned* it or said "yes, it's a problem, but we
> get around it by using this idiom". They just said "it's not a
> problem".
>
> Just to be a troll? Because I can't think of any other reason. I try
> to give people the benefit of the doubt, but shit like this makes it
> difficult.

No, that is once again meta-discussion. And perhaps somewhat
rhetorical. But I do thank you for your reply. So we now have:

a) multiple values, with a second "flag" value

b) keyword and/or optional arguments, allowing the user to specifying a
default disjoint from the expected data type

c) return a data structure (typically a cons) containing the result,
rather than returning the result directly.

I confess that c) is new to me. The other two are familiar.

-- Bruce

Andreas Bogk

unread,
Nov 30, 2001, 4:11:29 AM11/30/01
to
"Pierre R. Mai" <pm...@acm.org> writes:

> GETHASH is a function that can be employed in situations where an
> empty list, and "didn't find anything" are distinct situations. Its
> approach is one, that should make Andreas very happy, in that it uses
> true out-of-band signalling to signal the presence or absence of an
> entry, via its second return value.[1]

Actually, it does, it's a nicely designed function.

> [1] It also allows the user to supply another default/not-found value
> instead of NIL/(), which is again a good design decision.

I agree.

I think the perfect accessor function would additionally allow for a
third mode of operation: signal a restartable condition. That would
keep the local code simple (no need to pass around the found/not-found
information) while allowing to handle such a situation.

> Unless you can create a completely distinct "false" value for _all_
> values, including that "false" value itself[2], you are not going
> to be able to avoid conflating some of them. And that will pose
> problems if you insist on in-band signalling

Again, I agree.

> (note that in-band- and
> out-of-band signalling are usually defined w.r.t. to communication
> channels, not w.r.t. distinct alphabets).

One could argue that bindings, arguments and return values *are*
communication channels. Anyways, the terms have helped understanding
the nature of the problems involved.

> That's a total of around 650KLoC, of very different origins, with
> 1107 occurrences of gethash. Of those, there are only 22 occurrences
> of m-v-bind within two lines of context, of which probably less than
> half are actually uses of m-v-bind on the return value of gethash.

Thanks for the statistics. For comparison, I looked at the Gwydion
Dylan CVS (230KLoC). I have counted 3594 calls to ELEMENT. Only 132
of them make use of the default: keyword, so the vast majority is in
situations where unfound elements are considered an unexpected error.
In 108 cases, the default return value is #f. 8 call sites passed
bindings, 4 the empty list, 2 passed zero, 4 some special value like
'\n' or the identity function. Actually invoking the non-exported
binding trick to avoid the #f collision was necessary in a whopping
six cases.

> So even if we round this figure up excessively, we find that this is a
> thing that is rarely occurring. Either people are continuously
> writing incorrect code by omitting "required" checks for the second
> return value, or, far more likely, they are making good use of the
> default value nil/().

I think that my numbers show that in the majority of cases the
collection is *known* (or at least strongly suspected) to contain the
element. In these cases, the check is technically not required, so
nobody could be bothered writing extra code to check it. However, the
check would definitely help in finding code not behaving like you
think it should, so the exception that's generated is a valuable
debugging aid.

The way it is in CL, I'd expect to see bugs in my code where NIL pops
up in places where I don't expect it, whereas in the same situation in
Dylan I'd get an error message pointing at exactly the place where the
faulty call to ELEMENT is located.

> Of course this doesn't address the issue of the influence of that
> design decision on usage patterns. That said, given that Dylan's
> element GF signals an error to indicate "not-found" in its out-of-band
> mode, it seems that the designers of Dylan concurred that this is not
> a frequent usage pattern, making Dylan an unsuitable target for
> further investigation of that issue.

Well, see above numbers for how often not-found was actually an
expected outcome and not an error.

> a) CL isn't broken, it made an IMHO valid design trade-off (though it

I have no arguments to dispute that.

> b) Dylan isn't necessarily broken, it has just made another trade-off,
> and it is for the Dylan community to check whether that trade-off
> paid off in their day-to-day usage.

Yes, it's pretty convenient to use. I think it would be even better
if ELEMENT supported a second return value for found/not found, but
that would only very rarely be needed.

> c) That said, those issues are purely intellectual exercises, because
> neither language community is in any position to revise that
> decision now.

Yes. I said I am here to learn something, and I did.

Christopher Stacy

unread,
Nov 30, 2001, 4:49:37 AM11/30/01
to
>>>>> On 30 Nov 2001 05:11:29 +0100, Andreas Bogk ("Andreas") writes:
Andreas> The way it is in CL, I'd expect to see bugs in my code where NIL pops
Andreas> up in places where I don't expect it, whereas in the same situation in
Andreas> Dylan I'd get an error message pointing at exactly the place where the
Andreas> faulty call to ELEMENT is located.

In the situations where NIL is an incorrect value, writing the code
to check for that is going to be about the same as having made some
kind of type declarations for it. When there's a stray NIL about,
it doesn't take very long for it to get used in some very inappropriate
way (such as being function called, or as an argument of the wrong type).
Using interactive debugging facilities, it doesn't take very long to
find the proximal problem before you can proceed to the underlying bug.

Kent M Pitman

unread,
Nov 30, 2001, 7:03:12 AM11/30/01
to
Christopher Stacy <cst...@spacy.Boston.MA.US> writes:

> >>>>> On 30 Nov 2001 05:11:29 +0100, Andreas Bogk ("Andreas")

> Andreas> writes: The way it is in CL, I'd expect to see bugs in my
> Andreas> code where NIL pops up in places where I don't expect it,
> Andreas> whereas in the same situation in Dylan I'd get an error
> Andreas> message pointing at exactly the place where the faulty
> Andreas> call to ELEMENT is located.


>
> In the situations where NIL is an incorrect value, writing the code
> to check for that is going to be about the same as having made some
> kind of type declarations for it. When there's a stray NIL about,
> it doesn't take very long for it to get used in some very inappropriate
> way (such as being function called, or as an argument of the wrong type).
> Using interactive debugging facilities, it doesn't take very long to
> find the proximal problem before you can proceed to the underlying bug.

Upon reading Chris's remark, I suddenly had the following epiphany:

Is the reason that people focus so much on static type checking that it's
so hard to get a program to RUN in those languages? In CL, you can run a
partial program immediately upon writing it, and we often do. So in those
other programs, one runs the compiler to find errors on the basis of "static"
info. Whereas in CL you often also run a program fragment. In a language
that makes you wait longer to test your code, perhaps the sense of need
for static typechecking is higher, since that's all you can get for a long
time...

Bruce Hoult

unread,
Nov 30, 2001, 7:22:37 AM11/30/01
to
In article <sfw4rnc...@shell01.TheWorld.com>, Kent M Pitman
<pit...@world.std.com> wrote:

That's certainly what the Smalltalk XP people say.

On the other hand, testing can only show that there are no errors for
the data that you tested on, not for *every* possible run.

On the gripping hand, in an interactive environment you can easily set
up tests for code paths that are "never supposed to happen", which migth
be very very hard to test in a batch environement.

-- Bruce

Christian Lynbech

unread,
Nov 30, 2001, 7:58:34 AM11/30/01
to
>>>>> "Xah" == Xah Lee <x...@best.com> writes:

Xah> Dear Dylan lovers, i'd suggest you guys leave Common Lispers
Xah> alone. It's an old language obsesses by old people who will be
Xah> dead anytime soon.

This is not to question your definition of "old people" (I am younger
than lisp) but I for one does not hope to be dead anytime soon.

---

It was the dawn before the night of the full moon. The wise one rose
slowly from the high seat at the fire and gazed in the direction of
the rising sun.

Slowly he spoke: "Common Lisp and its descendants shall be dancing on
the graves of the mortal ones."

---

------------------------+-----------------------------------------------------
Christian Lynbech | Ericsson Telebit, Skanderborgvej 232, DK-8260 Viby J
Phone: +45 8938 5244 | email: christia...@ted.ericsson.dk
Fax: +45 8938 5101 | web: www.ericsson.com
------------------------+-----------------------------------------------------
Hit the philistines three times over the head with the Elisp reference manual.
- pet...@hal.com (Michael A. Petonic)

Erik Naggum

unread,
Nov 30, 2001, 8:11:00 AM11/30/01
to
* Kent M Pitman

| Is the reason that people focus so much on static type checking that it's
| so hard to get a program to RUN in those languages? In CL, you can run a
| partial program immediately upon writing it, and we often do. So in
| those other programs, one runs the compiler to find errors on the basis
| of "static" info. Whereas in CL you often also run a program fragment.
| In a language that makes you wait longer to test your code, perhaps the
| sense of need for static typechecking is higher, since that's all you can
| get for a long time...

Interesting perspective. If a CL program omits a function definition,
the debugger is invoked when it is called, and one may usually define it
and try the calling form again, even when the caller is compiled. If a
function in a static language program is omitted, there has traditionally
_not_ been a debugger to invoke because the debugger or any other part of
the development environment are not part of the "executable", so what do
you do? You could just terminate with a linking error, but that would
only be marginally more useful than having the compiler gripe about it --
and it is easy enough to write your own "stub function" that signals the
absence of a real function body. How useful would a debugger be for a
language that forces the programmer to recompile a large number of its
source files if you made changes?

The choice to use as much as possible of the available information from
the compilation process in the _caller_, instead of in the _callee_, may
account for more of the difference between languages than the static vs
dynamic nature of its type system, since that appears to be the fall-out
of the former choice, not fundamental to it, as the more you (want to)
optimize the _user_ of any object, the more static the whole language has
to be. However, as more and more information becomes available and is
known to be static, more and more of it _may_ be used in the caller.
This is probably also why declarations in static languages are promises
that are required, yet expected to be broken, so the compiler punishes
you when you do have lied (the IRS model of honesty), while they are
(optional) promises that are expected to be kept in Common Lisp (the
family model of honesty).

Andreas Bogk

unread,
Nov 30, 2001, 4:48:58 AM11/30/01
to
Erik Naggum <er...@naggum.net> writes:

> NO, you imbecile. It is that you want to make people feel their teeth
> with their tongue. Normal people walk through their entire life not
> feeling their teeth with their tongue. But, if something goes wrong,
> they keep feeling them all the time, and then they pay someone to fix it.
> What you are doing is to tell people that their teeth are wrong, when in
> fact they are not. You run around like a headless chicken in this

No, what we're doing is trying to compare what other people are
feeling to what we feel, to figure out whether *our* teeth need to be
fixed, for sticking one's tongue in somebody elses mouth over USENET
is a little difficult.

> with them up until then. This would raise "awareness" of something that
> really needs to be the subject of no awareness whatsoever, because it
> uses resources and concentration that should have had productive use.

It seems the finer points of the discussion are lost on you.

Andreas Bogk

unread,
Nov 30, 2001, 1:04:04 PM11/30/01
to
Christopher Stacy <cst...@spacy.Boston.MA.US> writes:

> Using interactive debugging facilities, it doesn't take very long to
> find the proximal problem before you can proceed to the underlying bug.

I would have expected that as well :).

Marco Antoniotti

unread,
Nov 30, 2001, 2:16:34 PM11/30/01
to

Andreas Bogk <and...@andreas.org> writes:

> KMP:


>
> > need for an extra type in a great many situations. This is evident in
> > the number of applications that do (PUSH X (GETHASH A B)) where they
> > don't check to see if (GETHASH A B) returns NIL, NIL or NIL, T because
> > it doesn't matter to them.
>
> The price to pay for not having it would be having to write:
>
> (PUSH X (GETHASH A B :DEFAULT NIL))

Please note that the above is not correct and that

(push x (gethash a b))

is equivalent to

(push x (gethash a b nil))


> Again,
>
> (INCF (GETHASH A B :DEFAULT 0))
>
> would have the same effect, with the same consequences on
> communicating the intent.

The correct CL is

(incf (gethash a b 0))

Cheers

--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
719 Broadway 12th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.

Marco Antoniotti

unread,
Nov 30, 2001, 2:24:42 PM11/30/01
to

I think this is an interesting concept, and I know that it is one of
the things the *ML crowd uses a lot (IMHO almost as an alternative to
macro processing).

Any idea about how to render them in CL (if possible)?

Cheers

Bruce Hoult <br...@hoult.org> writes:

--

Paolo Amoroso

unread,
Nov 30, 2001, 2:34:19 PM11/30/01
to
On Fri, 30 Nov 2001 08:11:00 GMT, Erik Naggum <er...@naggum.net> wrote:

> Interesting perspective. If a CL program omits a function definition,
> the debugger is invoked when it is called, and one may usually define it
> and try the calling form again, even when the caller is compiled. If a

Or maybe return the value expected from the called function without even
defining it.


Paolo
--
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://web.mclink.it/amoroso/ency/README
[http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/]

Pierre R. Mai

unread,
Nov 30, 2001, 3:29:25 PM11/30/01
to
Andreas Bogk <and...@andreas.org> writes:

> I think the perfect accessor function would additionally allow for a
> third mode of operation: signal a restartable condition. That would
> keep the local code simple (no need to pass around the found/not-found
> information) while allowing to handle such a situation.

That would have been an interesting possibility, mirroring the
out-of-bounds errors of other collection accessors. That said, I find
that uses of gethash where the absence of an element are errors are
also situations where it pays to have an abstract accessor function
(or macro), _and_ where it pays to report a more specific error than
"gethash couldn't find an entry in HASHTABLE xxxx for key YYYY".

So I'd write

(defun get-variable-type (variable)
(or
(gethash variable *variable-types* nil)
(error "Can't assign type to unknown variable ~S." variable)))

Or, if the situation is correctable, doing the same with a useful
restart.

> Thanks for the statistics. For comparison, I looked at the Gwydion
> Dylan CVS (230KLoC). I have counted 3594 calls to ELEMENT. Only 132
> of them make use of the default: keyword, so the vast majority is in
> situations where unfound elements are considered an unexpected error.

That is a very interesting statistic, and it probably shows the
influence of language design on usage patterns: At least for my
personal reference code base, situations where the absence of an entry
in a hash-table directly leads into an "programmer" error situation
are much, much rarer. The common situations that I can discern (using
examples from our in-house HTTP server) are:

a1) Absence of an entry is to be treated as a useful default value
(usually nil aka the empty list). The degeneration is often
helpful, and sometimes harmless, allowing the base algorithm to be
simplified.

a2) This often/sometimes occurs in combination with the "intern
pattern", i.e. an absent value isn't only defaulted on read, the
key is interned with the default value into the hash-table.

E.g. interning of HTTP version number objects, which are then used
in eql-dispatch methods.

b1) Absence of an entry is an error, but not one of program logic,
rather one of user origin. So the program will have to deal with
that situation, create informative error messages, log the
occurrence, and then signal a very specific condition, that allows
the user interface code to inform the user in a useful way.

Consider looking up URLs in a web-servers namespace (though we use
splay-trees for namespaces, not hash-tables). You want to signal
an http-error with :result-code +HTTP-Code-Not-Found+ (or one of
the related codes, if you know more about the absence), not any
other error, which will result in an internal server error being
presented to the user.

While you could still have gethash signal errors in such a
situation, which you handled and resignalled as another error,
this is both much more convoluted and error prone (what if you
catch an unrelated error, that shouldn't have been so handled?),
so let's not do this.

b2) Absence of an entry is either a programmer or user error. But the
point where the final gethash occurs is so removed from the actual
source of the problem, that simply signalling an error on the
gethash is not going to be helpful. Rather than raising the error
directly, return a documented invalid value (e.g. nil), and let
one of the callers that has enough context to give a useful error
message handle the situation.

This often occurs in combination with b1, resulting in a1
behaviour, e.g. namespace-lookup-url returning nil, instead of a
resource on failed lookups.

c) Absence of an entry is a direct violation of some invariant, hence
signalling an error is a good thing to do.

The last case is far and few in-between in my experience, but see
below.

> I think that my numbers show that in the majority of cases the
> collection is *known* (or at least strongly suspected) to contain the
> element. In these cases, the check is technically not required, so
> nobody could be bothered writing extra code to check it. However, the
> check would definitely help in finding code not behaving like you
> think it should, so the exception that's generated is a valuable
> debugging aid.

Actually, that is maybe the core of the difference: Contrary to
e.g. arrays or instances, where I more or less expect the aref or
slot-value/accessor call to succeed, unless I made a mistake
somewhere, I don't think of e.g. alists and has-tables that way. I
consider those to be dictionary style collections, where the absence
of an entry for a key is to be expected as part of the normal course
of operation, unless I have taken extra measures to ensure the
presence.

It is more like calling information, and inquiring for a phone number,
where failure to get the phone number is a frequent occurrance, and
part of normal operations.

I would guess that this difference in views is at least partly caused
by the behaviour of the two languages default accessors for such data
structures, though it may also be the other way around to some degree.

> The way it is in CL, I'd expect to see bugs in my code where NIL pops
> up in places where I don't expect it, whereas in the same situation in
> Dylan I'd get an error message pointing at exactly the place where the
> faulty call to ELEMENT is located.

While such errors do sometimes happen, you could only cure them by
making the default action of gethash being the error case. That would
be contrary to current usage patterns (apart from being an incompatible
change), so it would result in lots of "error where none was intended"
bugs in new code in the interim time.

One could instead create a new accessor that defaulted to signalling
an error by default, for people who don't want to think about
non-occurrence. Whether this would be worth it, considering usage
patterns, the low frequency of such bugs, and the fact that they will
normally be found during testing, because they are natural
border-cases that are included in any serious tests, is another
question.

> Well, see above numbers for how often not-found was actually an
> expected outcome and not an error.

It is my conjecture that the numbers are also influenced by the
design, and not only vice-versa.

> Yes. I said I am here to learn something, and I did.

In the end, once the questions were properly framed, I found this a
good opportunity to take a more detailed look at usage patterns in CL,
which together with hearing about Dylan usage patterns increased my
understanding of CL usage and the influences of design decisions. So
I learned something as well.

Regs, Pierre.

Tim Bradshaw

unread,
Nov 30, 2001, 4:23:05 PM11/30/01
to
Erik Naggum <er...@naggum.net> wrote in message news:<32160966...@naggum.net>...

>
> Interesting perspective. If a CL program omits a function definition,
> the debugger is invoked when it is called, and one may usually define it
> and try the calling form again, even when the caller is compiled. If a
> function in a static language program is omitted, there has traditionally
> _not_ been a debugger to invoke because the debugger or any other part of
> the development environment are not part of the "executable", so what do
> you do? You could just terminate with a linking error, but that would
> only be marginally more useful than having the compiler gripe about it --
> and it is easy enough to write your own "stub function" that signals the
> absence of a real function body. How useful would a debugger be for a
> language that forces the programmer to recompile a large number of its
> source files if you made changes?

Another take on debuggers is that in static languages it is *hugely*
more important to have a hairy debugger with stepping features than in
Lisp, because the time from one working version to another, even if
you only change a line, is minutes at least because of the hairy link
cycles (and elaborate dependency stuff in the build system. So while
a Lisp debugger's basic task is to tell you where you are and point
the editor at the bad bit of code, and then to let you restart the
call with now-redefined code with suitable print statements or
whatever (redefinition having taken several milliseconds), a
static-language debugger needs to help you make an exhaustive analysis
of the problem because any fix, no matter how small, is going to take
minutes or hours.

--tim

Pierre R. Mai

unread,
Nov 30, 2001, 4:28:04 PM11/30/01
to
Bruce Hoult <br...@hoult.org> writes:

> Arrrgghh. I *said* I didn't want to repoen this, and the message to
> which you are replying is part of a meta-discussion.

While I was aware of that, I got the impression (from the whole
thread, not only from the post I followed up), that the issues I
wanted to put across hadn't been communicated sucessfully, and I also
got the impression that the discussion had been partly about the wrong
thing, so I wanted to clarify some of that.

> That said, thank you for your very good summary. I see little to
> disagree with.

So it was worth the effort to reopen this. ;)

> I agree, and I said so in one of my early posts in this thread. I think
> #f is better than '() for this purpose but it's still not ideal. It
> should really be a true "bottom" value as used in the likes of ML &
> Haskell. This I think does solve the conflation problem.

Only if you don't allow that value to escape, e.g. by storing it
somewhere (e.g. in a hash-table), or passing it along. I rather
prefer the separate return value solution, which is a much more
general solution to the problem of wanting to return more than one
piece of information, than special-casing

> I'll just note that as a matter of usage, it's common in Dylan programs
> to create a custom boolean type using, say, one-of(#"FOO", #"NOT-FOO")
> -- i.e. type-union(singleton(#"FOO"), singleton(#"NOT-FOO")). It's a
> little more typing than using #t and #f but more self-documenting and
> the efficiency is actually identical, since the <boolean> type is
> defined as one-of(#f, #t) so it's all pointer comparisons anyway. And
> packed data structures can represent one type-union of two symbols in a
> single bit just as easily as they can represent any other type-union of
> two symbols.

Unless I missed something the types so created are not boolean types,
but rather "binary" types, in that you can't use the usual falseness
tests on them. That said, using keywords instead of nil and t is a
possible approach in CL, too, although I'd only use it if there was a
better keyword for the non-foo situation than :not-foo. Otherwise I'd
use :foo and nil.

> And the "element" GF also allows you to specify any default value that
> you want, as does CL GETHASH.

Yes, I was aware of that, but that wasn't relevant to the point I
wanted to make.

> > c) That said, those issues are purely intellectual exercises, because
> > neither language community is in any position to revise that
> > decision now.
>
> Maybe, maybe not. Dylan is a little more likely to be still malleable
> than CL, and there are also new languages popping up that might beneft

While it might still be more malleable (having only 2-3 common
implementations, and a smaller code base), I'm fairly certain that
changing something as basic as the falseness of empty lists is not
something that would go down well with its user community, unless they
are only in it for the intellectual exercise, which I kind of doubt.

As to new languages popping up, I thought my point d) addressed both
my stance to the usefulness of such things happening, and the
applicability of the particular lessons learned. The only thing that
designers could take on board from this discusion, IMHO, is that
(projected) usage patterns should influence language design, and
vice-versa, language design will affect usage patterns. But someone
contemplating designing a new language should have been aware of that
in the first place.

> terseness, which the Dylan designers sure didn't do. There are
> certainly times when "[+ _ 7]" might be more convenient and perhaps
> clearer than either "method(a) a + 7 end" or "(lambda (a) (+ a 7))".

Very cheap anonymous functions is something that the FP community has
been into for a long time. It is natural for them to do this,
because they need such functions all over the place, since they have
few other abstraction capabilities.

Having written several KLoC of programs in some of them, I'll make the
following observations:

- Making anonymous functions so cheap can lead to functions becoming
anonymous, which for documentation purposes alone should have been
named.

- Such an approach is more suitable in non-interactive languages,
where not naming functions doesn't affect interactive testability
(because there is no such thing anyway).

- Together with ubiquitous infix syntax, ubiquitous function
overloading based on argument types, and a mathematical bent, such
things can quickly lead to programs becoming as readable as basic
lambda calculus:

FUN <* : set[map[alpha,lessa,beta],lessm] **
set[map[alpha,lessa,beta],lessm] ->
set[map[alpha,lessa,beta],lessm]
DEF sm1 <* sm2 ==
flat((\\ i . ((\\ j . i <+ j) * sm2)) * sm1)

FUN search:
(alpha ** beta -> bool) ->
(alpha ** beta -> alpha ** beta -> bool) ->
set[alpha,lessa] ** set[beta,lessb] ->
set[map[alpha,lessa,beta],lessm]

DEF search(pointwisea)(mutuallya)(setAlpha,setBeta) ==
IF {}?(setAlpha) THEN {}'Set[map[alpha,lessa,beta],lessm]
ELSE
LET
a == arb(setAlpha)
fsearch == search(pointwisea)(mutuallya)(setAlpha - %(a), setBeta)
b_in_B == (\\ n. pointwisea(a, n)) | setBeta
IN
flat((\\ b .
((\\ fs_map .
pw(mutuallya(a,b))(fs_map))| fsearch) <* %(def(a,b,{}))) * b_in_B)
FI

This implements generic pointwise global search. Totally cool that it
can be sculpted with such succinctness. When writing such code, you
are in a state of mind that is more like creating a proof than writing
a novel. It is exhilerating when (after several hours) you have
gotten your 100 line program to type-check, which usually means it
will work for the cases you are interested in. Enjoy that feeling,
walk away and never return to that program. You will not be able to
understand your own program without investing nearly the same amount
of time that you did while writing it. Others will be able to work
through your proof^Wprogram, if they invest the required time. Don't
even think about changing one of the assumptions your program is based
on, without all hell breaking lose.

[ Note that OPAL -- the language in question -- also allows anonymous
functions to be specified using anonymous parameters, like the Arc
example above, e.g. _ + 5. Haskell throws automatic currying support
into the mix, which OPAL avoids. ]

While I sometimes long for the brevity of \\x.2*x, or the automatic
currying support, I don't think such features come without serious
downsides.

Regs, Pierre.

Kent M Pitman

unread,
Nov 30, 2001, 5:24:09 PM11/30/01
to
tfb+g...@tfeb.org (Tim Bradshaw) writes:

> Another take on debuggers is that in static languages it is *hugely*
> more important to have a hairy debugger with stepping features than in
> Lisp,

Nah. I don't use 'em. I just use print statements. What makes Java a win
is that they didn't make "does output to standard-output" part of the type
signature. If adding debuggging statements were considered a change of
signature, which arguably they should be in a language like Java that wants
to statically check everything in advance, it would be impossible for me to
debug anything. ;)

Lieven Marchand

unread,
Nov 30, 2001, 4:37:18 PM11/30/01
to
Andreas Bogk <and...@andreas.org> writes:

> It doesn't feel any more complex than the CL macro system to me. The
> only aspect of "underpoweredness" that I am aware of are procedural
> macros, and they are certainly implementable. If you know more,
> please let me know.

One line definition of CL DEFMACRO: You get the forms as lists of
symbols and you write a function that returns Lisp code in the form of
a list of symbols. (This neglects automatic DESTRUCTURING-BIND and a
few other niceties but it will do for a discussion).

It's a simple model that leaves the programmer the choice to be
hygienic or not, what cases to support or not, etc. Dylan's macros
have a lot more hair to deal with the misfix syntax, have an ugly hack
to allow variable capture and still aren't powerful enough in practice
to write something like LOOP, let alone SERIES.

Bruce Hoult and I had that argument a year or two ago. You'll likely
find it at groups.google.com.

--
Lieven Marchand <m...@wyrd.be>
She says, "Honey, you're a Bastard of great proportion."
He says, "Darling, I plead guilty to that sin."
Cowboy Junkies -- A few simple words

Bruce Hoult

unread,
Dec 1, 2001, 12:37:07 AM12/1/01
to
In article <y6czo54qq...@octagon.mrl.nyu.edu>, Marco Antoniotti
<mar...@cs.nyu.edu> wrote:

> Bruce Hoult <br...@hoult.org> writes:
>
> > In article <87herd9...@teonanacatl.andreas.org>, Andreas Bogk
> > <and...@andreas.org> wrote:
> >
> > > Before this discussion, I was also unaware of the fact that separating
> > > false and the empty list in Dylan wouldn't work so smoothly if it
> > > hadn't been for type unions and the default keyword in the ELEMENT
> > > function.
> >
> > I think type unions are an *extremely* important language feature, and
> > one I miss greatly in C++ & Java. They allow you to do OO kinda stuff
> > without requiring things to have a common base class. In fact, if I
> > understand it properly, the ML languages effectively use type-union
> > *instead* of inheritance. In ML you pick them apart with pattern
> > matching, but I think instead combining them with Generic Functions is
> > just as good, or better.
>

> I think this is an interesting concept, and I know that it is one of
> the things the *ML crowd uses a lot (IMHO almost as an alternative to
> macro processing).
>
> Any idea about how to render them in CL (if possible)?

The first thing to understand is that type-union is a property of
*bindings*, rather than of *objects*. So it is not at all the same
thing as, say, C union types, or Pascal variant records. Any particular
obeject has a concrete type, not a union type, but objects of different
types may be bound to the same variable at different times.

So normal bindings in Lisp are in fact type-union(everything you can
think of). The coolness comes in when you start declaring the types of
variables, because it allows you to say not just the a variable is of a
particular type, but that a variable might be of type "foo" or "bar" or
"baz" but it can't be anything else. This enables mechanical checks
that you covered all the cases (and makes manual checks easier), and
enables compiler optimizations.

This just doesn't exist in C or Pascal. At least not without a lot of
unsafe typecasting. Any Object-Oriented language of course provides
this idea, but in a quite limited way: the different types must all have
a common base class.

Type-union, on the other hand, lets you do it with *any* types. This is
used to good effect in *ML, where the standard type declaration not only
makes a union type, but also defines the individual types -- effectively
record or tuple types -- that make it up.

Type-union does something useful with data. Generic Functions do the
same useful thing with computations. You don't have to decide in
advance which virtual functions go with which classes. You can always
add entirely new GFs at any time, and specialize methods in them on any
type you want -- even someone else's class, or something from the
standard library.


The two together provide a powerful form of OO that doesn't depend on
inheritance at all.

-- Bruce

Bruce Hoult

unread,
Dec 1, 2001, 3:40:26 AM12/1/01
to
In article <87vgfsu...@orion.bln.pmsf.de>, "Pierre R. Mai"
<pm...@acm.org> wrote:

> > I'll just note that as a matter of usage, it's common in Dylan programs
> > to create a custom boolean type using, say, one-of(#"FOO", #"NOT-FOO")
> > -- i.e. type-union(singleton(#"FOO"), singleton(#"NOT-FOO")). It's a
> > little more typing than using #t and #f but more self-documenting and
> > the efficiency is actually identical, since the <boolean> type is
> > defined as one-of(#f, #t) so it's all pointer comparisons anyway. And
> > packed data structures can represent one type-union of two symbols in a
> > single bit just as easily as they can represent any other type-union of
> > two symbols.
>
> Unless I missed something the types so created are not boolean types,
> but rather "binary" types, in that you can't use the usual falseness
> tests on them.

Right. That's why I said that it's a little more typing -- you have to
use if(x = foo:) instead of if(x).


> That said, using keywords instead of nil and t is a
> possible approach in CL, too, although I'd only use it if there was a
> better keyword for the non-foo situation than :not-foo.

Agreed.


> > terseness, which the Dylan designers sure didn't do. There are
> > certainly times when "[+ _ 7]" might be more convenient and perhaps
> > clearer than either "method(a) a + 7 end" or "(lambda (a) (+ a 7))".
>
> Very cheap anonymous functions is something that the FP community has
> been into for a long time. It is natural for them to do this,
> because they need such functions all over the place, since they have
> few other abstraction capabilities.

True.


> This implements generic pointwise global search. Totally cool that it
> can be sculpted with such succinctness. When writing such code, you
> are in a state of mind that is more like creating a proof than writing
> a novel. It is exhilerating when (after several hours) you have
> gotten your 100 line program to type-check, which usually means it
> will work for the cases you are interested in. Enjoy that feeling,
> walk away and never return to that program. You will not be able to
> understand your own program without investing nearly the same amount
> of time that you did while writing it.

This is also true of many programs in C++ and Perl, though without the
expressive power.


> While I sometimes long for the brevity of \\x.2*x, or the automatic
> currying support, I don't think such features come without serious
> downsides.

Automatic currying scares me. It's handy to just be able to write "+ 1"
(or more likely "(+ 1)") but you can't ask "how many arguments does this
function take?". One, of course. And it returns a function which takes
an argument and returns a function that takes an argument and returns a
function that takes an argument and returns an integer. So the answer
I'm really interested in with that question is "4". "How many arguments
before w get a return value that isn't a function".

I'm not sure that most people are ready for that :-)

-- Bruce

Bruce Hoult

unread,
Dec 1, 2001, 3:52:55 AM12/1/01
to
In article <fbc0f5d1.01113...@posting.google.com>,
tfb+g...@tfeb.org (Tim Bradshaw) wrote:

> Another take on debuggers is that in static languages it is *hugely*
> more important to have a hairy debugger with stepping features than in
> Lisp, because the time from one working version to another, even if
> you only change a line, is minutes at least because of the hairy link
> cycles (and elaborate dependency stuff in the build system.

To be fair to them, I haven't had static language turn-around times of
anything *like* that since CodeWarrior came out on the first PowerMacs.
Prior to that, with MPW on 68k machines, it was pretty common to have
multi-minute cycle times on single line changes (and half an hour to
recompile the whole MacApp library), but as soon as CodeWarrior+60MHz
PPC appeared it took less than two minutes to recompile MacApp and
seconds to compile&go after a one line change in an implementation file.

-- Bruce

Bruce Hoult

unread,
Dec 1, 2001, 3:58:39 AM12/1/01
to
In article <m3bshkr...@localhost.localdomain>, Lieven Marchand
<m...@wyrd.be> wrote:

> It's a simple model that leaves the programmer the choice to be
> hygienic or not, what cases to support or not, etc. Dylan's macros
> have a lot more hair to deal with the misfix syntax, have an ugly hack
> to allow variable capture and still aren't powerful enough in practice
> to write something like LOOP, let alone SERIES.

Since the Dylan "for" loop is pretty much isomorphic to CL's "LOOP", and
Dylan's "for" is implemented as a macro, that claim would appear to be
false.

I haven't had a chance to look closely at SERIES. I downloaded it and
it's *enormous*!!

-- Bruce

Thomas F. Burdick

unread,
Dec 1, 2001, 4:23:11 AM12/1/01
to
Bruce Hoult <br...@hoult.org> writes:

This is true for small things. Large systems continue to grow, and
I've worked on a project where it wasn't unusual for a one-line change
to require 90 minutes of recompilation (if it was a one-line change in
the right module).

Kent M Pitman

unread,
Dec 1, 2001, 4:36:00 AM12/1/01
to
Bruce Hoult <br...@hoult.org> writes:

> In article <fbc0f5d1.01113...@posting.google.com>,
> tfb+g...@tfeb.org (Tim Bradshaw) wrote:
>

> > Another take on debuggers is that in static languages it is *hugely*
> > more important to have a hairy debugger with stepping features than in
> > Lisp, because the time from one working version to another, even if
> > you only change a line, is minutes at least because of the hairy link
> > cycles (and elaborate dependency stuff in the build system.
>

> To be fair to them, I haven't had static language turn-around times of
> anything *like* that since CodeWarrior came out on the first PowerMacs.
> Prior to that, with MPW on 68k machines, it was pretty common to have
> multi-minute cycle times on single line changes (and half an hour to
> recompile the whole MacApp library), but as soon as CodeWarrior+60MHz
> PPC appeared it took less than two minutes to recompile MacApp and
> seconds to compile&go after a one line change in an implementation file.

Assuming there is a compiled app to go to.

I was more comparing to starting off with something like:

(defun my-quicken-pro ()
(call-tool (select-tool)))

and then usefully doing:

(my-quicken-pro)

Sure, you end up in the debugger REALLY fast, but you can tell where you are
in the program and you can return values. You can write substitute code from
there and proceed your application. And the debugging state you get while
you're poking around is as meaningful as it would be in a complete app.

Other languages would really have no meaning to calling a program like this
that was just a fragment. Sure, once the tool is developed, with both
incremental and fast compilation, it can be fixed and started. But during
evolution, wanting to test a tool out of context, most languages don't have a
meaning to data independent of app, how to view it, how to type it, etc.
Yes, if it operates on data files, sometimes you can make a standalone app
that runs on a test data file and then quits, but that's about it.

Lisp isn't alone in having this capability. But languages like Java, C++,
and C don't seem to have it in the implementations I've seen.

Kenny Tilton

unread,
Dec 1, 2001, 4:05:40 AM12/1/01
to
I have been curious about current cycle times in the land of C++, been a
long time for me. I do remember the transition from Think's C+- which
still managed incremental linking to Symantec C++ which gave up on that.
I was very depressed by that.

Bruce Hoult wrote:
> but as soon as CodeWarrior+60MHz
> PPC appeared it took less than two minutes to recompile MacApp and
> seconds to compile&go after a one line change in an implementation file.

What is it like now with today's clock speeds, on PPC or Intel? I mean a
nice fat 100k LOC app. I gather it's uglier if you change a key header
file, so maybe two values: one for a key header used ubiquitously and
one for a single non-header file, say to add a debugging print
statement.

And is every link from scratch? Or are they able to save some work on a
re-link?

thx,

kenny
clinisys

Kenny Tilton

unread,
Dec 1, 2001, 5:52:38 AM12/1/01
to

"Thomas F. Burdick" wrote:
>
> This is true for small things. Large systems continue to grow, and
> I've worked on a project where it wasn't unusual for a one-line change
> to require 90 minutes of recompilation (if it was a one-line change in
> the right module).
>

Criminy o' golden!

Does that mean the XP crowd does not use C++? They go on about
refactoring, and indeed that is a Good Thing, lets you keep moving
towards The Light. I am forever changing data structures, juggling
inheritance, yada yada.

I guess big C++ projects spend more time thinking and planning and less
time tossing code around?

kenny
clinisys

Thomas F. Burdick

unread,
Dec 1, 2001, 7:23:50 AM12/1/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> "Thomas F. Burdick" wrote:
> >
> > This is true for small things. Large systems continue to grow, and
> > I've worked on a project where it wasn't unusual for a one-line change
> > to require 90 minutes of recompilation (if it was a one-line change in
> > the right module).
> >
>
> Criminy o' golden!
>
> Does that mean the XP crowd does not use C++? They go on about
> refactoring, and indeed that is a Good Thing, lets you keep moving
> towards The Light. I am forever changing data structures, juggling
> inheritance, yada yada.

I've gotten the impression that Real XP Types use SmallTalk. I'm sure
C++ types "do" XP, but they "do" a lot of things with about the same
level of success.

> I guess big C++ projects spend more time thinking and planning and less
> time tossing code around?

It depends, I think. In my experience, you sometimes go the
"rapid"[*] prototype -> complete rewrite -> incremental changes route;
but sometimes you're forced to do Lots Of Careful Planning. It all
depends on what part of the dependency graph you're working on, and
how good your Makefiles are. Incidentally, I wasn't very good at
Makefiles until I worked on a large C++ project. Making full use of
the GNU Makefile language was *vital* to my ability to write any
amount of code, because a naive build system would have sent me into
unnecessary Recompilation Hell.

[*] Scare quotes to indicate this is only true for C++ values of
"rapid," which have no realationship to the Lisp value of the same
name.

Thomas F. Burdick

unread,
Dec 1, 2001, 7:26:23 AM12/1/01
to
Kent M Pitman <pit...@world.std.com> writes:

> Lisp isn't alone in having this capability. But languages like Java, C++,
> and C don't seem to have it in the implementations I've seen.

Interestingly, I think GNU C was supposed to have this capability, via
a C interpreter in the debugger, but no one ever finished it. Now
*that* would have made for a nicer environment.

John Markus Bjorndalen

unread,
Dec 1, 2001, 10:37:14 AM12/1/01
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> What is it like now with today's clock speeds, on PPC or Intel? I mean a
> nice fat 100k LOC app. I gather it's uglier if you change a key header
> file, so maybe two values: one for a key header used ubiquitously and
> one for a single non-header file, say to add a debugging print
> statement.

Just to give you an example from simpler applications: Compiling a
100-line file using wxWindows or with a hardware simulation library
for C++ (I forgot the name and I really don't want to remember it
either) would take around 10 seconds on a 650MHz PIII. Change a line
in a header file or do some rearranging of code and you quickly start
measuring recompile time in minutes even for very small projects.

And then you link the compiled object files...

--
// John Markus Bjørndalen

Erik Naggum

unread,
Dec 1, 2001, 1:12:46 PM12/1/01
to
* Kenny Tilton

| I guess big C++ projects spend more time thinking and planning and less
| time tossing code around?

It appears to me that big C++ projects only actually work well if they
"lucked out" with their design early enough to avoid rethinking it. If
not, they die. When you have precise knowledge of the problem domain and
you are able to anticipate your requirements completely, C++ is not a bad
choice of language. This implies that the thinking and planning stage
must have started a long time before anyting actually start thinking and
planning for a particular project -- only if you do _not_ have to make
engineering decisions during the course of development does it make sense
to use C++. This contributes to the need for patterns and "patterns" in
C++ software development, and especially of avoiding questioning the way
things are done, which means good leadership and loyal team members.

But more than software problems, I think C++ produces social problems and
requires harsh solutions to them. I and others have been arguing for a
long time that there is no one unique right solution to a problem without
a context and that there are tradeoffs between all kinds of factors
depending on the context, and that allowing the "rightest" solution to
emerge as sufficient knowledge to make the best tradeoffs emerges, is the
only way to make those tradeoffs. If this is to succeed in a brittle and
frail language as C++, _people_ have to agree, or not be allowed to have
any "ideas" of their own about what is right to do. In my view, C++ is a
good language if you have a benevolent dictator and people who are
willing to accept orders from above down to the very tiniest details. In
other words, C++ is an excellent assembly-line programming language.

I think the kinds of problems that can be solved successfully in C++ are
limited by the mental capacity of the leading designer. Abstraction in
the language is not necessary, as it is cheaper to pay people to do the
menial labor of typing in a lot of code than to design with the right
abstractions, and this seems to account for the low abstracation level in
successful and large C++ projects. This also leads to the development of
other languages and tools to manage all the abstraction that is not to
occur in C++, because it is impossible to think design in C++ due to the
immense cognitive load of the language. If designing software is like
building a mechanical clock, it does nobody any good to have to do it
moleculy by molecule.

The reason I made up my mind never to use C++ again when a project died
on me back in 1994, was primarily that the information required for any
particular decision is not available until a long time after it must be
made. Now, dealing with uncertain information is no big deal by itself,
but the process of discovery of the required certainty is very expensive
in C++, and if you are fully aware of the decisions you make on missing
or insufficient information, the "backtrack log" grows much faster than
your "progress log", and if you are not aware of the decisions you make,
you will go seriously wrong. This is not unlike those people we see come
to comp.lang.lisp who base most of their opinions about (Common) Lisp on
guesswork and who refuse to question the assumptions on which they have
built their current set of conclusions, and who, amazingly, think they
are still as certain in their conclusions as they were with the little
bit of fact that they once acquired. Some people just _have_ to fill in
the blanks between the things they are certain about and are probably not
even aware of this seriously bad mental habit. This does not work well
in programming in general, but C++ is a language that really punishes you
for this kind of mistake, while it makes avoiding it and doing things
right is prohibitively expensive.

My conclusion is that C++ is not a language that _can_ be used by very
intelligent people -- it requires that you _not_ think carefully about
what you do -- but rather suitable for people who can tolerate a lot of
failure. Likes sales people who continue to have a great attitude even
though they get 99% rejections, I imagine that good C++ programmers must
tolerate doing _so_ much manual work, and repeating it several times,
which would tell me that I am doing something seriously wrong and quit
and find something else to do. ... which I did.

Wade Humeniuk

unread,
Dec 1, 2001, 3:35:29 PM12/1/01
to
> To be fair to them, I haven't had static language turn-around times of
> anything *like* that since CodeWarrior came out on the first PowerMacs.
> Prior to that, with MPW on 68k machines, it was pretty common to have
> multi-minute cycle times on single line changes (and half an hour to
> recompile the whole MacApp library), but as soon as CodeWarrior+60MHz
> PPC appeared it took less than two minutes to recompile MacApp and
> seconds to compile&go after a one line change in an implementation file.

There is not just the turn around time in a compile and link, but actually
running the code to where the error occurs again. The same sequence of
actions usually has to be recreated. This may take a while. (Say a
protoocl error between two apps). The setup time to run the code can be
very prohibitive.

Wade


Florian Weimer

unread,
Dec 1, 2001, 3:42:09 PM12/1/01
to
Kent M Pitman <pit...@world.std.com> writes:

> If adding debuggging statements were considered a change of
> signature, which arguably they should be in a language like Java
> that wants to statically check everything in advance, it would be
> impossible for me to debug anything. ;)

Therefore, in Ada, it's quite a challenge to debug pure library units
(which may not depend on other library units which may have side
effects, such as output). People work around this limitation by using
pragma Import/Export, completely bypassing type safety, elaboration
checking and what else. ;-)

Duane Rettig

unread,
Dec 1, 2001, 4:20:21 PM12/1/01
to

Don't forget also that you also have to set up your application's
environment again, which was lost when you had to restart it. In
a non-trivial application with lots of file accessing and cache building,
this can be nontrivial.

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

Bruce Hoult

unread,
Dec 1, 2001, 8:46:01 PM12/1/01
to
In article <hvu1vbd...@johnmnb.cs.uit.no>, John Markus Bjorndalen
<jo...@cs.uit.no> wrote:

My current project is porting a 400k line C++ program from Windows to
MacOS X and Linux. If I make a change in a typical implementation file
and hit "run" in VC++ it takes 2 - 3 seconds before I'm up and running
in the program. This on a PIII/1000.

Of course it is several minutes if you change something in a
heavily-used header file.

-- Bruce

John Markus Bjorndalen

unread,
Dec 1, 2001, 11:10:30 PM12/1/01
to
Bruce Hoult <br...@hoult.org> writes:

> My current project is porting a 400k line C++ program from Windows to
> MacOS X and Linux. If I make a change in a typical implementation file
> and hit "run" in VC++ it takes 2 - 3 seconds before I'm up and running
> in the program. This on a PIII/1000.

Using precompiled header files I would assume :)

That's one of the things that the Windows C++ compilers seemed to
quickly have a need for (and thus implemented). A C++ file with just a
few of the standard "C-type" includes should compile quickly even
without precompiled header files. It seems like the number of lines in
your project has less to do with the compile time than the selection
of include files and frameworks you choose to use.

Precompiled header files is definitely an advantage at times, but I
suspect that it can be a bit difficult maintaining them in a
consistent way. It is not _that_ uncommon to experience different
results if header files are included in different orders in the source
files for instance.

What got me a little suspicious about the idea was that VC++ seemed to
mess up it's own precompiled header files a few years ago resulting in
mysterious behaviour in the executable files. The simple fix was to
remove everything the compiler had generated (simply doing 'rebuild
all' did not help) and recompile, but the bad part of it (apart from
the annoyance and wasted time) was that I didn't really trust the
compiler after that.

On the other hand, I haven't experienced this problem with the latest
service packs (not that I have used the compiler that much lately).



> Of course it is several minutes if you change something in a
> heavily-used header file.

Yes :-/

Alain Picard

unread,
Nov 30, 2001, 9:44:42 AM11/30/01
to
Kent M Pitman <pit...@world.std.com> writes:

> Is the reason that people focus so much on static type checking that it's
> so hard to get a program to RUN in those languages?

Yes.

It's also the reason those people have such a hard time with XPน:
They say "why write all those unit tests? The _compiler_ can do
all that checking for you!"

They miss the point that the unit tests check the _semantics_ of
the functions/data/arguments, whatever, which usually

a) makes you think about your function harder when you design the test
b) lets you check types, if that's relevant (e.g. if the method is
a CLOS method specialized on something, well, you don't need typechecking.
You'll get a "no such method" error.
c) It's not a lot harder to write a unit test and to get it to run in
a dynamic environment like CL or smalltalk than it is to fight the compiler
until it blesses your program. The test, however, remains forever, can
be refactored, used as documentation for the method, etc etc.

I've had this fight many, many times.

The other main reason people love static type checking is they somehow
think it makes their programs safer. (I kid you not). Core dumps obviously
don't count.

I conclude from this that a large part of the IT industry is in total denial.

น XP grew up in smalltalk

--
It would be difficult to construe Larry Wall, in article
this as a feature. <1995May29....@netlabs.com>

Jens Kilian

unread,
Dec 4, 2001, 2:28:43 PM12/4/01
to
Duane Rettig <du...@franz.com> writes:
> Don't forget also that you also have to set up your application's
> environment again, which was lost when you had to restart it. In
> a non-trivial application with lots of file accessing and cache building,
> this can be nontrivial.

The first "real" application I worked on had start-up times upwards of
30 minutes. Most of that was due to a user interface written in interpreted
Lisp.

Five minutes after starting, it would crash (in the C++ part ;-)

Things got better when we started compiling the Lisp code...
--
mailto:j...@acm.org phone:+49-7031-464-7698 (TELNET 778-7698)
http://www.bawue.de/~jjk/ fax:+49-7031-464-7351
PGP: 06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]

rem...@yahoo.com

unread,
Dec 10, 2001, 11:16:45 PM12/10/01
to
t...@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) wrote in message news:<xcvu1vn...@conquest.OCF.Berkeley.EDU>...
> ... I
> *really* just wanted to refute the idea that it was nuts to separate
> NIL and false.

Actually on first glance it's nuts to separate 0 and false.
For efficiency, we have INUMs whereby the number 0 is represented
by an actual machine value of 0, 1 by a machine value of 1, etc.
up to the machine maximum positive value in a register, and likewise
-1 is represented by machine -1, etc. down to the most-negative machine
value in a register. So small-integer arithmetic can be done simply
as machine arithmetic with check for overflow after each single
operation, no conversion to/from LISP representation except when the
result exceeds the machine contents-of-register range.
For similar efficiency reasons, false is represented by machine zero
in most programming languages. That way a test for false (and skip
or jump according to the result is a single instruction that references
only a single machine register before deciding what to do. By comparison,
if false is not a machine zero, then testing for false requires comparing
two different registers to see if they are identical, the register of
interest and some register allocated to hold the false value all the
time. (In LISP, the false value is the internal representation of a
pointer to the symbol called NIL in the COMMON-LISP package.) On many
CPUs, this requires two instructions, one to compare the two registers
and set flags, and a second to actually skip or jump depending on the flags,
and it ties up a register, and requires referencing that register too.
So on first glance false should be machine-zero which we already are
using for LISP-zero-number, so () and false and 0 should all be the same
LISP object, namely machine zero. So why make up a totally new symbol
NIL for the false value and for the empty list the way LISP does??

Strawman: Well, functions that return indices into sequences like to
return 0 if the result is the very first index and false if nothing
was found.

Rebuttal: Those very special class of functions can use a different
convention for nothing-found without stepping on everyone else's toes.
They can return -1 to indicate the index of nothing found. Or they can
use 1-origin indexing like most other languages. Everyone else can
use 0 to represent false or empty list, and programmers can be warned
of this special class of functions that use -1 instead of 0 for failure
result, just as we're already warned that FIRST means NTH 0 instead
of NTH 1 etc. Restrict the weirdness to just those very few functions
that can't deal with the usual rule of 0 = () = false, instead of
making all machine code in the whole language run slower by having
false not the same as machine 0.

Strawman: But then 0 would be a special case of an object that is both
a number and a list.

Rebuttal: But NIL is a special case of an object that is both a symbol
and a list, and furthermore it is not in the keyword package yet you
aren't allowed to change its value to be anything other than itself.
Furthermore T is also a special case, where you aren't allowed
to change its value even though it's not in the keyword package.
If 0 were the standard false and emptylist object, and 1 were the
standard true value, both would be constants because they are really
numbers rather than as special cases. It's actually a royal pain that
in mathematical software I can't set T to be a number the way I
can set X Y Z W U V and S to be numbers. Also with 0=false and 1=true
it would be just like Boolean algebra instead of another way to re-invent
the wheel with NIL and T.

Furthermore, if 0 instead of NIL were the emptylist and false value,
a list of empty lists would print as far fewer characters (0 0 0 0 0)
and be much easier to visually inspect for non-false elements, compared
to (NIL NIL NIL NIL MIL NIL NIL NIL) which has one non-false element
but can you spot it instantly?? And a list of boolean values would
print uniformly as for example (0 1 1 0 1 0) instead of (NIL T T NIL T NIL)
making it a lot easier to format them for display in tabular form.

Furthermore, NIL, a contraction of Latin nihil, isn't even a common
word in English much less a word at all in some other languages,
whereas 0 is recognized as zero in all modern Western languages
and even orientals recognize the Western zero digit even if they don't
like to use it outside computer systems.

Summary: There's nothing wrong with a single value representing both
false and the empty list or empty set, with all other values being
treated as "true" for most purposes, but having that single falise value
be the contraction-of-Latin NIL instead of the number 0 seems absurd,
and having that false and empty value NOT be machine zero is dopey too.
It's too late to change it, but it's something slightly unreasonable
we just gotta accept when learning LISP rather than something that is
basically reasonble and we actually like. NIL is like CAR and CDR, sigh.
(L and R would be better names for left and right side of dotted pair,
given that LISP is written in English anyway??)
(Yeah, I know the IBM 7090 history, sigh.)
(Bad idea: For non-English speakers, M and N would be easier to remember
than CAR and CDR or L and R. So instead of CADDAR we'd have MNNM.)

Coby Beck

unread,
Dec 10, 2001, 11:29:48 PM12/10/01
to

<rem...@Yahoo.Com> wrote in message
news:ffdf399b.01121...@posting.google.com...

> t...@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) wrote in message
news:<xcvu1vn...@conquest.OCF.Berkeley.EDU>...
> > ... I
> > *really* just wanted to refute the idea that it was nuts to separate
> > NIL and false.
>
> Actually on first glance it's nuts to separate 0 and false.

good thing a second glance is possible!

--
Coby
(remove #\space "coby . beck @ opentechgroup . com")


rem...@yahoo.com

unread,
Dec 11, 2001, 12:58:03 AM12/11/01
to
Kent M Pitman <pit...@world.std.com> wrote in message news:<sfw8zcy...@shell01.TheWorld.com>...
> The Scheme community then works to minimize the number of premises
> they work from, as if minimizing this one axis in what is obviously a
> multivariate system will yield a consequent minimization of the other
> axes by magic.

When you are first starting to learn something new, the fewer things
you must learn just to get started the easier it is to get started.
I'm not saying Scheme starts with the right stuff, see later...

> ... THat is, a language that has has
> all 64 crayola crayon colors as primitive concepts is at a marked
> advantage for describing a sunset over one that has only the primary
> colors plus the modifier words "saturated", "bright", "dark" and
> adverbials like "not" and "very".

Agreed, but for an absolute beginner it's easier to get started with
only the primary colors, then the concept of mixing them together,
and lastly the other modifiers, before you start the horrendous task
of memorizing al those other specialized color names. The trick is
to have a system where you can start with just the simple stuff then
grow from there until you have learned how to keep track of and use
a wide range of 'utilities' (things you can rely on, like electricity,
telephone, water, mapping between name and color in crayon box, etc.).

> Now, second, the Scheme community has another very unwarranted premise
> underlying a great deal of its teaching, and it overflows sometimes
> into design: that's that if they can find a simpler way to express
> things (using their simplicity metric: smaller language) that this
> will autmatically lead something to be easier to learn.

If you're learning something consistent, such as mathematics or
computer programming, it's nice when first starting to have a minimal
set of utilities you must learn and then to re-invent the wheel
a few times to get a feel for the expressive power of that minimal
language. For example, our Arabic number system whereby we must learn
the digits 0123456789 plus the rule for values from the right being
ten times as large, and later the decimal point with values to the
right being only one tenth as large, is relatively simple compared to
a system where each different size had a different name with no pattern
for linking them together, such as fluid-ounces cups pints quarts gallons
barrels etc.

To my mind, computer programming consists of making use of already
existing utilities (written by other people), putting usages of such
utilities in sequence (*) so that output from an early-used one can
then be taken as input by a later-used one, and collecting such sequences
together under a single name thereby creating your own utility to
adjoin to the set of available utilities. For absolute beginners,
it seems to me the best way to reduce these concepts to essentials
and make them patently obvious to the student, and simultaneously
minimize the amount that must be learned to get started, is to use
PROG (with labels and GO and RETURN), SETQ (or SETF), and DEFUN,
as the only primitives for putting together sequences. Show the student
how to make calls to existing utilities that do the sorts of things
you'd expect to be doable on a computer (making arithmetic calculations,
searching strings for specific characters or kinds of characters).
Show the student how to assign results to variables via SETQ so the
result doesn't get lost and you can call it back in later. Show the
student how to break a simple task into pieces each of which is doable
by Common LISP built-in utilities, which involves making several function
calls and doing SETQ of the result of each and re-using each (except
the last) in later function calls. Show the student how to make a
function (using DEFUN) containing a canned sequence (via PROG) of
function calls which has a name so you can do that sequence as many times
as necessary. Here's a simple task that would be suitable for such a
very first programming lesson: Find the first number within a string:
Call POSITION-IF to find the index of the first digit. Call POSITION-IF-NOT
to find the index of the end of those consecutive digits. Call SUBSTR
using the two previous results to extract just those digits. RETURN
that sub-string of digits. If the result is wanted as an actual LISP
number then insert a call to PARSE-INTEGER after the SUBSTR before
the RETURN. After that basic understanding of sequence of function calls
is understood, then the student is ready to learn all the "better" things
such as nested function calls, and the technique of program loops,
and then the "better" way of expressing many program loops via the
LOOP or MAP etc. utilities, and someday the "better" way of doing many
local variables via LET instead of PROG and SETQ..

* (Sequence as used here is more general than the linear sequences
which are a data type in Common LISP. It's more like a directed graph,
also known as a flowchart.)

In summary, I think simple function calls, SETQ, PROG, and DEFUN,
in that sequence, are a very tiny number of concepts to learn yet
are effective in teaching the essence of computer programming
as well as excite the student about many of the wondrous utilities that
are built into Common LISP already. Every other utility in CL can
be treated on an as-needed basis. Like if you're searching for stuff in
strings, then you learn some of the string utilities such as POSITION-IF,
while if you're making arithmetic calculations you learn some of the
arithmetic functions such as + and >=. This method makes LISP programming
easier than Web browsing where you must learn how to click on links,
how to back up to where you were before, how to scroll, how to
select various windows that might be hidden behind others, how to save
bookmarks, how to use bookmarks later, how to resize windows, and how to
use the various search engines for finding starting points for effective
browsing.

> ... I
> think people have a highly parallel associative mechanism capable of
> efficiently managing an enormous amount of special cases at the same
> time.

Eventually, but not right at the start when learning a new kind of task
such as foreign language or how to program computers.

> But to me, the issue of what makes a language easy/hard to use is the
> dissonance between the mental representation of the user and the
> manifest structure of the program.

I agree very much. That's why I like PROG as a starting point, because
I think of doing this first, then using that to do this next, etc.,
and PROG expresses that nicely. PROGN would work as well, except it
doesn't have a place to declare local variables, and it takes one more
character to type the name (minus three characrters for space and ()
for empty argument list, so that's not really an argument). The average
person knows that a cooking recipe is a sequence: Boil 6 cups water.
Stir in macaroni. Boil 7-10 minutes. Drain water. Return macaroni
to pan. Stir in margarine milk and cheese powder. It's implicit that
the boiling water is used as input for stiring macaroni, and that combo
is passed through boiling and used as input for draining, etc.
In computer programming you just make it explicit what outputs from
earlier steps go as inputs to later steps, which makes it actually easier
than cooking in some sense.

Later after the student has programmed a couple PROG GO loops, we can
show how a LOOP or MAPLIST better matches the overall concept of what we
are trying to accomplish. Then we can introduce even more powerful
utilities such as SET-DIFFERENCE which are very simple mathematically
conceptually yet nontrivial to manually code with PROG or LOOP or MAPLIST.
The great thing about LISP is we can start with just four primitives and
everything else as-needed, doing everything from those barebones primitives,
then gradually learn about already-existing utilities that do most of
the low-level work for us. We don't have to learn the whole thing just
to get started, and the starting set to learn is VERY VERY small yet
universal in power if we allow some basic utilities for any given
data type we choose to deal with at any given time.

> ... I'm not trying to argue CL
> is an utterly simple language to learn and use.

Well, I'm arguing that, in the sense you can start very very simple
then learn new parts of the language on an as-needed basis, and the
manual is nicely organized around data types so it's easy to look up
any built-in utility you need for any desired task, to see how much
is already available and how much you still need to program yourself
on top of the built-in utilities.

rem...@yahoo.com

unread,
Dec 11, 2001, 1:33:49 AM12/11/01
to
Bruce Hoult <br...@hoult.org> wrote in message news:<bruce-9A9045....@news.paradise.net.nz>...
> Here's what I don't get about CL confusing false and the empty list:
> suppose you have a function (foo name) that returns a list of all the
> classes being taken by a student. If the function returns NIL, does
> that mean that the student is taking no classes at the moment, or does
> it mean that the student doesn't exist?

I agree with your assumption that for synchronization with a dynamically
shared database you want a SINGLE function to call to check if the student
exists and if so then check his/her classes, rather than two different
function calls in a block of DISABLE-INTERRUPTS or FREEZE-THE-WORLD.
Let the synchronization be handled inside the service routine rather
than by each and every programmer attempting to call it.

Given that assumption, CL has several tools available to use, and it
is up to the programmer to decide which he/she prefers to use:
- Return two values, one of which says whether student exists or not,
and other value says list of classes (which is indeterminate or
meaningless if the student doesn't exist).
- Set up your own special token such as NOSUCH to indicate there's
no such student as opposed to a student that exists but isn't taking
any classes. (READ Stream EOFerrorP EOFvalue) is an example of a
built-in function that uses a strategy vaguely like this if EOFerrorP=NIL.
- Throw something to a catcher or signal a normal error if there is
no such student, like READ if EOFerrorP is non-null.
- Return a list that is one longer than the number of classes, where
the CAR is the student ID number and the CDR is the actual list of
classes, but if no such student then return NIL instead of list of one element.
* Remember, as programmer you get to choose which way to write your
database-lookup utility, and LISP provides sufficient primitives to make
it easy to do it any of several ways.

> It seems to me that *every* datatype deserves to potentially have a
> "don't know" or "doesn't exist" value. Like NULL in SQL.

Global symbols can be bound or unbound, where unbound is somewhat like your
"don't know" state. If you want to directly make use of that facility
for your application without making ugly side-effects, you can use GENSYM
or similar facility to make a new identifier then pass the name of that
to your database-lookup utility, which will either make that symbol unbound
or make it bound with the list of courses or count of courses, and
then the calling function can call BOUNDP first to see whether it's
bound or not. Unlike returning two values, by this method you can keep
that non-interned symbol around and link to it from several places at
once and thereby share both whether student exists and if so course info,
and furthermore you can attach other properties to that same uninterned
symbol as you proceed with processing that person's application for whatever
prompted you to search for his/her student record.

> ... or can be declared to be NOT NULL
> and this is an important distinction. In any complex program some code
> needs to be written to cope with NULL values, and some code wants to
> assume that there is always valid data.

Any place in your program you're not sure if you've already tested for
existance of the student, and you want to proceed with confidence the
student really does exist, you can test whatever convention you have
programmed for non-existance and if so then signal an ERROR. So if
you indeed have goofed somewhere, you'll get a nice clean message that
student doesn't exist when we assumed he did, instead of some obscure
message about attempt to take CDR of a non-list.

rem...@yahoo.com

unread,
Dec 11, 2001, 1:58:42 AM12/11/01
to
Frode Vatvedt Fjeld <fro...@acm.org> wrote in message news:<2hlmgy2...@dslab7.cs.uit.no>...
> To me that would be (at least in principle) a poorly specified
> function that performs two unrelated tasks: Checking whether a student
> exists and listing a student's current classes. Those should be
> separate functions, and calling the latter function on an unknown
> student would be an error (exceptional situation).

No no. Typically you don't want to have to shut down the whole University
every time this program is run, to prevent somebody else from running
a database update that installed a new student or removed an old student
or corrected a mis-typed name by removing the mistaken student while
adding the correctly-spelled named student. Scenerio:
(1) Your program asks does Mary Janf exist? Gets back YES.
(2) Somebody else corrects Mary Janf to be Mary Jane.
(3) Your program asks classes Mary Janf is taking, gets an error,
which is reported as a program bug.
So you want check-if-student-still-exists and get-class-list to be
sealed inside a single function call, so if you call first you get back
Mary Janf is taking these classes whereas if you call later you get nice
clean Mary Janf is not a student any more.

> If for some reason
> those two tasks must be smashed into a single function, good style
> would be to return two values from that function. It would also be
> possible to return a designated symbol like :no-such-student, although
> I'd consider that an inferior option, stylewise.

It's a pain to pass multiple values more than one level up in a program,
so if you're going to pass around these two facts you should either
use the exceptional value or make a list (or dotted pair) of two elements
or use some other way to keep the two results together on a single object.
However it would be reasonable for the database-lookup utility to return two
values, then the application program to encapsulate them into a list or
other single-object representation for passing around within the application.

> > It seems to me that *every* datatype deserves to potentially have a
> > "don't know" or "doesn't exist" value.

> I disagree.

The point is moot since you can always use a general (undeclared)
data type which can be any LISP data type whatsoever at any time, so
in particular you can have one data type for valid results and another
datatype for "don't know" or "no such", and there's not a lot of overhead
in checking which of those two datatypes a return result is before
proceeding with the rest of processing the return result.
(let ((res (student-classes name)))
(if (success res) (print-schedule name res) (throw 'dbfail 'no-student)))
where success is a predicate that checks whether the returned result datatype
was valid or nosuch according to whatever your convention is, or
alternately with multiple returned values you would do:
(multiple-value-bind (existp classes) (student-classes name)
(if existp (print-schedule name classes) (throw 'dbfail 'no-student)))
Caveat, I haven't tested either of those code snippits, so beware of typos.

rem...@yahoo.com

unread,
Dec 11, 2001, 3:22:48 AM12/11/01
to
"Pierre R. Mai" <pm...@acm.org> wrote in message news:<87r8qq8...@orion.bln.pmsf.de>...
> > Quite possibly, though an exception is a pretty heavy-weight mechanism.
> > You might also want to delay the exception until the client code
> > actually tries to use the value inappropriately.
>
> Why would that be an appropriate thing to do? This seems like the C
> philosophy of doing error-checking: "Never report errors at the place
> where they actually occurred (calling a function that is specified to
> take the name of an existing student with something else), but delay
> it as long as necessary to destroy all relevant context; make it
> maximally inconvenient to check for error situations; and above all
> else, rather crash maximally fast, or produce wrong results, than
> throwing away one instruction on detecting errors".

I agree, and repeated your excellent rebuke of that idea for emphasis.
In general, an exceptional condition should be detected as soon as
possible and immediately diagnosed as to whether the rest of the program
can meaningfully continue under such circumstances, and if not then
a nice clean error should be reported somehow, and if proceedable then
the exception should be cleanly noted and handled specically in the
rest of the program. For example if ten people try to drop courses,
and only nine are legitimate students, the other being a typo, or a
prankster, it should report the one non-student but proceed to handle
the other nine normally.

> Furthermore why care about the cost of exceptions in such a situation?
> Unless your program is buggy as hell (i.e. calls foo with non-student
> names all of the time, in-spite of foo's specification), that is. If
> it is important to differentiate between non-students and students
> with no courses, _you don't call foo with an unchecked name_. Period.

I totally disagree. Think *distributed/shared*database*. Think concurrent
processes over a localnet. Think one part of Registrar's office handling
adding and deleting students and fixing typos in admission records, while
another part handles less drastic actions such as adding/removing courses,
and users completely outside the Registrar's office can do non-modifying
queries such as just listing the current courses in a report to the student's
academic supervisor. The application we are discussing is clearly of this
kind where a database record might disappear or be change out from under
a running program that has already checked that it exists, so EVERY
database query must allow for the possibility the desired record ceased
to exist since the last time we checked just a few microseconds ago.
Every time you make a call to the database-query utility, the utility must
check *again* to be sure the desired record still exists. It's not
acceptable to lock the whole database, or even lock one record, just
because some graduate student is debugging a utility to improve generation
of reports of student classes, while the Registrar is desperately trying
to delete a misspelled student record so that billing (due in less than
one hour) can run correctly. Better have the unimportant program merely
fail in a strange way (record which existed when we asked if it existed,
and again when we got student's name, and again when we got list of courses,
and again when we looked up the first three out of five courses for
details, suddenly ceased to exist) which the programmer can then check and
see indeed somebody has finally fixed that spelling error so we have to
re-start the debug run to proceed from this point.

> You write instead:
>
> (defun bar (some-random-name)
> (cond
> ((student-p name)
;;Registrar's program deleted that student at this inopportune moment.
> (let ((courses (foo name)))
;;This program crashes and burns somewhere around now...
> ;; Do something silly here...
> ))
> (t
> ;; Do something differently silly here...
> )))
>
> The only thing that a non-nil "NULL" value would give you here, is the
> ability to write instead
>
> (defun bar (some-random-name)
;;If registrar deleted record about here, then ...
> (let ((courses-or-student-status (foo name)))
> (cond
;;... program will get a nice clean detection of that fact here ...
> ((not courses-or-student-status)
> ;; Do something differently silly here...
;;... and a nice clean fail-soft action there was not at all silly.
> )
> (t
> ;; Do something silly with courses-or-student-status here, but
> ;; we now know it actually is a list, not some overloaded
> ;; other return value-type...
;;And if the Registrar deletes the record anywhere inside that code,
;; then there's yet another chance for fail-soft inside there if we
;; check for record-not-exist every time we call the db-query utility.
> ))))
>
> And that's the point where I'm thanking the powers that were, that we
> don't see this kind of code all over the place. FOO should never have
> been specified like this in the first place, if there really is a
> difference between non-students and students with no courses. What
> would be a descriptive name for foo? STUDENT-COURSES-AND-STUDENT-P?

There most definitely is a difference. If it's a student not taking
any courses, the student can always take one more course, just like
Alice and the teaparty, whereas if not a student then taking a course
is forbidden. Very important difference to any college!

We don't need a weird name like that. (READ Stream NIL EOFvalue)
normally just reads from a stream, but if it can't read because EOF
has already been reached then it returns the EOFvalue. Likewise,
(OPEN ... :IF-DOES-NOT-EXIST NIL) normally just opens the file,
but silently returns NIL if there's no such file to open, and we just
call that function OPEN rather than a weird name. Perhaps the database
query utility could likewise have keyword arguments for that to do
under various unusual situations (database doesn't exist, record doesn't
exist because there's no such studeht, record exists but forwards
to another record because a typo has been fixed), with defaults perhaps
being to signal an error in each unusual case where normal function
can't proceed. (STUDENT-COURSE &keyword :IF-SERVER-DOES-NOT-RESPOND
:IF-DATABASE-DOES-NOT-EXIST :IF-DATABASE-LOCKED :IF-RECORD-DOES-NOT-EXIST
:IF-RECORD-FORWARDS :IF-RECORD-LOCKED :IF-MACHINE-ERROR)

> > > It would also be possible to return a designated symbol like
> > > :no-such-student, although I'd consider that an inferior option,
> > > stylewise.
> >

> > I think that's a reasonable thing to do, and also that "false" is a
> > pretty good designated symbol to use.
>
> Well you can already do this. You just have to write
>
> (eq courses-or-student-status #f)

Better would be to define a predicate for testing that status, so
at compile/build time you can get told if you mis-typed it so are trying
to call a function that isn't in the build rather than a runtime strangness
that the upper-case F being passed back by the utility somehow is never
caught by this one place in the program even though it's caught everywhere
else. (if (db-result-valid-p courses) somethingUsual somethingElse)
This is especially useful if there are more than one kind of failure,
such as record temporarily locked vs. record doesn't exist at all.
The predicate can catch all those various exceptional conditions with
one TRUE result, or NIL result for a normal db return, then in the case
of exceptional condition somebody else can diagnose what to do in each
of the various cases.
(defun db-result-valid-p (dbresult)
(cond ((listp dbresult) t)
((member dbresult '(:locked :missing :crash)) nil)
(t (error "Unexpected return value from db query ~S" dbresult))))

> instead of
>
> (not courses-or-student-status)

Even in that case I might like to encapsulate the conventions in use:
(defun db-result-valid-p (dbresult)
(listp dbresult))
(defun db-result-record-numer (dbresult)
(car dbresult))
(defun db-result-course-list (dbresult)
(cdr dbresult))
;;Return value NIL means no such record or other problem accessing record,
;; otherwise return value is (recordNumber . listOfCourses)
(defun db-get-course-list (studentName)
... (return nil) ... (return nil) ... (return nil) ...
... (return (cons recnum courses)) ...)

> Not that I would consider code that did this to be well written code.
> It actively encourages the same kind of lossage you get in C, where we
> have all of those "failure" indicating values, that you have to
> manually check, and if you don't (who does), work very nicely to
> increase the time between error occurrance and error detection.

Good point. My solution with keyword arguments that specify if anything
other than signalling an error is to be done in case of trouble
would seem to be best. If the progammer is lazy, he/she gets a nice
clean error signaled from inside the database query utility, otherwise
presumably the programmer matched unusual return values specified by
those keyword arguments against code to check for those particular
return values. The specification of the keyword arguments in the call
are immediately before the place where the returned result is checked
for unusual cases, so it's pretty difficult to overlook a mismatch
where the keywords are supplied but no check for unusual return value
is done at all or explicit check for cases isn't same as possible cases
specified by keywords.

> Regardless of any (eq 'NIL '()) issue, I can't see any justifiable
> reason (senseless obsession about speed isn't one), for a function
> student-courses that returns anything but a list (or other collection
> datastructure).

See discussion of concurrent processes on local net accessing shared DB above.

> I'm even critical of a multiple-value version that _additionally_
> indicates whether we're really talking about a student. But in cases
> where this is justified, that additional value doesn't say "the
> primary value is valid or not". The primary value is always valid,
> and has the normal meaning.

Presumably the program leading into this db query will assure that
the data is syntactically valid, such as student's name must be
a string, or a list of four strings (first last middle Mr/Mrs/Ms),
but it might not be semantically valid (name of current student)
even if it was a moment ago so we must check for that every time.

rem...@yahoo.com

unread,
Dec 11, 2001, 4:26:53 AM12/11/01
to
Kent M Pitman <pit...@world.std.com> wrote in message news:<sfwr8qq...@shell01.TheWorld.com>...
> ... or look at the
> opposite outcome in the utterly stupid Base64 MIME encoding, which requires
> 65(!) characters to correctly represent it, so never really compacts up
> quite right.

Long ago, mid-late 1970's, I figured out a solution to this, long before
MIME ever was invented, to wit a reasonable syntax for strings that
doesn't need special escape characters within the string nor one extra
character outside the character-space to delimit strings. (Anybody
remember MRPP3 also known as POX on SU-AI = sail.stanford.edu ? This
was to be in the next MRPPn incarnation but I never got around to it.)
It works like this: You have two sets of pairs of nesting characters:
Assymtric ones like () [] {} <>
Symmetric ones like "" '' !! ||
A string segment is an open nesting character followed by any sequence
of characters not containing either opening or closing nesting character
followed by close nesting character. For example [foo!!(((baz] is a
string segment that has eleven characters. A string is any number of
string segments side by side with nothing intervening. So if you want
to include a whole bunch of characters which happened to include EVERY
one of the possible nesting characters, you merely need to break it up
into segments such that each segment consistently avoids whatever nesting
characters are used around it. For example, here's one possible way to
write the list of nesting pair with spaces between them:
"() [] {} <>"[ "" '' !! ||]
PRINT would of course try to minimize the number of segments with which
to express any given string, preferring to use a single segment bounded
by "" whenever none of the internal characters is " just as it does in CL now.
Note that this way of expressing strings avoids both the MIME problem
of needing an extra character that itself cannot be included inside
a string, and the Common LISP problem where any string that has lots
of " marks within it is very ugly, such as "\"\"\"\"\"\"\"\"\"\"" which
prints to more than twice the length of the actual string, as you see.
CL has a similar problem with names of symbols that contain special
characters, which could have been handled by an almost identical syntax.

Note, I would reserve () for lists, but probably use most/all the other
nesting pairs to delimit string segments. (In LISP you can't use ''
because ' already is a prefix read-macro for (quote ...), but in my
proposed super-POX that wouldn't have been a problem.) So why couldn't
MIME have come up with something like that?? (For that matter, why didn't
CL come up with something like that either??)

Ian Wild

unread,
Dec 11, 2001, 8:32:57 AM12/11/01
to
rem...@Yahoo.Com wrote:
>
> For similar efficiency reasons, false is represented by machine zero
> in most programming languages.

This is simply not true. *Most* programming languages are
quite concerned with providing a layer of abstraction between
the programmer and the raw bit patterns.

Ola Rinta-Koski

unread,
Dec 11, 2001, 9:46:58 AM12/11/01
to
rem...@Yahoo.Com writes:
> (1) Your program asks does Mary Janf exist? Gets back YES.
> (2) Somebody else corrects Mary Janf to be Mary Jane.
> (3) Your program asks classes Mary Janf is taking, gets an error,
> which is reported as a program bug.

The above behaviour would not be acceptable from a real-life
application, hence none (that I know of) work that way. The way this
would work is
1) Your program asks: "Does Mary Janf exist?" Gets back YES and Mary
Janf's student ID number XXX.
2) As above.
3) Your program asks classes student number XXX is taking, gets back
a list of classes. No error.
--
Ola Rinta-Koski o...@cyberell.com
Cyberell Oy +358 41 467 2502
Rauhankatu 8 C, FIN-00170 Helsinki, FINLAND www.cyberell.com

Kent M Pitman

unread,
Dec 11, 2001, 1:30:11 PM12/11/01
to
rem...@Yahoo.Com writes:

> t...@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) wrote in message news:<xcvu1vn...@conquest.OCF.Berkeley.EDU>...
> > ... I
> > *really* just wanted to refute the idea that it was nuts to separate
> > NIL and false.
>
> Actually on first glance it's nuts to separate 0 and false.

Absent compatibility and tradition constraints, I'm pretty sure it
would work fine to use 0 as the false value.

> It's too late to change it, but it's something slightly unreasonable
> we just gotta accept when learning LISP rather than something that is
> basically reasonble and we actually like. NIL is like CAR and CDR, sigh.

More or less I agree with this.

> (L and R would be better names for left and right side of dotted pair,
> given that LISP is written in English anyway??)

Indeed. People often wanted to replace CAR/CDR with FIRST/REST but it
never quite takes because people like CADR, etc. I've sometimes
suggested that LHS and RHS would compose better. (LRHS, for example,
could replace CADR. Of course, I'm about 10,000 times better at
telling car from cdr than I am at telling left from right. Even as I
wrote this example I wrote RLHS, not out of a transcription error but
because I was misremembering that Right is not the, er, leftmost
element. Sigh. Some human errors die hard. So something else more
critical might be lost if we moved to Right/Left distinctions... or
maybe I'd finally in my old age learn to tell right from left because
the distinction would become important enough to matter. Even when
driving, which I seem to reliably do right, having someone point
rather than say "turn right", helps a lot more...) But beyond all
that, CAR/CDR do have a lot of tradition there, and violating that
tradition has a cost.

Pierre R. Mai

unread,
Dec 11, 2001, 9:04:54 PM12/11/01
to
rem...@Yahoo.COm writes:

> > Furthermore why care about the cost of exceptions in such a situation?
> > Unless your program is buggy as hell (i.e. calls foo with non-student
> > names all of the time, in-spite of foo's specification), that is. If
> > it is important to differentiate between non-students and students
> > with no courses, _you don't call foo with an unchecked name_. Period.
>
> I totally disagree. Think *distributed/shared*database*. Think concurrent

The moment I think that, I also think competent programmers, which
know about transaction processing, etc. Cramming lots of
functionality into functions in the mistaken belief that this will
solve such problems is totally silly.

> academic supervisor. The application we are discussing is clearly of this
> kind where a database record might disappear or be change out from under
> a running program that has already checked that it exists, so EVERY
> database query must allow for the possibility the desired record ceased
> to exist since the last time we checked just a few microseconds ago.

No! You want ACID transactions.

> Every time you make a call to the database-query utility, the utility must
> check *again* to be sure the desired record still exists. It's not
> acceptable to lock the whole database, or even lock one record, just
> because some graduate student is debugging a utility to improve generation
> of reports of student classes, while the Registrar is desperately trying
> to delete a misspelled student record so that billing (due in less than
> one hour) can run correctly. Better have the unimportant program merely

Anyone who debugs programs on a live production database deserves
whatever they get. Anyone who lets graduate students near his
production databases deserves it doubly so.

If you need a plain old RDBMS, buy one, don't try to fake one using
"pseudo-atomic" function calls. Or if you really have to reinvent the
wheel, then do it properly, and provide a transaction processing
facility. Don't just try to dodge issues like read/read consistency,
read/write consistency, ...

> There most definitely is a difference. If it's a student not taking
> any courses, the student can always take one more course, just like
> Alice and the teaparty, whereas if not a student then taking a course
> is forbidden. Very important difference to any college!

And that's why it is a bad idea cramming them into the same function.
You want

(with-transaction (:isolation-level :repeatable-read :read-only-p t)
(unless (student-p name)
(error "~A is not an active student"))
(format T "Report on courses taken by ~A (Valid on: ~A):~2%"
name (current-date-string))
(dolist (course (student-courses name))
(format T "~7,'0D ~A~%" (course-id course) (course-name course))))

[ This ignores the problem that you wouldn't use a persons name as a
primary key ]

> We don't need a weird name like that. (READ Stream NIL EOFvalue)
> normally just reads from a stream, but if it can't read because EOF
> has already been reached then it returns the EOFvalue. Likewise,

That is because reaching EOF on a stream can be part of normal
operation (every file is finite). Trying to get courses of
non-students just isn't part of normal operations, it is a clear
indication that something is amiss.

> Presumably the program leading into this db query will assure that
> the data is syntactically valid, such as student's name must be
> a string, or a list of four strings (first last middle Mr/Mrs/Ms),
> but it might not be semantically valid (name of current student)
> even if it was a moment ago so we must check for that every time.

Checking things every time not only doesn't solve your consistency
problems, it will also be horrendously slow in distributed systems.

Regs, Pierre.

--
Pierre R. Mai <pm...@acm.org> http://www.pmsf.de/pmai/
The most likely way for the world to be destroyed, most experts agree,
is by accident. That's where we come in; we're computer professionals.
We cause accidents. -- Nathaniel Borenstein

Pierre R. Mai

unread,
Dec 11, 2001, 8:42:07 PM12/11/01
to
rem...@Yahoo.Com writes:

> Frode Vatvedt Fjeld <fro...@acm.org> wrote in message news:<2hlmgy2...@dslab7.cs.uit.no>...
> > To me that would be (at least in principle) a poorly specified
> > function that performs two unrelated tasks: Checking whether a student
> > exists and listing a student's current classes. Those should be
> > separate functions, and calling the latter function on an unknown
> > student would be an error (exceptional situation).
>
> No no. Typically you don't want to have to shut down the whole University
> every time this program is run, to prevent somebody else from running
> a database update that installed a new student or removed an old student
> or corrected a mis-typed name by removing the mistaken student while
> adding the correctly-spelled named student. Scenerio:

If you have a database, then you'd better have a useful transaction
mechanism. Cramming stuff into one function in the misguided belief
that this will magically solve your locking and transaction problems
is not the way to go.

If you are going to have true concurrent accesses, you will have to
lock the database data-structures, regardless, just in order to ensure
consistency of those data-structures. CL implementations don't
generally guarantee the atomicity of either function calls or things
like gethash/(setf gethash)...

Brian P Templeton

unread,
Dec 23, 2001, 1:13:03 AM12/23/01
to
Andreas Bogk <and...@andreas.org> writes:

[...]
> The price tag is probably reason #1. OpenGenera is still $5000 (if
> anybody of you has a license of OpenGenera lying around that he could
> lend, donate or sell cheaply to a student of Lisp and its history,
> I'd be very happy).
>
You can get a LispM for $600 from Symbolics, IIRC.

[...]

--
BPT <b...@tunes.org> /"\ ASCII Ribbon Campaign
backronym for Linux: \ / No HTML or RTF in mail
Linux Is Not Unix X No MS-Word in mail
Meme plague ;) ---------> / \ Respect Open Standards

Brian P Templeton

unread,
Dec 23, 2001, 1:13:08 AM12/23/01
to
"Pierre R. Mai" <pm...@acm.org> writes:

> Bruce Hoult <br...@hoult.org> writes:
>
[...]
>> I'll just note that as a matter of usage, it's common in Dylan programs
>> to create a custom boolean type using, say, one-of(#"FOO", #"NOT-FOO")
>> -- i.e. type-union(singleton(#"FOO"), singleton(#"NOT-FOO")). It's a
>> little more typing than using #t and #f but more self-documenting and
>> the efficiency is actually identical, since the <boolean> type is
>> defined as one-of(#f, #t) so it's all pointer comparisons anyway. And
>> packed data structures can represent one type-union of two symbols in a
>> single bit just as easily as they can represent any other type-union of
>> two symbols.
>
> Unless I missed something the types so created are not boolean types,
> but rather "binary" types, in that you can't use the usual falseness
> tests on them. That said, using keywords instead of nil and t is a
> possible approach in CL, too, although I'd only use it if there was a
> better keyword for the non-foo situation than :not-foo. Otherwise I'd
> use :foo and nil.
>
I'd use :foo and (not :foo). (IIRC, that suggestion was originally
from some Emacs Lisp programming style suggestions in Jari Aalto's
Tiny Tools package.)

Andreas Bogk

unread,
Dec 23, 2001, 1:35:23 AM12/23/01
to
Brian P Templeton <b...@tunes.org> writes:

> > The price tag is probably reason #1. OpenGenera is still $5000 (if
> > anybody of you has a license of OpenGenera lying around that he could
> > lend, donate or sell cheaply to a student of Lisp and its history,
> > I'd be very happy).
> You can get a LispM for $600 from Symbolics, IIRC.

That's the price for a MacIvory II, right. I'll probably buy one of
these once my Paypal account is active. I just hoped to get away
cheaper than that (a friend of mine has an old Alpha he's not using,
and it's got *way* more RAM than the MacIvory).

Anyways, for any serious work, one would want to run Open Genera on a
modern Alpha.

Andreas

--
"In my eyes it is never a crime to steal knowledge. It is a good
theft. The pirate of knowledge is a good pirate."
(Michel Serres)

Julian St.

unread,
Dec 24, 2001, 12:03:57 PM12/24/01
to
Brian P Templeton <b...@tunes.org> writes:


[...]

> You can get a LispM for $600 from Symbolics, IIRC.

[...]

Is there a free emulator around just to get the look&feel of a lisp
machine?

Regards,
Julian Stecklina

Kent M Pitman

unread,
Dec 24, 2001, 10:36:17 PM12/24/01
to
boel...@gmx.net (Julian St.) writes:

> Brian P Templeton <b...@tunes.org> writes:
>
>
> [...]
>
> > You can get a LispM for $600 from Symbolics, IIRC.
>
> [...]
>
> Is there a free emulator around just to get the look&feel of a lisp
> machine?

The original Symbolics is out of business but another has taken its place
and is just barely eeking by. It SELLS the emulator. Please do not
begrudge them that limited income stream.

israel r t

unread,
Dec 24, 2001, 11:12:24 PM12/24/01
to
On Mon, 24 Dec 2001 22:36:17 GMT, Kent M Pitman <pit...@world.std.com>
wrote:

>The original Symbolics is out of business but another has taken its place
>and is just barely eeking by. It SELLS the emulator. Please do not
>begrudge them that limited income stream.

from http://stony-brook.scrc.symbolics.com/www/index.html

" One of the old Symbolics' last products was a port of this
environment to the Compaq/DEC Alpha workstation, called "Open Genera
1.0".

Open Genera 2.0 is available from Symbolics Technology, Inc. It
includes software formerly sold as separate products (Statice, Joshua,
Concordia, Fortran, C, Pascal) and runs under Compaq/Digital Tru64
Unix on Compaq/DEC Alpha workstations. "

Kalman Reti is the bloke to contact at either re...@symbolics.com or at
re...@ai.mit.edu


Thomas F. Burdick

unread,
Dec 25, 2001, 7:37:51 PM12/25/01
to
Kent M Pitman <pit...@world.std.com> writes:

I doubt it's a grudge, but more of a wish. It's reasonable for a
tiny, barely surviving company to not give away free or cheap demos,
but $600 is a lot to drop for something you've heard highly
reccomended, but have no experience with yourself.

One thing you *can* fault Symbolics for is that crappy, useless web
site. Unless you already know the answer, it doesn't provide any
information. A simple summary of their products would probably answer
that question for most people, as opposed to leaving them confused and
wondering.

Once again, no MacIvory for chiristmas (nuts) :-)

--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'

Kenny Tilton

unread,
Dec 25, 2001, 10:54:55 PM12/25/01
to

"Thomas F. Burdick" wrote:
>
> One thing you *can* fault Symbolics for is that crappy, useless web
> site.

Amen, I went over there half inclined to plop for one but damned if I
could figure out what I was looking at it.

So what do they have? LispM on a board? I have a couple of Macs
gathering dust, is macIvory a good way to go? I'll try again on Google,
but clues are welcome.

Also, what is supposed to be so great about the LispM? Performance?
Development tools?

thx,

kenny
clinisys

Paolo Amoroso

unread,
Dec 26, 2001, 12:56:11 PM12/26/01
to
On Tue, 25 Dec 2001 22:54:55 GMT, Kenny Tilton <kti...@nyc.rr.com> wrote:

> "Thomas F. Burdick" wrote:
> >
> > One thing you *can* fault Symbolics for is that crappy, useless web
> > site.
>
> Amen, I went over there half inclined to plop for one but damned if I
> could figure out what I was looking at it.

You may try this site:

A few things I know about LISP Machines
http://fare.tunes.org/LispM.html


Paolo
--
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://web.mclink.it/amoroso/ency/README
[http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/]

Barry Margolin

unread,
Dec 26, 2001, 3:39:20 PM12/26/01
to
In article <xcvbsgn...@conquest.OCF.Berkeley.EDU>,

Thomas F. Burdick <t...@conquest.OCF.Berkeley.EDU> wrote:
>I doubt it's a grudge, but more of a wish. It's reasonable for a
>tiny, barely surviving company to not give away free or cheap demos,
>but $600 is a lot to drop for something you've heard highly
>reccomended, but have no experience with yourself.

You get an awful lot of stuff for that $600. You start with an operating
system far better than just about anything else available (it blows Windows
and Unix out of the water -- MacOS is the only popular OS that even
approaches it in elegance). You get compilers for 4 programming languages
(Lisp, C, Pascal, Fortran). You get an Object-Oriented Database System
(Statice) and an AI subtrate (Joshua). And you get a hypertext
documentation system that predated the WWW by 5 years.

All for twice the price of Microsoft Word.

--
Barry Margolin, bar...@genuity.net
Genuity, Woburn, 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.

Brian P Templeton

unread,
Jan 4, 2002, 12:59:03 AM1/4/02
to
Kenny Tilton <kti...@nyc.rr.com> writes:

> "Thomas F. Burdick" wrote:
>>
>> One thing you *can* fault Symbolics for is that crappy, useless web
>> site.
>
> Amen, I went over there half inclined to plop for one but damned if I
> could figure out what I was looking at it.
>
> So what do they have? LispM on a board? I have a couple of Macs
> gathering dust, is macIvory a good way to go? I'll try again on Google,
> but clues are welcome.
>

I'm planning to get a Symbolics 3600 LispM. They're $600 US; as Tril
<tr...@tunes.org> put it, ``cheaper per pound than a good hamburger''.
I don't know how much MacIvory costs. As Paolo mentioned, Farè's WWW
page about LispMs is an excellent source of information.

> Also, what is supposed to be so great about the LispM? Performance?
> Development tools?
>

The performance is not too good compared to newer machines. However,
many Lisp programmers who are familiar with them think that they are,
overall, the best available system, despite the mediocre performance.
(However, the emulator for Alpha machines and possibly MacIvory
probably have much better performance.)

> thx,
>
> kenny
> clinisys

hth,

Brian P Templeton

unread,
Jan 4, 2002, 12:59:07 AM1/4/02
to
Andreas Bogk <and...@andreas.org> writes:

> Brian P Templeton <b...@tunes.org> writes:
>
>> > The price tag is probably reason #1. OpenGenera is still $5000 (if
>> > anybody of you has a license of OpenGenera lying around that he could
>> > lend, donate or sell cheaply to a student of Lisp and its history,
>> > I'd be very happy).
>> You can get a LispM for $600 from Symbolics, IIRC.
>
> That's the price for a MacIvory II, right. I'll probably buy one of
> these once my Paypal account is active. I just hoped to get away
> cheaper than that (a friend of mine has an old Alpha he's not using,
> and it's got *way* more RAM than the MacIvory).
>

Are you sure? IIRC, that's the price for a Symbolics 3600 LispM.

> Anyways, for any serious work, one would want to run Open Genera on a
> modern Alpha.
>
> Andreas
>
> --
> "In my eyes it is never a crime to steal knowledge. It is a good
> theft. The pirate of knowledge is a good pirate."
> (Michel Serres)

--

Raymond Wiker

unread,
Jan 4, 2002, 8:06:18 AM1/4/02
to
Brian P Templeton <b...@tunes.org> writes:

> Andreas Bogk <and...@andreas.org> writes:
>
> > Brian P Templeton <b...@tunes.org> writes:
> >
> >> > The price tag is probably reason #1. OpenGenera is still $5000 (if
> >> > anybody of you has a license of OpenGenera lying around that he could
> >> > lend, donate or sell cheaply to a student of Lisp and its history,
> >> > I'd be very happy).
> >> You can get a LispM for $600 from Symbolics, IIRC.
> >
> > That's the price for a MacIvory II, right. I'll probably buy one of
> > these once my Paypal account is active. I just hoped to get away
> > cheaper than that (a friend of mine has an old Alpha he's not using,
> > and it's got *way* more RAM than the MacIvory).
> >
> Are you sure? IIRC, that's the price for a Symbolics 3600 LispM.

It's also the price of a MacIvory II (or was, when I got mine,
a year ago). You may want to budget for more memory (in case the
default is now 16MB), and possibly also a Symbolics keyboard & mouse.

--
Raymond Wiker Mail: Raymon...@fast.no
Senior Software Engineer Web: http://www.fast.no/
Fast Search & Transfer ASA Phone: +47 23 01 11 60
P.O. Box 1677 Vika Fax: +47 35 54 87 99
NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60

Try FAST Search: http://alltheweb.com/

rem...@yahoo.com

unread,
Jan 7, 2002, 3:08:38 AM1/7/02
to
"Pierre R. Mai" <pm...@acm.org> wrote in message news:<87k7vts...@orion.bln.pmsf.de>...

> If you have a database, then you'd better have a useful transaction
> mechanism.

I agree. Furthermore it is NOT right for each workstation to directly
update pointers in the database. Rather there should be a database
server which accepts requests for information and/or updates, performs
the lookups and/or modifications, and returns a report of what realy
happened. For a counselor/advisor inquiring whether a given student
is taking such and such class, or asking what classes that student
is taking, this would typically be a SINGLE transaction, in English:
Requesting info about Mary Jones, list of classes. The return could
be any of:
- Not a registered student.
- Registered studnet, but not taking any classes currently.
- Registered student, and taking Math 103, English 101, Drams 107 ...
For registration wanting to correct a reeported mistake, this
would be two transactions, first the above, then a second which
makes the correction:
- For student number 3426786 or for Mary Jones, etc.
change second course from English 101 to English 102.
The report that comes back could be any of:
- No such student.
- Course 2 was not English 101, it was Drama 107
- Succssful update, course 2 is now English 102.
The workstation, whether it be the registrar, the President of the
University, or some random adademic advisor, never touches the database
directly, merely talks to the database server, rather like a Web server,
just a different syntax and semantics for selecting records and fields
within fields etc. (Actually an actual Web server could in theory handle
such a taski, and doing so isn't totally unreasonable.)

> Cramming stuff into one function in the misguided belief
> that this will magically solve your locking and transaction problems
> is not the way to go.

I disagree. Splitting the verification of existance of a record
from the actual update to that record, so it takes two transactions
instead of just one, in a distributed environment where the record might
cease to exist at any time (except in the middle of a single transaction
when the database server is dedicated to finishing that particular
transaction before starting another), and treating such ceasing of
existance of the record between the two calls as a fatal error requiring
reprogramming, is plain dumb. Students aren't deleted from their registration
every day, but during the first few weeks of classes both deletion of
registration (because the cheque for paying some student fee bounced,
or the student didn't show up for class, or the student was involved
in crime and banished from campus) is a *normal* thing that happens
from time to time and ought to be considered when designing the program,
and ought to be handled gracefully without having to shut down the
whole database system to fix a "bug". It isn't a bug. But a progarm that
checks for the record then updates the record in a separate transaction
*is* a poorly written program.

> If you are going to have true concurrent accesses, you will have to
> lock the database data-structures, regardless, just in order to ensure
> consistency of those data-structures.

Locking the whole database during the service of a single transaction
is reasonable. Breaking it up into two separate transactions and
locking the database during the entire time between the two transactions
is unreasonable. Checking the existance of the record, and reading
what's in it, should be a single transaction, not two separate
transactions. Likewise checking the existance and verifying the old
data is what needs to be changed and changing it to a new value should
be a single transaction not two or three.

> CL implementations don't
> generally guarantee the atomicity of either function calls or things
> like gethash/(setf gethash)...

That's no problem if the overall system is designed properly:
On the server end, a SINGLE program that fields service requests
and processes them one at a time, finishing each request (successfully
or not) before starting another.
To deal with the problem of some client starting to make a request then
taking a very long time to finish it, the server can READ but not yet
execute multiple incoming connections, and whichever finishes first
is moved to the queue for actual processing.
On the user side, any number of clients that have varying levels of
access priviledges for asking the server to do things, either just
read data or read and modify data. The program can be interrupted as
many times as happen during accepting input from a user, validating
that input, forming a service request to send to the server, and
transmitting that service request to the server. Then when the
service response comes back, that client program can again spend as
much time as it wants and be interrupted as many times as happens,
before it's finished presenting the results to the user for study.
To keep the server software simple, the database server should have
it's own special socket for queries, and listen on that socket itself,
rather than using the standard WebServer method of having a system program
start up a new copy of the server for each new connection. But a standard
WebServer like that *can* be used if it's programmed carefully: Each
clone of the WebServer application should have a unique ID, such as
the Unix process-ID (PID), and use that ID to make unique filenames that
aren't going to be stepped on by any other process, and then the main
database server can merely watch for the appearance of new files written
by those cloned WebServer applications, talk with those clones one by one,
and dismiss each such clone *after* all temporary files have been cleaned
up for that particular clone, so that there's no race condition with
a new clone happening to get the same PID as some old clone whose files
are not yet cleaned up.
Summary: I see no problem caused by CL in developing such a distributed
system, providing it's done the way I suggesed, a single service request
(transaction) for both check-if-record-exists and if-so-then-do-something-
with-it together.

Andreas Bogk

unread,
Jan 9, 2002, 5:23:41 AM1/9/02
to
Brian P Templeton <b...@tunes.org> writes:

> >> You can get a LispM for $600 from Symbolics, IIRC.
> > That's the price for a MacIvory II, right. I'll probably buy one of

> Are you sure? IIRC, that's the price for a Symbolics 3600 LispM.

I am sure (having just bought one), and you don't want a 3600 (they
are bulky, and support no modern disks) if you can get a MacIvory for
the same price.

Of course, for $600 you don't get the Mac you need to run the board,
but you can get one on ebay. A MacIvory with a Mac around it is $1200
from Symbolics.

0 new messages