From: Ken Tilton
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <3357A898.7D93@bway.net>
Graham Matthews wrote:
> 
> Will Duquette wrote:
> > You'll notice that I've made no arguments about Tcl as a *language*.
> > Pragmatically speaking, though, it enables me to get my job done
> > easily, efficiently, and well.
> 
> At last a sensible attitude about Tcl. No unjustified claims to
> superiority, just pragmattics.
> 
> graham
> --
>                   You can blow out a candle
>                 But you can't blow out a fire
>                 Once the flame begins to catch
>                  The wind will blow it higher

Pragmatics have no place in a theological debate or language flame war.
They might blow out the fire. <g>

Seriously, offtimes DCL (the VMS shell language) let's me get my job
done. So what? It is not nor does it pretend to be a good language.
We're comparing languages, so I suggest we fight to the death over (or
until we agree upon) The One Best Language for Everything <g>.

I suggest Lisp. Any counter-offers must include full dynamism,
introspection, procedural macros, lexically-scoped closures and generic
functions and must not include static typing. You know, Lisp. <g>

Peace, love and simplicity,

   Ken

From: James Logajan
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <jameslE8uvL5.Kt9@netcom.com>
Ken Tilton (····@bway.net) wrote:
: Pragmatics have no place in a theological debate or language flame war.
: They might blow out the fire. <g>
...
: We're comparing languages, so I suggest we fight to the death over (or
: until we agree upon) The One Best Language for Everything <g>.
...
: I suggest Lisp. Any counter-offers must include full dynamism,
: introspection, procedural macros, lexically-scoped closures and generic
: functions and must not include static typing. You know, Lisp. <g>

I represent a rabble of one that takes no prisoners! Counterthrust:
where the bleep is human-factors in this never-ending thread? Anybody
care to actually reference what little research has been done in this
area?

I couldn't help but notice that the Ousterhout white paper had only one
reference to one measly result of human factors research; and it came
from a secondary source. I believe that ALL the designers of ALL the languages
this thread is cross-posted to (and many that aren't) didn't even attempt
to study software psychology (or psycholinguistics).

NOTE TO LISP AND FORTH FANS: one important reason your languages
have never caught on may be due to the fact that many natural languages
follow the "subject verb object" form. Usage of SOV, OSV, VSO, and VOS
are less likely (I don't have any references in front of me; if anybody
wants details, I'll try to locate what I have). They also lack visual
redundancy (they aren't alone in this short-coming of course).
From: Erik Naggum
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <3070400361379585@naggum.no>
* James Logajan
| NOTE TO LISP AND FORTH FANS: one important reason your languages have
| never caught on may be due to the fact that many natural languages follow
| the "subject verb object" form.  Usage of SOV, OSV, VSO, and VOS are less
| likely (I don't have any references in front of me; if anybody wants
| details, I'll try to locate what I have).  They also lack visual
| redundancy (they aren't alone in this short-coming of course).

I hope you find studies of human factors with _experienced_ users.  the
results coming from the ever-present inexperienced users has no validity
for more than inexperienced users, yet get touted as truths about the
languages.  this tends to annoy people who believe that "experience" is a
valid concept in any discipline.

for some reason, we don't see open heart surgery defamed by "research" into
how inexperienced users with a scalpel and an attitude kill people and that
it should therefore be a discommended practice.

many a Lisp programmer will testify that he thinks in Lisp and reads Lisp
code with _less_ "stack depth" and "cognitive load" than is needed for the
many other languages he knows.  e.g., I find C to be _much_ harder to read
than Lisp because I need to scan forward in hairy expressions a lot to know
how things work together, and to scan backwards for type information.  I
also have to work to remember operator precedence rules in the language.
in Lisp, I may have to scan back and upwards, but I've already been there
when I'm reading the code.  in C++, I need to keep in mind the classes of
all the variables so I can have a glimmer of hope of understanding _which_
function is being called.  the foo in x.foo is not the foo in y.foo, unless
the class of x and the class of y relate such that they are.  in CLOS, (foo
x) and (foo y) is the same generic function with different specializers and
a Lisp programmer is _much_ less likely to implement widely different
semantics with the same name than is a C++ programmer who is "alone" in his
class (hierarchy).

there should be a measure of "mental clutter" that each language leaves
with its (moderate to excellent) programmers.

somebody should tell those Subject-Verb-Object guys from the wrong
department that it is quite uncommon to nest sentences and expressions the
way it is done in programming languages, lest this invalid argument should
keep coming back from the argument grave yard yet again.  for some reason,
C/C++ programmers can't handle very deep nesting, while Lisp people can.
my take on this is that C/C++ already "use up" quite a number of "stack
levels" with its complex syntax, while Lisp does not, and can use those
"stack levels" for real work.

back in high school, I was reprimanded by my teachers for using too long
sentences and too complex sentence structure.  (my editors have said the
same.)  I found the rules they laid down for me to follow to be extremely
crippling in expressive power.  write short sentences.  use only simple
conjunctions.  don't use the passive voice.  the active voice helps
"involve" people.  this all gives me the creeps.  subject verb object.  I
just don't think that way.  I think of my sentences as evaluation of nested
expressions that yield intermediate values used by other parts of the
sentence and which conclude in communicating some meaning.  the paragraph
is similarly constructed to carry those sentence-values forward into a
concluding sentence.  this process _precludes_ the use of stunted forms and
the imperative, active style for me.  then again, I don't write children's
books or "Crotch Sniffing for Dummies".

and last time I checked, I was still human, despite all this bogus research
into human factors that pretends I and people like me don't exist.

#\Erik
-- 
I'm no longer young enough to know everything.
From: Paul Wilson
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <5ja35t$ntn@roar.cs.utexas.edu>
In article <················@netcom.com>,
James Logajan <······@netcom.com> wrote:
>Ken Tilton (····@bway.net) wrote:
>: Pragmatics have no place in a theological debate or language flame war.
>: They might blow out the fire. <g>

There is a difference between theories and theology, though either is often
easy to mistake for the other.

>: We're comparing languages, so I suggest we fight to the death over (or
>: until we agree upon) The One Best Language for Everything <g>.

I don't think many poeple here believe there is One Best Language for
Everything.  There are, however, languages that are good for more things
than others.  (Say Pascal vs. Modula-2, to pick a similar-but-different
pair.)

>: I suggest Lisp. Any counter-offers must include full dynamism,
>: introspection, procedural macros, lexically-scoped closures and generic
>: functions and must not include static typing. You know, Lisp. <g>

I like all of those features myself, but let's not get greedy.  :-)
(And by the way, generic functions are not part of Lisp per se, they're
part of Common Lisp with CLOS and some other languages that adopted
the idea, including some OOP languages.)

I suggest talking about which features are crucial and work well
together, so we can swipe the best features of various languages
and combine them into a coherent whole, rather than just kludging
scripting languages together.

There's too much of a religious/propagandistic tendency for people
to either say "A tool for each job", or to say "one tool for every
job," rather than talking about "a handy combination of a few
tools."  This just leads to misunderstanding and flame wars.
I for one, have never said that Scheme is the ideal scripting
language.  I know it's not. However, I do think some of the core
ideas of Scheme are very useful and would work well in that
setting.  I also think something like Self might be a good
start, and it's a very different language.

I also think that Tcl has some good stuff in it.  What I'm trying to
figure out is which features are due to simple lack of knowledge
of the alternatives, and which say something fairly deep about
how a scripting language should be designed.

>I represent a rabble of one that takes no prisoners! Counterthrust:
>where the bleep is human-factors in this never-ending thread? Anybody
>care to actually reference what little research has been done in this
>area?

Not the research I know about.  It's mostly baby-stuff because the
main issues are hard to conduct good, controlled experiments about.
(The results about how many characters of indenting are more readable
come to mind as some of the *better* research, though the studies weren't
thorough enough in several ways.   Beyond that, you tend to get
experiments that *seem* to say something basic, but it's not clear how
to apply it to the richer context of real programming in real languages,
or stuff that's so simplistic it's more likely wrong than right.
Counterexamples very welcome.) 

>I couldn't help but notice that the Ousterhout white paper had only one
>reference to one measly result of human factors research; and it came
>from a secondary source. I believe that ALL the designers of ALL the languages
>this thread is cross-posted to (and many that aren't) didn't even attempt
>to study software psychology (or psycholinguistics).

I don't know if that's true of the designers of the popular languages.
I know it's not true of all of the readers of this thread.  (I for one,
worked in HCI for a while, and studied psychology, some linguistics, and
philosophy of psychology in grad school.  Of course, that doesn't make 
me any kind of authority, though.)

I'm just saying that some of us are aware of some of the research, but it
tends to be hard to interpret for a realistic context.  Little studies
tend to be wildly unrealistic and test absolute beginners' skills, and
big ones tend to be hard to interpret because there are too many
uncontrolled variables.  For this stuff to be done well, there should
be lots of studies at various granularities, which will inevitably
support quite a few conflicting conclusions.  Only then will people
get a better idea of which questions to ask, to show *why* some
things turn out one way, and other work out in other wasy.  That's the
way work in psychology tends to go, because it's an intrinsically
difficult, multi-leveled subject.

>NOTE TO LISP AND FORTH FANS: one important reason your languages
>have never caught on may be due to the fact that many natural languages
>follow the "subject verb object" form. Usage of SOV, OSV, VSO, and VOS
>are less likely (I don't have any references in front of me; if anybody
>wants details, I'll try to locate what I have). 

I think this is mostly a red herring, but maybe not entirely.  First,
different natural languages tend to vary wildly in the orderings
of terms.  Consider French and Spanish postfix adjectives vs.
English prefix adjectives.  Which is better?  Hard to say.  And look
at basic sentence structure in English.  Often we force things into
our "normal" syntax when it makes no particular semantic sense, and
end up with funny constructions that confuse non-native speakers.

With respect to SVO structure, I think there's a good argument that
VSO is more natural for English speakers because in programming
languages we're often writing imperative sentences, e.g.,
"Put [ the ] cat [ on the ] mat" is more familiar than
"Cat put [yourself] on [the mat}".

The latter makes some sense in Smalltalk, where it's assumed there's
a privileged receiver of the message, and that we really are telling
the cat to put itself on the mat.  But some things don't fall
gracefully into that framework, which is why some OO languages now
have generic functions (or multimethods, which is essentially the
OOP term for the same thing).  Often method selection depends
on more than one argument, because the "sentence" has more than one
"object".  (If your language doesn't support that concept, you may
have to kludge it.)

The difference isn't usually crucial, because putting the action
(or function name) first often tips you off to facts about the
arguments.  e.g., if I say add(a,b) or (in Lisp syntax)
(+ a b), once you see the operator you can guess that the operands
are things it makes sense to add.

A major difference between computer 
>They also lack visual
>redundancy (they aren't alone in this short-coming of course).

I think this problem is largely due to bad teaching. (Especially
in programming language courses where neither the teacher nor
the writer of the textbook understands Lisp/Scheme style.)  The
visual redundancy in Lisp and Scheme comes largely from the indenting,
so you really have to teach/learn good indenting to be able to
read the code visually.  Indenting is important anyway, in
any language, so it should be taught regardless, but it's
crucial in Lisp/Scheme, so learners need to know the rules
and know what they signify.

On the other hand, I do allow that Lisp and Scheme have
fewer visual irregularities than other languages.  I'd like
to point out, though, that this is largely a choice by
Lispers and Schemers.  You could build a language based on
Lisp/Scheme technology with a more conventional syntax,
and more redundant keywords.  For example, it's trivial
to redefine if so that instead of writing

     (if (< a b)
         a
         b)

you could write

     (if (< a b)
         a
      else
         b)

Note that in Scheme we don't have to write returns, because everything's
an expression.  We don't have to use returns to return a value.  So
where in a C-influenced language like Java or Tcl we might write
something like

     proc min(a, b)
     {
        if (a < b)
           return a;
        else
           return b;
     }

In Scheme we'd write

     (define (min a b)
        (if (< a b)
            a
            b))

If you wanted a more conventional syntax, you could add infix
operators as well as extra keywords, and make it look pretty much 
like C or Tcl.  (If we really want terseness, we can use a C-like
ternary operator instead of if.  In a Scheme-like language if
works just like the ternary operator AND if, because everything
is an expression that returns a value, but which may have side 
effects.) 

Common Lisp and many Schemes also have keyword arguments, too, as
was shown earlier in this thread by translating Ousterhout's
Tcl/Tk example into Common Lisp.  So if you want more redundancy
and terseness within a basically Lisp-like framework, you can
easily get it.

By slapping a conventional-syntax parser on Scheme, and changing 
a few keywords, you can get a version of Scheme with a syntax like
this:

    proc min(a, b)
    {
       if (a < b)
       then a;
       else b;
    }

or this:

    proc min(a, b)
      (a < b) ? a : b;

depending on how much of a terseness fanatic you are.

-- 
| Paul R. Wilson, Comp. Sci. Dept., U of Texas @ Austin (······@cs.utexas.edu)
| Papers on memory allocators, garbage collection, memory hierarchies,
| persistence and  Scheme interpreters and compilers available via ftp from 
| ftp.cs.utexas.edu, in pub/garbage (or http://www.cs.utexas.edu/users/wilson/)      
From: John Ousterhout
Subject: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jbcvl$puh@engnews2.Eng.Sun.COM>
One of the most common criticisms of my white paper has been that the
distinction between scripting and system programming is artificial, and
that it is possible for a single language to be good at both tasks.
Lisp-like languages such as Scheme were suggested as living proof.  I
can't prove that it's impossible for a single language to be good at
both scripting and system programming, but I don't know of a good example
and I doubt that it will ever happen.  The reason for this is the
difference in typing, as I explained in the white paper. A given language
embodies a particular style of typing, which can range from very strongly
typed to totally untyped.  Once that decision has been made, the language's
position on the spectrum between system programming and scripting is set.
I think it's possible to have a language that's in the middle, but it's
not likely to be terrific at either task.

Let's take Lisp as an example.  I think that Lisp falls somewhere
between scripting and system programming.  Many of you have suggested that
it is an ideal language for both system programming and scripting, but I
think that it isn't really very good for either.  In fact I suspect that
this may be why Lisp hasn't been used much for practical programming.
Lisp isn't a good system programming language because it's too hard to
write efficient programs in it and it doesn't provide good low-level
access to machine facilities.  On the other hand, Lisp isn't good for
scripting either.  In order to be a good scripting language, you need
to be able to interoperate with lots of other things, which are often
written in other languages (the best glues are those that stick to lots
of different materials).  But Lisp has never been very good at this.
For example, it's hard to include C code with Lisp because they have
very different data types and memory models.  Lisp systems are typically
closed: you have to live entirely in the Lisp world.  Good scripting
languages are open and friendly: they talk to and work with everything.

Just to short-circuit the discussion that will ensue...

I'm sure that many of you will argue against these claims ("my new
version of Scheme is just as fast as C", "Lisp just needs a new garbage
collector that embodies the latest techniques", "I know someone who
combined C with Scheme and had no problems at all", etc.).  However,
I've seen a fair amount of evidence on this and the problems far
outnumber the success stories.  Many of the best minds in Computer
Science have worked on Lisp over the last 30 years, and they haven't
been able to fix the language so that it could be widely used either
for system programming or scripting tasks.  This says to me that there
is something fundamentally wrong with the language, at least for these
tasks.

By the way, I think that Lisp is a fascinating language with neat
mathematical properties.  It's great for a variety of meta-programming
tasks where you're experimenting with new programming paradigms, such as AI
and language theory.  It just isn't good for system programming or scripting.
This reinforces my claim that you should use different tools for different
tasks.  This is also why I didn't mention Lisp in the paper.  The things I
discussed in the white paper aren't the things that Lisp was designed for
or that it does best, so it isn't really fair to compare Lisp along those
dimensions.
From: Erik Naggum
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <3070479470939233@naggum.no>
* John Ousterhout
| The reason for this is the difference in typing, as I explained in the
| white paper.  A given language embodies a particular style of typing,
| which can range from very strongly typed to totally untyped.

I get the impression that John Ousterhout does not understand what "dynamic
typing" means.  "untyped" is recurring in his articles and his paper.
apparently, the concept that an object has type information, not the
variable that holds it, is hard to grasp for many programmers in the C
tradition.  yet, unions with type tags are common.  now, of course, a C
programmer would shudder at the very idea of using a union with a type tag,
so let's just say that this is well optimized in Lisp implementations,
often with support from the hardware.  (yes, CPU's _do_ have instructions
that C compilers don't use.)

| Let's take Lisp as an example.  I think that Lisp falls somewhere between
| scripting and system programming.  Many of you have suggested that it is
| an ideal language for both system programming and scripting, but I think
| that it isn't really very good for either.  In fact I suspect that this
| may be why Lisp hasn't been used much for practical programming.

there are many reasons why Lisp has not become popular.  they have all been
hashed out quite extensively over the years.  yours is totally new.  it is
safe to say that with the criticism presented to you that your distinction
between scripting and systems programming language is artificial, the fact
that you're the first to find this reason for Lisp's lack of use is
actually an argument _against_ your (artificial) distinction.  or proof of
incredibly sloppy thinking on your part.  perhaps both.

| Lisp isn't a good system programming language because it's too hard to
| write efficient programs in it and it doesn't provide good low-level
| access to machine facilities.

I have criticized the use of "Lisp per se" in comp.lang.lisp, as it seems
that "Lisp" means some sort of proto-Lisp to many people, including you.
since there is no such language, any discussion of Lisp that fails to be
precise in which Lisp it discusses is literally devoid of meaning.  that
you draw wide-ranging conclusions about an unspecific language is perhaps
significant, perhaps not.  in either case, it is disconcerting that you
don't bother to be specific.

| For example, it's hard to include C code with Lisp because they have very
| different data types and memory models.

this is getting quite amusing...

| Just to short-circuit the discussion that will ensue...
| 
| I'm sure that many of you will argue against these claims ("my new
| version of Scheme is just as fast as C", "Lisp just needs a new garbage
| collector that embodies the latest techniques", "I know someone who
| combined C with Scheme and had no problems at all", etc.).

this is the most ignorant nonsense I have ever seen anyone who pretends to
be serious has ever written!  if this is the best John Ousterhout can do
when he researches something, there's no _wonder_ Tcl is the way it is!

have you even _seen_ a Common Lisp compiler, John Ousterhout?

| However, I've seen a fair amount of evidence on this and the problems far
| outnumber the success stories.

why should anyone trust you on that?

| Many of the best minds in Computer Science have worked on Lisp over the
| last 30 years, and they haven't been able to fix the language so that it
| could be widely used either for system programming or scripting tasks.
| This says to me that there is something fundamentally wrong with the
| language, at least for these tasks.

the saddest, but still quite amusing, part of this ranting is that you rely
on the reader's acceptance of "widely used" to justify your arguments, yet
have made no distinction between, e.g., Bill Gates' beloved BASIC and Tcl.
Tcl is clearly a phenomenal failure compared to BASIC.  how can you have
the _gall_ to argue that Tcl is widely used and that Lisp is not if you
don't even consider "widely used" relative to their "markets"?

| By the way, I think that Lisp is a fascinating language with neat
| mathematical properties.  It's great for a variety of meta-programming
| tasks where you're experimenting with new programming paradigms, such as
| AI and language theory.  It just isn't good for system programming or
| scripting.  This reinforces my claim that you should use different tools
| for different tasks.  This is also why I didn't mention Lisp in the
| paper.  The things I discussed in the white paper aren't the things that
| Lisp was designed for or that it does best, so it isn't really fair to
| compare Lisp along those dimensions.

again, why should anyone trust your judgment on this?  you are clearly
unable to recognize the simple fact that you don't know Lisp in practice
well enough to pass judgment on it.  yet you make a big stink about
evidence and lots of important words that carry no _precise_ meaning.

ANSI Common Lisp, and even Common Lisp the Language, 2nd edition, specify a
language that is, in practice, _routinely_ compiled to code as fast as C,
often faster because Common Lisp programmers use better algorithms and have
more time to optimize where it is needed than C programmers.

it's _tragic_ to see that John Ousterhout is this affected by myths and
general ignorance, and doesn't even know he's out on a limb.

after what I have read from John Ousterhout, I have reached the sad
conclusion that he is intellectually dishonest and does not know when he no
longer has sufficient information to state a conclusion and when he must be
humble enough to request more information before he can do so.  a highly
acclaimed academic should not be _able_ to lose this ability just because
he's working for a company.

Richard Gabriel's "worse is better" may even apply to people in some ways.

#\Erik
-- 
I'm no longer young enough to know everything.
From: Paul Wilson
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jc0dt$rqv@roar.cs.utexas.edu>
In article <················@naggum.no>, Erik Naggum  <····@naggum.no> wrote:
>
>| Lisp isn't a good system programming language because it's too hard to
>| write efficient programs in it and it doesn't provide good low-level
>| access to machine facilities.
>
>I have criticized the use of "Lisp per se" in comp.lang.lisp, as it seems
>that "Lisp" means some sort of proto-Lisp to many people, including you.
>since there is no such language, any discussion of Lisp that fails to be
>precise in which Lisp it discusses is literally devoid of meaning.  that
>you draw wide-ranging conclusions about an unspecific language is perhaps
>significant, perhaps not.  in either case, it is disconcerting that you
>don't bother to be specific.

Sorry about the "Lisp per se" thing---I started that.  I was trying
to make things clearer.  The point I was making was that Common Lisp
gets a very bad rap for being "too big", "not interoperable" and
what have you.  (Of course Common Lisp doesn't look so big anymore
now that we have C++.)  Often people say that Lisp is this and Lisp is
that, when they really mean Common Lisp if they know what they're talking
about at all.

I was just making the point that a Lisp doesn't have to be big.  (For
example, standard Scheme.)  So if you're designing a language of your
own, as Ousterhout did, you don't have to take the whole package
of Common Lisp.  You can also make it interoperate Tcl-style, if you
want to.

People often err the other direction, too.  The most recent versions
of several language textbooks propagate misinformation like "Lisp only
has one data type" (which was never true) and "Lisp is dynamically scoped"
(which hasn't been true for a while) and "garbage collection is disruptive"
(which needn't be true if you get the right kind of GC) and "Lisp is a
special-purpose language for AI."  I've even run into a person who bashed 
Lisp both ways---saying it's bloated and slow, and only has one datatype!)

So to clarify what I mean by "Lisp per se", it's something like

     A simple and powerful language with

         1. dynamic typing (it is not really "untyped"--exactly the 
            opposite, because every value has a definite type),
         2. lexical scope by default
         3. higher-order procedures that are closures, 
         4. the ability to define new constructs in terms
            of old ones, via programmer-specified transformation 
            (macros, which are far more powerful than macros in
            most other languages),
         5. some handy data types, notably pairs (cons cells)
            and symbols (uniquified strings), and 
         6. (typically) support for interactive execution
            with an interpreter, or a compiler that compiles
            expressions and runs the code immediately.
         7. side-effects (i.e., assignments) are available.

     No one of these features is essential, but this is the general
     area of design space.

    #2 deserves some explanation.  The original Lisp was dynamically
       scoped, but that was an accident.  (McCarthy said it was just
       "a bug", and that Lisp should have been lexically scoped, as
       most Lisps are now, including Scheme, Common Lisp, and EuLisp.)
       As originally intended, most modern Lisps are lexically scoped,
       just like the Algol descendents (Pascal, Modula, Simula, C)
       and the Lambda calculus.  (Lexical scope is more useful in Lisps
       because procedures are closures.)

-- 
| Paul R. Wilson, Comp. Sci. Dept., U of Texas @ Austin (······@cs.utexas.edu)
| Papers on memory allocators, garbage collection, memory hierarchies,
| persistence and  Scheme interpreters and compilers available via ftp from 
| ftp.cs.utexas.edu, in pub/garbage (or http://www.cs.utexas.edu/users/wilson/)      
From: M. Prasad
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335B7CE0.7564@not4u.polaroid.com>
Erik Naggum wrote:
[snip]
> I get the impression that John Ousterhout does not understand what "dynamic typing" means.
[snip] 
> this is getting quite amusing...
[snip]
> this is the most ignorant nonsense I have ever seen anyone who pretends to
> be serious has ever written!  if this is the best John Ousterhout can do
> when he researches something, there's no _wonder_ Tcl is the way it is!
> 
> have you even _seen_ a Common Lisp compiler, John Ousterhout?

How about you stop giving Lisp a bad name with these
tactics of yours?  It gives the impression that
Lisp is only used by fanatics.

(I suggest that other people who do not want to see
this impression continue, should join in an attempt
to squelch this highly errant behavior...)

> again, why should anyone trust your judgment on this?  you are clearly
> unable to recognize the simple fact that you don't know Lisp in practice
> well enough to pass judgment on it.  yet you make a big stink about

Never stopped *you* from making comments about Lisp, now, did it?
From: Erik Naggum
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <3070479482046228@naggum.no>
* John Ousterhout
| The reason for this is the difference in typing, as I explained in the
| white paper.  A given language embodies a particular style of typing,
| which can range from very strongly typed to totally untyped.

I get the impression that John Ousterhout does not understand what "dynamic
typing" means.  "untyped" is recurring in his articles and his paper.
apparently, the concept that an object has type information, not the
variable that holds it, is hard to grasp for many programmers in the C
tradition.  yet, unions with type tags are common.  now, of course, a C
programmer would shudder at the very idea of using a union with a type tag,
so let's just say that this is well optimized in Lisp implementations,
often with support from the hardware.  (yes, CPU's _do_ have instructions
that C compilers don't use.)

| Let's take Lisp as an example.  I think that Lisp falls somewhere between
| scripting and system programming.  Many of you have suggested that it is
| an ideal language for both system programming and scripting, but I think
| that it isn't really very good for either.  In fact I suspect that this
| may be why Lisp hasn't been used much for practical programming.

there are many reasons why Lisp has not become popular.  they have all been
hashed out quite extensively over the years.  yours is totally new.  it is
safe to say that with the criticism presented to you that your distinction
between scripting and systems programming language is artificial, the fact
that you're the first to find this reason for Lisp's lack of use is
actually an argument _against_ your (artificial) distinction.  or proof of
incredibly sloppy thinking on your part.  perhaps both.

| Lisp isn't a good system programming language because it's too hard to
| write efficient programs in it and it doesn't provide good low-level
| access to machine facilities.

I have criticized the use of "Lisp per se" in comp.lang.lisp, as it seems
that "Lisp" means some sort of proto-Lisp to many people, including you.
since there is no such language, any discussion of Lisp that fails to be
precise in which Lisp it discusses is literally devoid of meaning.  that
you draw wide-ranging conclusions about an unspecific language is perhaps
significant, perhaps not.  in either case, it is disconcerting that you
don't bother to be specific.

| For example, it's hard to include C code with Lisp because they have very
| different data types and memory models.

this is getting quite amusing...

| Just to short-circuit the discussion that will ensue...
| 
| I'm sure that many of you will argue against these claims ("my new
| version of Scheme is just as fast as C", "Lisp just needs a new garbage
| collector that embodies the latest techniques", "I know someone who
| combined C with Scheme and had no problems at all", etc.).

this is the most ignorant nonsense I have ever seen anyone who pretends to
be serious has ever written!  if this is the best John Ousterhout can do
when he researches something, there's no _wonder_ Tcl is the way it is!

have you even _seen_ a Common Lisp compiler, John Ousterhout?

| However, I've seen a fair amount of evidence on this and the problems far
| outnumber the success stories.

why should anyone trust you on that?

| Many of the best minds in Computer Science have worked on Lisp over the
| last 30 years, and they haven't been able to fix the language so that it
| could be widely used either for system programming or scripting tasks.
| This says to me that there is something fundamentally wrong with the
| language, at least for these tasks.

the saddest, but still quite amusing, part of this ranting is that you rely
on the reader's acceptance of "widely used" to justify your arguments, yet
have made no distinction between, e.g., Bill Gates' beloved BASIC and Tcl.
Tcl is clearly a phenomenal failure compared to BASIC.  how can you have
the _gall_ to argue that Tcl is widely used and that Lisp is not if you
don't even consider "widely used" relative to their "markets"?

| By the way, I think that Lisp is a fascinating language with neat
| mathematical properties.  It's great for a variety of meta-programming
| tasks where you're experimenting with new programming paradigms, such as
| AI and language theory.  It just isn't good for system programming or
| scripting.  This reinforces my claim that you should use different tools
| for different tasks.  This is also why I didn't mention Lisp in the
| paper.  The things I discussed in the white paper aren't the things that
| Lisp was designed for or that it does best, so it isn't really fair to
| compare Lisp along those dimensions.

again, why should anyone trust your judgment on this?  you are clearly
unable to recognize the simple fact that you don't know Lisp in practice
well enough to pass judgment on it.  yet you make a big stink about
evidence and lots of important words that carry no _precise_ meaning.

ANSI Common Lisp, and even Common Lisp the Language, 2nd edition, specify a
language that is, in practice, _routinely_ compiled to code as fast as C,
often faster because Common Lisp programmers use better algorithms and have
more time to optimize where it is needed than C programmers.

it's _tragic_ to see that John Ousterhout is this affected by myths and
general ignorance, and doesn't even know he's out on a limb.

after what I have read from John Ousterhout, I have reached the sad
conclusion that he is intellectually dishonest and does not know when he no
longer has sufficient information to state a conclusion and when he must be
humble enough to request more information before he can do so.  a highly
acclaimed academic should not be _able_ to lose this ability just because
he's working for a company.

Richard Gabriel's "worse is better" may even apply to people in some ways.

#\Erik
-- 
I'm no longer young enough to know everything.
From: Donal K. Fellows
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jl4ga$cr7@m1.cs.man.ac.uk>
In article <················@naggum.no>, Erik Naggum  <····@naggum.no> wrote:
> * John Ousterhout
>> The reason for this is the difference in typing, as I explained in the
>> white paper.  A given language embodies a particular style of typing,
>> which can range from very strongly typed to totally untyped.
> 
> I get the impression that John Ousterhout does not understand what "dynamic
> typing" means.  "untyped" is recurring in his articles and his paper.
> apparently, the concept that an object has type information, not the
> variable that holds it, is hard to grasp for many programmers in the C
> tradition.  yet, unions with type tags are common.  now, of course, a C
> programmer would shudder at the very idea of using a union with a type tag,
> so let's just say that this is well optimized in Lisp implementations,
> often with support from the hardware.  (yes, CPU's _do_ have instructions
> that C compilers don't use.)

I take it you don't work in computer hardware design, and haven't even
looked at the field for at least 10 or 15 years, since that last
statement is plain wrong.  Maybe Vaxes had a "Reverse Bit Shift, Cast
to Type and Catch Fire if the Programmer is Stupid" instruction (with
mnemonic RBSCTCFPS :^) but technology is substantially advanced since
then.  RISC CPU's have only the instructions that are measured as
being needed in practice, and virtually all new designs are RISC (with
the notable distiction of the ix86 line of processors). In future, try
to check your facts, and especially those that have been contradicted
by people (with good reason) for loads of years...

Donal.
--
Donal K. Fellows   http://r8h.cs.man.ac.uk:8000/  (SAY NO TO COMMERCIAL SPAMS!)
(work) ········@cs.man.ac.uk     Dept. Comp. Sci, Univ. Manchester, U.K.
 |     ·····@ugglan.demon.co.uk  6,Randall Place, Heaton, Bradford, U.K. (home)
 +-> ++44-161-275-6137  Send correspondence to my office  ++44-1274-401017 <-+
From: Erik Naggum
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <3070804442620792@naggum.no>
* Erik Naggum
| (yes, CPU's _do_ have instructions that C compilers don't use.)
 
* Donal K. Fellows
| I take it you don't work in computer hardware design, and haven't even
| looked at the field for at least 10 or 15 years, since that last
| statement is plain wrong.  Maybe Vaxes had a "Reverse Bit Shift, Cast
| to Type and Catch Fire if the Programmer is Stupid" instruction (with
| mnemonic RBSCTCFPS :^) but technology is substantially advanced since
| then.  RISC CPU's have only the instructions that are measured as
| being needed in practice, and virtually all new designs are RISC (with
| the notable distiction of the ix86 line of processors). In future, try
| to check your facts, and especially those that have been contradicted
| by people (with good reason) for loads of years...

geez.

the SPARC architecture has several instructions that C compilers doesn't
use, but which are convenient with type-tagged languages.  the _fact_ is
that it has an the instruction, with Sun's recommended mnemonic "taddcctv",
that is specifically useful in Lisp, and specifically unused in C.  other
instructions are also measurably useful in languages _other_ than C.

C is _not_ the be-all, end-all of programming languages and C is _not_ the
universal assembler that some would like it to be.  that you cannot even
put this instruction to use without a lot of prior work that you also have
a hard time doing in C, shows that the SPARC designers thought of more than
increasingly myopic C crowd.

actually, I find it rather astonishing to learn that some people are so
belligerently ignorant as to believe they can pull off a stunt like the
above from D. K. Fellows.

but to demonstrate the point with a real-life example, take the following
(silly) function, compiled by Allegro Common Lisp for Unix on a SPARC:

(defun foo (x y) (declare (fixnum x y)) (+ x y))

   0:	cmp	%g3, #x2
   4:	tne	%g0, #x13
   8:	taddcctv	%g0, %g1, %g0
  12:	sra	%o0, #x2, %o0
  16:	sra	%o1, #x2, %o1
  20:	add	%o0, %o1, %o0
  24:	ld	[%g4 + 135], %g2	; fixnum-or-bignum
  28:	jmp	%g2 + 0
  32:	xor	%g0, #x1, %g3

the intelligent reader will recognize that this function sports a few
features not commonly found in C compiler output: the number of incoming
arguments is in a register, there are traps to handle error conditions, and
it concludes with a jump to a function instead of a call and return.  (no
programmer knowledgeable of pipelines RISCs will wonder why the jmp occurs
before the argument count is stored into %g3.)

I welcome suggestions on how to accomplish the _exact equivalent code_ from
C source code.  if this cannot be done, could Donal K. Fellows then accept
that some CPU's (1) do have instructions that C compilers don't use, and
(2) that he shot his mouth off?  I assume both, so let's return to our
regular program.

#\Erik
-- 
Bastard Sex Therapist from Hell: "Read the F*cking Manual!"
From: David Hanley
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335E61AE.3F53@nospan.netright.com>
Erik Naggum wrote:
> 
> * Erik Naggum
> | (yes, CPU's _do_ have instructions that C compilers don't use.)
> 
> * Donal K. Fellows
> | I take it you don't work in computer hardware design, and haven't even
> | looked at the field for at least 10 or 15 years, since that last
> | statement is plain wrong.  Maybe Vaxes had a "Reverse Bit Shift, Cast
> | to Type and Catch Fire if the Programmer is Stupid" instruction (with
> | mnemonic RBSCTCFPS :^) but technology is substantially advanced since
> | then.  RISC CPU's have only the instructions that are measured as
> | being needed in practice, and virtually all new designs are RISC (with
> | the notable distiction of the ix86 line of processors). In future, try
> | to check your facts, and especially those that have been contradicted
> | by people (with good reason) for loads of years...
> 
> geez.
> 
> the SPARC architecture has several instructions that C compilers doesn't
> use, but which are convenient with type-tagged languages.  the _fact_ is
> that it has an the instruction, with Sun's recommended mnemonic "taddcctv",
> that is specifically useful in Lisp, and specifically unused in C.  other
> instructions are also measurably useful in languages _other_ than C.

	Ok, so you found one example on one CPU.  Great.  Do you have any
others?
Because when you say 'cpu's XXX' it means that most or all cpu's have
that
feature.  But there's more..

> 
> C is _not_ the be-all, end-all of programming languages and C is _not_ the
> universal assembler that some would like it to be.  that you cannot even
> put this instruction to use without a lot of prior work that you also have
> a hard time doing in C, shows that the SPARC designers thought of more than
> increasingly myopic C crowd.

	I would think it's better to be myopic than to have your eyes shut.
The fact is, most newer chips are not designed for lisp at all.  The
basic
operations certianly are not based on type.  

	Accusing someone of being stupid, and making stupid arguments oneself
does make someone look like a fool though; though it's not who you're
insulting.

> 
> but to demonstrate the point with a real-life example, take the following
> (silly) function, compiled by Allegro Common Lisp for Unix on a SPARC:
> 
> (defun foo (x y) (declare (fixnum x y)) (+ x y))
> 
>    0:   cmp     %g3, #x2
>    4:   tne     %g0, #x13
>    8:   taddcctv        %g0, %g1, %g0
>   12:   sra     %o0, #x2, %o0
>   16:   sra     %o1, #x2, %o1
>   20:   add     %o0, %o1, %o0
>   24:   ld      [%g4 + 135], %g2        ; fixnum-or-bignum
>   28:   jmp     %g2 + 0
>   32:   xor     %g0, #x1, %g3
> 
> the intelligent reader will recognize that this function sports a few
> features not commonly found in C compiler output: the number of incoming
> arguments is in a register, there are traps to handle error conditions, and
> it concludes with a jump to a function instead of a call and return.  (no
> programmer knowledgeable of pipelines RISCs will wonder why the jmp occurs
> before the argument count is stored into %g3.)

	Once again, making broad allegations of stupidity doesn't make you look
smart when you say foolish things.  

	I'm glad that the usual C compiler will not produce the preceeding
code.
I'm glad the usual java compiler will not produce the preceeding code.  
First of all, it specifies fixnums, but appears to be performing the
computation
for all types--nice optimization.  And testing the number of parameters
is only
necessary due to the structure of lisp--berating C compilers for not
doing this is silly.  
Also, it appears that the whole function ought to be compiled to a
single tail-recursive jump or inlined for that matter.


> 
> I welcome suggestions on how to accomplish the _exact equivalent code_ from
> C source code.  if this cannot be done, could Donal K. Fellows then accept
> that some CPU's (1) do have instructions that C compilers don't use, and
> (2) that he shot his mouth off?  I assume both, so let's return to our
> regular program.

	Perhaps you could try counting to 100 before responding to someone
on the net?  The time might be used to actually think about what you're
posting,
which might work wonders.

> Bastard Sex Therapist from Hell: "Read the F*cking Manual!"

	A freudinan message??


	dave
From: Erik Naggum
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <3070826073518641@naggum.no>
* David Hanley
| Ok, so you found one example on one CPU.  Great.  Do you have any others?

amusing rejoinder.

| Accusing someone of being stupid, and making stupid arguments oneself
| does make someone look like a fool though; though it's not who you're
| insulting.

actually I don't generally accuse people of being stupid.  I demonstrate
it.  you, however, keep accusing people of being stupid, among a lot of
other irrelevant accusations.

| > (defun foo (x y) (declare (fixnum x y)) (+ x y))
| > 
| >    0:   cmp     %g3, #x2
| >    4:   tne     %g0, #x13
| >    8:   taddcctv        %g0, %g1, %g0
| >   12:   sra     %o0, #x2, %o0
| >   16:   sra     %o1, #x2, %o1
| >   20:   add     %o0, %o1, %o0
| >   24:   ld      [%g4 + 135], %g2        ; fixnum-or-bignum
| >   28:   jmp     %g2 + 0
| >   32:   xor     %g0, #x1, %g3

| I'm glad that the usual C compiler will not produce the preceeding code.
| I'm glad the usual java compiler will not produce the preceeding code.
| First of all, it specifies fixnums, but appears to be performing the
| computation for all types--nice optimization.

the incoming arguments are in %o0 and %o1.  they are shifted right two bits
because the type tag is in the two least significant bits.  (actually, they
are in the lowest _three_ bits, but even and odd integers have different
type tags that conveniently overlap with the least significant bit of the
value.  I told you tagged pointers were optimized in Lisp.)  the result is
added together, and then that value is passed to a system function that
builds a bignum if necessary (i.e., the most significant bit, apart from
the sign bit is 1).

| And testing the number of parameters is only necessary due to the
| structure of lisp--berating C compilers for not doing this is silly.

again, you demonstrate a belligerent ignorance that is just astonishing.
what's wrong with asking whether it can be turned off?  here's the same
function, now compiled with (declaim (optimize (speed 3) (safety 0))) in
effect:

   0:	add	%o0, %o1, %o0
   4:	mov	#x1, %g3
   8:	jmp	%o7 + 8
  12:	nop

note that this does not handle bignums, but it does return the number of
return values to the continuation.  it does not handle bignums because I
specified fixnum arguments, and I'm assumed to know what I'm doing if I use
(safety 0).  note that this is the same as C cannot escape.  I've had my
Lisp system crash with bad code compiled with (safety 0), but otherwise
not.  I can't force a failing C program not to crash by tweaking a simple
declaration!

| Also, it appears that the whole function ought to be compiled to a single
| tail-recursive jump or inlined for that matter.

looks to me like the function it could have jumped to _is_ inlined.  note
that the fixnum-or-bignum function is used by a lot of other functions.

| Perhaps you could try counting to 100 before responding to someone on the
| net?  The time might be used to actually think about what you're posting,
| which might work wonders.

how far did you count?

| > Bastard Sex Therapist from Hell: "Read the F*cking Manual!"
| 
| A freudinan message??

OK, so let's try another one.

#\Erik
-- 
if we work really hard, will obsolescence be farther ahead or closer?
From: William Clodius
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335EAA39.ABD@lanl.gov>
David Hanley wrote:
> 
> <snip>
> 
>         Ok, so you found one example on one CPU.  Great.  Do you have any
> others?
> Because when you say 'cpu's XXX' it means that most or all cpu's have
> that
> feature.  But there's more..

Learn your grammar. cpu's is the singular posesive. To prove his point
all he has to do is give one example.  It is a bit much to ask him to
give examples for a majority of the CPU's available on the market.

> 
> >
> > C is _not_ the be-all, end-all of programming languages and C is _not_ the
> > universal assembler that some would like it to be.  that you cannot even
> > put this instruction to use without a lot of prior work that you also have
> > a hard time doing in C, shows that the SPARC designers thought of more than
> > increasingly myopic C crowd.
> 
>         I would think it's better to be myopic than to have your eyes shut.
> The fact is, most newer chips are not designed for lisp at all.  The
> basic
> operations certianly are not based on type.
> 

He did not claim that CPU's were designed for Lisp. He claimed that they
were not exclusively designed for C. I would not be surprised to find
that there are instructions that Cobol or Ada, but not C, could use, or
instructions that an OS could use which has no C equivalent. And he did
not claim that any additional instructions that other languages might
use, and C could not use, involved types, other things could involve
garbage collecting, certain forms of exception handling, etc.

As a side point, does anyone know if the newer "Java" chips have
instructions that check types?

> <snip>

-- 

William B. Clodius		Phone: (505)-665-9370
Los Alamos Nat. Lab., NIS-2     FAX: (505)-667-3815
PO Box 1663, MS-C323    	Group office: (505)-667-5776
Los Alamos, NM 87545            Email: ········@lanl.gov
From: M. Prasad
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335F43C0.65D0@polaroid.com>
William Clodius wrote:
> 
> Learn your grammar. cpu's is the singular posesive. To prove his point
> all he has to do is give one example.  It is a bit much to ask him to
> give examples for a majority of the CPU's available on the market.

Have you learned yours?  If it is singular possesive,
it is just bad grammar in the given sentence.
If it is plural (as I assume yours is in the last
sentence above), it means more than one.
From: D. M. H. Walker
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335F7DDC.3D99@cs.tamu.edu>
One point that I want to reemphasize is that a LISP uP would not have
changed the course of history (TI had one anyway).  Designing a
competitive uP requires a significant investment, even if someone else
does the manufacturing, assembly, and test.  Probably the smallest
organization designing uPs today is Cyrix (with IBM doing the rest).  (I
am ignoring Exponential since they are not on the market yet and I doubt
their success).  Despite the fact that their volume is many times what a
LISP uP could achieve, their finances are shaky, and they could die at
any time.  The standard uP design teams then and now can afford to spend
10-100x more (maybe 1000x more in the case of Intel) than a LISP uP
team.  That difference is enough to overwhelm any language-specific
machine within a generation or two, especially considering that the LISP
uP must run other code at least okay to even stay in the market.

There is a lot to be said for winning by brute force.  Ted Lewis's
columns in IEEE Computer provide a good analysis of this as applied to
the computer industry.

Prediction:  Java machines will be losers, i.e. they will not achieve
significant market share, even if set-top boxes succeed.
From: ···@teco.net
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <s6y7mhtmczm.fsf@aalh02.alcatel.com.au>
David Hanley <·····@nospan.netright.com> writes:

> > the SPARC architecture has several instructions that C compilers doesn't
> > use, but which are convenient with type-tagged languages.  the _fact_ is
> > that it has an the instruction, with Sun's recommended mnemonic "taddcctv",
> > that is specifically useful in Lisp, and specifically unused in C.  other
> > instructions are also measurably useful in languages _other_ than C.
> 
> 	Ok, so you found one example on one CPU.  Great.  Do you have any
> others?
> Because when you say 'cpu's XXX' it means that most or all cpu's have
> that
> feature.  But there's more..

Eriks original statement was only that dynamic typing was well
optimised in good lisp implementations, and that there was "often"
support from the hardware.

He didn't say "always" support from the hardware, or even "mostly"
support. Only that there are some hardware platforms which provide
some support. He then went on to prove that probably the most common
RISC platform (Sparc) has some support. I'd say he proved his case.
 
> > C is _not_ the be-all, end-all of programming languages and C is _not_ the
> > universal assembler that some would like it to be.  that you cannot even
> > put this instruction to use without a lot of prior work that you also have
> > a hard time doing in C, shows that the SPARC designers thought of more than
> > increasingly myopic C crowd.
> 
> 	I would think it's better to be myopic than to have your eyes shut.
> The fact is, most newer chips are not designed for lisp at all.  The
> basic
> operations certianly are not based on type.
> 
> 	Accusing someone of being stupid, and making stupid arguments oneself
> does make someone look like a fool though; though it's not who you're
> insulting.

I didn't see Erik claim that chips are designed for lisp. All he said
was that you can better implement dynamic languages with assembler
than compiling through C. This is true for all architectures, even
"new" ones.

No wonder Erik gets angry with the pure ignorance that is put forward
as fact.
From: Donal K. Fellows
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5kccj2$bom@m1.cs.man.ac.uk>
In article <················@naggum.no>, Erik Naggum  <····@naggum.no> wrote:
> Donal K. Fellows wrote:
>> Erik Naggum wrote:
>>> (yes, CPU's _do_ have instructions that C compilers don't use.)
>> 
>> I take it you don't work in computer hardware design, and haven't even
>> looked at the field for at least 10 or 15 years, since that last
>> statement is plain wrong.  Maybe Vaxes had a "Reverse Bit Shift, Cast
>> to Type and Catch Fire if the Programmer is Stupid" instruction (with
>> mnemonic RBSCTCFPS :^) but technology is substantially advanced since
>> then.  RISC CPU's have only the instructions that are measured as
>> being needed in practice, and virtually all new designs are RISC (with
>> the notable distiction of the ix86 line of processors). In future, try
>> to check your facts, and especially those that have been contradicted
>> by people (with good reason) for loads of years...
> 
> the SPARC architecture has several instructions that C compilers doesn't
> use, but which are convenient with type-tagged languages.  the _fact_ is
> that it has an the instruction, with Sun's recommended mnemonic "taddcctv",
> that is specifically useful in Lisp, and specifically unused in C.  other
> instructions are also measurably useful in languages _other_ than C.

What does the instruction do?  I've not got a SPARC manual to hand and
I'm quite sure that there are other people reading this thread who are
also unaware of the meaning of that instruction.  I must admit that
when I read it, I immediately think of something to do with Closed
Circuit Television - obviously, I'm way off the mark with that!  :^)

> C is _not_ the be-all, end-all of programming languages and C is _not_ the
> universal assembler that some would like it to be.  that you cannot even
> put this instruction to use without a lot of prior work that you also have
> a hard time doing in C, shows that the SPARC designers thought of more than
> increasingly myopic C crowd.

I was thinking in reference to the ARM, x86 and MIPS architectures
(which I know much better than SPARC).  Erik, if you are going to
claim something about the general case, you should have more than one
example lined up to illustrate your case.

> actually, I find it rather astonishing to learn that some people are so
> belligerently ignorant as to believe they can pull off a stunt like the
> above from D. K. Fellows.

Now, now, now.  There was no need for that last paragraph.  It turns
your argument from one of (reasonable) strength into one of ad hominem
flaming.  If you wish your technical points to be taken seriously by
most people on USENET, cutting out this sort of thing is going to be
virutally essential.

BTW, if you can point to a special instruction used in Lisp but not C
in the ARM architecture, I would like to know so that I can pass that
information on to the asynchronous microprocessor design team in my
department.  At the moment, their benchmarking is done using standard
pieces of C, and adding a new benchmark which exercises parts of the
silicon that other benchmarks do not reach would be of great utility
to them.

Donal.  (still in a good mood)
--
Donal K. Fellows   http://r8h.cs.man.ac.uk:8000/  (SAY NO TO COMMERCIAL SPAMS!)
(work) ········@cs.man.ac.uk     Dept. Comp. Sci, Univ. Manchester, U.K.
 |     ·····@ugglan.demon.co.uk  6,Randall Place, Heaton, Bradford, U.K. (home)
 +-> ++44-161-275-6137  Send correspondence to my office  ++44-1274-401017 <-+
From: David Monniaux
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5kcha4$i2c@cri.ens-lyon.fr>
Donal K. Fellows (···········@man.ac.uk) wrote:
: > the SPARC architecture has several instructions that C compilers doesn't
: > use, but which are convenient with type-tagged languages.  the _fact_ is
: > that it has an the instruction, with Sun's recommended mnemonic "taddcctv",
: > that is specifically useful in Lisp, and specifically unused in C.  other
: > instructions are also measurably useful in languages _other_ than C.
: 
: What does the instruction do?  I've not got a SPARC manual to hand and
: I'm quite sure that there are other people reading this thread who are
: also unaware of the meaning of that instruction.

The Sparc architecture has support for a "tagged integer" data type.
The two low-weight bits of a tagged word contain a tag, the other bits contain
a 30-bit integer. The two provided operations (add and substract) work as
one would expect on words with tag=0. With other values, they generate an
overflow error. taddcctv (resp. tsubcctv) adds (resp. subtracts) two tagged
words, sets the condition codes (cc) and traps on overflow; alternatively,
one may use taddcc/tsubcc, which do not trap.

This is meant for use with dynamically typed languages. Integers are tagged 0,
and the most commonly used operations (add/sub) on them work transparently.
Pointers are tagged with 1, 2 or 3. If a pointer is mistakenly used as an
integer, it generates an error (and maybe a trap). To compensate for the tag,
data is accessed with relative offsets -1, -2 or -3 respectively from a
tagged pointer. As words are 4-byte aligned, addressing data with the wrong
offset generates a bus error. That is, data with one tag used mistakenly
as if it were to bear another tag make the processor trap.

(all this taken from "The Sparc architecture manual, version 8").

The tags may be used by the garbage collection process to see what words
contain integers and what words contain pointers. I do not have examples
of implementations using the Sparc tagged arithmetic, but the only garbage
collecting implementation I know quite well, Objective CAML, tags data
using the lowest weight bit.

Hope this helps.

-- David

PS: Sorry, but the overall aggressive tone of the discussions around
("You aren't competent on that topic! - Yes, I am, it's you who don't
know anything about what is talked of!") disturb me.
We should spend more time actually working on improving computer languages,
tools and libraries, and less arguing about, as Xavier Leroy said,
whether angels are male or female. :-)

PS2: I've trimmed the followup-to. If we are to discuss generally upon the
use of processor features for garbage collection and sanity checks in
garbage-collected language, I think we can restrict ourselves to
comp.lang.functional...

-- 
"If computers worked, it'd be known."
Computer science student at ENS, Lyon, France
http://www.ens-lyon.fr/~dmonniau
From: Gareth McCaughan
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <86vi52t6qd.fsf@g.pet.cam.ac.uk>
[Newsgroups trimmed to just comp.lang.lisp, and a copy sent to DKF
because I don't think he reads c.l.l -- gjm]

Donal Fellows wrote:

> BTW, if you can point to a special instruction used in Lisp but not C
> in the ARM architecture, I would like to know so that I can pass that
> information on to the asynchronous microprocessor design team in my
> department.  At the moment, their benchmarking is done using standard
> pieces of C, and adding a new benchmark which exercises parts of the
> silicon that other benchmarks do not reach would be of great utility
> to them.

I don't think Erik is obliged to do this in order to justify
his statement. He never claimed that all CPUs have instructions
useful for Lisp but not for C.

He might, however, be read as having claimed that all CPUs have
instructions not used by C compilers; for this I think he's
right about the ARM: does any C compiler generate the SWP
instruction? (I know that gcc does not; I have no idea whether
ARM's compiler does.) gcc also never generates the SWI
instruction (and I don't think ARM's compiler does unless
you tell it explicitly that a function is a SWI veneer,
which doesn't really count); ditto for most of the
coprocessor instructions. None of these is likely to be
of more use to Lisp than C, of course.

And, on the inevitable side-issue: I agree that Erik shouldn't
be accusing Donal of being "belligerently ignorant", but that
doesn't seem any more un-called-for than Donal's earlier "In
future, try to check your facts <etc>".

-- 
Gareth McCaughan       Dept. of Pure Mathematics & Mathematical Statistics,
·····@dpmms.cam.ac.uk  Cambridge University, England.
From: Howard R. Stearns
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <336A3674.58EEE8E@elwoodcorp.com>
FYI: Lucent's "Dis" virtual machine, designed to run their new Inferno
operating system and Limbo language, has a primitive CONS instruction
for making a memory managed list (i.e. monitored by the "machine level"
garbage collector).  The Dis names for car and cdr are HEAD and TAIL.

Could this be used for languages other than Lisp? Sure.  
Was it designed specifically for Lisp?  I don't know. (Anyone from 
  Lucent listening?)
Is it well suited for implementing any dialect of Lisp, and not so 
  obviously suited for implementing any standard dialect of C?  Yes, in 
  my opinion.

As for benchmarks, I believe I saw that SPEC was awarding cash prizes
for good benchmarks.  If you have a favorite one which begs for a Lisp
solution, send it in.

Gareth McCaughan wrote:
> 
> [Newsgroups trimmed to just comp.lang.lisp, and a copy sent to DKF
> because I don't think he reads c.l.l -- gjm]
> 
> Donal Fellows wrote:
> 
> > BTW, if you can point to a special instruction used in Lisp but not C
> > in the ARM architecture, I would like to know so that I can pass that
> > information on to the asynchronous microprocessor design team in my
> > department.  At the moment, their benchmarking is done using standard
> > pieces of C, and adding a new benchmark which exercises parts of the
> > silicon that other benchmarks do not reach would be of great utility
> > to them.
> 
> I don't think Erik is obliged to do this in order to justify
> his statement. He never claimed that all CPUs have instructions
> useful for Lisp but not for C.
> 
> He might, however, be read as having claimed that all CPUs have
> instructions not used by C compilers; for this I think he's
> right about the ARM: does any C compiler generate the SWP
> instruction? (I know that gcc does not; I have no idea whether
> ARM's compiler does.) gcc also never generates the SWI
> instruction (and I don't think ARM's compiler does unless
> you tell it explicitly that a function is a SWI veneer,
> which doesn't really count); ditto for most of the
> coprocessor instructions. None of these is likely to be
> of more use to Lisp than C, of course.
> 
> And, on the inevitable side-issue: I agree that Erik shouldn't
> be accusing Donal of being "belligerently ignorant", but that
> doesn't seem any more un-called-for than Donal's earlier "In
> future, try to check your facts <etc>".
> 
> --
> Gareth McCaughan       Dept. of Pure Mathematics & Mathematical Statistics,
> ·····@dpmms.cam.ac.uk  Cambridge University, England.
From: Henry Baker
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <hbaker-0305971112040001@10.0.2.1>
In article <················@elwoodcorp.com>, "Howard R. Stearns"
<······@elwoodcorp.com> wrote:

> FYI: Lucent's "Dis" virtual machine, designed to run their new Inferno
> operating system and Limbo language,

One question.  If 'Inferno' runs on an NCR Tower machine, does it become
a Towering Inferno ?
From: John Nagle
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <nagleE8x5Gz.9KL@netcom.com>
······@tcl.eng.sun.com (John Ousterhout) writes:
>One of the most common criticisms of my white paper has been that the
>distinction between scripting and system programming is artificial, and
>that it is possible for a single language to be good at both tasks.
>Lisp-like languages such as Scheme were suggested as living proof.  I
>can't prove that it's impossible for a single language to be good at
>both scripting and system programming, but I don't know of a good example
>and I doubt that it will ever happen.  

     The more modern forms of Visual Basic, of all things, come rather close.  
You can have typing if you want it, but you can declare dynamically
typed variables if you need them.  The language can be compiled to
machine code.  Within the Microsoft world, it talks to almost everything.
But it's not an everything-is-a-string language, like TCL and the various
UNIX shells.  Nor is it an "escaped" language. 
(You write 
    X = "A" 
in Visual Basic, not
    $X = A
as in typical shell and macro languages.  This scales better to large
work.)

     Visual Basic has been quite successful; it's supplanting COBOL in
the client side of business systems.  A sizable commercial market exists in
objects for Visual Basic, one of the few object-oriented systems for
which that has happened.  It's not widely used in academia,
but in the real world, things are different.  Don't laugh at VB4;
this is not your father's Dartmouth BASIC.  It's a decent language now.

     The scripting language for AutoCAD is a form of LISP.  This
is unusual, but the objects being dealt with are heavily numerical,
and it's worked out reasonably well.

					John Nagle
From: Cyber Surfer
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <MPG.dc3e037a80f4de4989782@news.demon.co.uk>
With a mighty <···············@netcom.com>,
·····@netcom.com uttered these wise words...

>     Visual Basic has been quite successful; it's supplanting COBOL in
> the client side of business systems.  A sizable commercial market exists in
> objects for Visual Basic, one of the few object-oriented systems for
> which that has happened.  It's not widely used in academia,
> but in the real world, things are different.  Don't laugh at VB4;
> this is not your father's Dartmouth BASIC.  It's a decent language now.

This is a point that I've been making, for a while now. VB and C++ 
compliment each other in just the way that JO claims is true for Tcl 
and Java, one for the "scripting" level, the other for "system" level.
The latest version of VB is 5.0 (yep, it's available: I've seen a non-
beta copy, tho it was still in its box at the time). It's a very 
serious grown-up Basic.

Sadly, there are people who'll slag off VB. The criticisms that I've 
seen have reminded me of the myths surrounding Lisp. When I see a VC++ 
programmer distorting the true capabilities of VB (downward, of 
course), the techniques they use appear to be _exactly_ the same. 
Perhaps they even share the same motivation? I don't know.

I'm not a VB programmer. I'm not sure I'd even call myself a C++ 
programmer, for various reasons. However, I don't feel any need to 
misrepresent VB's capabilities. If VB can do much of what I do in C++, 
then I'm overjoyed, as it may mean that I can use something else, like 
Java (or perhaps someday, my preference, Lisp) while a VB programmer 
writes that boring DLL etc.

Could it be that some C++ programmers feel threatened by VB? I find it 
ironic that a posting that's critical of VB might also slag off 
Delphi, which is a language far closer to C++, and yet still very easy 
to use. Therefore more threatening to a C++ programmer who doesn't 
like Pascal?

Again, I don't know, as I've never felt a bias so strongly that I had 
to distort the truth. I freely admit that I'm no fan of C/C++, but I 
also admit that these languages have some utility. I don't let that 
cloud my judgement by refusing to see the strengths of VB, Delphi, and 
even a few languages (and implementations) of a more esoteric nature.

Go figure.
-- 
<URL:http://www.wildcard.demon.co.uk/> You can never browse enough
  Martin Rodgers | Programmer and Information Broker | London, UK
            Please note: my email address is gubbish.
From: Andrew Koenig
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <E8xwzp.8tJ@research.att.com>
In article <·························@news.demon.co.uk> ············@gubbish.wildcard.demon.co.uk (Cyber Surfer) writes:

> Sadly, there are people who'll slag off VB.

For all X, there are people who will slag off X.

> Could it be that some C++ programmers feel threatened by VB?

For all Y and X, there are Y programmers who feel threatened by X.
That might be part of the reason that people slag off X for all X.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Henry Baker
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <hbaker-2004970914430001@10.0.2.1>
There are so many errors in your assertions, that it's difficult to know
where to start.

In article <··········@engnews2.Eng.Sun.COM>, ······@tcl.eng.sun.com (John
Ousterhout) wrote:

> One of the most common criticisms of my white paper has been that the
> distinction between scripting and system programming is artificial, and
> that it is possible for a single language to be good at both tasks.
> Lisp-like languages such as Scheme were suggested as living proof.  I
> can't prove that it's impossible for a single language to be good at
> both scripting and system programming, but I don't know of a good example
> and I doubt that it will ever happen.

Two words: 'Lisp Machine'.

> The reason for this is the
> difference in typing, as I explained in the white paper. A given language
> embodies a particular style of typing, which can range from very strongly
> typed to totally untyped.  Once that decision has been made, the language's
> position on the spectrum between system programming and scripting is set.
> I think it's possible to have a language that's in the middle, but it's
> not likely to be terrific at either task.

You've obviously never heard of Lisp declarations, or of 'soft typing'.

> Let's take Lisp as an example.  I think that Lisp falls somewhere
> between scripting and system programming.  Many of you have suggested that
> it is an ideal language for both system programming and scripting, but I
> think that it isn't really very good for either.

Two words: 'Lisp Machine'.

> In fact I suspect that
> this may be why Lisp hasn't been used much for practical programming.
> Lisp isn't a good system programming language because it's too hard to
> write efficient programs in it and it doesn't provide good low-level
> access to machine facilities.

Utter claptrap.  I've written many Lisp programs on the PDP-10 and the
68K (Mac) that run as fast as any hand-crafted assembler program.

Two more words: 'Lisp Machine'.

> On the other hand, Lisp isn't good for
> scripting either.  In order to be a good scripting language, you need
> to be able to interoperate with lots of other things, which are often
> written in other languages (the best glues are those that stick to lots
> of different materials).  But Lisp has never been very good at this.
> For example, it's hard to include C code with Lisp because they have
> very different data types and memory models.  Lisp systems are typically
> closed: you have to live entirely in the Lisp world.  Good scripting
> languages are open and friendly: they talk to and work with everything.

The Symbolics Lisp Machine also supported the C language, and an excellent
C language it was.  C on this machine wasn't particularly fast, but that was
because the Lisp Machine had better things to do than to twiddle bits.

> Just to short-circuit the discussion that will ensue...
> 
> Many of the best minds in Computer
> Science have worked on Lisp over the last 30 years, and they haven't
> been able to fix the language so that it could be widely used either
> for system programming or scripting tasks.  This says to me that there
> is something fundamentally wrong with the language, at least for these
> tasks.

I suppose that all of the excellent work in Lisp on scheduling space probe
operations, scheduling factory operations, handling your American Express
card credit ratings (in real-time, 7x24), scheduling Gulf War supplies,
demonstrating the next generation of fighter pilot cockpit aids, etc., was all
a mirage?  I guess you see what you want to see.

I'm embarrassed that a 'computer science professor' would be _so_ ignorant
of computer science that he would spout all of this nonsense.
From: Mike Pinkerton
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <mpinkert-2004971242230001@fire.cc.gatech.edu>
In article <·······················@10.0.2.1>, ······@netcom.com (Henry
Baker) wrote:

>Two words: 'Lisp Machine'.

Oh, yeah, and that was successful. I've got a friend with a Symbolics
machine he uses as a table.

--
Mike Pinkerton
········@cc.gatech.edu      http://www.cc.gatech.edu/~mpinkert

Cyberdog: On the Internet, no one knows you're an OpenDoc part
From: Erik Naggum
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <3070552431069683@naggum.no>
* Henry Baker
| Two words: 'Lisp Machine'.

* Mike Pinkerton
| Oh, yeah, and that was successful. I've got a friend with a Symbolics
| machine he uses as a table.

well, I for one expected this response.

do you remember the IBM PC?  a friend of mine claims he uses one as an
anchor.  was it successful?  how about any of the current crop of hardware
and software that is claimed, by the vendors themselves, to be useless and
unsupported and that you should never buy them?  (ask your favorite PC
salesdroid for a 386 with 4M RAM, a VGA card, 40M of disk, and whatever
MS-DOS version just preceded Windows, including Word Perfect 4.0 or
whatever it was.  then listen to the way he describes this once great
solution.  look at how the PC magazines describe their own progress.)

the Lisp Machines died for reasons totally unrelated to quality.  actually,
they died for the same reason that mind-bogglingly inferior systems won.
the answer is a single word: "marketing".  this is the one concept that
John Ousterhout has learned from history.  and very little else, it seems.

the Lisp Machines are still highly respected for their design and usability.
such will not happen to today's mass-marketed computers ten years hence any
more than it happens to their progenitors of ten years ago.

#\Erik
-- 
Bastard Sex Therapist From Hell: "Read The F*cking Manual!"
From: Mark A Harrison
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jg060$q3f$1@news.utdallas.edu>
Erik Naggum (····@naggum.no) wrote:

: the Lisp Machines died for reasons totally unrelated to quality.  actually,
: they died for the same reason that mind-bogglingly inferior systems won.
: the answer is a single word: "marketing".

I don't think this is true...  Lisp machines died because their
functionality was supplanted by other more general purpose machines.

Example: My former roomate (mid-80's) was a chip designer.  He had
two giant systems on his desk, a lisp machine (TI Explorer?) and
an Apollo.  He was always complaining about how inconvenient it
was that part of his work was done on the lisp machine (chip design)
and that the rest was done on the Apollo (word processing, email,
manufacturing apps).  When their software group was able to port
their applications to the same box their other applications ran
on, they dropped the lisp machine without hesitation.

In other words:  Marketing didn't kill lisp machines... Good lisp
environments that ran on general-purpose computers killed
lisp machines.

Mark.
From: Henry Baker
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <hbaker-2104971037550001@10.0.2.1>
In article <············@news.utdallas.edu>, ········@utdallas.edu (Mark A
Harrison) wrote:
> Lisp machines died because their
> functionality was supplanted by other more general purpose machines.
> 
> Example: My former roomate (mid-80's) was a chip designer.  He had
> two giant systems on his desk, a lisp machine (TI Explorer?) and
> an Apollo.  He was always complaining about how inconvenient it
> was that part of his work was done on the lisp machine (chip design)
> and that the rest was done on the Apollo (word processing, email,
> manufacturing apps).  When their software group was able to port
> their applications to the same box their other applications ran
> on, they dropped the lisp machine without hesitation.

This is complete BS.  The lisp machines had fabulous email systems,
and Symbolics went to a great deal of trouble to make TeX run on its
Lisp Machine.  The Symbolics Lisp Machine documentation was generated and
edited on Lisp Machines.  Perhaps TI bought the wrong Lisp Machines ?  ;-) ;-)

A number of the features of Emacs the people know and love today were first
developed and used on Lisp Machines.  Much of the productivity of Symbolics
customer service depended upon a sophisticated email system.

You can argue about whether a machine as expensive as the Symbolics Lisp
Machines should have been doing email, but that is an entirely different
question from whether they did it.  Yes, they did.
From: M. Prasad
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335BAB74.458F@polaroid.com>
Henry Baker wrote:
> 
> In article <············@news.utdallas.edu>, ········@utdallas.edu (Mark A
> Harrison) wrote:
> > Lisp machines died because their
> > functionality was supplanted by other more general purpose machines.
> >
> > Example: My former roomate (mid-80's) was a chip designer.  He had
> > two giant systems on his desk, a lisp machine (TI Explorer?) and
> > an Apollo.  He was always complaining about how inconvenient it
> > was that part of his work was done on the lisp machine (chip design)
> > and that the rest was done on the Apollo (word processing, email,
> > manufacturing apps).  When their software group was able to port
> > their applications to the same box their other applications ran
> > on, they dropped the lisp machine without hesitation.
> 
> This is complete BS.  The lisp machines had fabulous email systems,

If this experience is BS, what is the truth?  Why _did_
the Lisp machines die?  People keep blaming "marketing", but
did LMI/Symbolics founders not have enough smarts or the money
to hire some good marketing people?  I would doubt either
of these two was the case.

Or maybe the machines were just too expensive to produce,
to be able to sell them successfully.
From: Ron Natalie
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335BB4C6.66DF@sensor.com>
>> This is complete BS.  The lisp machines had fabulous email systems,

Yep, and they were really great at telling you how many machines
were available on the 7th floor and all sorts of stupid MIT-isms
that made the whole thing look like your typical student kludge.

> If this experience is BS, what is the truth?  Why _did_
> the Lisp machines die? 

I don't think the market was there.  At the time the commercial
lisp machines were coming out there were also a number of decent
lisps available for the General Purpose machines.  Workstations
clobbered the Lisp Machine and Mini market just as PC's are beginning
to wack away at the workstation market.

-Ron
From: Mike Haertel
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <slrn5lnl9m.la9.mike@ducky.net>
In article <·············@polaroid.com>, M. Prasad wrote:
>If this experience is BS, what is the truth?  Why _did_
>the Lisp machines die?

The Lisp machines died mostly because Lisp running on conventional
architectures began to beat LispM performance starting in the late
1980's.  The LispM market was not large enough to sustain the R&D
investment required to be performance-competitive with the workstation
RISC processors.  The conventional processors could also run many
other applications that could only have been ported to the LispM's
at great cost.

LispM proponents like to brag about the advantages of their
software, but conveniently neglect that it also had some
substantial disadvantages:

	* LispM's were not multi-user - they could have only
	  one logged-in user at a time, although they did
	  provide a degree of remote access.

	* LispM's were not secure - the whole system, including
	  the operating system kernel, ran in a single giant
	  address space.

The LispM's also cost too much--especially for single-user machines!

The lesson: If you're going to be different, you'd better offer
some *extremely* compelling advantages, or your more conventional
competitors will have you for lunch.
From: Samuel S. Paik
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <paik-2204970130110001@192.168.13.2>
(Newsgroups trimmed a bit)

In article <···················@ducky.net>, ····@ducky.net (Mike Haertel) wrote:
>The Lisp machines died mostly because Lisp running on conventional
>architectures began to beat LispM performance starting in the late
>1980's.

>The lesson: If you're going to be different, you'd better offer
>some *extremely* compelling advantages, or your more conventional
>competitors will have you for lunch.

This is an extremely important lesson.  If you are going to be off
the mainstream, it is not enough to be merely competitive, you
must demonstrate _significant_ (i.e. order of magnitude) advantages
for at least the near to middle-term, or you will be relegated to
very small niches or disappear entirely.

Examples to consider (you be the judge)

  Gallium Arsenide vs. Silicon
  Massively parallel (thousands of processors) vs. SMP/clusters
  Magneto-optical vs. magnatic disks
  Mac vs. Wintel
  Wintel vs. Unix RISC workstations
  Unix workstations vs. departmental servers
  Departmental servers vs. Mainframes
  Killer Micro vs. Minisuper
  FORTH processors vs. conventional processors
  RISC vs. x86
  dedicated logic & dsps vs. NSP

For example, for high performance CMOS gate arrays, you can get GaAs
not much less dense, with some speed advantage.  This is basically
not enough to overcome the inertia CMOS has in:  trained people, tools,
design methodology, standard libraries, test gear, etc.  Or consider
ECL vs. CMOS.  (hey, I'm not an expert on circuits, so maybe I'm off
base now, but this is my impression from newgroups, industry rags,
people I've talked to... perhaps I should stick to 3D, where
rasterization hardware has 1 to 2 orders magnitude better performance
than a CPU.)

Sam

-- 
Guy [Gavriel Kay]'s been living here in Toronto | Samuel S. Paik
for the last two years.  I believe that means   | ····@webnexus.com
the new book is going to be called THE BLUE     | 408-969-3258
JAYS OF AL-SKYDOME ...  - Robert J. Sawyer      | Speak only for self
From: Kelly Murray
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jh5pu$4mn$1@sparky.franz.com>
>If this experience is BS, what is the truth?  Why _did_
>the Lisp machines die?

There are many reasons, which have been discussed ad naseum,
I could say lots (as others probably will) but in my opinion 
there were two major factors:

 1. Market Share. Sun agressively lowered prices to pursue market share
    and increase sales volume (and other workstatations vendors too)
    When SUN came out with $5K workstations, 
    Symbolics only grudgingly came out with $20K entry machines
    and were convinced their machines were "worth it".  
    They failed to understand the big picture of market share,
    and was still flush from defense industry buyers of their expensive machines.  
    
 2. Low-cost application delivery.  Simply non-existent with LispMachines.
    UNIX had dirt-cheap ASCII terminals, SUN had diskless machines,
    and low-cost diskful machines.  
    Symbolics eventually had a 386-pc delivery vehicle, which was about 
    5 years too late, and didn't really work, as I recall.  
    LispM applications tended to use the non-portable graphics heavily, which made
    them hard to port over to the Lisp-on-Unix vendors systems.


-Kelly Murray   (speaking for myself)








    





    
From: Henry Baker
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <hbaker-2104972352300001@10.0.2.1>
In article <···················@ducky.net>, ····@ducky.net (Mike Haertel) wrote:

>         * LispM's were not multi-user - they could have only
>           one logged-in user at a time, although they did
>           provide a degree of remote access.

LispM's had a full multithreaded environment--something not seen in
personal computers until very recently.  Apple is still having difficulties
with this one.

>         * LispM's were not secure - the whole system, including
>           the operating system kernel, ran in a single giant
>           address space.

A better way of saying this is that LispM's are much _more_ secure, because
every item has its hardware datatype which is religiously checked on every
access.  LispM's weren't the machines crashing when those internet worm
attacks were going on!

> The LispM's also cost too much--especially for single-user machines!

The first two items aren't problems on PC's, so we can only conclude that
the third item--the cost--is the real problem here.  If Symbolics had achieved
their Lisp chip in the initially promised time frame--approximately 1985--
instead of 1988-9, the whole character of the argument would have changed.
Apple would have gone after the low end of the wimp market, and the Lisp
Machines would have captured the space currently occupied by low-end SGI
machines.  Even though it ran on a much slower processor, the Symbolics graphics
software was miles ahead of anything else in the late 1980's, and so it still
managed to compete for a while with its slow hardware.
From: Jason V. Robertson~
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jj43q$sk9@chnews.ch.intel.com>
In article <·······················@10.0.2.1>,
Henry Baker <······@netcom.com> wrote:
>
>In article <···················@ducky.net>, ····@ducky.net (Mike Haertel) wrote:
>
>>         * LispM's were not multi-user - they could have only
>>           one logged-in user at a time, although they did
>>           provide a degree of remote access.
>
>LispM's had a full multithreaded environment--something not seen in
>personal computers until very recently.  Apple is still having difficulties
>with this one.

Of course, being multithreaded has nothing to do with being multi-user.
Take NT, for example.

>>         * LispM's were not secure - the whole system, including
>>           the operating system kernel, ran in a single giant
>>           address space.
>
>A better way of saying this is that LispM's are much _more_ secure, because
>every item has its hardware datatype which is religiously checked on every
>access.  LispM's weren't the machines crashing when those internet worm
>attacks were going on!

Neither were PC's running Novell.  Of course LispM's wouldn't be affected - 
the worm targetted only Unix machines running Sendmail (I think?).
-- 
|Jason V. Robertson <········@sedona.intel.com> |
|Not speaking for Intel.                        |
From: ········@wat.hookup.net
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jllqp$ilq$1@nic.wat.hookup.net>
In <··········@chnews.ch.intel.com>, ········@sedona.intel.com (Jason V. Robertson~) writes:
> ...
>>access.  LispM's weren't the machines crashing when those internet worm
>>attacks were going on!
>
>Neither were PC's running Novell.  Of course LispM's wouldn't be affected - 
>the worm targetted only Unix machines running Sendmail (I think?).

Among other things.  I think it had three or for lines of attack (finger
was one of them), and depended on overwriting part of the stack with
machine code (I think it was sending binaries for 3 or 4 different CPUs
and OSes, Novell probably not among them, but most likely VMS).

Hartmann Schaffer
From: Scott Fahlman
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <yd3esg6hqz.fsf@CLYDE.BOLTZ.CS.CMU.EDU>
····@ducky.net (Mike Haertel) writes:

> 	* LispM's were not multi-user...
> 
> 	* LispM's were not secure...
> 
> The LispM's also cost too much--especially for single-user machines!

Also:

The Lisp Machines had a hellacious learning curve.  If you could
invest the months required to learn all their tricks, they provided a
software-development environment that has still not been surpassed.
But even some accomplished Lisp programmers never had time to get over
"the hump", and non-Lispers faced a really frightening barrier.
The documentation was designed for people who already knew the answer,
and Symbolics was remarkably unhelpful unless you wanted to spend a
week and a few thousand dollars for a training course. 

(This may have become a little better toward the end, but by then it
didn't matter.)

Early MS-DOS was even worse, of course, but there was much less of it
to conquer.

-- Scott
From: Henry Baker
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <hbaker-2404970503060001@10.0.2.1>
In article <··············@CLYDE.BOLTZ.CS.CMU.EDU>, Scott Fahlman
<···@clyde.boltz.cs.cmu.edu> wrote:

> The Lisp Machines had a hellacious learning curve.  If you could
> invest the months required to learn all their tricks, they provided a
> software-development environment that has still not been surpassed.
> But even some accomplished Lisp programmers never had time to get over
> "the hump", and non-Lispers faced a really frightening barrier.
> The documentation was designed for people who already knew the answer,
> and Symbolics was remarkably unhelpful unless you wanted to spend a
> week and a few thousand dollars for a training course. 

Gee, the courses that Novell & many others teach cost as much or more,
and when you get out, all you know is some real niggly bit-pushing stuff.

I agree that the LispM documentation could have been better for beginners,
but I think that most would agree it left the documentation of most
competitors--including some pretty large companies--in the dust.
From: Kelly Murray
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jobk8$e1d$1@sparky.franz.com>
In article <·······················@10.0.2.1>, ······@netcom.com (Henry Baker) writes:
>> 
>> In article <··············@CLYDE.BOLTZ.CS.CMU.EDU>, Scott Fahlman
>> <···@clyde.boltz.cs.cmu.edu> wrote:
>> 
>> > The Lisp Machines had a hellacious learning curve.  If you could
>> > invest the months required to learn all their tricks, they provided a
>> > software-development environment that has still not been surpassed.
>> > But even some accomplished Lisp programmers never had time to get over
>> > "the hump", and non-Lispers faced a really frightening barrier.
>> > The documentation was designed for people who already knew the answer,
>> > and Symbolics was remarkably unhelpful unless you wanted to spend a
>> > week and a few thousand dollars for a training course. 
>> 
>> Gee, the courses that Novell & many others teach cost as much or more,
>> and when you get out, all you know is some real niggly bit-pushing stuff.
>> 
>> I agree that the LispM documentation could have been better for beginners,
>> but I think that most would agree it left the documentation of most
>> competitors--including some pretty large companies--in the dust.

The later-years Symbolics documentation system was definitely excellent, 
and I understand it was one of their big assets when the company was sold,
and it was used successfully for non-lisp documentation purposes.

But before that (certainly in the ChinNual days), the system was clearly
for hackers only, with source code the ultimate documentation.  
Great stuff for hackers, but not for beginners.

-kelly murray 
From: Bj�rn Remseth
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <ajafmqsqrp.fsf@hridil.ifi.uio.no>
"M. Prasad" <·······@polaroid.com> writes:

> If this experience is BS, what is the truth?  Why _did_
> the Lisp machines die?  People keep blaming "marketing", but
> did LMI/Symbolics founders not have enough smarts or the money
> to hire some good marketing people?  I would doubt either
> of these two was the case.

Well, I am not too sure about that, I have seen worse examples of
misjudgements :)

My 0.02 USD worth of theory on the failure of the lisp-machines is:
The machines were pretty expensive. At least initially, they were also
targeted at a very limited market (the AI market) which then sort of
collapsed (details omitted :).  Now, the Lisp machines were truely
excellent at interoperability and communication with just about any
weird piece of hardware, language, file-format and network protocol,
so "not compatible" was probably a very minor issue. But you _did_
need to be very rich to get one in the first place.  If you had any
sanity at all (not all rich people do :), you probably also needed a
very good product idea before you could justify the kind of investment
such a machine represented, _and_ you needed to be pretty successfull
in the execution of your project to defend the investment afterwards.
This last issue was probably particularly true if your project ran
over budget, didn't complete properly or ran into any number of other
problem not necessarily related to your unconventional choice of
plattform

Now, are these kinds of issues marketing issues? Yes probably.


-- 
                                                    (Rmz)

Bj\o rn Remseth   !Institutt for Informatikk    !Net:  ···@ifi.uio.no
Phone:+47 22855802!Universitetet i Oslo, Norway !ICBM: N595625E104337
From: Bj�rn Remseth
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <aj912asq13.fsf@hridil.ifi.uio.no>
"M. Prasad" <·······@polaroid.com> writes:

> If this experience is BS, what is the truth?  Why _did_
> the Lisp machines die?  People keep blaming "marketing", but
> did LMI/Symbolics founders not have enough smarts or the money
> to hire some good marketing people?  I would doubt either
> of these two was the case.

Well, I am not too sure about that, I have seen worse examples of
misjudgement from management :)

My 0.02 USD worth of theory on the failure of the lisp-machines is:
The machines were pretty expensive. At least initially, they were also
targeted at a very limited market (the AI market) which then sort of
collapsed (details omitted :).  Now, the Lisp machines were truely
excellent at interoperability and communication with just about any
weird piece of hardware, language, file-format and network protocol,
so "not compatible" was probably a very minor issue. But you _did_
need to be very rich to get one in the first place.  If you had any
sanity at all (not all rich people do :), you probably also needed a
very good product idea before you could justify the kind of investment
such a machine represented, _and_ you needed to be pretty successfull
in the execution of your project to defend the investment afterwards.
This last issue was probably particularly true if your project ran
over budget, didn't complete properly or ran into any number of other
problem not necessarily related to your unconventional choice of
plattform

Now, are these kinds of issues marketing issues? Yes probably.


-- 
                                                    (Rmz)

Bj\o rn Remseth   !Institutt for Informatikk    !Net:  ···@ifi.uio.no
Phone:+47 22855802!Universitetet i Oslo, Norway !ICBM: N595625E104337
From: M. Prasad
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335E3AFB.73B4@polaroid.com>
Bj�rn Remseth wrote:
> 
> "M. Prasad" <·······@polaroid.com> writes:
> 
> > If this experience is BS, what is the truth?  Why _did_
> > the Lisp machines die?  People keep blaming "marketing", but
> > did LMI/Symbolics founders not have enough smarts or the money
> > to hire some good marketing people?  I would doubt either
> > of these two was the case.
> 
> Well, I am not too sure about that, I have seen worse examples of
> misjudgement from management :)
> 
> My 0.02 USD worth of theory on the failure of the lisp-machines is:
> The machines were pretty expensive. At least initially, they were also
> targeted at a very limited market (the AI market) which then sort of
> collapsed (details omitted :).  Now, the Lisp machines were truely
> excellent at interoperability and communication with just about any
> weird piece of hardware, language, file-format and network protocol,
> so "not compatible" was probably a very minor issue. But you _did_
> need to be very rich to get one in the first place.  If you had any
> sanity at all (not all rich people do :), you probably also needed a
> very good product idea before you could justify the kind of investment
> such a machine represented, _and_ you needed to be pretty successfull
> in the execution of your project to defend the investment afterwards.
> This last issue was probably particularly true if your project ran
> over budget, didn't complete properly or ran into any number of other
> problem not necessarily related to your unconventional choice of
> plattform
> 
> Now, are these kinds of issues marketing issues? Yes probably.

We seem to have lots of opinions, with a fair amount
of blame placement on management.  But you don't get to manage
a start-up with that many high-powered brains, unless
you are really good and proven.  So I still doubt the
"bad management" theory very much.

Maybe Lisp is just not suited for commercial use.  I have
also seen (been at, actually) a very highly successful
company, SAI, bet the farm on Lisp-like languages, and
lose it big.  Lisp success stories dramatic enought to balance
that, seem to be missing.

Or maybe it was just some really bad Karma :-)  I understand rms
was very unhappy with at least one of these dudes...
From: Erik Naggum
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <3070806242699875@naggum.no>
* M. Prasad
| We seem to have lots of opinions, with a fair amount of blame placement
| on management.  But you don't get to manage a start-up with that many
| high-powered brains, unless you are really good and proven.  So I still
| doubt the "bad management" theory very much.

I think it would be instructive for you to study the demise of Lucid, Inc.
and the way its founder, Richard P. Gabriel, was treated by the investors
(the _actual_ managers) of the company.

if a company fails, it's because of bad management.  if it succeeds, it's
because of good employees.  that is, companies with good employees and bad
management fail.  companies with bad employees and good management fail.
the latter combination does not occur in practice.

however, more often than not, the whoever holds the purse is the actual
management of a company.  and more often than not, people who make lots of
money are good at screwing people who trusted them, not at making good
technical decisions.  (no, Bill Gates is not an exception to this rule.)
and if you make good technical decisions, you need a small, privately held
company to make it to manager.

a quick look at the Lisp industry will show you what kind of people lead
them, what kind of companies are really in this market, and also the
commonality of the failures.  this is another reason I want to work with
Lisp.  I don't want to deal with software companies that let people like
John Ousterhout do their marketing.  (does that wrap this up?  nah.)

#\Erik
-- 
if we work really hard, will obsolescence be farther ahead or closer?
From: M. Prasad
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335E4E2F.776E@polaroid.com>
Erik Naggum wrote:
> 
> * M. Prasad
> | We seem to have lots of opinions, with a fair amount of blame placement
> | on management.  But you don't get to manage a start-up with that many
> | high-powered brains, unless you are really good and proven.  So I still
> | doubt the "bad management" theory very much.
> 
> I think it would be instructive for you to study the demise of Lucid, 

Is it just my perception, or does this gent really
have a severe attitude problem?
From: Rajappa Iyer
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <xnyenc1a2tt.fsf@placebo.hr.lucent.com>
"M. Prasad" <·······@polaroid.com> writes:

> Erik Naggum wrote:
> > 
> > * M. Prasad
> > | We seem to have lots of opinions, with a fair amount of blame placement
> > | on management.  But you don't get to manage a start-up with that many
> > | high-powered brains, unless you are really good and proven.  So I still
> > | doubt the "bad management" theory very much.
> > 
> > I think it would be instructive for you to study the demise of Lucid, 
> 
> Is it just my perception, or does this gent really
> have a severe attitude problem?

Erik may have an attitude problem, but what he writes is generally
right on. Why don't you take the high road and address the relevant
portions of his post and ignore the attitude?

Regards,
Rajappa
-- 
Rajappa Iyer <··········@fragola.hr.lucent.com>	   #include <std_disclaimer>
	They also surf who only stand on the waves.
From: M. Prasad
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335F508D.717A@polaroid.com>
Rajappa Iyer wrote:

> Erik may have an attitude problem, but what he writes is generally
> right on. Why don't you take the high road and address the relevant
> portions of his post and ignore the attitude?

I have watched this individual insert personal attacks
on an opponent (most recently on Ousterhout,) for no
good reason, in a discussion on something technical.

Personally, I don't like this -- and I think at some point
that _is_ an important issue in itself.  Erik very often knows
what he is talking about, but this does not give him
the right to needlessly attack others.  I don't
think this should be encouraged.
From: Samuel L. Bayer
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jnt59$bvh@top.mitre.org>
Look, I don't know what newsgroups the clowns responsible for posting this
thread all over creation actually live, but speaking for comp.lang.python,
I frankly couldn't care less whether Erik and M. Prasad shoot each other
in a duel, but I DO care whether my newsgroup continues to be flamed by
this ad hominem, irrelevant debate. I'm going to start a trend: I'm not 
posting this back to comp.lang.python. 

Take it outside, guys.
From: Erik Naggum
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <3070815436720561@naggum.no>
* M. Prasad
| Is it just my perception, or does this gent really have a severe attitude
| problem?

it's just your perception.  or rather, your uncanny ability to provoke.  if
you set out rumors about somebody or attack them without cause, such as you
do, I think it's evidence of a serious character flaw to attack them of
attitude problems if they don't like it.

specifically, I'm reacting to the persistent unfairness in your messages.
again, I find your negativism indicative of something more serious than
just attitude problems.  in fact, I think you appear to be vengeful and
unable to think clearly because negative emotions cloud your judgment.

this is the rest of the article from M. Prasad that I replied to:

    Maybe Lisp is just not suited for commercial use.  I have
    also seen (been at, actually) a very highly successful
    company, SAI, bet the farm on Lisp-like languages, and
    lose it big.  Lisp success stories dramatic enought to balance
    that, seem to be missing.

    Or maybe it was just some really bad Karma :-)  I understand rms
    was very unhappy with at least one of these dudes...

what have we learned from this?  which facts are communicated?  which ideas
have seen expression?  M. Prasad is the antithesis of communication.

the other day, we could read the following fascinating comments from him:

    How about you stop giving Lisp a bad name with these tactics of yours?
    It gives the impression that Lisp is only used by fanatics.

    (I suggest that other people who do not want to see this impression
    continue, should join in an attempt to squelch this highly errant
    behavior...)

    > again, why should anyone trust your judgment on this?  you are
    > clearly unable to recognize the simple fact that you don't know Lisp
    > in practice well enough to pass judgment on it.  yet you make a big
    > stink about

    Never stopped *you* from making comments about Lisp, now, did it?

these aren't arguments, this doesn't bring anything new to any discussion,
this only hits on Lisp (and/or me) for no good reason.  such is M. Prasad's
modus operandi.  M. Prasad goes on to prove that he has nothing whatsoever
to tell any of us in the article I'm responding to.

M. Prasad, to be specific, you seem to have a problem with _me_, not with
anything I do or say or think, but with me and only with me.  if you wish
to solve this problem, you can mail me, we can talk about it, and you can
perhaps get a (peaceful) life.  if you _don't_ want to solve your problem,
do it _away_ from USENET, OK?

#\Erik
-- 
if we work really hard, will obsolescence be farther ahead or closer?
From: Donal K. Fellows
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jn6bf$2hl@m1.cs.man.ac.uk>
[ I'm not quoting the original message, as you can read so many like
  it on USENET... ]

Erik, your problem with M. Prasad does not really belong in any of the
groups in the Newsgroups: line, but rather private email or alt.flame
instead [followups set].  I do happen to agree with MP that you are
not doing a particularly good job of advocacy (for that is what you
are doing) and that a more considered style of correspondence would be
more likely to be successful.  In particular, your "facts" often seem
to be either inaccurate, wrong or irrelevant to the discussion (which
has wandered a long way from comp.lang.tcl's charter too).

Donal.
--
Donal K. Fellows   http://r8h.cs.man.ac.uk:8000/  (SAY NO TO COMMERCIAL SPAMS!)
(work) ········@cs.man.ac.uk     Dept. Comp. Sci, Univ. Manchester, U.K.
 |     ·····@ugglan.demon.co.uk  6,Randall Place, Heaton, Bradford, U.K. (home)
 +-> ++44-161-275-6137  Send correspondence to my office  ++44-1274-401017 <-+
From: C. H. Graham
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jnn7d$man@nr1.toronto.istar.net>
The pot calls the kettle black...

Donal K. Fellows <···········@man.ac.uk> wrote in article
<··········@m1.cs.man.ac.uk>...
> [ I'm not quoting the original message, as you can read so many like
>   it on USENET... ]
> 
> Erik, your problem with M. Prasad does not really belong in any of the
> groups in the Newsgroups: line, but rather private email or alt.flame
> instead [followups set].  I do happen to agree with MP that you are
> not doing a particularly good job of advocacy (for that is what you
> are doing) and that a more considered style of correspondence would be
> more likely to be successful.  In particular, your "facts" often seem
> to be either inaccurate, wrong or irrelevant to the discussion (which
> has wandered a long way from comp.lang.tcl's charter too).
> 
> Donal.
> --
> Donal K. Fellows   http://r8h.cs.man.ac.uk:8000/  (SAY NO TO COMMERCIAL
SPAMS!)
> (work) ········@cs.man.ac.uk     Dept. Comp. Sci, Univ. Manchester, U.K.
>  |     ·····@ugglan.demon.co.uk  6,Randall Place, Heaton, Bradford, U.K.
(home)
>  +-> ++44-161-275-6137  Send correspondence to my office 
++44-1274-401017 <-+
> 
From: Erik Naggum
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <3070880758138585@naggum.no>
* Donal K. Fellows
| In particular, your "facts" often seem to be either inaccurate, wrong or

no, Donal, my facts are not inaccurate.  what I write is very seldom wrong.
when I am uncertain or know that I lack information to be certain, I don't
post.  (this does make the errors I make important, but it's easy to fix
big mistakes.  it is much harder to correct minor mistakes, so I have set a
goal not to make minor mistakes.)  I may have strong opinions on certain
issues, but that's not where you see me most irate.  the only thing I truly
hate is unmethodical people, because it is impossible to trust anything
they say.  if you have no consistent methodology for separating wish from
opinion from uncertainty from certainty, you _will_ post drivel and confuse
issues and make a hell of a lot of _easily avoidable_ mistakes.  _that_ is
what I object to in many articles.  (and no, even if your job is advocacy,
that doesn't make everybody else's job advocacy.  to correct misinformation
is more than enough work.  somebody else can do the advocacy.)

#\Erik
-- 
if we work really hard, will obsolescence be farther ahead or closer?
From: M. Prasad
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335F466D.5213@polaroid.com>
Erik Naggum wrote:

> the other day, we could read the following fascinating comments from him:
> 
>     How about you stop giving Lisp a bad name with these tactics of yours?
>     It gives the impression that Lisp is only used by fanatics.

This message of mine was preceded by several quotations
from you, which to me appeared ample justification.
I did not make a target of you for no good reason.
You were out there inserting personal attacks (on
one Mr. Ousterhout) in a technical discussion -- you
should be ready to take your own medicine.

You obviously have a following on the Usenet from
those who enjoy seeing the personal attacks.  But
I still don't think Lisp'ers do their cause any
favors by showing wild support to an attitude
like this.
From: Erik Naggum
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <3070883923129869@naggum.no>
* M. Prasad
| You obviously have a following on the Usenet from those who enjoy seeing
| the personal attacks.

you know, that tar brush you're wielding is awfully broad -- you must be
the biggest fan ever of personal attacks, so if there were _only_ personal
attacks in my messages (such as in yours), I'd fully expect you to enjoy
them and even request advance tickets to the live show.  but no, you and
all others who seem to enjoy (or hate) my articles, do so because I make
technically valid points, contradict hype, demonstrate ignorance, and
destroy "marketing arguments" aimed solely at the ignorant masses.  people
are certainly allowed to be ignorant, lying, mass-market propagandists, but
if they try to claim they are something else, they must be exposed.  I do
that.  some find it very entertaining.  this would not be possible with the
kind of personal attacks that you work so hard to find in my articles to
the exclusion of everything else they contain, but it's hard to show that
somebody is a pathological liar _in_ his arguments without at least someone
confusing the issue and thinking that his (in their opinion valid) argument
is dismissed _because_ he is called a pathological liar (which would have
been an argumentum ad hominem).

I don't think _I_ have a following.  I think people would like to see the
arguments I'm making more often, and are happy that I make them.  if _I_
had a following, it would be immaterial what I wrote, and the idiocy you
attribut to them would be possible.  fortunately, I have never met anyone
who has suggested that they like my articles because of the harsh treatment
I give the incompetent fools I don't suffer -- that's just the spice.  for
many it's actually too hot.  but very few are unable to taste the real meat
only because they are too sensitive to the spice.  curiously, those who are
seem to be candidates for world championship in personal attacks without
any form of substantiation, giving like M. Prasad serious competition.

it is typical of such lame-brained idiots to associate something they don't
think they like with something they already hate, to justify things to
themselves, I guess.  M. Prasad thinks of Lisp.  the other day, I got a
very nasty letter from some environMENTAList who accused me of being in
favor of multiple death sentences on anti-whaler Paul Watson since I'm from
Norway.  events like these remind me of a joke about Stevie Wonder, who was
asked "have you never been discriminated against because you're blind?"
where he shall have answered "no, but I'm glad I'm not black -- I hear
that's rough."

(this article was sponsored by the Lisp Defamation League.)

#\Erik
-- 
if we work really hard, will obsolescence be farther ahead or closer?
From: Frederic BONNET
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <3360CA87.6F1B@irisa.fr>
Following the example of Samuel L. Bayer (···@linus.mitre.org), I've
removed comp.lang.tcl from the Xpost list. I think most people there
don't care about the Erik Naggum vs. M. Prasad shootout.

TIA.

See you, Fred
From: CsO
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <u4tcwd2ym.fsf@gecm.com>
"M. Prasad" <·······@polaroid.com> writes:
[about Erik Naggum]
> You obviously have a following on the Usenet from
> those who enjoy seeing the personal attacks.  But
> I still don't think Lisp'ers do their cause any
> favors by showing wild support to an attitude
> like this.
I don't this Eric has a 'following' or 'wild support' for his
attitude. A few individuals have simply pointed out that if you read
what he says it is often spot on.
BTW I think Eric may have done a lot more for Lispers & their cause
than you give him credit for. Try asking him a question & he might
well try his best to help *you* out.
From: Cyber Surfer
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <MPG.dc91c2f50bc979798979d@news.demon.co.uk>
With a mighty <·············@polaroid.com>,
·······@polaroid.com uttered these wise words...

> Is it just my perception, or does this gent really
> have a severe attitude problem?

He's making a valid point: study the reasons for the failures and 
learn from them. Lucid failed for purely business reasons, not 
anything technical. I doubt that MS, for example, will fail for the 
same reasons, but perhaps 15 years ago, when they were much smaller, 
they could've. The lesson here may to be take great care when entering 
a new market (e.g. C compilers).

On the hardware front, CCC failed not because the Cray 4 didn't work 
(apparently it _did_ work), but because they ran out of money before 
finding their first customer. Ask any of the ex-CCC employees, if you 
have doubts. Another $30 million could've saved the company, i.e. the 
cost of one sale. This is a sad way for a company to die, but it has 
nothing to do with the quality of the product.

Lucid also died because of a business gamble. Perhaps they should've 
tried the data-mining market, instead.

All I'll say about Erik's attitude is that he's being well and truely 
provoked. Nobody needs an attitude problem to react strongly to your 
argument - not that I recommend anything but sober debate. Insults 
won't get us anywhere useful.
-- 
<URL:http://www.wildcard.demon.co.uk/> You can never browse enough
  Martin Rodgers | Programmer and Information Broker | London, UK
            Please note: my email address is gubbish.
From: Mike Coffin
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jo1mp$11s@engnews1.Eng.Sun.COM>
In article <·············@polaroid.com>,
M. Prasad <·······@polaroid.com> wrote:

>Is it just my perception, or does this gent [Eric Naggum] really
>have a severe attitude problem?

Eric is a very smart and knowledgable person who makes a lot of very
good points on many subjects.  I suggest you do what many of us do:
ignore his rhetorical flourishes and personal opinions, but pay
attention to his technical arguments.

-mike
From: Henry Baker
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <hbaker-2304971254470001@10.0.2.1>
In article <·············@polaroid.com>, ·······@polaroid.com wrote:

> Maybe Lisp is just not suited for commercial use.  I have
> also seen (been at, actually) a very highly successful
> company, SAI, bet the farm on Lisp-like languages, and
> lose it big.  Lisp success stories dramatic enought to balance
> that, seem to be missing.

Gensym? Cadence?
From: Paul Prescod
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <E957En.J6@undergrad.math.uwaterloo.ca>
In article <·············@polaroid.com>,
M. Prasad <·······@polaroid.com> wrote:
>We seem to have lots of opinions, with a fair amount
>of blame placement on management.  But you don't get to manage
>a start-up with that many high-powered brains, unless
>you are really good and proven.  

???

You have a frightening faith in capitalism. It doesn't work that well,
though that's what they would like you to believe.

 Paul Prescod
From: M. Prasad
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335F990B.6D5F@polaroid.com>
Paul Prescod wrote:
> 
> In article <·············@polaroid.com>,
> M. Prasad <·······@polaroid.com> wrote:
> >We seem to have lots of opinions, with a fair amount
> >of blame placement on management.  But you don't get to manage
> >a start-up with that many high-powered brains, unless
> >you are really good and proven.
> 
> ???
> 
> You have a frightening faith in capitalism. It doesn't work that well,
> though that's what they would like you to believe.
> 
>  Paul Prescod

I don't mean all startups are like that...  But the
cases discussed here were very high visibility ones.
From: Chris Bitmead uid(x22068)
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <s6y2081m6w2.fsf@aalh02.alcatel.com.au>
"M. Prasad" <·······@polaroid.com> writes:

> We seem to have lots of opinions, with a fair amount
> of blame placement on management.  But you don't get to manage
> a start-up with that many high-powered brains, unless
> you are really good and proven.  So I still doubt the
> "bad management" theory very much.

All too often start-ups are not managed by people who really
understand the technology and where they should be headed. Often they
are glorified salesmen and hype merchants.

I can think of several start-up companies which should be taking the
market by storm, but can't get it together.
From: Tim Bradshaw
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <ey3ohb3uxrv.fsf@staffa.aiai.ed.ac.uk>
(newsgroups trimmed)

* M Prasad wrote:
[About failure of LMI/Symbolics]

> We seem to have lots of opinions, with a fair amount
> of blame placement on management.  But you don't get to manage
> a start-up with that many high-powered brains, unless
> you are really good and proven.  So I still doubt the
> "bad management" theory very much.

I suspect bad management had quite a lot to do with it actually.
There are stories (from people who worked for them) about Symbolics
saying `we're going to be making xxx 3620s (or some other small
machine) a month by next year, so we need to buy all this expensive
factory space', when xxx was comparable to the number of Lisp
programmers then in the world.  Sounds like a recipe for disaster to
me, and not surprisingly it was.

--tim
From: Bj�rn Remseth
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <ajiv18ydc8.fsf@hridil.ifi.uio.no>
"M. Prasad" <·······@polaroid.com> writes:

> We seem to have lots of opinions, with a fair amount
> of blame placement on management.  But you don't get to manage
> a start-up with that many high-powered brains, unless
> you are really good and proven.  So I still doubt the
> "bad management" theory very much.

Didn't say it was "bad", and I don't remember mentioning blame
anywhere in my message.  Perhaps what I described was good management
in practice, perhaps the lisp machines deserved to die, and the
mechanisms i sketched out was just how they went about to do it.

-- 
                                                    (Rmz)

Bj\o rn Remseth   !Institutt for Informatikk    !Net:  ···@ifi.uio.no
Phone:+47 22855802!Universitetet i Oslo, Norway !ICBM: N595625E104337
From: Bj�rn Remseth
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <ajg1wcyab1.fsf@hridil.ifi.uio.no>
"M. Prasad" <·······@polaroid.com> writes:

> We seem to have lots of opinions, with a fair amount
> of blame placement on management.  But you don't get to manage
> a start-up with that many high-powered brains, unless
> you are really good and proven.  So I still doubt the
> "bad management" theory very much.

Didn't say it was "bad", and I don't remember mentioning blame
anywhere in my message.  Perhaps what I described _was_ good
management in practice, perhaps the lisp machines deserved to die, and
the mechanisms i sketched out was just how they went about to do it?
I simply don't make any judgement one way or the other, I observe
and try as best I can to understand.

-- 
                                                    (Rmz)

Bj\o rn Remseth   !Institutt for Informatikk    !Net:  ···@ifi.uio.no
Phone:+47 22855802!Universitetet i Oslo, Norway !ICBM: N595625E104337
From: Henry Baker
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <hbaker-2104972333170001@10.0.2.1>
In article <·············@polaroid.com>, ·······@polaroid.com wrote:

> If this experience is BS, what is the truth?  Why _did_
> the Lisp machines die?  People keep blaming "marketing", but
> did LMI/Symbolics founders not have enough smarts or the money
> to hire some good marketing people?  I would doubt either
> of these two was the case.
> 
> Or maybe the machines were just too expensive to produce,
> to be able to sell them successfully.

The very short answer is that Symbolics promised a 'Lisp Chip' within
a certain time frame that would bring the price down to the point of
being available to the masses, and they were many years late with this chip.
The chip itself wasn't all that complicated, but the politics surrounding
getting it funded certainly were.
From: Bill House
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <01bc4f8b$1f0067e0$03d3c9d0@wjh_dell_133.dazsi.com>
M. Prasad <·······@polaroid.com> wrote in article
<·············@polaroid.com>...
> 
> Or maybe the machines were just too expensive to produce,
> to be able to sell them successfully.
> 
I think you've hit the nail on the head -- the Lisp machines probably died out
because smaller, cheaper general purpose machines overtook them -- an economy
of scale thing.

If there were a generally-available Lisp VM that was tightly integrated with
Windows, MacOS and UNIX, providing binary portability across those platforms,
do you think it would be successful in today's market?

Bill House
-- 
http://www.dazsi.com
Note: my e-mail address has been altered to
confuse the enemy. The views I express are
mine alone (unless you agree with me).
From: Marc Wachowitz
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jlcmp$r1g$1@trumpet.uni-mannheim.de>
Bill House (······@dazsi.nospam.com) wrote:
> If there were a generally-available Lisp VM that was tightly integrated with
> Windows, MacOS and UNIX, providing binary portability across those platforms,
> do you think it would be successful in today's market?

If you're looking for a reasonably expressive VM from a not too narrow
background, it may be worth following the fate of "Inferno", in case it
gains reasonable market share. For more info, see comp.os.inferno, and

http://inferno.bell-labs.com/inferno/index.html
          
ftp://ftp.ugcs.caltech.edu/pub/ryip/infdoc


-- Marc Wachowitz <··@ipx2.rz.uni-mannheim.de>
From: Rainer Joswig
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <joswig-ya023180002504970806120001@news.lavielle.com>
In article <··························@wjh_dell_133.dazsi.com>, "Bill
House" <······@dazsi.nospam.com> wrote:

> M. Prasad <·······@polaroid.com> wrote in article
> <·············@polaroid.com>...
> > 
> > Or maybe the machines were just too expensive to produce,
> > to be able to sell them successfully.
> > 
> I think you've hit the nail on the head -- the Lisp machines probably died out
> because smaller, cheaper general purpose machines overtook them -- an economy
> of scale thing.

The early Lisp machines were not designed to compete with the Macs, the
PCs, the "workstations". They were targetting a dying market
(they were big, complicated, expensive, ...). To be successful
one had to be less arrogant. The technological base was
cool, but usable only by a few. It was more like selling
research systems. A next generation would have brought
the breakthrough (IMHO), but that never happened.

A new Lisp machine would be different. It would be market- and
customer-driven, instead of mostly technology-driven.
Use existing hardware standards and write applications
that can be used on conventional Lisp systems, too.

-- 
http://www.lavielle.com/~joswig/
From: Ray Dillinger
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335BB755.4B88@sonic.net>
Henry Baker wrote:
> 
> In article <············@news.utdallas.edu>, ········@utdallas.edu (Mark A
> Harrison) wrote:

> > Example: My former roomate (mid-80's) was a chip designer.  He had
> > two giant systems on his desk, a lisp machine (TI Explorer?) and
> > an Apollo.  He was always complaining about how inconvenient it
> > was that part of his work was done on the lisp machine (chip design)
> > and that the rest was done on the Apollo (word processing, email,
> > manufacturing apps).  

> This is complete BS.  The lisp machines had fabulous email systems,
> and Symbolics went to a great deal of trouble to make TeX run on its
> Lisp Machine.  

Lisp machines may have had fabulous email systems, but how much good 
does that do if the rest of the company is running on *another* email 
system?  You want to buy lisp machines for every secretary and marketing 
rep, just so they can all use the same email system?

And who told you that TeX was an acceptable format for WP documents in 
that company?

I realize this sounds goofy today, when email is 99+% IP/SMTP and every 
system that supports email supports that standard, but even today you get 
similar problems when some schmoe decides to run a braindead product like 
MS-Mail -- every UNIX user on the system then has to either get a bitty 
box crippled with an MS operating system or scream in rage at what MS-mail 
does to the formatting as it makes its pathetic attempt to convert to
"standard" email format.  Normally this is a mere annoyance, but if part 
of the mail you're passing is sourcecode, getting the format hashed or 
unexpected line breaks or quote characters inserted can kill you.

If everybody else in the company was running some proprietary email system 
and the lisp machine/software wasn't compatible with it (PC-pursuit anyone?
or FIDOmail? ) then it really doesn't matter how good the lisp machine's 
email facilities are/were.

In exactly the same way, it doesn't matter how good any language is, if 
it can't call out to the compiled C code that everyone else in the company 
is writing and produce compiled modules that can be called from the C 
that everyone else in the company is writing.  Being good isn't enough; 
email systems and development tools also have to fit in their environment.

					Bear



					Bear
From: Henry Baker
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <hbaker-2104972339270001@10.0.2.1>
In article <·············@sonic.net>, Ray Dillinger <····@sonic.net> wrote:
> Lisp machines may have had fabulous email systems, but how much good 
> does that do if the rest of the company is running on *another* email 
> system?  You want to buy lisp machines for every secretary and marketing 
> rep, just so they can all use the same email system?

Symbolics email system was compatible with every email system on the
arpanet, from unix boxes, to vms boxes, to dec-20 boxes, to pc's.  If Apollo
couldn't handle internet mail, then that was Apollo's problem, not the Lisp
Machines.

There were _some_ forms of mailer gateways, and in the later years, Symbolics
may very well have supported those, as well.

Oh by the way, I understand that all of the email sent to the White House
is being handled by a Lisp mail system that may very well be still running
on a Lisp Machine.  This project was being run out of MIT a year or two
ago.
From: Ray Dillinger
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335C6CCB.1E1F@sonic.net>
Henry Baker wrote:
> 
> In article <·············@sonic.net>, Ray Dillinger <····@sonic.net> wrote:
> > Lisp machines may have had fabulous email systems, but how much good
> > does that do if the rest of the company is running on *another* email
> > system?  You want to buy lisp machines for every secretary and marketing
> > rep, just so they can all use the same email system?
> 
> Symbolics email system was compatible with every email system on the
> arpanet, from unix boxes, to vms boxes, to dec-20 boxes, to pc's.  If Apollo
> couldn't handle internet mail, then that was Apollo's problem, not the Lisp
> Machines.

Oh, how nice, if the rest of your business happens to be using SMTP 
email (SMTP was the standard on ARPANET, as I recall, even back before 
it became the internet).  But at the time, there WAS NO STANDARD that 
commanded more than a small fraction of the market.  ARPANET was a few 
thousand machines mostly at military bases and a few universities.  
Software houses were using PC-pursuit and SEADOG, for godssake!  They 
went for SMTP no doubt because it was the biggest -- but even so, I bet 
it "fit in" with less than a quarter of their clients' email systems.

> There were _some_ forms of mailer gateways, and in the later years, Symbolics
> may very well have supported those, as well.

Mailer gateways?  You wanna send interoffice memos through mailer 
gateways in 1984? All the mailer gateways that existed at the time 
required you to stand on your head, manually fill in forward-to 
addresses, click your heels together three times, do a backflip,
keep your lines shorter than 40 characters and your posts under 
80 lines long, wave a dead chicken over your monitor, and guess 
how many nulls your host needed at end-of-line.  Most of them 
delayed mail by at least four hours, and most of them reformatted 
your mail for line length -- and let's not forget dropping 
characters on the floor due to line noise about every two lines 
(remember, at that time if it wasn't arpanet it didn't have an 
error-correcting protocol).

Mailer gateways were a bleeding nightmare in 1984.  I know, because 
I ran one.  You don't wanna go there, really.  

				Bear



> 
> Oh by the way, I understand that all of the email sent to the White House
> is being handled by a Lisp mail system that may very well be still running
> on a Lisp Machine.  This project was being run out of MIT a year or two
> ago.
From: D. M. H. Walker
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335CCA76.2594@cs.tamu.edu>
I've trimmed the ridiculous cross-post list.

Henry Baker wrote:
> In article <············@news.utdallas.edu>, ········@utdallas.edu (Mark A
> Harrison) wrote:
> > Lisp machines died because their
> > functionality was supplanted by other more general purpose machines.
> This is complete BS.  The lisp machines had fabulous email systems,
> and Symbolics went to a great deal of trouble to make TeX run on its
> Lisp Machine.  The Symbolics Lisp Machine documentation was generated and
> edited on Lisp Machines. 
> 
> You can argue about whether a machine as expensive as the Symbolics Lisp
> Machines should have been doing email, but that is an entirely different
> question from whether they did it.  Yes, they did.

You are both right.  LISP machines had nice environments.  But they were
built of, by, and for the LISP priesthood using a
functionality-is-everything approach.  As a result, they were so
expensive that only a few people could buy them.  And many of these
customers abandoned LISP machines when something acceptable and much
cheaper came along.

The fundamental error that the LISP machine companies (and Xerox and
NeXT) made was thinking that high functionality and high price was
viable because the software would be developed by the company and its
customers.  History has shown that the key to success is a large
third-party software base, and this base only appears when the potential
market is large enough, which means the machine has to be cheap enough. 
Sun understood this early on.  And of course DEC workstations could run
all existing DEC software.  I once heard a good talk about the economic
issues at the Design Automation Conference by Bill Joy.  Note that even
at the time LISP machines hit the market, many people (like me)
predicted their failure due to their high cost and divergence from the
technology curve (i.e. killer micros would kill them).
From: Henry Baker
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <hbaker-2204971034120001@10.0.2.1>
In article <·············@cs.tamu.edu>, "D. M. H. Walker"
<······@cs.tamu.edu> wrote:

> The fundamental error that the LISP machine companies (and Xerox and
> NeXT) made was thinking that high functionality and high price was
> viable because the software would be developed by the company and its
> customers.  History has shown that the key to success is a large
> third-party software base, and this base only appears when the potential
> market is large enough, which means the machine has to be cheap enough. 

I agree that Lisp Machines were too expensive to reach a mass market.
But don't confuse SW functionality with cost.  The SW part of the
Lisp Machine functionality was cheap.  The HW part was expensive, and
Symbolics & TI did not do what they needed to do to get their HW costs
down.

The amount of memory and disk that cost Symbolics so much back then is
quite cheap today.  Even now, the cost of a medium workstation is not
in the processor, but in the display, the memory, the disk, etc., etc.

Symbolics realized how important certain things like a large screen
(in terms of resolution) were to productivity, and they paid a big
price for this in terms of cost.  But I never heard any of our customers
complain about the big displays---they loved them!
From: ozan s. yigit
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <x6wwpux310.fsf@ds9.rnd.border.com>
re: lisp machines and software

some years ago, i unsuccessfully tried to locate the source tapes
for lmi because it seemed that all this good software could be put to
use again, under cheaper hardware. [it would also give people something
to look at instead of just imagining what it must have been like]

where is greenblatt?

oz
From: Henry Baker
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <hbaker-2204972210260001@10.0.2.1>
In article <··············@ds9.rnd.border.com>, ··@ds9.rnd.border.com
(ozan s. yigit) wrote:

> re: lisp machines and software
> 
> some years ago, i unsuccessfully tried to locate the source tapes
> for lmi because it seemed that all this good software could be put to
> use again, under cheaper hardware. [it would also give people something
> to look at instead of just imagining what it must have been like]
> 
> where is greenblatt?
> 
> oz

The last phone number I had was 617.547.7171.  The last email address was
something like ··@ai.ai.mit.edu  (note the _two_ ai's).
From: Olin Shivers
Subject: Source tapes for LispM's
Date: 
Message-ID: <qijohb57hss.fsf_-_@lambda.ai.mit.edu>
> In article <··············@ds9.rnd.border.com>, ··@ds9.rnd.border.com
> (ozan s. yigit) wrote:
> 
> > re: lisp machines and software
> > 
> > some years ago, i unsuccessfully tried to locate the source tapes
> > for lmi because it seemed that all this good software could be put to
> > use again, under cheaper hardware. [it would also give people something
> > to look at instead of just imagining what it must have been like]
> > 
> > where is greenblatt?

This might not be necessary. In 1985, when I worked at CMIRH in Paris, they
ran LispM's with software that Stallman almost single-handledly
maintained. The Chineual manual for RMS's free version was orange, not blue or
black. Richard was just around then pinning down his free software philosophy,
which is why he'd taken to supporting this system -- to have a copy not
owned by Symbolics. You could contact RMS to see about getting ahold of these
bits.

However. You wouldn't be getting the Genera stuff Symbolics did later.

You might also do well to talk to John Mallery, who is a current LispM user
(and a very productive one) -- ····@ai.mit.edu. John knows what's what at the
current-day Symbolics. I have heard they've ported their whole system over to
an Alpha byte-code emulator. I imagine it's for commercial customers that
absolutely gotta run their important LispM systems (e.g., the military
logistics guys or perhaps the White House). He could point you to people
at Symbolics with whom you should speak if you thought they ought to make
a cheap version of their system available for random users -- Peter Deutsch
does quite well, I hear, giving away ghostscript to randoms and selling it
to companies.

Finally, I would talk to Howie Shrobe (···@ai.mit.edu) and David Moon.
They would probably know where you could get ahold of the bits.
    -Olin
From: Jeffrey Mark Siskind
Subject: Re: Source tapes for LispM's
Date: 
Message-ID: <xohohb4go1v.fsf@ai.emba.uvm.edu>
Olin Shivers <·······@lambda.ai.mit.edu> writes:

> This might not be necessary. In 1985, when I worked at CMIRH in Paris, they
> ran LispM's with software that Stallman almost single-handledly
> maintained. The Chineual manual for RMS's free version was orange, not blue or
> black. Richard was just around then pinning down his free software philosophy,
> which is why he'd taken to supporting this system -- to have a copy not
> owned by Symbolics. You could contact RMS to see about getting ahold of these
> bits.
> 
> However. You wouldn't be getting the Genera stuff Symbolics did later.
> 
> You might also do well to talk to John Mallery, who is a current LispM user
> (and a very productive one) -- ····@ai.mit.edu. John knows what's what at the
> current-day Symbolics. I have heard they've ported their whole system over to
> an Alpha byte-code emulator. I imagine it's for commercial customers that
> absolutely gotta run their important LispM systems (e.g., the military
> logistics guys or perhaps the White House). He could point you to people
> at Symbolics with whom you should speak if you thought they ought to make
> a cheap version of their system available for random users -- Peter Deutsch
> does quite well, I hear, giving away ghostscript to randoms and selling it
> to companies.
> 
> Finally, I would talk to Howie Shrobe (···@ai.mit.edu) and David Moon.
> They would probably know where you could get ahold of the bits.

FWIW, the the Technology Licensing Office at MIT used to license System 98,
the last version of the CADR software released when the LISPM project was
still at MIT. The CADR and System 98 were the common basis of Symbolic's LM-2,
the LMI Lambda, and the TI Explorer. All three efforts later diverged. For all
I know, you might still be able to get a copy of System 98 from the TLO.

    Jeff (home page http://www.emba.uvm.edu/~qobi)
From: Georg Bauer
Subject: Source tapes for LispM's
Date: 
Message-ID: <199704241936.a12266@ms3.maus.de>
Hi!

OS> He could point you to people
OS> at Symbolics with whom you should speak if you thought they ought to
make
OS> a cheap version of their system available for random users

I once asked Symbolics for a copy of CLOE - the DOS/Windows-based version
of their Emulator. The product isn't in store anymore, so I thought they
might sell it for a nominal fee. I was wrong. They wanted the full price -
some thousand bucks. Too bad. Ok, I do have a 3640, so I can get my hands
on Genera, but a portable Symbolics - even if it is only a emulation -
would be really great. Just to complete my collection ;-)

bye, Georg
From: Bill Gooch
Subject: Re: Source tapes for LispM's
Date: 
Message-ID: <3361444D.2BC6@flash.net>
Georg Bauer wrote:
>  
> I once asked Symbolics for a copy of CLOE - the DOS/Windows-based version
> of their Emulator. 

CLOE (on the Windoze side) was never an "emulator," 
it was just a Common Lisp + CLIM compiler and runtime.  
It did not implement most of the Symbolics extensions 
to Common Lisp, and it was not by itself a development 
environment worth mentioning.  Coupled with the LispM
side CLOE environment, though, it was pretty neat as 
a way to develop LispM code and port it to PCs.  (This
would have been especially true with a more mature CLIM 
than the broken early-beta one I used.)

>  The product isn't in store anymore, so I thought they
> might sell it for a nominal fee. I was wrong. They wanted the full price -
> some thousand bucks. Too bad.  Ok, I do have a 3640, so I can get my hands
> on Genera, but a portable Symbolics - even if it is only a emulation -
> would be really great. Just to complete my collection ;-)

CLOE is certainly not a "portable Symbolics."  That still
doesn't exist, and if we'd had such a thing at the time 
CLOE was released, I think Symbolics might have been able
to make a decent comeback.

-- 
Bill Gooch			······@flash.net
From: Georg Bauer
Subject: Re: Source tapes for LispM's
Date: 
Message-ID: <199704271556.a20376@ms3.maus.de>
Hi!

BG> CLOE is certainly not a "portable Symbolics."

But it's as near as you can get. I don't know how to come as near to a
"portable Symbolics" any other way. And since I do have a 3640, I could
combine them two. Ah, no use in dreaming. I won't get CLOE, at least not if
it doesn't get much cheaper or someone sells me a used copy.

bye, Georg
From: Bill Gooch
Subject: Re: Source tapes for LispM's
Date: 
Message-ID: <3364F539.4FF5@flash.net>
Georg Bauer wrote:
> 
> BG> CLOE is certainly not a "portable Symbolics."
> 
> But it's as near as you can get. I don't know how to come as near to a
> "portable Symbolics" any other way. And since I do have a 3640, I could
> combine them two. Ah, no use in dreaming. I won't get CLOE, at least not if
> it doesn't get much cheaper or someone sells me a used copy.

Sadly (for you and for Symbolics), sale of a "used" copy
would violate the original license, which prohibits its
transfer to another party.

The other part of what I'm pointing out is that the PC
side of CLOE isn't worth the trouble unless you also get 
the Symbolics side, and use the two together.  Then again, 
you can just use Genera to develop CL code without using
SCL extensions, and then run it under Allegro CL (or some 
such) on the PC.

-- 
Bill Gooch			······@flash.net
From: Christopher J. Vogt
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <vogt-2104971424290001@204.248.25.27>
In article <············@news.utdallas.edu>, ········@utdallas.edu (Mark A
Harrison) wrote:

Try as I might not to reply to this, I just can't resist.  I admit it, I'm weak.

> Erik Naggum (····@naggum.no) wrote:
> 
> : the Lisp Machines died for reasons totally unrelated to quality.  actually,
> : they died for the same reason that mind-bogglingly inferior systems won.
> : the answer is a single word: "marketing".
> 
> I don't think this is true...  Lisp machines died because their
> functionality was supplanted by other more general purpose machines.

Exactly what functionality is it that can't be implemented on a LispM? 
Word processing?  email?  IMHO Eric is right, LispMs died to to
marketing.  Marketing is more than just advertisements in newspapers and
magazines.  Where marketing did in the LispM was in not getting
applications developed for the LispM, not pricing LispMs competively with
Suns and in selling LispMs as "Special Purpose Machines", ie. not "General
Purpose Machines".  

> 
> Example: My former roomate (mid-80's) was a chip designer.  He had
> two giant systems on his desk, a lisp machine (TI Explorer?) and
> an Apollo.  He was always complaining about how inconvenient it
> was that part of his work was done on the lisp machine (chip design)
> and that the rest was done on the Apollo (word processing, email,
> manufacturing apps).  When their software group was able to port
> their applications to the same box their other applications ran
> on, they dropped the lisp machine without hesitation.
> 
> In other words:  Marketing didn't kill lisp machines... Good lisp
> environments that ran on general-purpose computers killed
> lisp machines.

Not that I have seen it all, and I won't make any generalization here, but
*I* have yet to use a Lisp development environment that supported me as
well as Symbolics Genera did, and we're talking 15 year old technology
here!  If it were practical for me to use Genera right now, I would.  I
suspect that I'm not alone in feeling this way.

-- 
···········@novia.net
Omaha, NE
http://www.novia.net/~vogt/
From: Lyman S. Taylor
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5jgvh0$rj6@pravda.cc.gatech.edu>
In article <·····················@204.248.25.27>,
Christopher J. Vogt <····@novia.net> wrote:
>In article <············@news.utdallas.edu>, ········@utdallas.edu (Mark A
>Harrison) wrote:

>> : the Lisp Machines died for reasons totally unrelated to quality.....
....
>> : the answer is a single word: "marketing".
>> 
>> I don't think this is true...  Lisp machines died because their
>> functionality was supplanted by other more general purpose machines.
....

>....  Where marketing did in the LispM was in not getting
>applications developed for the LispM, not pricing LispMs competively with
>Suns and in selling LispMs as "Special Purpose Machines", ie. not "General
>Purpose Machines".  

   In the "priced to sell" catagory the LispM vendors probably could have sold
   anemic "subcompact" workstations to go along with their "Cadillac" 
   workstations too ( like the general purpose folks did...).

   To futher supplement that "it was the marketing.... " viewpoint, 
   BusinessWeek has an article this week about how the Alpha is both the 
   fastest general purpose microprocessor out. And the one with the smallest 
   market share. 

	http://www.businessweek.com/1997/17/b3524142.htm

   While marketing was not solely responsible in the Lisp Machine "demise", 
   it was a significant factor. There were a myriad of other contributing
   factors too that had very little to do with the differences in the 
   CPU's ( e.g. Symbolics real estate investments , etc. )
   
>> In other words:  Marketing didn't kill lisp machines... Good lisp
>> environments that ran on general-purpose computers killed
>> lisp machines.

   There was also the factor of moving "legacy" software over to the 
   LispM.  Although like attested to below, in some ways Genera was far ahead 
   of its time for its day.  However, some folks just can't let go of that
   trusty old 20 year old hammer ( legacy tools ).  Note that this also
   has little to do with the CPU's and more to do with the "operating system"
   API differences between "LispM OS" and classic workstation, "hacked up 
   Berkeley Unix tape", OS. 

>*I* have yet to use a Lisp development environment that supported me as
>well as Symbolics Genera did, and we're talking 15 year old technology
>here!  

-- 
					
Lyman S. Taylor           "I'm a Doctor, not a doorstop... "
(·····@cc.gatech.edu)     	The EMH Doctor in "Star Trek: First Contact".
 
			        
From: Matthew D. Healy
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <Matthew.Healy-2204971624420001@pudding.med.yale.edu>
In article <··········@pravda.cc.gatech.edu>, ·····@cc.gatech.edu (Lyman
S. Taylor) wrote:

> 
>    To futher supplement that "it was the marketing.... " viewpoint, 
>    BusinessWeek has an article this week about how the Alpha is both the 
>    fastest general purpose microprocessor out. And the one with the smallest 
>    market share. 
> 
>         http://www.businessweek.com/1997/17/b3524142.htm
> 

Yup.  I read this in the printed version of {Business Week} during my
lunch break today.

One especially interesting detail: _APPLE_ approached DEC about using
Alphas for their next generation of Macs, but DEC wasn't interested,
so they went the PowerPC route.

Apple's having their share of problems these days, mostly because their
long-standing tradition of shooting themselves repeatedly in both feet
finally caught up with them, so AlphMacs might not have saved them
from themselves, but wouldn't they have been _nifty_ boxes!

For of all sad words of tongue or pen,
The saddest are these: "It might have been!"�
-John Greenleaf Whittier

If, of all the words of tongue and pen, 
The saddest are, "It might have been,'' 
More sad are these we daily see: 
"It is, but hadn't ought to be.'' 
- Bret Harte
---------
As of 19 Apr 1997, 986 days till Y2K....
·············@yale.edu
http://paella.med.yale.edu/~healy
"But I thought it was pointed at the rabbit *between* my feet!"
---------
Help a victim of severe email harrassment, see
http://www.geocities.com/~hitchcockc/story.html#fund
---------
From: Rainer Joswig
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <joswig-ya023180002004972208010001@news.lavielle.com>
In article <·························@fire.cc.gatech.edu>,
········@cc.gatech.edu (Mike Pinkerton) wrote:

> In article <·······················@10.0.2.1>, ······@netcom.com (Henry
> Baker) wrote:
> 
> >Two words: 'Lisp Machine'.
> 
> Oh, yeah, and that was successful. I've got a friend with a Symbolics
> machine he uses as a table.

I got two in my office. Working. Daily. Cool.

-- 
http://www.lavielle.com/~joswig/
From: Alaric B. Williams
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335a53b4.14068008@news.demon.co.uk>
On 19 Apr 1997 21:20:53 GMT, ······@tcl.eng.sun.com (John Ousterhout)
wrote:

>Let's take Lisp as an example.  I think that Lisp falls somewhere
>between scripting and system programming.  Many of you have suggested that
>it is an ideal language for both system programming and scripting, but I
>think that it isn't really very good for either.  In fact I suspect that
>this may be why Lisp hasn't been used much for practical programming.
>Lisp isn't a good system programming language because it's too hard to
>write efficient programs in it and it doesn't provide good low-level
>access to machine facilities.  On the other hand, Lisp isn't good for
>scripting either.  In order to be a good scripting language, you need
>to be able to interoperate with lots of other things, which are often
>written in other languages (the best glues are those that stick to lots
>of different materials).  But Lisp has never been very good at this.
>For example, it's hard to include C code with Lisp because they have
>very different data types and memory models.  Lisp systems are typically
>closed: you have to live entirely in the Lisp world.  Good scripting
>languages are open and friendly: they talk to and work with everything.

How about Dylan? I'm looking into it right now in the hope that it
will "bridge the gap". Not completely - I still think a "dummy
language" for customisation by people who don't want to spend ages
being trained is a Good Thing, but to cover both systems stuff and
VHLL gluing. But anyway, to cut a long story short, Dylan lets you
write in a dynamically typed way, which is powerful and high-level,
but where you want performance, you insert pragma-like things to tell
the compiler to restrict the types of bindings etc, so it an be
efficient at a systems level. 

ABW
--
"Plug and Play support: WfEWAD will autodetect any installed
Nuclear Arsenals, Laser Satellites, Battlefield Control Networks,
Radar Installations, Fighter Squadrons, and other WfEWAD compliant
devices, including the new Macrosoft Unnatural Keyboard, with
full support for the now-famous Big Red Buttom(tm)."

(Windows for Early Warning and Defence User's manual P26)

Alaric B. Williams Internet : ······@abwillms.demon.co.uk
<A HREF="http://www.abwillms.demon.co.uk/">Hello :-)</A>
From: Rainer Joswig
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <joswig-ya023180002004972325320001@news.lavielle.com>
In article <··········@engnews2.Eng.Sun.COM>, ······@tcl.eng.sun.com (John
Ousterhout) wrote:

> I can't prove that it's impossible for a single language to be good at
> both scripting and system programming, but I don't know of a good example
> and I doubt that it will ever happen.

Xerox Lisp Machine, TI Explorer, LMI Lambda, Symbolics 36xx and Ivory
series, ... All those machines have had an OS that was completely
programmed in a high-level language which also was the extension
language. On those machine you never needed a "scripting language",
because those particular Lisp dialects (InterLisp, ZetaLisp,
Symbolics Common Lisp, ...) had all the needed power
(access to low-level machine details *and* application building
*and* glueing things together).

They failure was due their binding to a particular (expensive) hardware.

Symbolics Genera, for example, uses Lisp throughout the whole system and
offers a command interpreter, where you can type
"(copy-file f1 f2)"  or  something like "Copy File f1 to f2",
the latter with completion of the commands and the args, with
online help, providing default args, instant creation of dialogs
for these commands, etc, etc.

>  The reason for this is the
> difference in typing, as I explained in the white paper. A given language
> embodies a particular style of typing, which can range from very strongly
> typed to totally untyped.  Once that decision has been made, the language's
> position on the spectrum between system programming and scripting is set.

This it not true. Typing is not the issue. It's the capability
for interactive programming *and* total system control. This
has been provided already by several Lisp systems. The typing
theme is misleading. Typing is a non issue for most real world
Lisp systems, due to heavy object-oriented programming with
dynamic capabilities (like changing object's classes at
runtime) and incremental compilers.

> this may be why Lisp hasn't been used much for practical programming.

You mean things like Emacs, AutoCAD, Interleaf Publisher,
ATM switches from Lucent and Alcatel, ICAD, CL-HTTP,
Webmaker, ...? Oh...

> Lisp isn't a good system programming language because it's too hard to
> write efficient programs in it

On my *laptop* I'm using Macintosh Common Lisp. This stuff is so fast
on the PowerPC that I can shut off all optimizations for
my usual programming (web stuff). I never care about inlining,
tail recursion, type declarations, consing, ... - still
it runs fast enough. If I'd care I'd spend a few hours first
on optimizing algorithms and memory usage. The other stuff
comes last. The only weak point is the I/O system, which
could need some tuning.
 
> and it doesn't provide good low-level
> access to machine facilities.

No? How could people write SCSI, Ethernet, TCP/IP, DecNET,
RPC, NFS and various other stuff in Lisp - like in Symbolics Genera?
Even object-oriented? SMTP server, DNS, window systems, 3d animation
software, video capturing, ... ?

>  On the other hand, Lisp isn't good for
> scripting either.  In order to be a good scripting language, you need
> to be able to interoperate with lots of other things, which are often
> written in other languages (the best glues are those that stick to lots
> of different materials).  But Lisp has never been very good at this.

How could it be that Apple wrote their software testing stuff
in Lisp? I mean they were not testing Lisp software. How
can it be that Macintosh Common Lisp communicates easy
via AppleEvents with other applications (I have just used
this for my own testing stuff)?

Doing stuff like this a bit more difficult in some
otherlanguages.

Define a function for creating a particular AppleEvent:

(defun create-start-monitor-event (the-desc the-target id &rest create-keywords)
  (declare (dynamic-extent create-keywords))
  (apply 'create-appleevent the-desc +corona-signature+ :|MoGo| the-target
         create-keywords)
  (ccl::ae-put-parameter-longinteger the-desc #$keyDirectObject id))

Define a function for sending the AppleEvent:

(defun send-start-monitor-event (id)
  (check-type id number)
  (with-aedescs (appleevent reply target)
    (ccl::create-signature-target target +corona-signature+)
    (create-start-monitor-event appleevent target id)
    (send-appleevent appleevent reply)))

; (send-start-monitor-event (send-id-of-nth-monitor-event 1))

And use it in your Lisp code (send-number-of-monitors,
and send-id-of-nth-monitor-event are also functions built
with AppleEvents). Later you won't even care how this
this stuff works inside - it integrates completely into the Lisp
system:

(defun start-monitor (&optional (n 1))
  (if (> (send-number-of-monitors) 0)
    (send-start-monitor-event (send-id-of-nth-monitor-event n))
    (error "some error message here")))

This is surely no rocket science.

The "Open Scripting Architecture" also
would make it possible to use MCL as a system wide
scripting language (though this hasn't been done).

If you happen to have a Lisp OS - even better, then calling
C, Pascal, Prolog, Fortran, etc. should be really easy - like
on Symbolics Genera.

> For example, it's hard to include C code with Lisp because they have
> very different data types and memory models.

It's sometimes not that easy, but in Macintosh Common Lisp
I just load shared libraries or call the system traps.
Not that difficult.

>  Lisp systems are typically closed: you have to live
> entirely in the Lisp world.

Then I'd like to know how I could be using the OpenTransport TCP/IP
libs on my Mac from Macintosh Common Lisp? How do people
call drawing operations? I mean, how do I call the
Quickdraw system call to draw an oval?

(#_FillOval r pattern)

Looks no different from other languages. "r" is a rect record
and "pattern" is a pattern datastructure. I'm using
the usual manuals (Inside Mac) while programming with Lisp.

> I'm sure that many of you will argue against these claims ("my new
> version of Scheme is just as fast as C",

My versions of Common Lisp are almost as fast as C. Fast enough for
my purposes. ***Much*** faster than TCL - without added effort.

> "Lisp just needs a new garbage
> collector that embodies the latest techniques",

Most commercial Lisp have pretty good GCs (generational GC,
ephemeral GC, ...). Full GC of 17 MB memory runs in 2-4 seconds
on my slow laptop, but this does not happen very often
due to the the nice combination of ephemeral GC and generational GC.

> Science have worked on Lisp over the last 30 years, and they haven't
> been able to fix the language so that it could be widely used either
> for system programming or scripting tasks.

I'd like to see that changed. 

The success and excellent design of Newton OS 2.0, the
Emate 300 and the Newton MessagePad 2000 gives good
motivation to think the unthinkable. Basically these
are Lisp machines (GC, OOP, functions&closures, tagged data,
incremental compiler, dynamically typed, ...) for a large
audience.

-- 
http://www.lavielle.com/~joswig/
From: Jacques GARRIGUE
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <l2lo6d9i98.fsf@safran.kurims.kyoto-u.ac.jp>
······@tcl.eng.sun.com (John Ousterhout) writes:

> One of the most common criticisms of my white paper has been that the
> distinction between scripting and system programming is artificial, and
> that it is possible for a single language to be good at both tasks.
> Lisp-like languages such as Scheme were suggested as living proof.  I
> can't prove that it's impossible for a single language to be good at
> both scripting and system programming, but I don't know of a good example
> and I doubt that it will ever happen.  The reason for this is the
> difference in typing, as I explained in the white paper. A given language
> embodies a particular style of typing, which can range from very strongly
> typed to totally untyped.  Once that decision has been made, the language's
> position on the spectrum between system programming and scripting is set.
> I think it's possible to have a language that's in the middle, but it's
> not likely to be terrific at either task.
> 
> Let's take Lisp as an example.  [..]

Since Lisp is dynamically typed, according to your hierarchy of
typing, it is in the middle between TCL and C. It is then easy to make 
your point.

But you have completely ignored here another thread of comments: there 
exist now typing systems that both are stronger than C, and give you
(almost) as much programming freedom as Lisp.

Typically, when one speaks of "strongly typed" languages, this is
talking about strongly typed functional languages, like ML or
Haskell. Strong here means both that the constraint is stronger --you
do not use cast in these languages, meaning types give you absolute
security--, and that the expressive power is strong --otherwise you
won't be able to write in such languages.

There was an example a while ago in TkGofer: did you realize that it
was _strongly typed_. You can express things with the same concision
as TCL, and be more strictly typed than JAVA !

I do not contest the expressive power of TCL (as a scripting
language), and even think that it's syntax to use the Tk library is
very nice. That is why we intended to stay as close to TCL as possible
in the LablTk library. This library is built on Objective Label, a
derivative of Objective Caml, in the ML family.

Let's see a small example:

(TCL)
button .b -text Hello -font {Times 12} -relief sunken

(LablTk)
let b = Button.create parent:top text:"Hello" font:"Times 12" relief:`Sunken

Again, the syntax is not more difficult. Allegedly a little bit more
verbose, but not really bothering. The difference is that everything
that can be checked is checked at compile time (or even before, using
the interactive editor):

* that Button has text, font, and relief configuration option
* that sunken is a valid relief

In order to do this, we had to extend ML's type system, which is
already powerful, in two ways: labeled and optional arguments, and
polymorphic variants (the `Sunken). But this was possible, keeping all 
the nice properties.

So, how such a language compares to Tcl. The essential difference is
that you can write and manage big applications in it, and do not need
to use a specific scripting language for the GUI. One could even think 
of allowing scripting and extensions in the language itself (dynamic
loading is already available).

Speed also: very fast bytecode compilation should give you code
already orders faster. And you can also use a native code compiler to
compete with C.

OK, what's my point. Not that this language is the solution to all
problems. But that in the future languages and type systems of this
kind will undergo huge progresses, and eventually make irrelevant your
distinction between system and scripting languages --at least for
applications.  Let's call them "strongly typed" languages (that's
what they are called now).

Will C then disappear ? I do not believe so. I think that we should
rather use a 3-level classification, if we want to follow your view.

* Low-level, system programming languages, for really computation
intensive or very low level tasks: C, C++ (I don't believe JAVA fits
in here)

* Application development languages: C++, JAVA, "strongly typed"
languages, and many other

* Script languages: Tcl, Guile..., "strongly typed" languages

I do not know the end of the story, but since low level tasks will be
more and more delegated to drivers and libraries, I think the ability
to handle the last two kinds of programming in a uniform framework is
an important one.

---------------------------------------------------------------------------
Jacques Garrigue	Kyoto University      ········@kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>
From: David Fox
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <y5ad8rnnuvl.fsf@graphics.cat.nyu.edu>
In article <··············@safran.kurims.kyoto-u.ac.jp> Jacques GARRIGUE <········@safran.kurims.kyoto-u.ac.jp> writes:

] Let's see a small example:
] 
] (TCL)
] button .b -text Hello -font {Times 12} -relief sunken
] 
] (LablTk)
] let b = Button.create parent:top text:"Hello" font:"Times 12" relief:`Sunken
] 
] Again, the syntax is not more difficult. Allegedly a little bit more
] verbose, but not really bothering. The difference is that everything
] that can be checked is checked at compile time (or even before, using
] the interactive editor):

I've been pondering this issue of scripting vs. programming, and the
two communities they represent.  I think this example captures the
conflict pretty well.  To someone writing a script, the subtle control
and data structures are just extraneous and annoying: Create?  Of
course, what else?  Parent:top?  Who cares?  The difference between
the two examples is small in terms of the amount of text, but to the
script writer the additions are just annoying.  Its like having to
write "and" between each entry in your grocery shopping list.

The scripting community will always be much larger than the
programming community, but you can't have one without the other.  So
there is no point to getting the world to stop using simple languages.
No offense, but its a little like trying to teach a pig to sing.  Its
a waste of time and it annoys the pig.
-- 
David Fox            http://www.cat.nyu.edu/fox            xoF divaD
NYU Media Research Lab     ···@cat.nyu.edu    baL hcraeseR aideM UYN
From: Jacques GARRIGUE
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <l2enbzrhpc.fsf@safran.kurims.kyoto-u.ac.jp>
···@c a t . n y u . e d u (David Fox) writes:

> In article <··············@safran.kurims.kyoto-u.ac.jp> Jacques GARRIGUE <········@safran.kurims.kyoto-u.ac.jp> writes:
> 
> ] Let's see a small example:
> ] 
> ] (TCL)
> ] button .b -text Hello -font {Times 12} -relief sunken
> ] 
> ] (LablTk)
> ] let b = Button.create parent:top text:"Hello" font:"Times 12" relief:`Sunken
> ] 
> ] Again, the syntax is not more difficult. Allegedly a little bit more
> ] verbose, but not really bothering. The difference is that everything
> ] that can be checked is checked at compile time (or even before, using
> ] the interactive editor):
> 
> I've been pondering this issue of scripting vs. programming, and the
> two communities they represent.  I think this example captures the
> conflict pretty well.  To someone writing a script, the subtle control
> and data structures are just extraneous and annoying: Create?  Of
> course, what else?  Parent:top?  Who cares?  The difference between
> the two examples is small in terms of the amount of text, but to the
> script writer the additions are just annoying.  Its like having to
> write "and" between each entry in your grocery shopping list.

Well, for parent:top, you care: in Tk, the parenting of widgets is
fixed. Tcl does that by name: writing button $w.b, like you often do
in Tcl, is the same thing as "let b = Button.create parent:w".

For create the need is clear again, this is to provide a neat module
structure. You could argue that one can do without it in a scripting
language, but as soon as your script is integrated in an application,
hard to avoid it, or you will have serious name space problems.

> The scripting community will always be much larger than the
> programming community, but you can't have one without the other.  So
> there is no point to getting the world to stop using simple languages.
> No offense, but its a little like trying to teach a pig to sing.  Its
> a waste of time and it annoys the pig.

You may have a point. Scripting languages will always be simpler than
programming languages, since they are more specialized, and do not
care about security.

But, the problem is that very often scripts grow in size, to a point
such that

 1) it becomes impossible to maintain them 

 2) speed arises as a real problem

If the goal of your script is limited enough that those two problem
will never happen, you are erfectly happy with scripting -- many
people are in this situtation.

But, if you bump eventually into one of these problems, you certainly
have better learn a programming language. In the medium term, this is
a good investment.

By the way, what I was pointing here is just that programming
languages can become very close to scripting ones, close enough that
the productivity argument does not go to the script side. No doubt,
nothing free: there is a learning cost.

	Jacques

---------------------------------------------------------------------------
Jacques Garrigue	Kyoto University      ········@kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>
From: Cimarron Taylor
Subject: Lisp is not the issue
Date: 
Message-ID: <335C5B52.32B4@dis.org>
John Ousterhout wrote:
> 
> One of the most common criticisms of my white paper has been that the
> distinction between scripting and system programming is artificial, and
> that it is possible for a single language to be good at both tasks.
> [...]

	I think this statement is as bad a simplification of the 
	criticism of your paper as your paper itself is a simplification 
	of the problems solved by programming languages.

	Your paper concludes "scripting will become an even more 
	important programming paradigm in the next century than it 
	is today."  

	My criticism is that this conclusion does not follow because 
	of simplistic assumptions about the roles and uses of programming
	languages in computing. You yourself say 

> By the way, I think that Lisp is a fascinating language [...] It just isn't 
> good for system programming or scripting. This reinforces my claim that you 
> should use different tools for different tasks.  This is also why I didn't 
> mention Lisp in the paper.  The things I discussed in the white paper aren't 
> the things that Lisp was designed for or that it does best, so it isn't
> really fair to compare Lisp along those dimensions.

	This is precisely my point.  If you should use different tools
	for different tasks than it is the nature of the tasks which
	determine the tools you should use, not some academic argument
	about typing or some other feature.

	There may exist a compelling argument that scripting will become
	more important, but your paper does not make it.

	In the introduction of your own book you write that Tcl and Tk 
	were born out of frustration with the tools that predated them.  
	In the 21st century I predict we will use tools born from the 
	frustration of using tools such as Tcl and Tk.	



	Cimarron Taylor
	········@dis.org
From: Chris Bitmead uid(x22068)
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <s6yk9lxmbtb.fsf@aalh02.alcatel.com.au>
······@tcl.eng.sun.com (John Ousterhout) writes:

> One of the most common criticisms of my white paper has been that the
> distinction between scripting and system programming is artificial, and
> that it is possible for a single language to be good at both tasks.
> Lisp-like languages such as Scheme were suggested as living proof.  I
> can't prove that it's impossible for a single language to be good at
> both scripting and system programming, but I don't know of a good example
> and I doubt that it will ever happen.  The reason for this is the
> difference in typing, as I explained in the white paper. A given language
> embodies a particular style of typing, which can range from very strongly
> typed to totally untyped.  Once that decision has been made, the language's
> position on the spectrum between system programming and scripting is set.

You don't tell us though what typing has got to do with "systems vs
scripting". You don't say why a dynamically typed language can't be a
good systems language (lisp), or a statically typed language can't be
good at scripting (ML perhaps?)

> I think it's possible to have a language that's in the middle, but it's
> not likely to be terrific at either task.
> 
> Let's take Lisp as an example.  I think that Lisp falls somewhere
> between scripting and system programming.  Many of you have suggested that
> it is an ideal language for both system programming and scripting, but I
> think that it isn't really very good for either.  In fact I suspect that
> this may be why Lisp hasn't been used much for practical programming.
> Lisp isn't a good system programming language because it's too hard to
> write efficient programs 

I don't find it hard to write efficient programs in it. On what basis
do you make this comment?

> in it and it doesn't provide good low-level
> access to machine facilities.  

This is news to me. Give us an example.

> On the other hand, Lisp isn't good for
> scripting either.  In order to be a good scripting language, you need
> to be able to interoperate with lots of other things, which are often
> written in other languages (the best glues are those that stick to lots
> of different materials).  But Lisp has never been very good at this.
> For example, it's hard to include C code with Lisp because they have
> very different data types and memory models.  

This is a very strange comment indeed. Tcl and C have *very* different
data types and memory models. But you would have us to believe they
complement each other perfectly. Now you say that Lisp isn't good at
this because it has different types and memory model to C?? Actually
Lisp is much closer to C than Tcl is to C. So what?

> Lisp systems are typically
> closed: you have to live entirely in the Lisp world.  

This is news to me. All lisp systems that I've used allow you to link
in C libraries.

> Good scripting
> languages are open and friendly: they talk to and work with everything.
> 
> Just to short-circuit the discussion that will ensue...
> 
> I'm sure that many of you will argue against these claims ("my new
> version of Scheme is just as fast as C", "Lisp just needs a new garbage
> collector that embodies the latest techniques", "I know someone who
> combined C with Scheme and had no problems at all", etc.).  However,
> I've seen a fair amount of evidence on this and the problems far
> outnumber the success stories.  Many of the best minds in Computer
> Science have worked on Lisp over the last 30 years, and they haven't
> been able to fix the language so that it could be widely used either
> for system programming or scripting tasks.  This says to me that there
> is something fundamentally wrong with the language, at least for these
> tasks.

Is this the extent of your research into this subject? A few anecdotes
and a few usage statistics?

When I think of a good systems programming language I think of a
language that would be good for writing the UNIX systems utilities
in. Having written a few of these myself (like "ls") in C, I can say
with certainty that something like lisp or scheme would be much nicer
than C, and probably just as efficient. It would probably avoid some
of the built in limitations that tend to crop up in UNIX utilities
(like line length and error handling), because it's just too much
effort to do it "right" in C.
 
> By the way, I think that Lisp is a fascinating language with neat
> mathematical properties.  It's great for a variety of meta-programming
> tasks where you're experimenting with new programming paradigms, such as AI
> and language theory.  It just isn't good for system programming or scripting.
> This reinforces my claim that you should use different tools for different
> tasks.  This is also why I didn't mention Lisp in the paper.  The things I
> discussed in the white paper aren't the things that Lisp was designed for
> or that it does best, so it isn't really fair to compare Lisp along those
> dimensions.

Isn't fair for who :-)
From: Richard A. O'Keefe
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <5k45qk$4kd$1@goanna.cs.rmit.EDU.AU>
·············@alcatel.com.au (Chris Bitmead uid(x22068)) writes:

>You don't tell us though what typing has got to do with "systems vs
>scripting". You don't say why a dynamically typed language can't be a
>good systems language (lisp), or a statically typed language can't be
>good at scripting (ML perhaps?)

I note that Unisys (formerly the Burroughs part) have been using a
statically typed 'scripting language' for decades.  It's called WFL
(Work Flow Language).  Was it ICL whose language SCL (?something Command
Language) was loosely modelled on Algol 68?

Ousterhout wrote:
>> Lisp isn't a good system programming language because it's too hard to
>> write efficient programs 

This is a truly weird comment.  From where I sit, Lisp is a perfectly
ordinary language with perfectly ordinary data types, and the costs of
operations on those data types follow perfectly obvious rules.  Writing
efficient code in Lisp isn't just as easy as writing efficient code in
a high level language (say, Modula 3, Ada, Eiffel) it's pretty much the
*same* thing.  You design or select clean data structures, you profile
to find where the time is really going, you tune where necessary (in
Lisp this may involve adding declarations).  Like all languages,
 - you need to understand your problem
 - you need to understand the primitives the language gives you
 - you need clean code that the compiler can understand well.
Now, I would love to spit on PERL's grave, but I have to say that the
built in data structures of PERL are a pretty practical set which are
actually fairly close to Lisp.  I would say that it is much easier to
write efficient code in Perl than it is in Tcl, simply because you
have better data structure primitives and structuring methods to start
from.

Ousterhout says
>> in it and it doesn't provide good low-level
>> access to machine facilities.  

Well, I'm constantly amazed at the people who think 'pointer' types
in C are guaranteed to be identical to machine 'addresses'.  Of
course they aren't, and this fact is actually very useful.  (Yes
friends, there _is_ a "bounds checking" version of gcc.)  There are
quite a few things on this machine (an UltraSPARC) that are not
accessible from C except by calling an external function.

Of all people, Ousterhout should know that Sun have a very nice
Scheme implementation which is freely available.  It's called "esh"
(I believe it originally stood for 'embeddable shell' hint hint).
And it offers the smoothest simplest interoperation with C that I
have ever seen.  I do wish Sun would either make it a product or
else release the sources so that someone else could.  Is the attempt
to pretend that Scheme _can't_ work well with C really an piece of
internal politicking against the ESH people?

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Jack Campin
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <2729@purr.demon.co.uk>
··@goanna.cs.rmit.EDU.AU (Richard A. O'Keefe) writes:
> ·············@alcatel.com.au (Chris Bitmead uid(x22068)) writes:
>> You don't tell us though what typing has got to do with "systems vs
>> scripting". You don't say why a dynamically typed language can't be a
>> good systems language (lisp), or a statically typed language can't be
>> good at scripting (ML perhaps?)
> I note that Unisys (formerly the Burroughs part) have been using a
> statically typed 'scripting language' for decades.  It's called WFL
> (Work Flow Language).  Was it ICL whose language SCL (?something Command
> Language) was loosely modelled on Algol 68?

ICL used an Algol 68 dialect for their systems programming language, S3,
which is what the whole of their VME operating system is written in.  SCL
has a vaguely similar syntax but a far simpler type system; it's still a
very nice scripting language with an efficient compiler and some useful
high-level primitives.  (This is from distant memory, it's years since I
wrote any SCL, but it came as a breath of sanity after the macro-based model
of Unix shell scripts).

-----------------------------------------------------------------------------
Jack Campin   2 Haddington Place, Edinburgh EH7 4AE, Scotland   0131 556 5272
http://www.purr.demon.co.uk/purrhome.html  food intolerance data and recipes,
Mac logic fonts, Scots folk music from "Off the Edge", and McCarrison Society
From: Rainer Joswig
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <joswig-ya023180000305970924300001@news.lavielle.com>
In article <············@goanna.cs.rmit.EDU.AU>, ··@goanna.cs.rmit.EDU.AU
(Richard A. O'Keefe) wrote:

> Of all people, Ousterhout should know that Sun have a very nice
> Scheme implementation which is freely available.  It's called "esh"
> (I believe it originally stood for 'embeddable shell' hint hint).
> And it offers the smoothest simplest interoperation with C that I
> have ever seen.  I do wish Sun would either make it a product or
> else release the sources so that someone else could.  Is the attempt
> to pretend that Scheme _can't_ work well with C really an piece of
> internal politicking against the ESH people?

For now they are going with TCL. See http://www.sun.com/970430/cover/
and Ousterhoud's text is the "White Paper"
http://www.sunlabs.com/people/john.ousterhout/scripting.html .

See also http://sunscript.sun.com .

Sigh.

-- 
http://www.lavielle.com/~joswig/
From: Ben Hanson
Subject: Re: Lisp is neither (was Re: Ousterhout and Tcl lost the plot)
Date: 
Message-ID: <335CAE55.7FE@cristie.co.uk>
John Ousterhout wrote:
<SNIP>
> This reinforces my claim that you should use different tools for different
> tasks.  This is also why I didn't mention Lisp in the paper.  The things I
> discussed in the white paper aren't the things that Lisp was designed for
> or that it does best, so it isn't really fair to compare Lisp along those
> dimensions.

Lots of Irritating Spurious Parenthesis!

Ben
From: Fergus Henderson
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <5jbsjc$dnm@mulga.cs.mu.OZ.AU>
······@cs.utexas.edu (Paul Wilson) writes:

>You could build a language based on
>Lisp/Scheme technology with a more conventional syntax,
>and more redundant keywords.

Sure, you could, but has anyone done it?


P.S.  Follow-ups redirected to comp.lang.misc!
I wish everyone else in this thread would do the same.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Erik Naggum
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <3070521785789755@naggum.no>
* Paul Wilson
| You could build a language based on Lisp/Scheme technology with a more
| conventional syntax, and more redundant keywords.

* Fergus Henderson
| Sure, you could, but has anyone done it?

yes.  it's called DYLAN, for DYnamic LANguage.  see comp.lang.dylan.

#\Erik
-- 
I'm no longer young enough to know everything.
From: Rainer Joswig
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <joswig-ya023180002004971652320001@news.lavielle.com>
In article <················@naggum.no>, Erik Naggum <····@naggum.no> wrote:

> * Paul Wilson
> | You could build a language based on Lisp/Scheme technology with a more
> | conventional syntax, and more redundant keywords.
> 
> * Fergus Henderson
> | Sure, you could, but has anyone done it?
> 
> yes.  it's called DYLAN, for DYnamic LANguage.  see comp.lang.dylan.

NewtonScript, Sk8Script, AppleScript, ...

All from Apple.

-- 
http://www.lavielle.com/~joswig/
From: Paul Wilson
Subject: List Syntax vs. Conventional Syntax (was Re: Ousterhout...)
Date: 
Message-ID: <5k3qn4$p43@roar.cs.utexas.edu>
In article <················@naggum.no>, Erik Naggum  <····@naggum.no> wrote:
>* Paul Wilson
>| You could build a language based on Lisp/Scheme technology with a more
>| conventional syntax, and more redundant keywords.
>
>* Fergus Henderson
>| Sure, you could, but has anyone done it?
>
>yes.  it's called DYLAN, for DYnamic LANguage.  see comp.lang.dylan.

There are a bunch of others, one notable one being Pop.  Pop has
been around for a long time, has books published about it, etc.,
and is still in use.  (see comp.lang.pop)

Even McCarthy's early Lisp system had a different syntax
available, which was expected to become the standard syntax.
(It doesn't look a whole lot like C, though.  But then, C
wasn't going to exist for a while, so not many people grumbled
about that.)

The "code" syntax fell away in favor of the "data" syntax,
I suspect largely because in those days people were fond
of treating code as data, and calling eval.  These days,
that's much less common because once you have lexical
scope and closures, it's much more efficient and safe
to use lambda and calling than eval.  In other cases, where
you need to control whether and when arguments are evaluated,
macros are usually better than eval.  (Eval should be used
very carefully and sparingly in normal apps, because it is
slow and tends to confuse compilers so that they can't
optimize *other* code as well.  You can usually get the
effect you want straightforwardly with lambda (for the non
Lispers, think of it as "make-procedure"), and it'll be
tons faster.

Once you have lexical scope and closures, much of the advantage
of "code looks like data" syntax is reduced.  (This is why ML,
Haskell, et al. didn't inherit this from Lisp.  Unfortunately,
they also didn't inherit macros, which are a much cooler
thing than most people realize.)

There have been a bunch of other Algol-ish or C-ish parsers for
Lisp, but once the looks-like-data syntax had become entrenched as
"what Lisp looks like", they had little chance among serious
Lisp users.  This may have entrenched the division between
Lisp and conventional programming languages, which I consider
to be one of the most unfortunate splits in CS.

Part of this was probably due to the fact that Lisp macros
required having a convenient data structure to operate on,
because they're basically procedural.  Only recently have
there been macro and compiler extension facilities that
would work with more conventional syntax and give you most
of the power of Lisp macros.  (As a side benefit, the
constraints on those systems make them easier to use correctly.)

-- 
| Paul R. Wilson, Comp. Sci. Dept., U of Texas @ Austin (······@cs.utexas.edu)
| Papers on memory allocators, garbage collection, memory hierarchies,
| persistence and  Scheme interpreters and compilers available via ftp from 
| ftp.cs.utexas.edu, in pub/garbage (or http://www.cs.utexas.edu/users/wilson/)      
From: Henry Baker
Subject: Re: List Syntax vs. Conventional Syntax (was Re: Ousterhout...)
Date: 
Message-ID: <hbaker-2904970822220001@10.0.2.1>
In article <··········@roar.cs.utexas.edu>, ······@cs.utexas.edu (Paul
Wilson) wrote:

> (Eval should be used
> very carefully and sparingly in normal apps, because it is
> slow and tends to confuse compilers so that they can't
> optimize *other* code as well.  You can usually get the
> effect you want straightforwardly with lambda (for the non
> Lispers, think of it as "make-procedure"), and it'll be
> tons faster.

Of course, you can always do 'apply' of 'compile' of consed stuff instead
of 'eval'.  This 'JIT' compilation solves the speed problem.  (You _do_ have a
builtin compiler, don't you?)
From: Paul Wilson
Subject: Re: List Syntax vs. Conventional Syntax (was Re: Ousterhout...)
Date: 
Message-ID: <5k583c$rrm@roar.cs.utexas.edu>
In article <·······················@10.0.2.1>,
Henry Baker <······@netcom.com> wrote:
>In article <··········@roar.cs.utexas.edu>, ······@cs.utexas.edu (Paul
>Wilson) wrote:
>
>> (Eval should be used
>> very carefully and sparingly in normal apps, because it is
>> slow and tends to confuse compilers so that they can't
>> optimize *other* code as well.  You can usually get the
>> effect you want straightforwardly with lambda (for the non
>> Lispers, think of it as "make-procedure"), and it'll be
>> tons faster.
>
>Of course, you can always do 'apply' of 'compile' of consed stuff instead
>of 'eval'. 

Right.  (For example, in RScheme and some other schemes, this is how
eval is actually implemented---it just compiles what you give it,
and runs the resulting code immediately.)

>This 'JIT' compilation solves the speed problem.  

Not the one I was talking about.  A lot of naive users don't understand
that eval is a weird thing to do, and may be rather slow because it
involves either interpretation  or compilation.  In contrast, lambda
is generally quite fast, because it doesn't actually create  new
code, just a new closure to pair code with an environment.

In many scripting apps, this doesn't matter much, but when you start
writing whole programs in a language, it's good to be able to avoid
eval.  Using lambda and procedure calling (or macros if necessary)
is usually cleaner and easier anyway.

>(You _do_ have a builtin compiler, don't you?)

Sure.  (We don't have an interpreter in the usual sense.)

-- 
| Paul R. Wilson, Comp. Sci. Dept., U of Texas @ Austin (······@cs.utexas.edu)
| Papers on memory allocators, garbage collection, memory hierarchies,
| persistence and  Scheme interpreters and compilers available via ftp from 
| ftp.cs.utexas.edu, in pub/garbage (or http://www.cs.utexas.edu/users/wilson/)      
From: Marnix Klooster
Subject: Re: List Syntax vs. Conventional Syntax (was Re: Ousterhout...)
Date: 
Message-ID: <5k5bpf$rte@cantaloupe.srv.cs.cmu.edu>
Paul Wilson wrote:

> Once you have lexical scope and closures, much of the advantage
> of "code looks like data" syntax is reduced.  (This is why ML,
> Haskell, et al. didn't inherit this from Lisp.  Unfortunately,
> they also didn't inherit macros, which are a much cooler
> thing than most people realize.)

What "cool" things would be possible if ML and Haskell had macros?

> Part of this was probably due to the fact that Lisp macros
> required having a convenient data structure to operate on,
> because they're basically procedural.  Only recently have
> there been macro and compiler extension facilities that
> would work with more conventional syntax and give you most
> of the power of Lisp macros.  (As a side benefit, the
> constraints on those systems make them easier to use correctly.)

Is this what Dylan does?  Could you sketch what such a macro facility
would look like, or provide some pointers?

> | Paul R. Wilson

Groetjes

 <><

Marnix
--
Marnix Klooster              |   If you post a reply to a
·········@research.baan.nl   |   News article of mine, please
······@worldonline.nl        |   send me a copy by e-mail.
From: Brian Rogoff
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <Pine.SGI.3.95.970419124714.2165B-100000@shellx.best.com>
On Fri, 18 Apr 1997, James Logajan wrote:
> 
> NOTE TO LISP AND FORTH FANS: one important reason your languages
> have never caught on may be due to the fact that many natural languages
> follow the "subject verb object" form. Usage of SOV, OSV, VSO, and VOS
> are less likely (I don't have any references in front of me; if anybody
> wants details, I'll try to locate what I have). They also lack visual
> redundancy (they aren't alone in this short-coming of course).

Best quote on this topic I've read lately

	The use of the Chomsky formalism is also responsible for the term 
	"programming language", because programming languages seemed to
	exhibit a strucure similar to spoken languages. We believe that
	this term is rather unfortunate on the whole, because a programming 
	language is not spoken, and therefore is not a language in the true
	sense of the word. Formalism or formal notation would have been
	more appropriate terms. 

	Niklaus Wirth

In Wirth's opinion, and the opinion of many reputable linguists like
Steven Pinker, the analogy betweem formal notations :-) and human
languages is bogus. "Spoken" is the key point to consider.

-- Brian    
From: Thant Tessman
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <335B9CA3.41C6@nospam.acm.org>
Brian Rogoff wrote:

> In Wirth's opinion, and the opinion of many reputable linguists like
> Steven Pinker, the analogy betweem formal notations :-) and human
> languages is bogus. "Spoken" is the key point to consider.

I'm only about a third of the way through Pinker's book (The Language 
Instinct?), but I haven't picked this up at all.    Language is the structure 
upon which one hangs meaning.  If one is careful to keep separate the concept 
of meaning from the concept of language structure, and if one acknowledges 
that humans have an ability to perceive and invent novel structure that 
computers don't have (hence the greater need for formalism when dealing with 
computers), then I don't think it would be a lie to say that there is no 
*qalitative* difference between human languages and programming languages.  
(But those are of course very big qualifications.)

And as for Logajan's original post about subject/verb/object structure
being more natural, the other thing I've gotten out of Pinker's book is 
that human languages can and do have an extremely wide variety of structures, 
and that what is 'natural' about human languages is not any particular 
structure, but the aforementioned ability to perceive and invent structure.

To put it simply, what I've gotten out of the book so far is that the biggest
difference between spoken languages and programming languages is that the 
former are a *lot* more interesting.  (Unfortunately, the latter pays better.)

Obligatory Ousterhout slam:  The argument I hate the most from people is "X 
is better than Y because more people use X than Y."   This argument is 
particularly infuriating when it comes from people like Ousterhout and 
Stroustrup and Gates because they are clearly content to perpetuate people's 
ignorance of superior alternatives, thus protecting their trump-card argument.  
(Not that it's their job to inform people of superior alternatives.)

One more note:  Erik Naggum keeps writing stuff that I agree with, but in a 
way that I wish I didn't.

-thant
From: Bjarne Stroustrup
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <E91IDz.IL9@research.att.com>
From: Thant Tessman <·····@nospam.acm.org> writes

 > Obligatory Ousterhout slam:  The argument I hate the most from people is "X 
 > is better than Y because more people use X than Y."   This argument is 
 > particularly infuriating when it comes from people like Ousterhout and 
 > Stroustrup and Gates because they are clearly content to perpetuate people's 
 > ignorance of superior alternatives, thus protecting their trump-card argument.  
 > (Not that it's their job to inform people of superior alternatives.)

An Hmmm. I don't know what - if anything - Ousterhout said to deserve
that label, and I find it hard to think of something significant to say
that applies to "Ousterhout and Stroustrup and Gates."

I do not think that I ever said:

	"C++ is better than Y because more people use C++ than Y."

To repeat what I posted last time someone accused me of making
that argument in comp.lang.c++:

	The furthest I go is to claim that unless C++ had at least some
	of the virtues I claim for it, it would have died during the
	early years where there were essentially no C++ marketing and
	alternatives languages with marketing dollars behind them existed.

	Naturally, even that is invariably mistaken for the disreputable
	"5 million morons cannot be wrong" argument :-(

I recommend "The Design and Evolution of C++" (Addison-Wesley) for people
who are interested in what I actually claim for C++.

	- Bjarne

Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html
From: Thant Tessman
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <335D64A7.167E@nospam.acm.org>
Bjarne Stroustrup wrote:

> [...] and I find it hard to think of something significant to say
> that applies to "Ousterhout and Stroustrup and Gates."

All three of you have a sign on your back that says "Kick me!"

[...]

> The furthest I go is to claim that unless C++ had at least some
> of the virtues I claim for it, it would have died during the
> early years where there were essentially no C++ marketing and
> alternatives languages with marketing dollars behind them existed.

I was one of those early adopters.  At the time I and many others
were looking for a better C, and in our ignorance we thought C++ was 
really great.  Isn't it time to admit it was a mistake?

[...]

> I recommend "The Design and Evolution of C++" (Addison-Wesley) for people
> who are interested in what I actually claim for C++.

And I recommend folks learn *any* language that supports higher-order 
functions, automatic memory management, and incremental compilation
to see how truly wretched C++ is, regardless of whatever claims 
Stroustrup makes for it.

-thant
From: Thant Tessman
Subject: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <335D8429.41C6@nospam.acm.org>
I wrote:

[...wretched C++...]

If what I wrote sounds harsh, let me explain what I had just spent
the previous two hours doing.

I had this:

	struct A { /* ... */ }

	template <class T>
	struct B : A { /* ... */ }

I wanted to do this:

	A* a = new B<whatever>;

	B<whatever>* b = dynamic_cast<B<whatever>*>(a);

I managed to figure out that in order for this to work, it's 
not enough that the compiler see the entire definition of B<T>, 
but it also needs to see B<whatever> explicitly instantiated.  
According to the ANSI C++ proposal, this is done like so:

	template class B<whatever>;

But of course the compiler I'm using doesn't support this yet.
(IRIX 6.2 C++ 7.1) so you have to do this instead:

	#pragma instantiate B<whatever>

There were no warnings, and no clues about what I was doing 
wrong.  dynamic_cast just consistently returned zero.

C++ is *full* of bullshit like this and I've spent way too
much of my life fighting it.

-thant
From: Ben Hanson
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <335DDD6B.6AC8@cristie.co.uk>
Thant Tessman wrote:
>         #pragma instantiate B<whatever>
> 
> There were no warnings, and no clues about what I was doing
> wrong.  dynamic_cast just consistently returned zero.
> 
> C++ is *full* of bullshit like this and I've spent way too
> much of my life fighting it.
> 
> -thant

Fair comment. Shoot the compiler writer. (Actually shoot the company who
decided releasing sub-standard product was acceptable!!)

Ben
From: Erik Naggum
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3070776814510479@naggum.no>
* Ben Hanson
| Fair comment. Shoot the compiler writer. (Actually shoot the company who
| decided releasing sub-standard product was acceptable!!)

I really don't think genocide is a good idea.

#\Erik
-- 
Bastard Sex Therapist from Hell: "Read the F*cking Manual!"
From: Erik Naggum
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3070775097664615@naggum.no>
* Thant Tessman
| C++ is *full* of bullshit like this and I've spent way too much of my
| life fighting it.

it was C++ that finally made me realize that I should pursue Common Lisp as
my programming language of choice.  that was after I had written about 2000
lines of C++ code in a hacked-up language that I processed with Emacs Lisp
to reduce the phenomenal clutter and redundancy of C++.  my code was 600
lines in this proto-language, and 300 lines of Emacs Lisp.  I had
reinvented a tiny portion of CLOS.  if it were not for C++, it might have
taken more a little longer to get to Common Lisp.  my conclusion was that
"life is too long to know C++ well", and that in C++, "reinvention is its
own reward".

#\Erik
-- 
Bastard Sex Therapist from Hell: "Read the F*cking Manual!"
From: David Thornley
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5jl2rn$5gf$1@darla.visi.com>
In article <·············@nospam.acm.org>,
Thant Tessman  <·····@nospam.acm.org> wrote:
>I wrote:
>
>[...wretched C++...]
>
>If what I wrote sounds harsh, let me explain what I had just spent
>the previous two hours doing.
>
>I had this:
>
>	struct A { /* ... */ }
>
>	template <class T>
>	struct B : A { /* ... */ }
>
>I wanted to do this:
>
>	A* a = new B<whatever>;
>
>	B<whatever>* b = dynamic_cast<B<whatever>*>(a);
>
OK, looks like templates and RTTI.  These aren't exactly the latest
features in the draft standard, but I don't expect them to be
completely stable yet.

>I managed to figure out that in order for this to work, it's 
>not enough that the compiler see the entire definition of B<T>, 
>but it also needs to see B<whatever> explicitly instantiated.  
>According to the ANSI C++ proposal, this is done like so:
>
>	template class B<whatever>;
>
>But of course the compiler I'm using doesn't support this yet.
>(IRIX 6.2 C++ 7.1) so you have to do this instead:
>
>	#pragma instantiate B<whatever>
>
>There were no warnings, and no clues about what I was doing 
>wrong.  dynamic_cast just consistently returned zero.
>
OK, so your compiler doesn't support the draft ANSI standard,
and doesn't provide warnings or clues.  This looks like an
implementation problem to me.  In particular, I don't think
it's actually Stroustrup's fault you spent hours figuring this
out.

>C++ is *full* of bullshit like this and I've spent way too
>much of my life fighting it.
>
No, C++ compilers are full of bullshit.  On my favorite platform,
the C++ libraries automatically installed are really, really
shaky, requiring explicit iterator_traits declarations just
in able to do a simple vector<Fnord, allocator<Fnord> >
(which, of course, should be writable as vector<Fnord>).

C++ started when Stroustrup wanted to program with the ease of
Simula and the efficiency of C.  It's taken a while, but it
looks to me like the C++ standard is something like the closure
(in the mathematical sense, sort of) of the facilities he needs
to program his way over the possible facility space.  In other
words, the C++ committee has largely been following Stroustrup's
lead, and continuing in logical directions.  This isn't a bad
way to design a programming language, but no way is perfect
or guaranteed success.

The current result is certainly massive, but my HTML copy of
the latest draft takes up a lot less of my disk than the Common
Lisp Hyperspec.  I don't think it's necessarily too complicated,
but it has been moving fast and implementations will need to
catch up.

When the dust is settled, C++ will have many of the things I like
about Lisp, and will be cheaper, more readily available, and will
be better about producing stand-alone applications.  Further, I
think C++ will be very usable, and that many of its faults can
be corrected with libraries, just as many things that should be
in Common Lisp have been implemented with macros.  (Yes, there is
at least one freely available garbage collection library for C++.)

In the meantime, I suggest that, when you spend hours in frustration
with your C++ system, let your vendor know.  (You should have seen
the fireworks in comp.sys.mac.programmer.codewarrior after CW 11
was released!)  Let whoever makes decisions on buying systems know.
Vendors in a competitive field don't like to have their customers
angry at them.

Not that this has a whole lot to do with Lisp, but I at least
mentioned it twice above.

David Thornley

"Remember, we're the Phone Company.  We don't care.  We don't have to."
-Lily Tomlin on Saturday Night Live
From: Chris Bitmead uid(x22068)
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <s6y4tcxm8gx.fsf@aalh02.alcatel.com.au>
········@visi.com (David Thornley) writes:

> OK, so your compiler doesn't support the draft ANSI standard,
> and doesn't provide warnings or clues.  This looks like an
> implementation problem to me.  In particular, I don't think
> it's actually Stroustrup's fault you spent hours figuring this
> out.
> 
> >C++ is *full* of bullshit like this and I've spent way too
> >much of my life fighting it.
> 
> No, C++ compilers are full of bullshit.  On my favorite platform,
> the C++ libraries automatically installed are really, really
> shaky, requiring explicit iterator_traits declarations just
> in able to do a simple vector<Fnord, allocator<Fnord> >
> (which, of course, should be writable as vector<Fnord>).

The fact is, C++ has reached a level of complexity that even given
infinite resources and talent, it's near (but not quite) impossible to
write a fully conforming C++ implementation without bugs or
quirks. The language definition itself is ambiguous. (Think about all
the ways you can use ">" and "<" as an example.) Forget about writing
one which actually compiles and links fast.

By contrast Lisp is infinitely more powerful and expressive as a
language, and yet before I even learnt how to write a loop in lisp I
sat down one weekend and wrote a lisp interpreter. Wow! what sort of
Lisp compilers would we have if Sun and others sunk the same effort
they do with C++ compilers into lisp?

> When the dust is settled, C++ will have many of the things I like
> about Lisp, and will be cheaper, more readily available, and will
> be better about producing stand-alone applications.  Further, I
> think C++ will be very usable, and that many of its faults can
> be corrected with libraries, just as many things that should be
> in Common Lisp have been implemented with macros.  

Oh boy. The problems of C++ are nothing to do with the cleverness of
the libraries. C++ is beyond hope. Yes you can do lots of powerful
things in C++. Even more so as more libraries become available. But
you can't do big projects in non-geological timeframes.
From: Marc Wachowitz
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5jodhp$nf1$1@trumpet.uni-mannheim.de>
[Newsgroup list cut down considerably.]

Chris Bitmead uid(x22068) (·············@alcatel.com.au) wrote:
> The language definition itself is ambiguous. (Think about all
> the ways you can use ">" and "<" as an example.) Forget about writing
> one which actually compiles and links fast.

There may or may not be ambiguities in the language of the most recent
pre-standard text, but to what you allude to above isn't technically
ambiguous unless the standard requires that it be accepted but refuses
to specify which way it should be interpreted. Also, while a parser for
C++ isn't exactly a trivial task likely to result in an award for beauty
in software, I'm quite confident that it can be translated efficiently if
one approaches the problems with the experience and effort appropriate for
a large project (as any excellent implementation for a reasonably expressive
programming language is going to be), rather than being annoyed because
one couldn't just e.g. throw the grammar at yacc and have everything work
fine on a rainy sunday afternoon. (This doesn't deny the criticism that
the syntax of C++ should be simpler, whether for the human reader or for
some established parsing algorithms, but let's not lose the perspective
on what's implied in engineering a high-quality product. You may be able
to write e.g. a Scheme interpreter on a weekend, but I doubt you'd be able
to implement a complete conforming Common Lisp so easily - even if you'd
not pay much attention to efficient code generation, in contrast to what
most implementations for either if those languages will need to do.)

> But you can't do big projects in non-geological timeframes.

If the project is the kind of work for which C++ is suitable, and the
designers/programmers are competent both about the problem and the
approaches which work well in C++, I don't see how the size of some
project would affect a high-quality implementation with C++ much beyond
the general problems of big projects. Now the kind of projects on which
you're working may not be of that sort, or you may not want gain the
experience in C++ needed to do a really big project in it (it's not my
dream either), but that's fine - just use something else. Surely there's
also some "marketing euphoria" around C++ (like around many broadly and
commercially relevant areas), and some people will use it very badly -
but just as it's wrong to project lots of prejudices or outdated quirks
onto modern Lisp, it's wrong to project all this hype and incompetence
onto C++ as a programming language.

While the choices which have been made for C++ aren't the ones which I'd
favour (Common Lisp is much more like that than most languages I know),
seriously considering the following quote from Bjarne Stroustrup's book
"The Design and Evolution of C++" could cut down most of the nonsense
which has been posted in the recent discussions - or most nonsense which
has been brought up against Lisp, for that matter.

"[...] Language comparisons are rarely meaningful and even less often
 fair. A good comparison of major programming languages requires more
 effort than most people are willing to spend, experience in a wide
 range of application areas, a rigid maintenance of a detached and
 impartial point of view, and a sense of fairness. [...]
 I also worry about a phenomenon I have repeatedly observed in honest
 attempts at language comparisons. The authors try hard to be impartial,
 but are hopelessly biased by focusing on a single application, a single
 style of programming, or a single culture among programmers. Worse,
 when one language is significiantly better known than others, a subtle
 shift in perspective occurs: Flaws in the well-known language are
 deemed minor and simple workarounds are presented, whereas similar
 flaws in other languages are deemed fundamental. Often, the workarounds
 commonly used in the less-well-known languages are simply unknown to
 the people doing the comparison or deemed unsatisfactory because they
 would be unworkable in the more familiar language."

Even though I'm not using C++ now, and wouldn't mind if I never had
to do so, I nevertheless wouldn't want to miss the reflections about
programming and programming languages which have been influenced by
reading this book (among lots of others, to be sure), and even the
parts of "The C++ Programming Language" beyond superficial language
rules. If the majority of people making decisions about programming
(and the usage of programming languages) ranging from technical to
management, would have read and really thought about what's mentioned
there, many problems which tend to be perceived as "problems of C++"
or "problems of [insert other programming language]" could be avoided.

Though (or because) I like the approaches of programming which are more
typical for Lisp very much, I suspect the amount of trash one would
see if e.g. Common Lisp had the popularity of C++ - including all the
incompetence one sees in that realm - would also be quite "impressive"
to an expert seeing it as an excellent language with very considerable
internal coherence ;-)

-- Marc Wachowitz <··@ipx2.rz.uni-mannheim.de>
From: Bill House
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <01bc5100$f8cf0d20$03d3c9d0@wjh_dell_133.dazsi.com>
Marc Wachowitz <··@ipx2.rz.uni-mannheim.de> wrote in article
<············@trumpet.uni-mannheim.de>...
>
>[...] 
> Though (or because) I like the approaches of programming which are more
> typical for Lisp very much, I suspect the amount of trash one would
> see if e.g. Common Lisp had the popularity of C++ - including all the
> incompetence one sees in that realm - would also be quite "impressive"
> to an expert seeing it as an excellent language with very considerable
> internal coherence ;-)
> 
Agreed, although in CL minor programming errors wouldn't normally lead to reformatted
hard drives and memory protection errors. <g>

Bill House
-- 
http://www.dazsi.com
Note: my e-mail address has been altered to
confuse the enemy. The views I express are
mine alone (unless you agree with me).
From: David Thornley
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5jqva1$3ac$1@darla.visi.com>
In article <··························@wjh_dell_133.dazsi.com>,
Bill House <······@dazsi.nospam.com> wrote:
>Marc Wachowitz <··@ipx2.rz.uni-mannheim.de> wrote in article
><············@trumpet.uni-mannheim.de>...
>>
>>[...] 
>> Though (or because) I like the approaches of programming which are more
>> typical for Lisp very much, I suspect the amount of trash one would
>> see if e.g. Common Lisp had the popularity of C++ - including all the
>> incompetence one sees in that realm - would also be quite "impressive"
>> to an expert seeing it as an excellent language with very considerable
>> internal coherence ;-)
>> 
>Agreed, although in CL minor programming errors wouldn't normally lead to reformatted
>hard drives and memory protection errors. <g>
>
Usually, no.  The sorts of C/C++ errors that cause these are related to
improper use of pointers.  Now, pointers are very difficult to use
properly, and it is essentially impossible to avoid using them in
C.  It is possible to design safe pointer and array classes in C++,
and anybody using raw pointers and arrays instead of these deserves
whatever happens to his/her hard drive (in my not particularly
humble opinion).

(Parenthetically, this is what I like about C++:  you can shape the
language much more efficiently than most other languages.  If you
don't like the current behavior, you have a lot of ability to change
it.  No other mainstream language comes anywhere near as close to
Lisp in this regard.)

The other thing about C++ and C is that they are almost always compiled
at (declare (optimize (safety 0))) with no option to do otherwise.
This is something of a culture thing.  Compiler writers generally
take "undefined" to mean "kill the hard dwive", when they could take
it to mean "optionally warn the programmer".  I think it's a market
thing, and anybody who wrote a compiler that didn't crash the system
with mysterious behavior every so often following careless memory
use would find that it bombed in the marketplace.  You've got
to follow consumer demand, after all.

There is also the cult of efficiency among C/C++ programmers that
makes them upset if they aren't using the full power of their
200 MHz Pentium Pro/PPC 604e/whatever to sort a ten-position array
or find the prime numbers below 1000.  If everybody was running
around using Lisp, there would be a lot of this culture, and
lots of people would have little function templates that look like

(defun XXX (XXX)
	(declare (optimize (safety 0) (speed 3) (debug 0)))
)

and people would be bitching that ACL++ crashed Harlequin Windows 95
again last night.

Sometimes there's comfort in being part of a small minority.

David Thornley
From: Bill House
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <01bc51af$0145a780$03d3c9d0@wjh_dell_133.dazsi.com>
David Thornley <········@visi.com> wrote in article <············@darla.visi.com>...
>
> Usually, no.  The sorts of C/C++ errors that cause these are related to
> improper use of pointers.  Now, pointers are very difficult to use
> properly, and it is essentially impossible to avoid using them in
> C.  It is possible to design safe pointer and array classes in C++,
> and anybody using raw pointers and arrays instead of these deserves
> whatever happens to his/her hard drive (in my not particularly
> humble opinion).
>
Agreed. However, this illustrates the downside of a higher-level language built on top
of a lower-level language without the full benefit of encapsulation. Our Lisp VM is
written in ANSI C for speed and portability, but you simply cannot reformat the drive
or generate a memory protection error using AgentBase (well, you can't unless you call
a C function via the C function interface<g>). 

I also appreciate your cultural points. There are many human-factor issues to take into
account. Languages are inextricably bound to culture.

Certainly, in the historical hardware environment, the efficiency of C and C++ was
needed. Nowadays, it's harder to justify taking all the extra risks and doing all that
extra work when you could easily afford to let a VM handle most of the gritty details.
Java is demonstrating this idea, but I'll be glad when competing VM systems become
widely available -- Java isn't everyone's cup of tea. 

Bill House
-- 
http://www.dazsi.com
Note: my e-mail address has been altered to
confuse the enemy. The views I express are
mine alone (unless you agree with me).
From: Chris Bitmead uid(x22068)
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <s6yiv18lzq2.fsf@aalh02.alcatel.com.au>
········@visi.com (David Thornley) writes:

> Usually, no.  The sorts of C/C++ errors that cause these are related to
> improper use of pointers.  Now, pointers are very difficult to use
> properly, and it is essentially impossible to avoid using them in
> C.  It is possible to design safe pointer and array classes in C++,
> and anybody using raw pointers and arrays instead of these deserves
> whatever happens to his/her hard drive (in my not particularly
> humble opinion).

Actually it's NOT POSSIBLE to write safe pointer and array
classes. Imagine you have class hierarchy A inherits from B. Now in
C++ you can assign an A object to a B pointer. Fine, that's what
polymorphism is all about. But what if you use a "safe" pointer class
called say Pointer<T>. Now if I try to assign a Pointer<A> to a
Pointer<B> the compiler won't let me because Pointer<A> and Pointer<B>
are different types. I can typecast of course, but then you can say
goodbye to safety right?
 
> (Parenthetically, this is what I like about C++:  you can shape the
> language much more efficiently than most other languages.  If you
> don't like the current behavior, you have a lot of ability to change
> it.  No other mainstream language comes anywhere near as close to
> Lisp in this regard.)

C++ doesn't go anywhere near to lisp as far as this is concerned.
 
From: Andrew Koenig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9CKun.K4D@research.att.com>
In article <···············@aalh02.alcatel.com.au> ·············@alcatel.com.au (Chris Bitmead uid(x22068)) writes:

> Actually it's NOT POSSIBLE to write safe pointer and array
> classes. Imagine you have class hierarchy A inherits from B. Now in
> C++ you can assign an A object to a B pointer. Fine, that's what
> polymorphism is all about. But what if you use a "safe" pointer class
> called say Pointer<T>. Now if I try to assign a Pointer<A> to a
> Pointer<B> the compiler won't let me because Pointer<A> and Pointer<B>
> are different types. I can typecast of course, but then you can say
> goodbye to safety right?

The claim `Now if I try to assign a Pointer<A> to a Pointer<B> the compiler
won't let me' isn't quite true: It ought to be possible to define an
assignment operator that will let you assign Pointer<A> to Pointer<B>
if and only if A is derived from B.

It is certainly possible if you use run-time type identification,
but I suspect it is possible at compile time as well, using the
same kinds of techniques as the iterator_category function uses in
the standard library.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Matt Austern
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <fxt4tcr6rq1.fsf@isolde.mti.sgi.com>
···@research.att.com (Andrew Koenig) writes:

> > Actually it's NOT POSSIBLE to write safe pointer and array
> > classes. Imagine you have class hierarchy A inherits from B. Now in
> > C++ you can assign an A object to a B pointer. Fine, that's what
> > polymorphism is all about. But what if you use a "safe" pointer class
> > called say Pointer<T>. Now if I try to assign a Pointer<A> to a
> > Pointer<B> the compiler won't let me because Pointer<A> and Pointer<B>
> > are different types. I can typecast of course, but then you can say
> > goodbye to safety right?
> 
> The claim `Now if I try to assign a Pointer<A> to a Pointer<B> the compiler
> won't let me' isn't quite true: It ought to be possible to define an
> assignment operator that will let you assign Pointer<A> to Pointer<B>
> if and only if A is derived from B.
> 
> It is certainly possible if you use run-time type identification,
> but I suspect it is possible at compile time as well, using the
> same kinds of techniques as the iterator_category function uses in
> the standard library.

You don't really need to do anything so tricky, though, right?  I
think that a straightforward member template assignment operator (and
copy constructor) is all that you need.

template <class T> struct Pointer {
  Pointer(T* p) : ptr(p) {}

  // We need to define both of these, because a member 
  //  template is not considered to be a copy constructor.
  Pointer(Pointer P) : ptr(P.ptr) {}
  template <class U> Pointer(const Pointer<U>& P) : ptr(P.ptr) {}

  template <class U>
  Pointer& operator=(const Pointer<U>& P) {
    ptr = P.ptr;
    return this;
  }

private:
  T* ptr;
};

A real "smart pointer" class would have much more than this, of
course.  I've put in just enough to show that it's possible to define
a type that works as you'd expect: A Pointer<T1> can be assigned to a
Pointer<T2> if and only if a T1* can be assigned to a T2*.

(This isn't quite the same as requiring that T1 is derived from T2,
but it's close.  I think it's probably more or less what the original
poster had in mind.)
From: Chris Bitmead uid(x22068)
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <BITMEADC.97Apr29135021@Alcatel.com.au>
In article <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

>In article <···············@aalh02.alcatel.com.au> ·············@alcatel.com.au (Chris Bitmead uid(x22068)) writes:
>
>> Actually it's NOT POSSIBLE to write safe pointer and array
>> classes. Imagine you have class hierarchy A inherits from B. Now in
>> C++ you can assign an A object to a B pointer. Fine, that's what
>> polymorphism is all about. But what if you use a "safe" pointer class
>> called say Pointer<T>. Now if I try to assign a Pointer<A> to a
>> Pointer<B> the compiler won't let me because Pointer<A> and Pointer<B>
>> are different types. I can typecast of course, but then you can say
>> goodbye to safety right?
>
>The claim `Now if I try to assign a Pointer<A> to a Pointer<B> the compiler
>won't let me' isn't quite true: It ought to be possible to define an
>assignment operator that will let you assign Pointer<A> to Pointer<B>
>if and only if A is derived from B.

Oh sure, if you want to write a conversion operator for every parent
class throughout the entire class hierarchy. And do this for every
single class. Does it sound like fun writing a few hundred of these?

Personally I havn't got time because I'm too busy writing lots of
functions of the form...

int Foo::getbar() { return _bar; }

>It is certainly possible if you use run-time type identification,
>but I suspect it is possible at compile time as well, using the
>same kinds of techniques as the iterator_category function uses in
>the standard library.
From: Matt Austern
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <fxtpvvd6349.fsf@isolde.mti.sgi.com>
·············@Alcatel.com.au (Chris Bitmead uid(x22068)) writes:

> >The claim `Now if I try to assign a Pointer<A> to a Pointer<B> the compiler
> >won't let me' isn't quite true: It ought to be possible to define an
> >assignment operator that will let you assign Pointer<A> to Pointer<B>
> >if and only if A is derived from B.
> 
> Oh sure, if you want to write a conversion operator for every parent
> class throughout the entire class hierarchy. And do this for every
> single class. Does it sound like fun writing a few hundred of these?

I don't think that anything of that sort is necessary in C++.

It's often true that you'd like to write a template Foo<T>, with the
property that you can convert a Foo<X> to Foo<Y> if and only of you
can convert an X to a Y.

With member templates, this is not only possible but easy.  The
standard C++ library, for example, uses this technique in the pair<>
template.

Application of this technique to "smart pointers" is left as a 
trivial exercise for the reader.
From: Chris Bitmead uid(x22068)
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <s6yk9lom01o.fsf@aalh02.alcatel.com.au>
··@ipx2.rz.uni-mannheim.de (Marc Wachowitz) writes:

> [Newsgroup list cut down considerably.]
> 
> Chris Bitmead uid(x22068) (·············@alcatel.com.au) wrote:
> > The language definition itself is ambiguous. (Think about all
> > the ways you can use ">" and "<" as an example.) Forget about writing
> > one which actually compiles and links fast.
> 
> There may or may not be ambiguities in the language of the most recent
> pre-standard text, but to what you allude to above isn't technically
> ambiguous unless the standard requires that it be accepted but refuses
> to specify which way it should be interpreted. 

My definition of ambiguous is that which I believe is a fairly common
understanding of the term in the computer language field. i.e.

foo<bar> baz;

may be a declaration of a variable baz of type foo templated over
bar. Or it may be an expression testing whether foo is less than bar
which is less than baz.

Yes you can make an informed decision in this case by looking up the
symbol tables, but is an ambiguous grammar never the less.


> Also, while a parser for
> C++ isn't exactly a trivial task likely to result in an award for beauty
> in software, I'm quite confident that it can be translated efficiently if
> one approaches the problems with the experience and effort appropriate for
> a large project (as any excellent implementation for a reasonably expressive
> programming language is going to be), rather than being annoyed because
> one couldn't just e.g. throw the grammar at yacc and have everything work
> fine on a rainy sunday afternoon. 

Have you actually had experience doing this? C++ is extremely
difficult to implement.

> (This doesn't deny the criticism that
> the syntax of C++ should be simpler, whether for the human reader or for
> some established parsing algorithms, but let's not lose the perspective
> on what's implied in engineering a high-quality product. You may be able
> to write e.g. a Scheme interpreter on a weekend, but I doubt you'd be able
> to implement a complete conforming Common Lisp so easily 

I think I could actually, not including the standard libraries, just
the core language.

> - even if you'd
> not pay much attention to efficient code generation, in contrast to what
> most implementations for either if those languages will need to do.)
> 
> > But you can't do big projects in non-geological timeframes.
> 
> If the project is the kind of work for which C++ is suitable, and the
> designers/programmers are competent both about the problem and the
> approaches which work well in C++, I don't see how the size of some
> project would affect a high-quality implementation with C++ much beyond
> the general problems of big projects. Now the kind of projects on which
> you're working may not be of that sort, or you may not want gain the
> experience in C++ needed to do a really big project in it (it's not my
> dream either), but that's fine - just use something else. Surely there's
> also some "marketing euphoria" around C++ (like around many broadly and
> commercially relevant areas), and some people will use it very badly -
> but just as it's wrong to project lots of prejudices or outdated quirks
> onto modern Lisp, it's wrong to project all this hype and incompetence
> onto C++ as a programming language.

My guess is you havn't done any big C++ projects given the above
comments. I've done many, and believe me I'd use something else if I
had the choice. But it's not my decision.
 
> While the choices which have been made for C++ aren't the ones which I'd
> favour (Common Lisp is much more like that than most languages I know),
> seriously considering the following quote from Bjarne Stroustrup's book
> "The Design and Evolution of C++" could cut down most of the nonsense
> which has been posted in the recent discussions - or most nonsense which
> has been brought up against Lisp, for that matter.
> 
> "[...] Language comparisons are rarely meaningful and even less often
>  fair. A good comparison of major programming languages requires more
>  effort than most people are willing to spend, experience in a wide
>  range of application areas, a rigid maintenance of a detached and
>  impartial point of view, and a sense of fairness. [...]
>  I also worry about a phenomenon I have repeatedly observed in honest
>  attempts at language comparisons. The authors try hard to be impartial,
>  but are hopelessly biased by focusing on a single application, a single
>  style of programming, or a single culture among programmers. Worse,
>  when one language is significiantly better known than others, a subtle
>  shift in perspective occurs: Flaws in the well-known language are
>  deemed minor and simple workarounds are presented, whereas similar
>  flaws in other languages are deemed fundamental. Often, the workarounds
>  commonly used in the less-well-known languages are simply unknown to
>  the people doing the comparison or deemed unsatisfactory because they
>  would be unworkable in the more familiar language."

Well Stroustrup would say nonsense like this wouldn't he? Apparently
meaningful comparisons between languages are just too hard and are
meaningless anyway so we should all shut up and just use whatever
we're told.

> Even though I'm not using C++ now, and wouldn't mind if I never had
> to do so, I nevertheless wouldn't want to miss the reflections about
> programming and programming languages which have been influenced by
> reading this book (among lots of others, to be sure), and even the
> parts of "The C++ Programming Language" beyond superficial language
> rules. If the majority of people making decisions about programming
> (and the usage of programming languages) ranging from technical to
> management, would have read and really thought about what's mentioned
> there, many problems which tend to be perceived as "problems of C++"
> or "problems of [insert other programming language]" could be avoided.

Oh, I think there are many clever things about C++. I would not
dispute that for a minute. I liked C++ for a long long time until I
realised how badly it screws you up on big projects. And then I found
there were better solutions for big and small projects alike.
 
> Though (or because) I like the approaches of programming which are more
> typical for Lisp very much, I suspect the amount of trash one would
> see if e.g. Common Lisp had the popularity of C++ - including all the
> incompetence one sees in that realm - would also be quite "impressive"
> to an expert seeing it as an excellent language with very considerable
> internal coherence ;-)
> 
> -- Marc Wachowitz <··@ipx2.rz.uni-mannheim.de>
From: Andrew Koenig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9Bt5L.8FE@research.att.com>
In article <···············@aalh02.alcatel.com.au> ·············@alcatel.com.au (Chris Bitmead uid(x22068)) writes:

> My definition of ambiguous is that which I believe is a fairly common
> understanding of the term in the computer language field. i.e.

> foo<bar> baz;

> may be a declaration of a variable baz of type foo templated over
> bar. Or it may be an expression testing whether foo is less than bar
> which is less than baz.

> Yes you can make an informed decision in this case by looking up the
> symbol tables, but is an ambiguous grammar never the less.

In C, it is impossible to tell whether

	x(y);

is a declaration or an expression without knowing whether or not x
is the name of a type.  So this species of ambiguity is hardly new in C++.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Bill House
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <01bc538f$f0665bc0$03d3c9d0@wjh_dell_133.dazsi.com>
Andrew Koenig <···@research.att.com> wrote in article <··········@research.att.com>...
> 
> In C, it is impossible to tell whether
> 
> 	x(y);
> 
> is a declaration or an expression without knowing whether or not x
> is the name of a type.  So this species of ambiguity is hardly new in C++.

As father, like son?

Bill House
-- 
http://www.dazsi.com
Note: my e-mail address has been altered to
confuse the enemy. The views I express are
mine alone (unless you agree with me).
From: Chris Bitmead uid(x22068)
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <BITMEADC.97Apr29134551@Alcatel.com.au>
In article <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

>> Yes you can make an informed decision in this case by looking up the
>> symbol tables, but is an ambiguous grammar never the less.
>
>In C, it is impossible to tell whether
>
>	x(y);
>
>is a declaration or an expression without knowing whether or not x
>is the name of a type.  So this species of ambiguity is hardly new in C++.

True, but also C++ takes the issue to new levels of obscurity. Firstly
templated things don't have to be types, they can be templated
functions and also there tends to be lots and lots of type and
variable scoping in C++ that you don't find much in C. "x" might be a
type on one context and a variable in another context and a function
in another context. The result of this is that compiler error messages
tend to be next to useless. 


Compare to a language like Sather. The compiler always tells you
exactly what you did wrong, and in practice there's only about 3 or 4
different messages you tend to get.

I guess C++ might be the language that helps the economists achieve
full employment.
From: Andrew Koenig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9EGLp.KHH@research.att.com>
In article <······················@Alcatel.com.au> ·············@Alcatel.com.au writes:

> In article <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

> >> Yes you can make an informed decision in this case by looking up the
> >> symbol tables, but is an ambiguous grammar never the less.

> >In C, it is impossible to tell whether

> >	x(y);

> >is a declaration or an expression without knowing whether or not x
> >is the name of a type.  So this species of ambiguity is hardly new in C++.

> True, but also C++ takes the issue to new levels of obscurity. Firstly
> templated things don't have to be types, they can be templated
> functions and also there tends to be lots and lots of type and
> variable scoping in C++ that you don't find much in C. "x" might be a
> type on one context and a variable in another context and a function
> in another context. The result of this is that compiler error messages
> tend to be next to useless. 

> Compare to a language like Sather. The compiler always tells you
> exactly what you did wrong, and in practice there's only about 3 or 4
> different messages you tend to get.

> I guess C++ might be the language that helps the economists achieve
> full employment.

No rational direct response is possible to this debating technique,
so instead of responding directly, I would like to identify the technique.

The original statement: ``C++ is bad because its grammar is ambiguous.''

My response: ``C is similarly ambiguous, so C++ has no choice about it.''
(implicitly: any language based as strongly on C as C++ is will be ambiguous
in similar ways, so this is not a legitimate criticism of C++)

Rebuttal: ``The mere existence of the ambiguity isn't important (although
that is what I said originally) -- what matters is how ``obscure'' it is.
Anyway C++ has all these other syntactic problems that I hadn't mentioned
before''  [Incidentally, in C it is possible for "x" to be a type in
one context, a function, in another, and a variable in a third:

	void x() { }
	/* x is a function here */

	void y() {
		int x;
		/* x is a variable here */
	}

	void z() {
		typedef int x;
		/* x is a type here */
	}

so again this is not a legitimate criticism of C++]

The argument continues by shifting to yet another ground (how many error
messages you get from a particular compiler) and then ends with a
gratuitous insult.

So I can summarize the discussion this way:

	X: C++ is lousy because foo.

	Y: Foo is true of C, and will be true of any language descended from C.

	X: But foo is bad in C++ and not in C, and C++ has bar and baz,
	   and yer mother wears army shoes!

Which is why I claim that no direct, rational response is possible.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Erik Naggum
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3071316429917663@naggum.no>
* Andrew Koenig
| So I can summarize the discussion this way:
| 
| 	X: C++ is lousy because foo.
| 
| 	Y: Foo is true of C, and will be true of any language descended from C.
| 
| 	X: But foo is bad in C++ and not in C, and C++ has bar and baz,
| 	   and yer mother wears army shoes!
| 
| Which is why I claim that no direct, rational response is possible.

let's make it:

    X: C++ is lousy because of FOO.

    Y: FOO/n is true of C, etc

    X: but n is a huge number!  C++ _multiplies_ most weaknesses of C by
       this huge number, and does very little to alleviate any others.

    Y: no direct, rational response is possible.

example from real life:

    X: junk food is lousy because of the fat and colesterol.

    Y: but your body needs fat and colesterol, and any food prepared for
       human beings will have to contain fat and colesterol.

    X: don't you get it?  it's an issue of the _amount_ of fat and
       colesterol.

    Y: no direct, rational response is possible.

somehow, Andrew Koenig reminds me of the "nutrition guides" I found
prominently displayed at a MacDonald's some time ago.  however, I may
actually agree with him.  no direct, rational is possible when someone is
so consistently excellent at dogding the issues.

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: Joe Keane
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5ke17p$91j@shellx.best.com>
In article <··········@research.att.com>
Andrew Koenig <···@research.att.com> writes:
>	x(y);

No one would write a declaration like that.

In real man's C, every user-defined type begins with "struct", and we
like it that way.  This style has several real advantages.

Letting users add type names is some new-fangled OO thing, but it does
have its merits.  We know that it adds some feedback into the parser,
but once this is done, it's case closed on any example like above.

In article <······················@Alcatel.com.au>
Chris Bitmead uid(x22068) <·············@Alcatel.com.au> writes:
>True, but also C++ takes the issue to new levels of obscurity.

It's sublime.

In normal C, a block has some declarations, a blank line, then what
follows is executable code.  (I never use local initializers myself.)
It just doesn't happen that anyone could confuse the two.

With C++, anything goes, and you just never know.  It's a good joke if
you're in the right mood and you don't really need your program to work.
The exact same thing can be a declaration or executable code depending
on what you had for dinner, and don't look at it funny either.

In article <················@naggum.no>
Erik Naggum <····@naggum.no> writes:
>    X: C++ is lousy because of FOO.
>
>    Y: FOO/n is true of C, etc
>
>    X: but n is a huge number!  C++ _multiplies_ most weaknesses of C by
>       this huge number, and does very little to alleviate any others.

I'm with Mr. Naggum here.  I think Mr. Koenig's argument is like saying,
someone once broke wind, so we might as well set off the hydrogen bombs.

--
Joe Keane, amateur mathematician
From: Andrew Koenig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9M64I.M3o@research.att.com>
In article <··········@shellx.best.com> Joe Keane <···@jgk.org> writes:

> In real man's C, every user-defined type begins with "struct", and we
> like it that way.  This style has several real advantages.

Don't make the mistake of believing that your taste is universal.

> In normal C, a block has some declarations, a blank line, then what
> follows is executable code.  (I never use local initializers myself.)
> It just doesn't happen that anyone could confuse the two.

That's simply not true.  Such ambiguities exist in C as well:

	typedef int x;

	void f()
	{
		const x;    /* ? */
	}

Is the line with the comment a redeclaration of x as a variable of type
`const int' or is it a declaration of an empty list of variables of
type `const x' ?  C needs a special disambiguating rule to handle this case.

> With C++, anything goes, and you just never know.  It's a good joke if
> you're in the right mood and you don't really need your program to work.
> The exact same thing can be a declaration or executable code depending
> on what you had for dinner, and don't look at it funny either.

Have you ever heard of the Obfuscated C contest?

People can write incomprehensible trash in C, or in C++, or in any language.
They can also write crystal-clear programs.

> I'm with Mr. Naggum here.  I think Mr. Koenig's argument is like saying,
> someone once broke wind, so we might as well set off the hydrogen bombs.

It is very easy to come up with clever insults.  Even a child can do it.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Joe Keane
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5kop55$nls@shellx.best.com>
In article <··········@research.att.com>
Andrew Koenig <···@research.att.com> writes:
>Don't make the mistake of believing that your taste is universal.

No problem there.

>	typedef int x;
>
>	void f()
>	{
>		const x;    /* ? */
>	}

I really don't know what that means, and i don't care because i don't
see code like that.  If i had my may, it'd just be a syntax error.

These corner cases and weird constructions are meat-and-potatoes to
language lawyers, compiler writers, standards committees, and IOCCC
participants, and they cause much discussion on Usenet.

But in comparing languages, i think the question must be, what happens
when a programmer tries to write good code?  How easy is it to fall into
traps?  How sure is it that code does what it seems to do?  How likely
is it that a good compiler will catch simple slips?

>People can write incomprehensible trash in C, or in C++, or in any language.

Exactly.

>They can also write crystal-clear programs.

That's what we're debating.

>It is very easy to come up with clever insults.  Even a child can do it.

Right then: your argument is bogus.

C has some problems, as you pointed out.  In a `better C', like my C-,
some problems can be fixed by banning archaic constructions.  This does
not remove any expressive power, rather it just asks that the programmer
clearly state his intentions.  And of course, it's highly compatible,
since any conforming C- program will compile with a C compiler.

You point to some small problem in C, as if that exonerates C++ for
having such problems in much larger quantity.  It's just not a good
argument, and i think that Mr. Naggum fairly pointed that out.

--
Joe Keane, amateur mathematician
From: Andrew Koenig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9v5GB.1Hx@research.att.com>
In article <··········@shellx.best.com> Joe Keane <···@jgk.org> writes:

> You point to some small problem in C, as if that exonerates C++ for
> having such problems in much larger quantity.  It's just not a good
> argument, and i think that Mr. Naggum fairly pointed that out.

Well, not quite.  It's more like this:

Someone points out a problem in C++, and uses that as a reason
to claim that C++ is inferior to C.

I point out that C has the same problem, because doing so refutes
the claim of inferiority.

So the reply is that the problem is more widespread in C++.  Now, that
may be true or it may not, but it is not what was originally claimed.
Moreover, whether the revised claim is true or not is now irrelevant
to the original claim that C++ is inferior to C.

What is relevant is whether the claimed problem actually causes trouble
in practice -- but again that was not part of either the original
or the revised claim.

A model of the discussion might look like this:

	C++ has syntactic ambiguities, so it's worse than C.
	[the conclusion relies on the implicit claim: C doesn't have them]

	But C has syntactic ambiguities too [refutation of claim]

	Ah, but they're worse in C++ [change from factual claim
	to unsupported opinion]

How can one respond to this?  If one says

	No they aren't!

then the discussion has degenerated to the `Is!' `Isn't!' stage.

So I guess I should say this:  Every language has problems, and people's
opinion of the severity of those problems vary greatly from each other.
I believe that the advantages of C++ outweigh its problems for most of
the purposes for which C++ was intended.  In particular, the fact that
programmers *can* get themselves into trouble with C++ is relatively
unimportant compared with the fact that most of the ones I know *don't*
get themselves into trouble.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Thant Tessman
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3371F8D9.167E@nospam.acm.org>
Andrew Koenig wrote:

> [...] In particular, the fact that programmers *can* get 
> themselves into trouble with C++ is relatively unimportant 
> compared with the fact that most of the ones I know *don't* 
> get themselves into trouble.

I don't believe this at all.  Every C++ programmer I know gets
into trouble all the time.  It's just that most of them think 
it's par for the course because they've never worked with 
anything better.

-thant
From: Craig Franck
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5kt2nn$idr@mtinsc04.worldnet.att.net>
Thant Tessman <·····@nospam.acm.org> wrote:
>Andrew Koenig wrote:
>
>> [...] In particular, the fact that programmers *can* get 
>> themselves into trouble with C++ is relatively unimportant 
>> compared with the fact that most of the ones I know *don't* 
>> get themselves into trouble.
>
>I don't believe this at all.  Every C++ programmer I know gets
>into trouble all the time.  It's just that most of them think 
>it's par for the course because they've never worked with 
>anything better.

I could be glib and say that Andrew hangs with a better class of 
programmer (no pun intended) however, it is true that OO design
can be more difficult than a simple procedural model. You should
read chapter 13 "Design of Libraries" in BS's book on the language. 

There are also ways to control perceived defects in the language
as in 11.2.2 "Ambiguity Control" in "Design and Evolution".

Also, you do not need to use every feature of the language: if 
overloading operators or multiple inheritance bothers you, don't
use it.

The idea that C++ is gut shot and competent programmers can't develop
defect free software with a reasonable amount of effort is just silly.

-- 
Craig
········@worldnet.att.net
Manchester, NH
BBN has the brightest bit-heads on the planet. -- David Goodtree
From: Thant Tessman
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <337231EA.41C6@nospam.acm.org>
Craig Franck wrote:


> [...]  Also, you do not need to use every feature of the 
> language: if overloading operators or multiple inheritance 
> bothers you, don't use it.

Memory violations represent the vast majority of bugs in C++.
They are caused by the use of pointers.  Any way to avoid
the use of pointers in C++?

-thant
From: Craig Franck
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5ktl1v$gsm@mtinsc05.worldnet.att.net>
Thant Tessman <·····@nospam.acm.org> wrote:
>Craig Franck wrote:
>
>
>> [...]  Also, you do not need to use every feature of the 
>> language: if overloading operators or multiple inheritance 
>> bothers you, don't use it.
>
>Memory violations represent the vast majority of bugs in C++.
>They are caused by the use of pointers.  Any way to avoid
>the use of pointers in C++?

It depends on what you are trying to do. Anyway, proper use of
pointers do not cause memory violations, even though it may take
a good deal of semantic analysis to determine proper usage will
not be violated. And hey, if you determin the entire language
sucks, you can always move on to another.

-- 
Craig
········@worldnet.att.net
Manchester, NH
BBN has the brightest bit-heads on the planet. -- David Goodtree
From: Thant Tessman
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <33735A92.59E2@nospam.acm.org>
Craig Franck wrote:

> [...]  And hey, if you determin the entire language
> sucks, you can always move on to another.

I'm *trying* to get enough of you folks to go with me
to convince the vendors that their efforts supporting C++
would be better spent on languages that didn't suck as much.

-thant
From: Jason Shankel
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <33737737.25EE@pobox.com.confusespamblockremovers.ha.ha>
Thant Tessman wrote:
> 
> Craig Franck wrote:
> 
> > [...]  And hey, if you determin the entire language
> > sucks, you can always move on to another.
> 
> I'm *trying* to get enough of you folks to go with me
> to convince the vendors that their efforts supporting C++
> would be better spent on languages that didn't suck as much.
> 
> -thant
Perhaps that is your problem.
You seem to be trying to convince experienced people to disregard their
own judgement in favor of your agenda.  
Other languages are available.
Use them.
The core of the criticism against C++ seems, time and again, to be "C++
sucks because it allows construction X".  The response to this is,
invariably, "Don't use construction X".
This is a stalemate.
Good programmers can employ good practices in C++.
The fact that bad programmers can employ bad practices in C++ does not
invalidate this.
Above all, C++, it seems, was designed for practicality and that is why
it has been the target of such harsh criticism.  Among the practical
constraints on C++:
	As much compatibility with C as possible.  This is the source of much
of the (valid) criticism of C++.  However, if C++ had not been (mostly)
compatible with C, it would not have succeeded.
	Support for idiomatic programming.  C++ is NOT your object-oriented
mother.  You want global functions, global data, public member data,
etc?  Knock yourself out.  C++ assumes that YOU know what you're doing. 
It is often frustrating to people when a language allows programmers to
do things that they deign unacceptable.  For the sake of practicality,
however, we all know that no single idiom is appropriate for each and
every programming subtask.  If you belive that OO is the only way,
nothing about C++ will stop you from living and coding that way.  If, on
the other hand, you can think of simple, elegant, non-OO or semi-OO
constructions, C++ won't stop you there either.
	Appropriate for systems programming.  This includes embedded systems. 
Thus, high-overhead or operating-system service based language features
(such as windowing systems, GC, hidden pointers, etc) had to be
rejected.  To say that "pointers cause too many bugs and should be
hidden from the programmer" is a nice sentiment.  But the fact is that
machine architecture is based on very dangerous constructions.  Are
those of us tasked with writing code straight to machine architecture to
be denied the advantages of OO and other HLL techniques simply because
machine architecture is too "messy" to provide "safe" environments for
these techniques?  Is the object approach so weak that it cannot handle
being to close to the metal?  Certainly, if you can afford the overhead
of a VM or other secure runtime environment, C++ might not be your best
option.  But some of us have to write device drivers, you know.

Ultimately, I think C++ has and will prevail for large-scale work for
the same reasons that C prevailed over, say, Pascal.  If a language is
too perfect, too clean, too pure, be afraid.  That is an indication (not
proof, just an indication) that the messy details of the real world have
been hidden from you.  For an application developer, this might be fine
(in fact, I think we might see a shift to Java or a Java-like language
for most GUI desktop development in the next few years).  For a systems
programmer or developer of performance intensive (i.e. games)
applications, this can be the kiss of death.  
	C++, in fact, has often been criticized in high-performance development
as being too abstract, allowing too much inefficency.  C++ is about as
close to the metal as an object-oriented language can reasonably get. 
Just imagine how other, more 'pure' languages would fare in these
development communities.

Jason Shankel
Maxis, Inc.
From: Thant Tessman
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3375F2AD.41C6@nospam.acm.org>
Jason Shankel wrote:

> [...]   The core of the criticism against C++ seems, time and again, 
> to be "C++ sucks because it allows construction X".  The response to 
> this is, invariably, "Don't use construction X".  [...]

Actually, I'm coming from the other end.  I *like* the idea of multiple 
inheritance.  I *really like* the idea of templates.  What I can't stand
is their manifestation in C++.

Despite all the flaming I do, I know that Stroustrup and Koenig and Stepanov
are thoroughly brilliant people--far smarter than I ever hope to be.  I think 
the problem is that they've personally invested so much in C++ and had it
in their faces for so long that they can't see how ugly it is.

As for C++ being "practical", practicality is not the same thing as
compatibility with C which in turn is not the same thing as being a 
superset of C.  It is easier to become competent at C and, say, a
C compatible version of Scheme than it is to become competent at C++.
So there is no need to give up C when you absolutely need it merely
to program in a language that doesn't hurt so much.

-thant
From: Paul Prescod
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <EA2M6w.ny2@undergrad.math.uwaterloo.ca>
In article <·············@nospam.acm.org>,
Thant Tessman  <·····@nospam.acm.org> wrote:
>As for C++ being "practical", practicality is not the same thing as
>compatibility with C which in turn is not the same thing as being a 
>superset of C.  It is easier to become competent at C and, say, a
>C compatible version of Scheme than it is to become competent at C++.
>So there is no need to give up C when you absolutely need it merely
>to program in a language that doesn't hurt so much.

This may be true in the long run, but the reason C++ is so popular is that
people think in the short run. First they want a C with a little better support
for encapsulation. Then they want polymorphism. Then they experiment with 
genericity. There is no individual point at which it is profitable *in the 
short term* to learn functional programming and write Scheme-bindings for C
functions and objects. More advanced languages will not gain popular support
until they take this issue of incremental cost seriously.

 Paul Prescod
From: Thant Tessman
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <33777018.41C6@nospam.acm.org>
Paul Prescod wrote:

> [...] the reason C++ is so popular is that people think in the short 
> run. First they want a C with a little better support for encapsulation. 
> Then they want polymorphism. Then they experiment with genericity. [...]

...which by no coincidence describes the development of C++ itself.

-thant
From: Dean Roddey
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3379519C.1CD1@ng.netgate.net>
Paul Prescod wrote:
> 
> In article <·············@nospam.acm.org>,
> Thant Tessman  <·····@nospam.acm.org> wrote:
> >As for C++ being "practical", practicality is not the same thing as
> >compatibility with C which in turn is not the same thing as being a
> >superset of C.  It is easier to become competent at C and, say, a
> >C compatible version of Scheme than it is to become competent at C++.
> >So there is no need to give up C when you absolutely need it merely
> >to program in a language that doesn't hurt so much.
> 
> This may be true in the long run, but the reason C++ is so popular is that
> people think in the short run. First they want a C with a little better support
> for encapsulation. Then they want polymorphism. Then they experiment with
> genericity. There is no individual point at which it is profitable *in the
> short term* to learn functional programming and write Scheme-bindings for C
> functions and objects. More advanced languages will not gain popular support
> until they take this issue of incremental cost seriously.
> 

Most people in the real world would argue just the same, though I can
certainly understand where you are coming from. You have to understand
that a significantly size company is not a light on its feet as a whole
as individuals or very small company. For most of them, just going whole
hog and jumping all the way in right off the bat (regardless of the
language) would create a massive disaster, not development Nirvana. C++,
here again, covers a lot of territory, so that it allows you to walk
from here to there within a single language framework.

-----------------------
Dean Roddey
The CIDLib Class Libraries
'CIDCorp
·······@ng.netgate.net
http://ng.netgate.net/~droddey/

"Software engineers are, in many ways, similar to normal people"
From: Andrew Koenig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <EA2w60.3IB@research.att.com>
In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

> Despite all the flaming I do, I know that Stroustrup and Koenig and Stepanov
> are thoroughly brilliant people--far smarter than I ever hope to be.  I think 
> the problem is that they've personally invested so much in C++ and had it
> in their faces for so long that they can't see how ugly it is.

I've published more than 30 articles pointing out problems with C++,
so it's hardly fair to claim that I don't know where they are.

As far as ugliness and beauty go, I think C++ isn't close to either
extreme.  In that respect, it's like a pickup truck:  It's not the most
elegant thing around, but it wasn't meant to be.  Moreover, continuing
the vehicle analogy, people disagree dramatically about what they find
beauful or ugly.

The thing about beautiful languages is that unless they're also useful,
all they're good for is being admired.  There's nothing wrong with that --
art in all its forms is a fundamental part of what makes us human.
But my involvement with C++ is as a tool, not an artwork, and when that
happens, I turn utilitarian real fast.



				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark

				  (if you click `photography' on my web page,
				   you'll see some of my attempts at art)
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Thant Tessman
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3377C4E4.41C6@nospam.acm.org>
Andrew Koenig wrote:


> [...]  The thing about beautiful languages is that unless they're also 
> useful, all they're good for is being admired.  [...]

I've been programming professionally since I was fifteen.  I've used C++ 
longer than I've used any other language.  I've actually assigned to the 
"this" pointer.  (Anybody remember that?)  I've never taken a computer 
science class in my life so any sense of elegance I may have developed 
came from doing Real Work (TM).  I was lucky enough to have some friends 
who taught me Scheme, and the experience was like realizing that a 
gigantic practical joke had been played on me.

You should know by now that when I say that C++ is ugly, I mean that 
C++ makes it difficult to do real work.  If it weren't possible to 
compare languages in absolute terms there wouldn't be any point in 
advancing the craft of computer programming at all.  And in absolute 
terms C++ sucks.

-thant
From: Alisdair Johnson
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <01bc5f71$f093ea20$58148d82@ayj>
>the experience was like realizing that a 
gigantic practical joke had been played on me.

I felt like that when I went from VC++ to Delphi. The problem is that
industry uses C/C++ so I have to.... <sigh>.

BTW. What's Scheme?
From: Matt Austern
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <fxtn2pyc4ku.fsf@isolde.mti.sgi.com>
"Alisdair Johnson" <········@telsci.co.uk> writes:

> BTW. What's Scheme?

It's a dialect of lisp.  My impression is that Scheme and Common Lisp
are the two most important dialects of lisp nowadays.  (With the
possible exception of various applications' macro languages, such as
GNU Emacs lisp and AutoCAD lisp.)
From: Alaric B. Williams
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3378bfbd.7173865@news.demon.co.uk>
On 13 May 1997 07:45:05 GMT, "Alisdair Johnson"
<········@telsci.co.uk> wrote:

>>the experience was like realizing that a 
>gigantic practical joke had been played on me.

>I felt like that when I went from VC++ to Delphi. The problem is that
>industry uses C/C++ so I have to.... <sigh>.

[sad violin music]

>BTW. What's Scheme?

Ah! It's a small language, but designed for maximum "utility per
feature" - so you have a small feature set capable of doing a lot,
since each feature is as general as possible.

This opens some interesting possibilities for optimisation, since the
compiler can focus on implementing a small set of conceptually
orthogonal features efficiently, but it somewhat hinders some
optimisations where more information is needed from the programmer. I,
personally, would like to see optional static typing, although type
inferences (that guess the types of variables being used and thus
remove runtime checks) have been successul from what I hear.

Scheme does suffer a bit from minimality, but the next standard
release, R5RS, should hopefully cover must of the conceptual gaps,
and there is an informal standard extension library called SLIB. A
major complaint I hear is that Scheme lacks a standard C interface;
there are many Scheme implementations, each with a different way of
importing C functions, which has provided hinderances to growth unseen
by languages like TCL that have definitive implementations!

Anyway, aside from these points, Scheme is a great language, and will
continue to improve as the standard is expanded. For a great
introduction, read "Structure and Interpretation of Computer Programs"
(MIT Press, Abelson and Sussman).

ABW
            ##### UNIX IS LAME - EVEN LINUX! ##### 

(My previous nice signature file was just vapourised by
a Linux kernel crash that ate almost all of my main
partition, so we will have to make do with a boring and
slightly bitter .sig)

Alaric B. Williams, ······@abwillms.demon.co.uk

FUN: http://www.abwillms.demon.co.uk/alaric/wfewad.htm
INTERESTING: http://www.abwillms.demon.co.uk/os/
OTHER: http://www.abwillms.demon.co.uk/
From: Craig Franck
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5l8j34$2jp@mtinsc05.worldnet.att.net>
Thant Tessman <·····@nospam.acm.org> wrote:
>Andrew Koenig wrote:

>> [...]  The thing about beautiful languages is that unless they're also 
>> useful, all they're good for is being admired.  [...]
>
>I've been programming professionally since I was fifteen.  

>I was lucky enough to have some friends 
>who taught me Scheme, and the experience was like realizing that a 
>gigantic practical joke had been played on me.

Sounds almost like a religous conversion of some sort.

>You should know by now that when I say that C++ is ugly, I mean that 
>C++ makes it difficult to do real work.  

Compared to what? Scheme?

>And in absolute terms C++ sucks.

Yes, but she makes quite a vacuum. ;-)

-- 
Craig
········@worldnet.att.net
Manchester, NH
BBN has the brightest bit-heads on the planet. -- David Goodtree
From: Thant Tessman
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3379ED13.446B@nospam.acm.org>
Ray Fischer wrote:

> [...]  Different languages serve different purposes.  Try writing 
> real-time interrupt code in Scheme.  [...]

Actually I have.  And as a matter of fact, continuations plus 
Chez Scheme's signal handling capabilities made it surprisingly 
easy.  We were extremely worried that GC was going to be a problem 
but it turned out to be a complete non-issue.

-thant
From: Rainer Joswig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <joswig-ya023180001805970138280001@news.lavielle.com>
In article <·············@netcom.com>, ···@netcom.com (Ray Fischer) wrote:

> Try writing
> a full-featured word processor that can run in 2MB of Ram in Scheme.

Why should that not be possible?

-- 
http://www.lavielle.com/~joswig/
From: ·····@telstra.com.au
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <BITMEADC.97May13165739@Alcatel.com.au>
In article <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

>> the problem is that they've personally invested so much in C++ and had it
>> in their faces for so long that they can't see how ugly it is.
>
>I've published more than 30 articles pointing out problems with C++,
>so it's hardly fair to claim that I don't know where they are.

Ok, so you've noticed some problems with C++. That's not too hard
actually :-).

But why have you not noticed how *severe* these problems are? You need
to either work on a 30 person project or research what's going on in
these large projects. Perhaps then you might be inclined to recognise
that C++ is not so much a "pick-up truck", as you like to describe it,
but rather a rick-shaw with a V8 engine.

Hey I liked C++, for a long time! Then the reality of using it for a
large project hit ":(
From: Hrvoje Niksic
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <kig7mh3zut6.fsf@jagor.srce.hr>
·····@telstra.com.au writes:

> Hey I liked C++, for a long time! Then the reality of using it for a
> large project hit ":(

Many people seem to like C++ until they actually try to use it.  I
sympathize with the sentiment.

-- 
Hrvoje Niksic <·······@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
Unspeakable horrors from outer space paralyze the living and
resurrect the dead!
From: Henry Baker
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <hbaker-1305970912330001@10.0.2.1>
In article <·········@research.att.com>, ···@research.att.com (Andrew
Koenig) wrote:

> In article <···············@jagor.srce.hr> Hrvoje Niksic
<·······@srce.hr> writes:
> 
> > Many people seem to like C++ until they actually try to use it.  I
> > sympathize with the sentiment.
> 
> And many people claim to dislike C++ while showing no evidence of having
used it.

Name some.  I've never seen a comment describing a misfeature of C++ that
wasn't on target.  And yes, I've programmed extensively in C++ (in one of
the best environments -- Metrowerks) and have acquired a very thorough
dislike for it.  C does what it does, and there's so little there, there's
not that much to dislike.  C++, on the other hand, flaunts its flaws, and
the C++ standards committee seems quite proud of them.  Only the arrogance of
the Ada standards committee has been able to exceed that of the C++ committee.

As to the assumption that one can turn a C programmer into a C++ programmer --
good luck!  I doubt that 6 months will suffice, and in the mean-time, you'd
better just kiss off the programmer (and all of his code that he writes
during that period).
From: Andrew Koenig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <EA56Jn.G6n@research.att.com>
In article <·······················@10.0.2.1> ······@netcom.com (Henry Baker) writes:

> Name some.  I've never seen a comment describing a misfeature of C++ that
> wasn't on target.

I have better things to do than remember the names of twits.
Reasoned criticism is one thing, but there are plenty of people
who just fling blind insults at C++ and never say anything with
any thought or substance behind it.

C++ has lots of misfeatures -- I've published more than 30 articles
detailing them.  Nevertheless, I think C++ has done a good job of
solving the problems it was intended to solve.  Those problems include
the constraint of having to run in the same environments as C;
in my opinion, that constraint accounts for most of C++'s misfeatures.

> C++, on the other hand, flaunts its flaws, and
> the C++ standards committee seems quite proud of them.  Only the arrogance of
> the Ada standards committee has been able to exceed that of the C++ committee.

This is an example of what I mean by blind insults.

Have you attended even a single meeting of the committee?
If not, on what facts can you base a claim of pride or arrogance?

> As to the assumption that one can turn a C programmer into a C++ programmer --
> good luck!  I doubt that 6 months will suffice, and in the mean-time, you'd
> better just kiss off the programmer (and all of his code that he writes
> during that period).

One strategy that has been successful is to bring a few
experienced C++ programmers into a project and have them
define classes that capture the key abstractions for that
project.  The rest of the staff can use those abstractions
productively without having to become experts immediately.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Henry Baker
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <hbaker-1305971923210001@10.0.2.1>
In article <··········@research.att.com>, ···@research.att.com (Andrew
Koenig) wrote:

> In article <·······················@10.0.2.1> ······@netcom.com (Henry
Baker) writes:
> 
> > Name some.  I've never seen a comment describing a misfeature of C++ that
> > wasn't on target.
> 
> I have better things to do than remember the names of twits.
                                                        ^^^^^
> > C++, on the other hand, flaunts its flaws, and
> > the C++ standards committee seems quite proud of them.  Only the
arrogance of
> > the Ada standards committee has been able to exceed that of the C++
committee.
> 
> Have you attended even a single meeting of the committee?
> If not, on what facts can you base a claim of pride or arrogance?

If the shoe fits..... (See ^^^^^ above)
From: Andrew Koenig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <EA69zD.MAn@research.att.com>
In article <·······················@10.0.2.1> ······@netcom.com (Henry Baker) writes:

> > In article <·······················@10.0.2.1> ······@netcom.com (Henry
> Baker) writes:

> > > Name some.  I've never seen a comment describing a misfeature of C++ that
> > > wasn't on target.

> > I have better things to do than remember the names of twits.
>                                                         ^^^^^

> > Have you attended even a single meeting of the committee?
> > If not, on what facts can you base a claim of pride or arrogance?

> If the shoe fits..... (See ^^^^^ above)

Oh well, if you're going to quote me selectively so as to change the
meaning of what I said, I'd better say it again.

I thought it made it clear by the original context that I was referring
to people who express blind hatred of C++ without citing facts at all.
Your response, cited above, is scarcely relevant, because I wasn't talking
about people who `describe misfeatures of C++.'  Indeed, I went on to say
that I knew perfectly well that C++ has plenty of misfeatures, and that
I've published more than 30 articles that describe them.

So ... by a `twit' I meant someone -- and there are several such people
in this newsgroup -- whose level of understanding is limited to
`I hate C++ and if you disagree with me, I hate you too!'

I can't imagine what good could possibly come from hunting down such
postings.  If you think that opinion is arrogant, then you have an odd
definition of arrogance.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Chris Bitmead uid(x22068)
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <BITMEADC.97May14130918@Alcatel.com.au>
In article <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

>C++ has lots of misfeatures -- I've published more than 30 articles
>detailing them.  Nevertheless, I think C++ has done a good job of
>solving the problems it was intended to solve.  Those problems include
>the constraint of having to run in the same environments as C;
>in my opinion, that constraint accounts for most of C++'s misfeatures.

Except for two things: 

1) Nobody seems to have a realistic explanation of what C
compatibility buys you. Java has proved that all people ever wanted
was a similar general style, and Eiffel has proved that you can have
something a lot different to C and still use legacy C code easily.

2) Even if there are some good cases for C compatibility they surely
can't extend to every second new software project in the world which
C++ seems to have expanded to.
From: Jason Shankel
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3378BCFC.58B6@pobox.com>
Andrew Koenig wrote:
> 
> In article <···············@jagor.srce.hr> Hrvoje Niksic <·······@srce.hr> writes:
> 
> > Many people seem to like C++ until they actually try to use it.  I
> > sympathize with the sentiment.
> 
> And many people claim to dislike C++ while showing no evidence of having used it.
> --
And then there are those, such as myself, who disliked C++ until I had
to use it.

Jason Shankel
Maxis, Inc.
From: Daniel P Hudson
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5leuv9$htd@huron.eel.ufl.edu>
Jason Shankel <·················@pobox.com> wrote:
>Andrew Koenig wrote:
>> 
>>> Many people seem to like C++ until they actually try to use it.  I
>>> sympathize with the sentiment.
 
>> And many people claim to dislike C++ while showing no evidence of 
>> having used it.

>And then there are those, such as myself, who disliked C++ until I had
>to use it.

I don't think people dislike C++ as much as they dislike having to 
learn OOP with it. It really is a GOOD idea to learn SmallTalk or
anopther small OO language and use ot for an extended period fo time
before trying complex OO languages like C++, Ada, etc..
From: Andrew Koenig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <EA8Eos.MF9@research.att.com>
In article <··········@huron.eel.ufl.edu> ········@freenet2.afn.org (Daniel P Hudson) writes:

> I don't think people dislike C++ as much as they dislike having to 
> learn OOP with it. It really is a GOOD idea to learn SmallTalk or
> anopther small OO language and use ot for an extended period fo time
> before trying complex OO languages like C++, Ada, etc..

It is almost always a good idea to learn more than one language
thoroughly; preferably more than two.  It gets easier after the second.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: David Chase
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <33834467.7C01@world.std.com>
Andrew Koenig wrote:

> And many people claim to dislike C++ while showing no evidence of having used it.

SparcCompiler 3.0, the optimizing backend (nbe), >250KL of C++.

C++Expert, a grab-bag of C and C++, parsing, processing,
and emitting C++, not sure how many lines of code.

I don't like C++.

yours,

David Chase
From: Andrew Koenig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <EAL805.7st@research.att.com>
In article <·············@world.std.com> ·····@world.std.com writes:

> Andrew Koenig wrote:

> > And many people claim to dislike C++ while showing no evidence of having used it.

> C++Expert, a grab-bag of C and C++, parsing, processing,
> and emitting C++, not sure how many lines of code.

> I don't like C++.

You've made that clear on many occasions -- but your dislike of C++ does not
gainsay what I said.

I'm certainly not going to try to argue you out of your taste.  I mean,
I don't like mushrooms, but I like even less when people try to tell me
``Oh, but you SHOULD like mushrooms!''

But a goodly number of the postings on this newsgroup seem to come from
people who mostly want to score points by thinking up clever insults,
and haven't really given any serious thought to programming languages
or tools at all.  Not all, but enough to notice.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: David Chase
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <33859765.7C95@world.std.com>
Andrew Koenig wrote:

> But a goodly number of the postings on this newsgroup seem to come from
> people who mostly want to score points by thinking up clever insults,
> and haven't really given any serious thought to programming languages
> or tools at all.  Not all, but enough to notice.

Ah, but it goes both ways.  Nothing like having someone give advice
on how to write "good code with a garbage collector" when they've never
used one.  There's tremendous benefits to some of these other features,
that you do not appreciate until you've used them for a while.  For
instance, I've never used Eiffel, but the way some of its proponents
talk about its assertion checking, I suspect that there's something
good there.  In the Scheme world, where I have used the "ordinary"
Lispish features of the language, I get the impression that there's
supposed to be something marvelous about continuations, though what
it is, I cannot tell (There is always the theoretical appeal of reducing
all control flow problems to a single hammer, er, hedgehog).

It was common, back when I worked at Sun, to run into people who
believed that C was "faster than" Fortran (said people, of
course, never used Fortran, didn't know squat about compiler
optimization, and probably think that "aliasing" is something
that you do when you are hiding from the law).  I see discussions
here about "great stuff" that you can do with gcc, except
that (oops) gcc seems to be deficient at eliminating tail-calls,
at least relative to one vendor's compiler (why not try another
compiler?  Isn't that part of the point of using C as your
intermediate language?)  Sometimes, you can still find someone
talking about how "lazy evaluation" is good because it
lets you avoid unnecessary computation, without a thought
to the mountain of bookkeeping that lazy evalation generally
requires.

People are incredibly parochial.

David Chase, ·····@world.std.com
From: Kaz Kylheku
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5m4irn$onj@bcrkh13.bnr.ca>
In article <·············@world.std.com>,
David Chase  <·····@world.std.com> wrote:
>It was common, back when I worked at Sun, to run into people who
>believed that C was "faster than" Fortran (said people, of
>course, never used Fortran, didn't know squat about compiler
>optimization, and probably think that "aliasing" is something
>that you do when you are hiding from the law).  I see discussions

Oh man, I'm SMBOTFL.
From: Andrew Koenig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <EAnApH.Ht1@research.att.com>
In article <·············@world.std.com> ·····@world.std.com writes:
> Andrew Koenig wrote:

> > But a goodly number of the postings on this newsgroup seem to come from
> > people who mostly want to score points by thinking up clever insults,
> > and haven't really given any serious thought to programming languages
> > or tools at all.  Not all, but enough to notice.

> Ah, but it goes both ways.  Nothing like having someone give advice
> on how to write "good code with a garbage collector" when they've never
> used one.

Hmmm... isn't such behavior an instance of what I just said?
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Kaz Kylheku
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5l5of9$as6@bcrkh13.bnr.ca>
In article <·············@pobox.com.confusespamblockremovers.ha.ha>,
Jason Shankel  <·······@pobox.com.confusespamblockremovers.ha.ha> wrote:
>Thant Tessman wrote:
>> 
>> Craig Franck wrote:
>> 
>> > [...]  And hey, if you determin the entire language
>> > sucks, you can always move on to another.
>> 
>> I'm *trying* to get enough of you folks to go with me
>> to convince the vendors that their efforts supporting C++
>> would be better spent on languages that didn't suck as much.
>> 
>> -thant
>Perhaps that is your problem.
>You seem to be trying to convince experienced people to disregard their
>own judgement in favor of your agenda.  
>Other languages are available.
>Use them.
>The core of the criticism against C++ seems, time and again, to be "C++
>sucks because it allows construction X".  The response to this is,
>invariably, "Don't use construction X".

This is also the core of much criticism against C. Some of us C lovers
nevertheless recognize the validity of this criticism. I sometimes
teach people C, and I find myself rationalizing some of its features,
and even apologizing on its behalf. :)

The problem with ``don't use construction X'' is that it's too akin
to the doctor who ways ``don't do that'' when the patient complains
that ``it hurts when I do this''.

The problem is that people will use construction X. Construction X may even
be an essential language feature, but one that has design flaws that lead
to pitfalls. Should C++ programmers avoid inheritance just because of
the pitfalls involving accidentally overriden virtual functions? Heck no;
it just requires extra care and effort that could be put to better use.


>This is a stalemate.
>Good programmers can employ good practices in C++.

So what? Good programmers can employ good practices in 6502 assembly language
as well, and they have. If you put enough effort into it, you can, in any
language, implement a program that is provably correct.

I guess that comparative discussions of programming languages must hence be
impossible.
From: David Thornley
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5kvd1i$6dc$1@darla.visi.com>
In article <·············@nospam.acm.org>,
Thant Tessman  <·····@nospam.acm.org> wrote:
>Craig Franck wrote:
>
>
>> [...]  Also, you do not need to use every feature of the 
>> language: if overloading operators or multiple inheritance 
>> bothers you, don't use it.
>
>Memory violations represent the vast majority of bugs in C++.
>They are caused by the use of pointers.  Any way to avoid
>the use of pointers in C++?
>
OK, here we get into Stroustrup's statement that "library design
is language design".  It is perfectly possible to put pointers
behind the scenes in a library.  Inside the library, they can be
range-checked, garbage-collected, what have you.

Now, consider any Common Lisp implementation.  There's a whole lot
of pointers shuffling around inside, but the language implementation
(usually) doesn't drop any where they don't belong.  This, among other
things, makes CL one heck of a safer language than C.

If you're willing to consider a library (which may not even be
standard) as part of an implementation, then it's generally not
necessary to use raw pointers in C++, any more than in Common
Lisp.  In fact, classes that replace the usual and dangerous arrays
and strings are mandated by the draft standard, and will be shipped
as part of any standard implementation.

C programmers usually use pointers for passing variables by address,
implementing arrays, and making dynamic data structures.  The first
is handled more directly in C++ with references, and the other two
are easily handled with array classes and string classes and linked list
and tree classes and whatever.  The pointers are still in there, but
they don't have to come out.  At the cost of writing somebody writing
a library beforehand, everybody can avoid pointers and most of the
nastiest bugs in C.

David Thornley
From: Thant Tessman
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3373595F.15FB@nospam.acm.org>
David Thornley wrote:


> [...]  It is perfectly possible to put pointers behind the 
> scenes in a library.

Yes, you can, with a *lot* of effort, hide pointers behind 
other machinery.  And in fact, when I program in C++, this 
is what I spend *most* of my time doing.


> [...]  In fact, classes that replace the usual and dangerous 
> arrays and strings are mandated by the draft standard, and 
> will be shipped as part of any standard implementation.

Oh goody, soon C++ will include data structures almost as
safe as the ones that other languages have had for years.


> [...]  At the cost of writing somebody writing a library 
> beforehand, everybody can avoid pointers and most of the 
> nastiest bugs in C.  [...]

Who's lucky enough to find every data structure and 
algorithm they need defined in a library?

Pointers are inherent in C++.  They are unavoidable.  Try,
for example, expressing a subtype relationship (which
in C++ is acomplished via inheritance) without using 
pointers.


-thant

--
Philosophy is the search for the set of principles 
that will finally free us from the need to think.
From: Jonathan Guthrie
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5kvdlp$o84$1@news.hal-pc.org>
In comp.lang.scheme Thant Tessman <·····@nospam.acm.org> wrote:

> > [...]  Also, you do not need to use every feature of the 
> > language: if overloading operators or multiple inheritance 
> > bothers you, don't use it.

> Memory violations represent the vast majority of bugs in C++.
> They are caused by the use of pointers.  Any way to avoid
> the use of pointers in C++?

I read this newsgroup (comp.lang.scheme) to find out about Scheme, not
to participate in a language dicksize war.  However, your statement is
simply untrue so I cannot let it go unchallenged.

You seem to be saying that most defects in software written in C++ are
caused by errors in the manipulation of pointers.  In my experience,
most defects in software written in C++ are caused by incomplete or
invalid specifications and faulty logic on the part of the designer.
It may be true (although it isn't, in my experience,) that the most
difficult-to-find bugs are the result pointer errors, but I have had
more trouble finding problems that stem from uninitialized variables
and out-of-bounds array indexes than from invalid pointer manipulation.
You should also not overlook the fact that it is possible to have
subtle and hard to find errors in the design that resist all efforts
to diagnose.

In example might prove instructive, here.  I used to do embedded-systems
programming for a subsidiary of a large technology company.  We produced
systems that could accurately measure and control the flow of natural gas
through pipelines.  One of our customers was a major international energy
company with subsidiary that had a subsidiary that operated a pipeline
running from Canada to Missouri.  At one station (in northern Iowa) they
had an odd behavior.  The gas-flow computer in question has an
"accumulator" for each pipeline that keeps track (for billing purposes)
of the total volume of gas that has flowed through the pipeline during
the previous day and hour.  There is another accumulator (this one is 
configurable and can read the values from whichever pipelines they're
interested in controlling) that is used to control the flow rate through
the pipeline.  At this one station, the volumes didn't match.  There
was a descrepancy of between 5-10% between the two values with the
billing accumulator always reporting a smaller value than the control
accumulator.

After working this problem for six months, we finally figured out what
the problem was.  The limits on the behavior of the unit were never
specified so we built the system in whichever way appeared to be
appropriate.  As it happens, I coded the "custody transfer" (that is,
"billing") accumulator, and someone else coded the control accumulator
and we have different ideas of what is "appropriate."  The upshot of
this is that the billing accumulator is designed to stop accumulating
when an input goes out of range, but under the same conditions, the
control accumulator keeps accumulating using whatever the last valid
input was.  As it happens, there was a loose wire in the static-pressure
loop so that circuit (normally a 4-20mA currenty loop) would occasionally
produce a negative pressure.  This was causing the gas-flow calculation
to flag the flow rate as "invalid" turning off the billing accumulator,
but the control accumulator kept right on chugging with a constant value
for the flow rate.  "Fixing" the control accumulator so that it
stopped accumulating when it had an invalid input (and fixing the loose
wire on the static-pressure input) solved the problem.

Unfortunately for your case, the same thing causes most of the defects
in Scheme, CL, ML, Modula-X, Ada, and so forth.  (You will notice that
I didn't even mention what language I was programming in at any time
during my example.)  While I personally find C++ to be an ugly and
convoluted language (and I find Scheme to be subtle and elegant) the
real difficulty of creating expressions in that language is determining
what to express, not in the features of the language itself.  This is
because the design of the program is an essential difficulty in the
program.

One opinion, worth what you paid for it.

I now return you to the ongoing language dicksize war.
-- 
Jonathan Guthrie (········@brokersys.com)
Information Broker Systems   +281-895-8101   http://www.brokersys.com/
12703 Veterans Memorial #106, Houston, TX  77014, USA

We sell Internet access and commercial Web space.  We also are general
network consultants in the greater Houston area.
From: Xavier Huet
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3372CCDE.37589B0D@fifi.org>
Thant Tessman wrote:
> 
> Craig Franck wrote:
> 
> > [...]  Also, you do not need to use every feature of the
> > language: if overloading operators or multiple inheritance
> > bothers you, don't use it.
> 
> Memory violations represent the vast majority of bugs in C++.
> They are caused by the use of pointers.  Any way to avoid
> the use of pointers in C++?

You can with References (alias) but it's true that it won't resolve 
all your problem since they behave like const pointer, i.e they're
not "reseatable".

	int i = 1;
	int j = 2;
	int& r = i;  // r is an alias for i
	r = j;	     // r is still an alias for i whose value is 2 now.


~Xavier.
From: loq
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <33737278.47D0@dfwlx3.netcom.com>
Thant Tessman wrote:
> 
> Craig Franck wrote:
> 
> > [...]  Also, you do not need to use every feature of the
> > language: if overloading operators or multiple inheritance
> > bothers you, don't use it.
> 
> Memory violations represent the vast majority of bugs in C++.
> They are caused by the use of pointers.  Any way to avoid
> the use of pointers in C++?
> 
> -thant

Simple.  If you use new, use delete when finished.
If you use new and give it to something, make sure it uses delete when
its finished or you use delete when you know its through.
From: Greg Morrisett
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <01bc5f13$2a578f50$e5d35480@hickory>
loq <···@dfwlx3.netcom.com> wrote in article
<·············@dfwlx3.netcom.com>...
> Simple.  If you use new, use delete when finished.
> If you use new and give it to something, make sure it uses delete when
> its finished or you use delete when you know its through.
> 

And if you use someone else's code, read through it carefully to determine
whether
they're done using it and delete it, or heck, change their code so that you
delete it,
or if they don't give you the source code, just don't worry about it and
the problem
will go away (sort of). If you're lucky, they've allocated another word for
a reference count.
If you're luckier still, they've actually maintained the right counts.   Of
course, they
might have, but you don't know what protocol they're using with the
reference counts.
Become very confused when you find out that some of the time, the objects
they're
dealing with are stack-allocated, and some of the time, they're heap
allocated, so
a simple reference-counting strategy won't work at all.  Cycles?  Never
arise, don't
worry.  

Next, go buy a copy of Purify to determine space leaks (long after you've 
identified places where you deleted long before you should've).
Ignore the space leaks coming from lack of stack-space because everything
was
"optimized" so that it could be allocated on the stack instead of the heap
and the
fact that your C compiler won't eliminate tail calls.  Cross your
fingers that an exception never gets raised, or else that funky code over
there will
actually run and the reference counts will go to hell.  Run the code only
on
"small" test cases, because Purify slows down your code so much that
you can't afford to really test the full thing.

Now you can start debugging the multi-threaded version of the code.  Damn,
you half
to insert all those locks for all those reference counting operations. 
Hmmm, maybe
a race condition won't arise here.  

At the end of the period, congratulate yourself for spending all of this
time on stuff
that could've been fully automated for you.  But hey, it runs faster!  (I
think -- hmm, turns out
the implementation of new and delete calls a pretty slow version of
malloc/free.  Maybe
I'll go rewrite those tomorrow...  And geez, that operating system sure is
slow.  That's
Thursday's project.  I just know I can do a better job of that.)
From: Andrew Koenig
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9vL6D.JL5@research.att.com>
In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

> I don't believe this at all.  Every C++ programmer I know gets
> into trouble all the time.  It's just that most of them think 
> it's par for the course because they've never worked with 
> anything better.

I've worked with lots of languages and systems,
and every one offers its own ways of getting into trouble.

The ones that try to reduce the ways of getting into trouble,
invariably pay a price, which may or may not be significant
depending on the context.

Saying that one language is better than another, without supplying
a context, is just plain naive.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Henry Baker
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <hbaker-0905970745320001@10.0.2.1>
In article <··········@research.att.com>, ···@research.att.com (Andrew
Koenig) wrote:
> I've worked with lots of languages and systems,
> and every one offers its own ways of getting into trouble.
> 
> The ones that try to reduce the ways of getting into trouble,
> invariably pay a price, which may or may not be significant
> depending on the context.

I agree.  The worst languages try so hard to protect you from yourself,
that you can't get anything done.  Prime example -- the C preprocessor.

> Saying that one language is better than another, without supplying
> a context, is just plain naive.

I disagree.  Languages can be absolutely better on a cost/feature basis.

For example, Ada's type-fastidiousness is every bit as costly as that of
a garbage-collected language, and then they didn't offer garbage collection!
Modula-3 & Eiffel showed that going ahead and offering GC was a big win, for
no additional cost.

There are many additional examples of poor cost/feature tradeoffs in computer
languages, including many in C and C++.
From: Thant Tessman
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <336B781B.167E@nospam.acm.org>
Joe Keane wrote:

> [...]  In real man's C, every user-defined type begins with 
> "struct", and we like it that way.  This style has several 
> real advantages.  [...]

When you want to start a fire by rubbing two sticks together,
is it more important for the sticks to be pointy or rounded?

-thant
From: Michael Furman
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9por5.7Gx@mv.mv.com>
In article <··········@shellx.best.com>, ···@jgk.org says...
>
>In article <··········@research.att.com>
>Andrew Koenig <···@research.att.com> writes:
>>       x(y);
>
>No one would write a declaration like that.
>
>In real man's C, every user-defined type begins with "struct", and we
>like it that way.  This style has several real advantages.

What if it is not a struct? I guess "real man" just did not learn
about typedef.

---------------------------------------------------------------
--- To reply by mail: remove "XXX" from address ---------------
Michael Furman,                       (603)893-1109
Geophysical Survey Systems, Inc.  fax:(603)889-3984
13 Klein Drive -                      engr @
P.O. Box 97 
North Salem,                          71543 . 1334 @
NH 03073-0097 
---------------------------------------------------------------
From: Lawrence Kirby
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <862920987snz@genesis.demon.co.uk>
In article <··········@mv.mv.com> ····@GSSI.XXX.MV.COM "Michael Furman" writes:

>In article <··········@shellx.best.com>, ···@jgk.org says...
>>
>>In article <··········@research.att.com>
>>Andrew Koenig <···@research.att.com> writes:
>>>       x(y);
>>
>>No one would write a declaration like that.
>>
>>In real man's C, every user-defined type begins with "struct", and we
>>like it that way.  This style has several real advantages.
>
>What if it is not a struct? I guess "real man" just did not learn
>about typedef.

typedef doesn't define a new type, it just defines a new name for an
existing type. However it is certainly true that using typedef you can
refer to structure types without using an explicit ``struct'' keyword.
There is also the matter of union and enum types.

-- 
-----------------------------------------
Lawrence Kirby | ····@genesis.demon.co.uk
Wilts, England | ·········@compuserve.com
-----------------------------------------
From: William Clodius
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3366662C.6201@lanl.gov>
Andrew Koenig wrote:
> <snip>
> My response: ``C is similarly ambiguous, so C++ has no choice about it.''
> (implicitly: any language based as strongly on C as C++ is will be ambiguous
> in similar ways, so this is not a legitimate criticism of C++)
> <snip>

I would phrase this differently. I view this as a legitimate criticism
of any language strongly based on C in contexts that involve comparisons
with languages not strongly based on C.

-- 

William B. Clodius		Phone: (505)-665-9370
Los Alamos Nat. Lab., NIS-2     FAX: (505)-667-3815
PO Box 1663, MS-C323    	Group office: (505)-667-5776
Los Alamos, NM 87545            Email: ········@lanl.gov
From: David Hanley
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <336612F2.69A7@nospan.netright.com>
Andrew Koenig wrote:
> 
> In article <······················@Alcatel.com.au> ·············@Alcatel.com.au writes:
> 
> > True, but also C++ takes the issue to new levels of obscurity. Firstly
> > templated things don't have to be types, they can be templated
> > functions and also there tends to be lots and lots of type and
> > variable scoping in C++ that you don't find much in C. "x" might be a
> > type on one context and a variable in another context and a function
> > in another context. The result of this is that compiler error messages
> > tend to be next to useless.
> 
> > Compare to a language like Sather. The compiler always tells you
> > exactly what you did wrong, and in practice there's only about 3 or 4
> > different messages you tend to get.
> 
> > I guess C++ might be the language that helps the economists achieve
> > full employment.
> 
> No rational direct response is possible to this debating technique,
> so instead of responding directly, I would like to identify the technique.
> 
> The original statement: ``C++ is bad because its grammar is ambiguous.''
> 
> My response: ``C is similarly ambiguous, so C++ has no choice about it.''
> (implicitly: any language based as strongly on C as C++ is will be ambiguous
> in similar ways, so this is not a legitimate criticism of C++)

	I think this is a case where both parties are right and wrong in
different ways.

	Saying that C++ inhereted this syntax from C isn't a defense.  It's
simply
stating why this behaviour exists.  This is similar to a mugger telling
the 'cops he needed
the money..  It may be an accurate statement, but it's not going to get
him out of jail.  

	Now, I agree to Mr Bitmead to some extent, that C++ is somewhat more
cryptic than
necessary, but I think he overstates his case just a little bit..  In
practice you 
usually don't have a type, function, and variable all named 'x', and I
can usually, with
a bit of effort, figure out what the C++ compiler is trying to tell me.

	The large class of errors which are easy in C++ which are not syntax
errors is
another matter entirely.  

char *strdup( char *c )
{
    char *c2 = (char *)malloc( strlen(c+1));
    strcpy( c2,c);
    return c2;
}
	Is in a class of errors I've seen a number of times, in many different
ways. 
> 
> Rebuttal: ``The mere existence of the ambiguity isn't important (although
> that is what I said originally) -- what matters is how ``obscure'' it is.
> Anyway C++ has all these other syntactic problems that I hadn't mentioned
> before''  [Incidentally, in C it is possible for "x" to be a type in
> one context, a function, in another, and a variable in a third:
> 
>         void x() { }
>         /* x is a function here */
> 
>         void y() {
>                 int x;
>                 /* x is a variable here */
>         }
> 
>         void z() {
>                 typedef int x;
>                 /* x is a type here */
>         }
> 
> so again this is not a legitimate criticism of C++]

	I don't see how this arguement works!  Pointing out that some other
language is worse
doesn't prove a thing.  Arguing that the rules which produce this
ambiguity may have another 
positive side-effect might.  

	dave
From: Chris Bitmead uid(x22068)
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <s6yn2qhmjua.fsf@aalh02.alcatel.com.au>
David Hanley <·····@nospan.netright.com> writes:

> 	Now, I agree to Mr Bitmead to some extent, that C++ is somewhat more
> cryptic than
> necessary, but I think he overstates his case just a little bit..  In
> practice you 
> usually don't have a type, function, and variable all named 'x', and I
> can usually, with
> a bit of effort, figure out what the C++ compiler is trying to tell me.

Sure it is unusual having having three things called 'x'. That's why
it's so damned hard to track down the problem when you accidently do
come accross it. And yes, 95% of the time you can figure out somewhat
easily what the error was. It's just that the last 5% costs billions
of $ per year in wasted time, and the 95% could have probably been
halved with a clearer syntax, and the half that's left could have been
fixed 2x as fast with better compiler errors.

Oh, don't start me talking about template compilation problems, or
this thread may never end.
From: Chris Bitmead uid(x22068)
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <s6yohaxmk60.fsf@aalh02.alcatel.com.au>
···@research.att.com (Andrew Koenig) writes:

> No rational direct response is possible to this debating technique,
> so instead of responding directly, I would like to identify the technique.
> 
> The original statement: ``C++ is bad because its grammar is ambiguous.''
> 
> My response: ``C is similarly ambiguous, so C++ has no choice about it.''
> (implicitly: any language based as strongly on C as C++ is will be ambiguous
> in similar ways, so this is not a legitimate criticism of C++)
> 
> Rebuttal: ``The mere existence of the ambiguity isn't important (although
> that is what I said originally) -- what matters is how ``obscure'' it is.

I never said ambiguity isn't important. I was the one who said it IS
important.

And yes, it is a fact that it is a problem in C too, and that is
bad. In practice it is much much worse in C++ for the reasons I
stated. I would of thought it obvious that ambiguities that lead to
obscurity is worse than ones that don't.

> Anyway C++ has all these other syntactic problems that I hadn't mentioned
> before''  [Incidentally, in C it is possible for "x" to be a type in
> one context, a function, in another, and a variable in a third:

Yes sure, but not only has C++ inherited this problem from C, it has
expanded the problem to new heights, and embedded it within new
enormous levels of complexity so that it is now out of control.

> so again this is not a legitimate criticism of C++]

Of course it's legitimate, as it is as well of C. But it is even more
legitimate a criticism of C++ because the problem has been compounded.
 
> The argument continues by shifting to yet another ground (how many error
> messages you get from a particular compiler) 

It is not another ground! It is exactly the same ground!

The main reason that C++ compiler messages are so obfuscated is
because of the complicated, ambiguous syntax which is what this whole
thread about. I then compared it to a language with similar goals and
functionality to C++ (Sather) which has a clear, well defined,
non-ambiguous syntax. I pointed out that it produces wonderful error
messages, and that compiler complaints become almost a thing of the
past.

> and then ends with a
> gratuitous insult.

If C++ leads to zero unemployment, then I would have thought that a
complement :-) C++ - the saviour of mankind - Is that better?

> So I can summarize the discussion this way:
> 
> 	X: C++ is lousy because foo.

Yep.
 
> 	Y: Foo is true of C, and will be true of any language descended from C.

Yep.
 
> 	X: But foo is bad in C++ and not in C, 

No, foo is bad in C, and appallingly bad in C++.

>      and C++ has bar and baz,

Yep.

> 	   and yer mother wears army shoes!

I had no idea you had such maternal feelings towards a brain-dead
programming language. My apologies.
 
> Which is why I claim that no direct, rational response is possible.

I guess it's not possible to respond to. That's the big problem with
the truth.
From: Ben Hanson
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3366F7D8.17C5@cristie.co.uk>
Chris Bitmead uid(x22068) wrote:
<snip>
> The main reason that C++ compiler messages are so obfuscated is
> because of the complicated, ambiguous syntax which is what this whole
> thread about. I then compared it to a language with similar goals and
> functionality to C++ (Sather) which has a clear, well defined,
> non-ambiguous syntax. I pointed out that it produces wonderful error
> messages, and that compiler complaints become almost a thing of the
> past.
<snip>

One of the most important aspects of C++ is its backwards compatibility
with C (if not its _most_ important feature...).  If you read The Design
and Evolution of C++ (maybe you have already), you will find Stroustrup
agonises about C compatibility all through the book.

We all know just how quick and dirty (not to mention _ancient_) C is and
how appalling the grammer is, but, yes its time to wheel out the old
favourite (sorry about this), for the level of programming C cannot be
ignored as a language of choice for programmers/corporations.

The plan was to grab C by the scruff of the neck and drag it fighting
and screaming into the eighties/nineties.  This has had _some_ success
(C++ is very popular), but there are plenty of C coders who either
refuse to change, or think C++ coding means single line comments and the
use of new and delete.  C++ is a victim of its own flexibility.

If you want to flame C, then you have the backing of a lot of C++
programmers, but remember: C++ was always going to be imperfect right
from the start.

It's a compromise thing!

Regards

Ben
From: David Hanley
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <33677988.3150@nospan.netright.com>
Ben Hanson wrote:
> 
> Chris Bitmead uid(x22068) wrote:
> <snip>
> > The main reason that C++ compiler messages are so obfuscated is
> > because of the complicated, ambiguous syntax which is what this whole
> > thread about. I then compared it to a language with similar goals and
> > functionality to C++ (Sather) which has a clear, well defined,
> > non-ambiguous syntax. I pointed out that it produces wonderful error
> > messages, and that compiler complaints become almost a thing of the
> > past.
> <snip>
> 
> One of the most important aspects of C++ is its backwards compatibility
> with C (if not its _most_ important feature...).  If you read The Design
> and Evolution of C++ (maybe you have already), you will find Stroustrup
> agonises about C compatibility all through the book.
> 
> We all know just how quick and dirty (not to mention _ancient_) C is and
> how appalling the grammer is, but, yes its time to wheel out the old
> favourite (sorry about this), for the level of programming C cannot be
> ignored as a language of choice for programmers/corporations.

	I always though it might have been nice to have a 'conpanion language':
A language that could be mixed with C, call C, etc.  It would compile to
C,
so as to utilize existing system tools.  

	Of course, along this path lies all kinds of perils as well--how will
the 'companion language' interpret C arrays, unions and the like,
without
compromising it's own structure?  

	And, to stay somewhat on the subject of this newsgroup, what if this
were a 
functional language?  Or an oop one, for that matter.  The idea is that
calling
your old C code would be so trivial so as to not be an issue.

	dave
From: Ben Hanson
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <33672B6C.5931@cristie.co.uk>
Marc Wachowitz wrote:
> if one approaches the problems with the experience and effort appropriate for
> a large project (as any excellent implementation for a reasonably expressive
> programming language is going to be), rather than being annoyed because
> one couldn't just e.g. throw the grammar at yacc and have everything work
> fine on a rainy sunday afternoon. (This doesn't deny the criticism that
> the syntax of C++ should be simpler, whether for the human reader or for
> some established parsing algorithms, but let's not lose the perspective
> on what's implied in engineering a high-quality product.

Yes, exactly.  But that does leave one nagging doubt... shouldn't we all
be coding in Java?  (Surely _someone_ must be writing a compiler to
compile to native code - yes I know that defeats the object! No pun
intended)

It would be a shame to ignore Java's potential as a traditionally
compiled language instead of purely concentrating on the 'portable code'
argument.  Whether anyone would 'buy' into this is another matter...

Oh well, that's the I.T. industry for you!  :^)

Regards,

Ben
From: Per Bothner
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5k8eup$ev8$1@rtl.cygnus.com>
In article <·············@cristie.co.uk>,
Ben Hanson  <····@cristie.co.uk> wrote:
>Yes, exactly.  But that does leave one nagging doubt... shouldn't we all
>be coding in Java?  (Surely _someone_ must be writing a compiler to
>compile to native code - yes I know that defeats the object! No pun
>intended)

But of course.  Cygnus for one, using Gcc - see my home page for pointers.

>It would be a shame to ignore Java's potential as a traditionally
>compiled language instead of purely concentrating on the 'portable code'
>argument.  Whether anyone would 'buy' into this is another matter...

We're hoping lot of people will buy into this argument.
Of course, we intend to allow mixing pre-compiled code with
dynamically loaded (interpreted or JIT-compiled) Java code.

-- 
	--Per Bothner
Cygnus Solutions     ·······@cygnus.com     http://www.cygnus.com/~bothner
From: Jon S Anthony
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <JSA.97Apr23214114@alexandria>
In article <············@darla.visi.com> ········@visi.com (David Thornley) writes:

> When the dust is settled, C++ will have many of the things I like
> about Lisp, 

??!?!?  Like what????


> (Yes, there is at least one freely available garbage collection
> library for C++.)

Yes, there are several "freely" available conservative collectors that
can be bolted on to your application.  There is nothing C++ specific
about them.


> In the meantime, I suggest that, when you spend hours in frustration
> with your C++ system, let your vendor know.  (You should have seen

I guess the question is, why?  Why do this when there are readily
available viable alternatives which don't have this problem?
Certainly people do go through this, but why?  I suppose this is
really, "why does management force such lunacy on their technical
staff when they have no knowledge or understanding for any of the
rationales or consequences involved?"

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
···@organon.com
From: Thant Tessman
Subject: Re: wretched C++ (Was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <335F6D90.41C6@nospam.acm.org>
David Thornley wrote:

> OK, looks like templates and RTTI.  These aren't exactly the latest
> features in the draft standard, but I don't expect them to be
> completely stable yet.

According to section 5.2.7 of the proposed C++ standard, in order for 
dynamic_cast<T> to work, T must be a "complete" class--hence
the need for an explicit instantiation of T if it is a template.
This is an aspect of the language, not the compiler.

The section doesn't make clear whether the compiler has an obligation
to warn if T is an incomplete class.  But even if it did, I'm writing
a toolkit and I resent the fact that its users (who aren't going to
be as familiar with C++'s quirks as I am) are going to have to know 
and remember to use mysterious incantations in order for stuff to work.


> OK, so your compiler doesn't support the draft ANSI standard,
> and doesn't provide warnings or clues.  This looks like an
> implementation problem to me.  In particular, I don't think
> it's actually Stroustrup's fault you spent hours figuring this
> out.  [...]

I admit haven't used many C++ compilers, (I don't program for PCs,
just SGIs and (rarely) Macs) but I have yet to use a C++ compiler 
that worked as advertised, let alone supported the draft ANSI standard.  
I've said before that the only thing I can imagine being worse than 
programming in C++ is trying to implement C++.  And this *is* 
Stroustrup's fault.

I'll let someone else address the comparison to Lisp.

-thant

[...followups trimmed...]
From: Andrew Koenig
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <E93EJr.IBr@research.att.com>
In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

> And I recommend folks learn *any* language that supports higher-order 
> functions, automatic memory management, and incremental compilation
> to see how truly wretched C++ is, regardless of whatever claims 
> Stroustrup makes for it.

I learned Standard ML, which has all three of these properties,
several years ago, and I can say with confidence that from where
I sit, C++ is not wretched by comparison -- just different.
Each language has its strengths and weaknesses.

For example, I can write programs that manipulate trees and tree-like
data structures much more easily in ML than I can in C++, as long as
I stick to the operations that ML supports.  But it can be useful sometimes
to do things that ML doesn't support well, and those things are much
harder to implement in a language that has trees virtually built in
than in a language where trees are built on top of a lower-level
abstraction.

Here is a somewhat simplistic example.  The following ML code defines a
binary-tree data structure where each node contains a value and is
either a leaf or has two subtrees:

	datatype 'a Tree = LEAF of 'a | TREE of 'a Tree * 'a Tree

Gorgeous!  It's hard to imagine how such structures could be easier
to define.  Now let me define a function that takes a tree and a
pair of values x and y and yields a new tree in which all nodes containing
x now contain y:

	fun replace(t, x, y) =
		case t of
			LEAF a => LEAF (if a=x then y else a)
		      | TREE (left, right) =>
				TREE(replace(left, x, y), replace(right, x, y))

Again, it's really nice to be able to write code like this.

But now suppose we want to be able to identify a specific subtree of a tree.
If I had gone to the trouble of creating a tree abstraction in C++, I could
identify a particular subtree by the address of its root.  But there's no
corresponding facility in ML.  Trees are values, and although one can compare
them for equality, there is no notion of object identity.

One way to solve that problem is to use ML references for the tree nodes.
But then the trees really do become objects, and treating them as values
becomes much more difficult.  Moreover, I might not have thought I would
need to identify particular subtrees, and changing an existing data structure
to use references requires rewriting all of the code that uses it.

I have discussed this particular problem with people who know ML far better
than I do, and they agree that it is a problem.  The best solution anyone has
offered is to define another abstraction that represents a path from the root
of a tree to a particular node, and traverse the tree in terms of such abstract
paths.  This is not particularly hard to do in the example above, because there
are only two kinds of nodes involved.  But if we were dealing with parse trees
in a programming environment, there might be dozens of kinds of nodes, and
the solution would become much more difficult.

Of course the real answer is to structure one's ML programs so as to avoid
such knotty problems.  But that's exactly my point!  Although ML offers
abstractions that make some programs extremely easy to write, it does so at
a cost.  A professional attitude toward solving problems involves looking
at the tools available, picking the most useful one for the context --
the WHOLE context -- and then using it.

Incidentally, this whole discussion talks only about language.  In deciding
what programming tools to use, there is more than that to consider.  After
all, if all you care about is how easy the language is for you to use, why not
just invent your own language?  You won't have a compiler for it unless you
write one, but if ease of programming is all you care about, that doesn't
matter.  Of course, this facetious remark is intended to illustrate that
having a compiler that works well in your context matters too.  But even that
is not all that matters.  There is also the question of what tools your colleagues
use, and what tools the people might be using who will be maintaining your
code, and what machines you might be called on to support in the future.

C++ built on C precisely so that it would appeal to the existing C community.
As a result, support tools, a body of knowledge, and a community came along
more readily than they would have if the language had been designed totally
from scratch.  And that knowledge and community, and those tools, are among
the main reasons why C++ is now in widespread commercial use and so many
of the designed-from-scratch languages are not.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Thant Tessman
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <335FB314.167E@nospam.acm.org>
Andrew Koenig wrote:

> [...]  For example, I can write programs that manipulate trees and 
> tree-like data structures much more easily in ML than I can in C++, 
> as long as I stick to the operations that ML supports.  But it can 
> be useful sometimes to do things that ML doesn't support well, and 
> those things are much harder to implement in a language that has 
> trees virtually built in than in a language where trees are built 
> on top of a lower-level abstraction.

SML does not have trees "virtually built in."  Its type system 
understands discriminated unions.  This, plus pattern matching plus 
automatic memory management is what makes it so easy to build trees 
(and many other things) in SML compared to C++.

The *only* high-level semantic concept that C++ supports that SML
doesn't is (C++'s very awkward form of) subtyping polymorphism.  
And SML's support for generic polymorphism coupled with support for 
higher-order functions more than makes up for it.


> [...] But now suppose we want to be able to identify a specific subtree 
> of a tree.  If I had gone to the trouble of creating a tree abstraction 
> in C++, I could identify a particular subtree by the address of its root.  
> But there's no corresponding facility in ML.  Trees are values, and 
> although one can compare them for equality, there is no notion of object 
> identity.
> 
> One way to solve that problem is to use ML references for the tree nodes.
> But then the trees really do become objects, and treating them as values
> becomes much more difficult.  Moreover, I might not have thought I would
> need to identify particular subtrees, and changing an existing data structure
> to use references requires rewriting all of the code that uses it.
>
> [...]

I fail to see in what way C++ provides any advantage over SML in this 
example.  The problem of deciding what semantics your data structures 
should have doesn't get any easier merely because you're using C++.  
To the contrary, SML's type system is far more powerful than C++'s.  
This is what makes it easier to get data structure semantics right.  
Exposing memory addresses may provide a "built-in" concept of object 
identity, but only by imposing a huge memory management burden on the 
programmer, a far bigger burden than using refs in the (rare!) 
instances that you might need them.  (And adding a garbage collector
to C++ only addresses part of that burden.)

In contrast, it's easy to come up with examples of tasks that are 
trivial in SML and extremely difficult in C++.  I can't describe
what I'm working on, but I was recently glancing through "Design 
Patterns" by Gamma et al and happened to notice what they call the 
"Command" technique.  An entire chapter is devoted to something that 
can be accomplished *trivially* in any language that supports 
higher-order functions.  And I bet if I actually read more of the 
book I'd find it was nothing but a catalog of examples of why C++ 
sucks.


> Incidentally, this whole discussion talks only about language.  In
> deciding what programming tools to use, there is more than that to 
> consider.  After all, if all you care about is how easy the language 
> is for you to use, why not just invent your own language?  You won't 
> have a compiler for it unless you write one, but if ease of 
> programming is all you care about, that doesn't matter.   [...]

Since you mention it (even if only facetiosly), this is exactly what 
makes Scheme so great.  It is easy to implement mini-languages for 
specific problem sets.  My beef is that too many people who have
been trained to think in C/C++ don't even know that this is very
often exactly what they want to do.

Scheme has a simplicity and flexibility that SML doesn't have.  SML has
efficiency and safety that Scheme doesn't have.  Both make programming
in C++ feel like crawling through broken beer bottles in comparison.


> [...]  But even that is not all that matters.  There is also the 
> question of what tools your colleagues use, and what tools the people 
> might be using who will be maintaining your code, and what machines 
> you might be called on to support in the future.  [...]

In other words, C++ is better than SML because more people use C++
than SML?

-thant

[...followups trimmed...]
From: Peter Ludemann
Subject: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <wujsp0gz0y5.fsf_-_@wistaria.i-have-a-misconfigured-system-so-shoot-me>
···@research.att.com (Andrew Koenig) writes:

[snip]

> Here is a somewhat simplistic example.  The following ML code defines a
> binary-tree data structure where each node contains a value and is
> either a leaf or has two subtrees:
> 
> 	datatype 'a Tree = LEAF of 'a | TREE of 'a Tree * 'a Tree

[snip]

> But now suppose we want to be able to identify a specific subtree of a tree.
> If I had gone to the trouble of creating a tree abstraction in C++, I could
> identify a particular subtree by the address of its root.  But there's no
> corresponding facility in ML.  Trees are values, and although one can compare
> them for equality, there is no notion of object identity.

Absolutely correct and correctly so.

If two things LOOK the same, then they ARE the same.  It's called
"referential transparency" and it's a Good Thing, as opposed to
"pointers" which are a Bad Thing.  Why confuse your life with "object
identity"?

And why do you want to use the memory address for object identity to
identify it --- an address can change during garbage collection.  Why
not use a time stamp of object creation?  Oh, it's for efficiency
reasons, you say ... ah-ha!

But let's suppose that you really really really do need to identify a
particular subtree.  In other words, you want to NAME it.  No problem:
just create a dictionary (hash table) that maps names to subtrees.
That'll let you have two differently named entries which might happen
to have the same values.  And it won't expose pointers.  And it'll be
efficient.

Or, perhaps you need names attached to the nodes; then define:

	datatype 'a NamedTree = LEAF of 'a
	                      | TREE of string * 'a NamedTree * 'a NamedTree

It's trivial to translate between NamedTree and Tree and you can also
combine NamedTree with a dictionary to allow fast access to individual
sub-trees.

Repeat after me: "if two things look the same and act the same, then
they are the same".  Don't depend on some hidden property (pointer) to
differentiate them.  If there are important differences, then don't be
shy: bring them out in the open and NAME them.

[I once took an object-oriented database that used object-IDs and
translated it to a relational form which just used names for things;
performace improved by about about an order of magnitude.  But that's
another rant for another day ...]

-- 
Peter Ludemann		+1.415.813.6806  (fax: +1.415.813.7499)
Software Architect	········@inxight.com
InXight Software, Inc.	http://www.inxight.com
PAHV 105, 3400 Hillview Ave., Palo Alto, CA 94304 
From: Andrew Koenig
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9726L.Aqq@research.att.com>
In article <··················@wistaria.i-have-a-misconfigured-system-so-shoot-me> Peter Ludemann <········@inxight.com> writes:
> ···@research.att.com (Andrew Koenig) writes:

> > Here is a somewhat simplistic example.  The following ML code defines a
> > binary-tree data structure where each node contains a value and is
> > either a leaf or has two subtrees:
> > 
> > 	datatype 'a Tree = LEAF of 'a | TREE of 'a Tree * 'a Tree

> > But now suppose we want to be able to identify a specific subtree of a tree.
> > If I had gone to the trouble of creating a tree abstraction in C++, I could
> > identify a particular subtree by the address of its root.  But there's no
> > corresponding facility in ML.  Trees are values, and although one can compare
> > them for equality, there is no notion of object identity.

> Absolutely correct and correctly so.

> If two things LOOK the same, then they ARE the same.  It's called
> "referential transparency" and it's a Good Thing, as opposed to
> "pointers" which are a Bad Thing.  Why confuse your life with "object
> identity"?

I think this paragraph, which argues against my local point, nicely proves
my global point, which I will admit is a little more subtle.

My original posting was a response to someone who said something to the
effect that languages without closures, lambda expressions, etc. were
inferior.  So I gave an example of a problem I would like to be able to
solve that at least one such langauge does not make easy to solve.

The reply to that is ``You shouldn't be wanting to solve that problem;
not being able to do so is a Good Thing.''

And all I can say to that is ``Some people consider it a Good Thing,
and others do not.''  Which is exactly my global point.

> And why do you want to use the memory address for object identity to
> identify it --- an address can change during garbage collection.  Why
> not use a time stamp of object creation?  Oh, it's for efficiency
> reasons, you say ... ah-ha!

No, I did not say that.  One reason, though, might be that the typical
textbook in classical data structures assumes object identity, so
that expressing such structures without it may require a substantial
translation.

And, although I did not say it before, efficiency sometimes does matter.

> But let's suppose that you really really really do need to identify a
> particular subtree.  In other words, you want to NAME it.  No problem:
> just create a dictionary (hash table) that maps names to subtrees.
> That'll let you have two differently named entries which might happen
> to have the same values.  And it won't expose pointers.  And it'll be
> efficient.

Yes and no.  In a language that is completely referentially transparent,
generating the names can be a problem, because there is no way to define
a piece of code that represents the abstraction `Each time I build one of
these nodes, I want it to have a globally unique label.'  The language
wouldn't be referentially transparent if I could write such a program.
So the knowledge of the labels now has to pervade the entire system.

I imagine that next you're going to say `But you can use monads to solve
that problem.'  And indeed I can.  Which only proves my point even more.

> Repeat after me: "if two things look the same and act the same, then
> they are the same".  Don't depend on some hidden property (pointer) to
> differentiate them.  If there are important differences, then don't be
> shy: bring them out in the open and NAME them.

Repeat after me: "Different programming cultures solve problems differently."
Don't assume that the whole world thinks the same way you do.  If there
are important differences between how you think and how other people think,
don't be shy: bring them out in the open and NAME them.

But please do not assume that there is only one right way of thinking.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Matthias Blume
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <iziv1brvji.fsf@mocha.CS.Princeton.EDU>
In article <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

   My original posting was a response to someone who said something to the
   effect that languages without closures, lambda expressions, etc. were
   inferior.  So I gave an example of a problem I would like to be able to
   solve that at least one such langauge does not make easy to solve.

   The reply to that is ``You shouldn't be wanting to solve that problem;
   not being able to do so is a Good Thing.''

Actually, it is possible to solve the problem, and it is even quite
trivial. I have written a lot of SML code where I needed some sort of
identity for tree (actually: DAG) nodes, and it was _not hard at all_,
much less impossible.

The SML model just doesn't give you that concept _by default_, which
means the compiler doesn't have to worry about it _by default_.  And
_that_'s a Good Thing.

[newsgroups trimmed _somewhat_]

-- 
-Matthias
From: Thant Tessman
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <33622224.41C6@nospam.acm.org>
Andrew Koenig wrote:

[...]

> My original posting was a response to someone who said something to the
> effect that languages without closures, lambda expressions, etc. were
> inferior.  So I gave an example of a problem I would like to be able to
> solve that at least one such langauge does not make easy to solve.
> 
> The reply to that is ``You shouldn't be wanting to solve that problem;
> not being able to do so is a Good Thing.''
>
> [...]

Just to make things clear to folks, I was the one that said languages with 
higher-order functions are superior.  And the above was not my reply.

The example Koenig brought up tried to show that sometimes you want to use 
the concept of object-identity to make solving certain kinds of problems 
easier.  I don't disagree.

What I disagreed with (object to!) is Koenig's implication that C++'s use 
of addresses as a "built-in" concept of object identity is in anyway 
superior to SML's use of references.   (The imperitave versus functional 
argument is interesting, but irrelevant with regard to SML (the example 
language brought up) because it supports both (as does Lisp).)

-thant

[...followups trimmed...]
From: Andrew Koenig
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9Appv.Dn9@research.att.com>
In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

> What I disagreed with (object to!) is Koenig's implication that C++'s use 
> of addresses as a "built-in" concept of object identity is in anyway 
> superior to SML's use of references.

I would object to that argument too, and I did not make it.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Thant Tessman
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3364CAB2.167E@nospam.acm.org>
Andrew Koenig wrote:
> 
> In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:
> 
> > What I disagreed with (object to!) is Koenig's implication that C++'s use
> > of addresses as a "built-in" concept of object identity is in anyway
> > superior to SML's use of references.
> 
> I would object to that argument too, and I did not make it.

Okay, whatever.  However, you did say:

> [...]  I can say with confidence that from where I sit, C++ is not 
> wretched by comparison [to SML] -- just different.  Each language has 
> its strengths and weaknesses.

You yourself provided an example of how much easier it is to manipulate
trees in SML compared to C++.  What problems can C++ address more naturally
than SML?  (since problems involving object identity aren't an example)

(Of course SML does have its weaknesses, but by comparison, a discussion
of C++'s strengths and flaws always sounds like an argument about whether
one should face north or east when one is sacrificing one's goat to the 
rain god.)

-thant
From: Andrew Koenig
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9DADp.5w5@research.att.com>
In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

> You yourself provided an example of how much easier it is to manipulate
> trees in SML compared to C++.  What problems can C++ address more naturally
> than SML?  (since problems involving object identity aren't an example)

As one example, several years ago I tried doing an exact implementation
in ML of the "hoc" desk calculator program that appears in the book
``The Unix Programming Environment'' by Kernighan and Pike.  I found
two things:

	1. The ML version was about half the size of the original C version,
	   but ran about twice as slowly.

	2. I was not able to complete the ML version because the compiler
	   available to me at the time lacked any facility for converting
	   an ASCII string to the floating-point equivalent.  Although I had
	   accurate routines in C to convert ASCII to floating point,
	   there was no easy way to call those routines from ML.
	
Since then, I have periodically asked the ML compiler people I know when
there will be a version of their system that will let me interface to tools
written in other languages.  The answer is always that it's almost ready.
Perhaps when it is finally ready, I will be able to consider ML for serious
programming.  Meanwhile, though, the support is just not there.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: ···@teco.net
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <s6ylo61mjlh.fsf@aalh02.alcatel.com.au>
> In Thant Tessman <·····@nospam.acm.org> writes:

> > What problems can C++ address more naturally
> > than SML?  (since problems involving object identity aren't an example)

···@research.att.com (Andrew Koenig) responds:

> 	1. The ML version was about half the size of the original C version,
> 	   but ran about twice as slowly.
> 
> 	2. I was not able to complete the ML version because the compiler
> 	   available to me at the time lacked any facility for converting
> 	   an ASCII string to the floating-point equivalent.  Although I had
> 	   accurate routines in C to convert ASCII to floating point,
> 	   there was no easy way to call those routines from ML.

Well I guess you win Andrew. C++ really is more natural than SML
From: E. Young
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <ptcrafsmb7h.fsf@hammer.thor.cam.ac.uk>
···@research.att.com (Andrew Koenig) writes:
> Since then, I have periodically asked the ML compiler people I know when
> there will be a version of their system that will let me interface to tools
> written in other languages.  The answer is always that it's almost ready.
> Perhaps when it is finally ready, I will be able to consider ML for serious
> programming.  Meanwhile, though, the support is just not there.

I believe Objective Caml (http://pauillac.inria.fr/ocaml) allows
programs to interface with C code. It's in the manual, but I've never
used this facility so I don't know how well it works in practice.

-Edwin
From: Jeffrey Mark Siskind
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <xoh67x3hiit.fsf@ai.emba.uvm.edu>
> As one example, several years ago I tried doing an exact implementation
> in ML of the "hoc" desk calculator program that appears in the book
> ``The Unix Programming Environment'' by Kernighan and Pike.  I found
> two things:
> 
> 	1. The ML version was about half the size of the original C version,
> 	   but ran about twice as slowly.
> 
> 	2. I was not able to complete the ML version because the compiler
> 	   available to me at the time lacked any facility for converting
> 	   an ASCII string to the floating-point equivalent.  Although I had
> 	   accurate routines in C to convert ASCII to floating point,
> 	   there was no easy way to call those routines from ML.
> 	
> Since then, I have periodically asked the ML compiler people I know when
> there will be a version of their system that will let me interface to tools
> written in other languages.  The answer is always that it's almost ready.
> Perhaps when it is finally ready, I will be able to consider ML for serious
> programming.  Meanwhile, though, the support is just not there.

Might I suggest that you try this exercise in Scheme/Stalin. I bet that the
Scheme version will be the same size as the ML version (or smaller) and Stalin
will generate code that will be as fast as C. And Stalin will let you
interface to C code that converts ASCII to floating point. (It also has a
builtin STRING->NUMBER procedure.)

    Jeff (home page http://www.emba.uvm.edu/~qobi)
From: Thant Tessman
Subject: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3368C7CF.41C6@nospam.acm.org>
I asked:

> What problems can C++ address more naturally than SML?

Andrew Koenig wrote:

> As one example, several years ago I tried doing an exact implementation
> in ML of the "hoc" desk calculator program that appears in the book
> ``The Unix Programming Environment'' by Kernighan and Pike.  I found
> two things:
> 
>         1. The ML version was about half the size of the original C 
>            version, but ran about twice as slowly.

I suspect that if you tried your experiment again that you would find that 
the SML version's performance was much more in line with the C version, 
unless the algorithm required much dynamic memory management in which case 
the SML version would be faster.


>         2. I was not able to complete the ML version because the compiler
>            available to me at the time lacked any facility for converting
>            an ASCII string to the floating-point equivalent.  Although I 
>            had accurate routines in C to convert ASCII to floating point,
>            there was no easy way to call those routines from ML.

This hasn't been true for a while.  And in fact, there is now an SML 
Standard Basis Library  which includes utilities such as this.  

  http://www.research.att.com/~jhr/sml/basis/index.html

(Check out, for example, SBL's support for wide characters for another 
good example of why C++ sucks.)


> Since then, I have periodically asked the ML compiler people I know when
> there will be a version of their system that will let me interface to tools
> written in other languages.  The answer is always that it's almost ready.
> Perhaps when it is finally ready, I will be able to consider ML for serious
> programming.  Meanwhile, though, the support is just not there.

MLWorks and SML/NJ both have C foreign interfaces.  Admittedly, they are
currently a little awkward to use compared to the overall elegance of SML, 
but they do work and they are improving.  (SML developers felt that it
was more important to first reduce the need to resort to C at all, hence
the SBL.  Also, there are of course implementations of other languages
that support higher-order functions that interface extremely well with C.)

***

The above is really a distraction from the original question.  Yes, much 
more energy has gone into developing C++'s tools than has gone into 
developing tools for any of the far superior languages that exist.  But 
this is exactly why I hate C++ so much, and the point I keep trying to
make.  So much work (including my own) has been wasted trying to make C++ 
merely not suck so much when we should have been building truly powerful
applications.

-thant
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <E9J3Fx.Gx9@research.att.com>
In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

> more energy has gone into developing C++'s tools than has gone into 
> developing tools for any of the far superior languages that exist.

Which suggests that perhaps your opinion of what is superior is not universal.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Darin Johnson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5mkihg.32v.darin@connectnet1.connectnet.com>
>> more energy has gone into developing C++'s tools than has gone into 
>> developing tools for any of the far superior languages that exist.
>
>Which suggests that perhaps your opinion of what is superior is not universal.

There are three conflicting trains of thought on this.

1) Things that are superior become popular.
2) Things that are popular are claimed to be superior.
3) Superiority and popularity are unrelated.

-- 
Darin Johnson
·····@usa.net.delete_me
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <E9LzF1.J6r@research.att.com>
In article <····················@connectnet1.connectnet.com> ·····@usa.net.delete_me (Darin Johnson) writes:

> There are three conflicting trains of thought on this.

> 1) Things that are superior become popular.
> 2) Things that are popular are claimed to be superior.
> 3) Superiority and popularity are unrelated.

I believe

  4) Saying that one thing is superior to another is meaningful only
     in context, which usuallly includes a purpose.

Anyone who claims, for example, that a Ferrari is superior to a Ford
without considering context is cordially invited to try to get a Ferrari
up my driveway with two inches of snow on it.  In that context, a
Ferrari is probably useless and a Ford is so-so, unless it happens
to have four-wheel drive, in which case it might be OK.

If you don't agree on a context before comparing tools, the result of
the comparison is unlikely to have any useful meaning.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Erik Naggum
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3071563530695899@naggum.no>
* Thant Tessman
| more energy has gone into developing C++'s tools than has gone into 
| developing tools for any of the far superior languages that exist.

* Andrew Koenig
| Which suggests that perhaps your opinion of what is superior is not
| universal.

the odd thing about energy and superiority is that more work is always
_necessary_ on the inferior product than on the superior.  we also observe
that much more is published on inferior products than on superior products,
such as on virus detection and protection for Microsoft "operating
systems", such as undocumented features in MS-DOS to make the machine
perform reasonably fast in the display subsystem of games, etc.  we find
that the more someone is dissatisfied with his working environment, the
more fuss they make, too.  the whole of USENET can be seen as evidence that
people do not write articles to express their agreement with each other.

it is rather curious that someone who _must_ know better argues that the
superiority of something and the energy poured into it are not inversely
related.  or are you saying that C++ is a superior language for the same
reason that MS-DOS is a superior operating system, Andrew?

that said, the draft subject to the second ISO CD registration vote for C++
contains remarkably good work in the standard template library.  it's a
pity all that energy is wasted on C++.  "what a magnificent waste!"

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: Alexander Stepanov
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336A4D79.41C6@mti.sgi.com>
Erik Naggum wrote:
> 
> * Thant Tessman
> | more energy has gone into developing C++'s tools than has gone into
> | developing tools for any of the far superior languages that exist.
> 
> * Andrew Koenig
> | Which suggests that perhaps your opinion of what is superior is not
> | universal.
> 
> the odd thing about energy and superiority is that more work is always
> _necessary_ on the inferior product than on the superior.  we also observe
> that much more is published on inferior products than on superior products,
> such as on virus detection and protection for Microsoft "operating
> systems", such as undocumented features in MS-DOS to make the machine
> perform reasonably fast in the display subsystem of games, etc.  we find
> that the more someone is dissatisfied with his working environment, the
> more fuss they make, too.  the whole of USENET can be seen as evidence that
> people do not write articles to express their agreement with each other.
> 
> it is rather curious that someone who _must_ know better argues that the
> superiority of something and the energy poured into it are not inversely
> related.  or are you saying that C++ is a superior language for the same
> reason that MS-DOS is a superior operating system, Andrew?
> 
> that said, the draft subject to the second ISO CD registration vote for C++
> contains remarkably good work in the standard template library.  it's a
> pity all that energy is wasted on C++.  "what a magnificent waste!"

Being responsible for the standard template library, I could assure you that 
C++ does have merits. I tried to implement STL in a variety of languages 
and failed. I had a very modest goal - to be able to express linear search
in a such way that it would work for any data structure for which it makes
sense. C++ was the only language in which I could do it. There are many 
things I do not like about it - OOP is the main example. There are
some things that I really miss - an ability to describe conforming families
of types (iterators, for example). But I still do not know any other language
in which I could express what I wanted to express. I teach a course on Generic
Programming at my place of work, and while I curse C++ constantly during my
lectures, I still use it.

Do I mean to say that C++ is the ultimate programming language? Perish the 
thought! We do need a better programming language. But I do not believe that
anything better already exists. And, yes, I tried Scheme, ML, Ada, Java...
And I tried them quite seriously, spending years on every fad that comes out
of POPL. 

So there is at least one person who believes that C++ with all its flaws is 
the most remarkable piece of work in programming languages since C, and that
any future progress in programming languages must be based on lessons of C++.




> 
> #\Erik
> --
> if we work harder, will obsolescence be farther ahead or closer?

-- 
Alexander Stepanov
········@sgi.com

Silicon Graphics
2011 N. Shorline Boulevard
Mountain View, CA 94043-1389

tel.: (415)933-6121
From: David Chase
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <E9Kvry.2nF@world.std.com>
Alexander Stepanov wrote:

> So there is at least one person who believes that C++ with all its flaws is
> the most remarkable piece of work in programming languages since C, and that
> any future progress in programming languages must be based on lessons of C++.

Yes, I can see myself saying exactly the same words, but I'd probably
intend
them to mean something else.

David Chase
From: james anderson
Subject: patterns and dynamic languages
Date: 
Message-ID: <336CC40B.269D@ibm.net>
greetings,
i have been following discussions for some time now regarding "patterns"
and program design. and am wondering if anyone has written on patterns
(especially the direction pree is taking them) from a dynamic-language
perspective.

i've seen references to gabriel's book, but oxford press claims i won't
be able to get one until june. (if it's even relevant)

any other pointers?
thanks,
From: Rob Warnock
Subject: Re: patterns and dynamic languages
Date: 
Message-ID: <5kmr9r$f9t@tokyo.engr.sgi.com>
james anderson  <·······@ibm.net> wrote:
+---------------
| i've seen references to gabriel's book, but oxford press claims i won't
| be able to get one until june.
+---------------

How odd! A local technical store had them in stock a couple of months
ago when I bought my copy...

+---------------
| (if it's even relevant)
+---------------

Well, Gabriel's book provides (IMHO) a nice overview of the meta-issues.
And some musings about the probable limitations of "patterns".


-Rob

-----
Rob Warnock, 7L-551		····@sgi.com   http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 415-933-1673  FAX: 415-933-4392
2011 N. Shoreline Blvd.		[after 8/2/1997 ==> 650-933-xxxx]
Mountain View, CA  94043	PP-ASEL-IA


-Rob

-----
Rob Warnock, 7L-551		····@sgi.com   http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 415-933-1673  FAX: 415-933-4392
2011 N. Shoreline Blvd.		[after 8/2/1997 ==> 650-933-xxxx]
Mountain View, CA  94043	PP-ASEL-IA
From: Chris Bitmead uid(x22068)
Subject: Re: patterns and dynamic languages
Date: 
Message-ID: <BITMEADC.97May23183725@Alcatel.com.au>
In article <·············@ibm.net> james anderson <·······@ibm.net> writes:

>i have been following discussions for some time now regarding "patterns"
>and program design. and am wondering if anyone has written on patterns
>(especially the direction pree is taking them) from a dynamic-language
>perspective.


My understanding of patterns, at least in a lisp/functional context,
is that this is the way things are always done anyway. Patterns seem
to only be a new concept to the C++ crowd.

Someone correct me if I misunderstand the use of this term.
From: Fergus Henderson
Subject: Re: patterns and dynamic languages
Date: 
Message-ID: <5m3uuc$dio@mulga.cs.mu.OZ.AU>
·············@Alcatel.com.au (Chris Bitmead uid(x22068)) writes:

>james anderson <·······@ibm.net> writes:
>
>>i have been following discussions for some time now regarding "patterns"
>>and program design. and am wondering if anyone has written on patterns
>>(especially the direction pree is taking them) from a dynamic-language
>>perspective.
>
>My understanding of patterns, at least in a lisp/functional context,
>is that this is the way things are always done anyway. Patterns seem
>to only be a new concept to the C++ crowd.
>
>Someone correct me if I misunderstand the use of this term.

Sure, there's nothing new under the sun.
People have always written code (in whatever language) using
various different design patterns.

The point is to analyze these patterns: to give each one a name,
and to gain an understanding of its advantages and disadvantages,
to try to distill some of the traditional wisdom that has accumulated
about various different design patterns.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Chris Cole
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <ud8r9v7xs.fsf@espresso.visix.com>
  Being responsible for the standard template library, I could assure you that 
  C++ does have merits. I tried to implement STL in a variety of languages 
  and failed. I had a very modest goal - to be able to express linear search
  in a such way that it would work for any data structure for which it makes
  sense. C++ was the only language in which I could do it. 

Your comparative language experiences would make a great article
(or book).  Any chance you've published an account of your various
attempts anywhere?

-Chris
From: Darin Johnson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5ml08o.c75.darin@connectnet1.connectnet.com>
In article <·············@mti.sgi.com>, Alexander Stepanov wrote:
>Being responsible for the standard template library, I could assure you that 
>C++ does have merits. I tried to implement STL in a variety of languages 
>and failed. I had a very modest goal - to be able to express linear search
>in a such way that it would work for any data structure for which it makes
>sense. C++ was the only language in which I could do it.

Really?  How odd.  Why couldn't this be done in Smalltalk, Eiffel, or Java?

My biggest gripes with STL is that it's inefficient and bloated (ie,
you store objects directly meaning that full copies must be made often
when manipulating things; and you get the *entire* class in a
template, not just a template that provides a type safe wrapper to a
library).  I could live with such problems if the C++ experts would
actually admit they're problems rather than cite these as benefits
(which implies they're not going to bother fixing them).

-- 
Darin Johnson
·····@usa.net.delete_me
From: Thant Tessman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336CB307.41C6@nospam.acm.org>
Darin Johnson wrote:
> 
> In article <·············@mti.sgi.com>, Alexander Stepanov wrote:
> > Being responsible for the standard template library, I could 
> > assure you that C++ does have merits. I tried to implement STL 
> > in a variety of languages and failed. I had a very modest goal 
> > - to be able to express linear search in a such way that it 
> > would work for any data structure for which it makes sense. 
> > C++ was the only language in which I could do it.
> 
> Really?  How odd.  Why couldn't this be done in Smalltalk, Eiffel, 
> or Java?  [...]

Imagine trying to write a sort routine that worked not on just
arrays, but any data structure that supported a specific set of 
operations, like get_next_item.  The beauty of the STL is that you
can mix and match algorithms and data structures.  This is hard
to do in a purely traditional message-based object-oriented 
framework.

However, it's easy to do in any language that supports CLOS-style
generic functions, like Dylan, Scheme (with the appropriate library),
and, oh yeah, Common Lisp.

And if your language doesn't support generic functions, but it 
does support higher-order functions, then you're only slightly
inconvenienced by the need to build and pass in the functions
that the sort routine (or whatever) needs to manipulate the data 
structures.

A preference for C++ is not a matter of taste but of ignorance.

-thant

--
Philosophy is the search for the set of principles 
that will finally free us from the need to think.
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <E9o2y7.5xw@research.att.com>
In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

> A preference for C++ is not a matter of taste but of ignorance.

A preference for mindless insults is not cleverness but immaturity.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Mike Rubenstein
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336f0269.212389680@nntp.ix.netcom.com>
···@research.att.com (Andrew Koenig) wrote:

> In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:
> 
> > A preference for C++ is not a matter of taste but of ignorance.
> 
> A preference for mindless insults is not cleverness but immaturity.

It's almost as if you are suggesting that someone could agree with
Thant Tessman for some reason other than ignorance.


Michael M Rubenstein
From: Mike Rubenstein
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <337210a4.216033229@nntp.ix.netcom.com>
···@research.att.com (Andrew Koenig) wrote:

> In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:
> 
> > A preference for C++ is not a matter of taste but of ignorance.
> 
> A preference for mindless insults is not cleverness but immaturity.

It's almost as if you are suggesting that someone could disagree with
Thant Tessman for some reason other than ignorance.



Michael M Rubenstein
From: Erik Naggum
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3071779357830923@naggum.no>
* Thant Tessman
| A preference for C++ is not a matter of taste but of ignorance.

* Andrew Koenig
| A preference for mindless insults is not cleverness but immaturity.

one may judge the maturity of a person by what he finds insulting and why.

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: Zooko
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kklru$6ag@lace.colorado.edu>
 Erik Naggum  <····@naggum.no> wrote:
>* Thant Tessman
>| A preference for C++ is not a matter of taste but of ignorance.
>
>* Andrew Koenig
>| A preference for mindless insults is not cleverness but immaturity.
>
>one may judge the maturity of a person by what he finds insulting and why.


Spare change can often be found under car seats.


Zooko Journeyman

signatures follow

                                      +       island Life in a chaos sea
Not speaking for DigiCash or          /.
the University of Colorado            /           ·····@colorado.edu or
                                      ---*            ·····@digicash.com
From: Thant Tessman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336F6E15.41C6@nospam.acm.org>
Zooko wrote:
> 
>  Erik Naggum  <····@naggum.no> wrote:
> >* Thant Tessman
> >| A preference for C++ is not a matter of taste but of ignorance.
> >
> >* Andrew Koenig
> >| A preference for mindless insults is not cleverness but immaturity.
> >
> > one may judge the maturity of a person by what he finds insulting 
> > and why.
> 
> Spare change can often be found under car seats.

My hovercraft is full of eels.

-thant
From: Benjamin Franksen
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <338F2B71.43D0@bii.bessy.de>
This is becoming a funny thing finally:

Thant Tessman wrote:
> 
> Zooko wrote:
> >
> >  Erik Naggum  <····@naggum.no> wrote:
> > >* Thant Tessman
> > >| A preference for C++ is not a matter of taste but of ignorance.
> > >
> > >* Andrew Koenig
> > >| A preference for mindless insults is not cleverness but immaturity.
> > >
> > > one may judge the maturity of a person by what he finds insulting
> > > and why.
> >
> > Spare change can often be found under car seats.
> 
> My hovercraft is full of eels.
> 
Has C++ buddha nature?

	Ben
-- 
The Notorious Neb Nesknarf
// snail: BESSY II, Rudower Chaussee 5, D-12489 Berlin, Germany
// email: ········@bii.bessy.de
// phone/fax: +49(30)6392-4865 / 6392-4859
From: Gareth McCaughan
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <86wwog8uty.fsf@g.pet.cam.ac.uk>
Benjamin Franksen wrote:

> Has C++ buddha nature?

Lambda.

-- 
Gareth McCaughan       Dept. of Pure Mathematics & Mathematical Statistics,
·····@dpmms.cam.ac.uk  Cambridge University, England.
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EBB8J0.Cs0@research.att.com>
In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:
> Benjamin Franksen wrote:
> > 
> > Thant Tessman wrote:
> > >
> > > Zooko wrote:
> > > >
> > > > Erik Naggum wrote:
> > > > > 
> > > > > Andrew Koenig wrote:
> > > > > >
> > > > > > Thant Tessman wrote:
> > > > > > > 
> > > > > > > A preference for C++ is not a matter of taste but 
> > > > > > > of ignorance.
> > > > > > 
> > > > > > A preference for mindless insults is not cleverness 
> > > > > > but immaturity.
> > > > >
> > > > > One may judge the maturity of a person by what he 
> > > > > finds insulting and why.
> > > > 
> > > > Spare change can often be found under car seats.
> > >
> > > My hovercraft is full of eels.
> > 
> > Has C++ buddha nature?
> 
> No.  Wanna fight about it?

If you fight, you deny your own-buddha nature.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: T. K. Lakshman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5klqjs$jvn@fido.asd.sgi.com>
A followup

Alex sent me an appropriate
response which i'm including (with Alex's permission)

--------------------------------------------------------------

From ········@wotan  Mon May  5 14:59:29 1997
Received: from wotan.mti.sgi.com by sanganak.mti.sgi.com via ESMTP (950413.SGI.8.6.12/940406.SGI.AUTO)
        for <········@sanganak.mti.sgi.com> id OAA00118; Mon, 5 May 1997 14:59:28 -0700
Received: by wotan.mti.sgi.com (950413.SGI.8.6.12/930416.SGI.AUTO-MTI)
        for lakshman id OAA08799; Mon, 5 May 1997 14:59:27 -0700
Date: Mon, 5 May 1997 14:59:27 -0700
From: ········@wotan (Alexander Stepanov)
Message-Id: <·····················@wotan.mti.sgi.com>
Apparently-To: ········@wotan
Status: OR

Thant Tessman wrote:
> A preference for C++ is not a matter of taste but of ignorance.

It is worse than that. Many leading C++ people have strong communist
background. Bjarne Stroustrup's grandfather was a notorious union
organizer and Alex Stepanov was a member of several youth communist
organizations for over a decade.

It is a duty of every honest American to denounce them to the proper
authorities.

Alex

---------------------------------------------------------------------
From: ···@teco.net
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <s6yg1w0m2hy.fsf@aalh02.alcatel.com.au>
········@sanganak.mti.sgi.com (T. K. Lakshman) writes:

> > A preference for C++ is not a matter of taste but of ignorance.
> 
> It is worse than that. Many leading C++ people have strong communist
> background. Bjarne Stroustrup's grandfather was a notorious union
> organizer and Alex Stepanov was a member of several youth communist
> organizations for over a decade.

This makes sense. C++ reduces both coding gurus and ignorant morons to
the same pathetic level of productivity, and therefore salary. It also
supports full employment. Very communist!

Seriously though, STL is very clever and I respect the design a
lot. It's not enough to turn a sow's ear into a silk purse however.

> It is a duty of every honest American to denounce them to the proper
> authorities.
From: Nathan Davis
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <33708F30.1BB8@usa.net>
> > > A preference for C++ is not a matter of taste but of ignorance.
> > 
> > It is worse than that. Many leading C++ people have strong communist
> > background. Bjarne Stroustrup's grandfather was a notorious union
> > organizer and Alex Stepanov was a member of several youth communist
> > organizations for over a decade.
> 
> This makes sense. C++ reduces both coding gurus and ignorant morons to
> the same pathetic level of productivity, and therefore salary. It also
> supports full employment. Very communist!
Just one quick question:  have you ever tried programming in C++?

How can you say that that C++ reduces everyone to the same "pathetic"
level of productivity.  I learned C++ in my early teens, with hardly any
trouble at all.  I am very productive with it.  I have yet to see a
language that is so easy to use that gives you the power you need (I
haven't actually used JAVA yet, but I'm guessing it's probably similar
since its based on C++, except the
class.names.are.so.long.they.take.up.five.hundred.lines).  The only
other impression I have of JAVA is that it isn't as well organized as
C++ (although, it was probably just the coder).

There is one thing we all have to keep in mind:  it takes a while to get
used to a new language.  I think that probably a lot of these JAVA
hypers probably didn't have the patience to actually learn C++.  Sure,
JAVA can probably get morons to turn out simple applications in a couple
of hours.  However, will they get much farther than that?  If they are
truly morons, we C++ programmers don't have anything to worry about
because they won't have the technical skills to do anything significant
(i.e. optimized code).

One more thing:  I use C++, and I am *not* a communist (I am a
conservative, thank you very much!).

--Nathan Davis
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-0905971815540001@10.0.2.1>
In article <·············@usa.net>, Nathan Davis <······@usa.net> wrote:

> > This makes sense. C++ reduces both coding gurus and ignorant morons to
> > the same pathetic level of productivity, and therefore salary. It also
> > supports full employment. Very communist!
> Just one quick question:  have you ever tried programming in C++?
> 
> How can you say that that C++ reduces everyone to the same "pathetic"
> level of productivity.  I learned C++ in my early teens, with hardly any
> trouble at all.  I am very productive with it.  I have yet to see a
> language that is so easy to use that gives you the power you need...

I'm sure that your productivity is high compared with most other C++
programmers, but that still probably leaves you in the 'pathetic'
category compared with other languages/systems.

The fact that you used C++ in your teens makes you young, indeed, and you
probably still believe the myth that 'languages are getting monotonically
better' over time.  Unfortunately, they _aren't_ getting monotonically better,
because the software industry still thinks that it can produce quality software
with minimum wage programmers and the minimum productivity tools that they are
willing to provide them.  Today's languages provide less leverage for a
top programmer than languages and systems available nearly 20 years ago.

Languages and tools are built for the needs of the _vendor_, not the
programmer.  The vendor can make a lot more money selling large numbers of
low-productivity tools, than by selling small numbers of high-productivity
tools.  In effect, the vendor would be cutting his own throat if he
provided his customers with higher productivity, because fewer programmers
would then be required.
From: Daniel J. Salomon
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5l271m$4ge$1@canopus.cc.umanitoba.ca>
In article <·······················@10.0.2.1>,
[.. Long diatribe against C++ deleted.]
> The vendor can make a lot more money selling large numbers of
> low-productivity tools, than by selling small numbers of
> high-productivity tools.  In effect, the vendor would be cutting his
> own throat if he provided his customers with higher productivity,
> because fewer programmers would then be required.

Apparently you don't know the history of C++.  Bjarne Stroustrup
originally distributed C++ compilers for free.  He really believed that
he had a better language for programmers.  Furthermore, an excellent
implementation of C++, namely g++, is still free.  Not only is g++
free, but it also keeps up-to-date with changes in the language, and
often leads other implementations with innovations.

C++ is not a pretty language, and its is not a safe language, but you
have to use it for a couple of advanced projects before you fully
appreciate its contribution to language design.  I can't say I really
like programming in C++, or teaching it, but I do respect the language
for its advanced features.

In short, there are solid reasons for the success of C++.  It is not
just a fluke, or some kind of industry conspiracy.  Critics should try
to include some solid facts in their attacks, instead of just throwing
out wild accusations or ridicule.
-- 
Daniel J. Salomon -- ·······@cs.UManitoba.CA
       Dept. of Computer Science / University of Manitoba
       Winnipeg, Manitoba, Canada  R3T 2N2 / (204) 474-8687
From: Matt Kennel (Remove 'nospam' to reply)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5neqgn.5ih.kennel@lyapunov.ucsd.edu>
On 10 May 1997 16:16:54 GMT, Daniel J. Salomon <·······@silver.cs.umanitoba.ca> wrote:
:In article <·······················@10.0.2.1>,
:[.. Long diatribe against C++ deleted.]
:> The vendor can make a lot more money selling large numbers of
:> low-productivity tools, than by selling small numbers of
:> high-productivity tools.  In effect, the vendor would be cutting his
:> own throat if he provided his customers with higher productivity,
:> because fewer programmers would then be required.
:
:Apparently you don't know the history of C++.  Bjarne Stroustrup
:originally distributed C++ compilers for free.  He really believed that
:he had a better language for programmers.  Furthermore, an excellent
:implementation of C++, namely g++, is still free.  Not only is g++
:free, but it also keeps up-to-date with changes in the language, and
:often leads other implementations with innovations.

There are lots of good languages with free compilers whose implementation
quality exceeds the early C++ compilers.  And yet, what happened?

:-- 
:Daniel J. Salomon -- ·······@cs.UManitoba.CA
:       Dept. of Computer Science / University of Manitoba
:       Winnipeg, Manitoba, Canada  R3T 2N2 / (204) 474-8687

-- 
Matthew B. Kennel/Institute for Nonlinear Science, UCSD/
Don't blame me, I voted for Emperor Mollari. 
From: Daniel J. Salomon
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5lakn9$d0m$1@canopus.cc.umanitoba.ca>
In article <·····················@lyapunov.ucsd.edu>,
Matt Kennel (Remove 'nospam' to reply) <······@nospam.lyapunov.ucsd.edu> wrote:
|> 
|> There are lots of good languages with free compilers whose implementation
|> quality exceeds the early C++ compilers.  And yet, what happened?

Modula-3 falls into this category.  I had high hopes for it at one
time.  It is safer to use than C++ and has a nicer syntax.  I found
that when I used it, I spent my effort on debugging my algorithms, and
not just my code, as compared to C++.  Nevertheless, I don't use it
anymore.  I found that it fell short in features and efficiency.  For
instance, Modula-3 does not have function and operator overloading, and
because of fundamental design decisions, this feature cannot be added
to the language.  In addition, Modula-3 has lately turned into a
lifestyle choice:  if you choose Modula-3, you have to use their whole
developement environment.

The answer to your question is that developers "voted with their feet"
and chose C++.  Your opionion of "better quality" seems not to be
shared by the majority of developers.

-- 
Daniel J. Salomon -- ·······@cs.UManitoba.CA
       Dept. of Computer Science / University of Manitoba
       Winnipeg, Manitoba, Canada  R3T 2N2 / (204) 474-8687
From: Farshad Nayeri
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <337941D4.2F1CF0FB@cmass.com>
Daniel J. Salomon wrote:
> 
> In article <·····················@lyapunov.ucsd.edu>,
> Matt Kennel (Remove 'nospam' to reply) <······@nospam.lyapunov.ucsd.edu> wrote:
> |>
> |> There are lots of good languages with free compilers whose implementation
> |> quality exceeds the early C++ compilers.  And yet, what happened?
> 
> Modula-3 falls into this category.  I had high hopes for it at one
> time.  It is safer to use than C++ and has a nicer syntax.  I found
> that when I used it, I spent my effort on debugging my algorithms, and
> not just my code, as compared to C++.  Nevertheless, I don't use it
> anymore.  

It's sad to hear that. I think most people who have used both M3 and C++
seriously agree with about the safety and ease of use of Modula-3 and how
"they could concentrate on their work".

> For instance, Modula-3 does not have function and operator overloading, and
> because of fundamental design decisions, this feature cannot be added
> to the language.  

It is not that operator overloading can't be added, it's that 
designers didn't/don't feel it should be added. (Whether 
it's a good design choice is a topic of religious belief.) 
An important factor in design of Modula-3 was to allow the
code to be very readable by keeping the language design simple.
(Imagine that your program just crashed in line 2259 of
 some module and you are trying to figure out what went
 wrong. A good backtrace is usually allow you need to
 figure out why an M3 program crashed. I don't think the
 same is true for most C++ programs.)

Anyway, this push for simplicity is how they got the 
core language to be only 50 pages long! I admire the 
M3 designers because they set a limit as to where to 
stop in their design, M3's design is simple, 
in the spirit of Scheme and C, and its philosophy is quite 
different from the 'indefinitely expanding' designs of C++ or Ada.
(Though I do take your point--perhaps they should have set the
limit at 75 and included operator overloading.)

Though what's interesting about Modula-3 is that it includes many 
of the features that attracts developers to *either* C++
or Java, e.g., it has garbage collection, but it also allows
efficient, untraced pointers for systems programming. Despite 
its power, M3's design is significantly simpler than either Java 
or C++!

> I found that it fell short in features and efficiency.  

Well, I'd suggest that 'short on features' may also be
interpreted as 'high on simplicity'. As for efficiency,
it is difficult to measure without knowing the type
of application. However, Modula-3 has been used for
tasks where efficiency has been a concern. 

For example, the SPIN project at University of Washington 
uses M3 to build an extensible operating system kernel
(see the entry for SPIN at http://www.cmass.com/cm3/projects.html#Spin) 
The M3 compiler, runtime, etc., is also written in Modula-3; 
many systems where efficiency has been a concern have been
written in M3 over the past 8 years. Perhaps you can 
elaborate...

> In addition, Modula-3 has lately turned into a lifestyle choice:
> if you choose Modula-3, you have to use their whole
> developement environment.

This is certainly *not* true. You can get standalone compilers
for M3, and you can easily link in C code with it. In fact, you can
download our CM3 compiler today from http://www.cmass.com/cm3/ 
which comes with examples of linking your code with C on Unix and M3.
Of course, we are continuing to improve the integration front--that's 
a continual process as the world changes--for example to support COM.

Perhaps what you are refering to the fact that--since Modula-3
compiler has a good grasp on the module dependencies--you don't
need to use utilities like 'make'. I would take this as
a plus, not a minus! At any rate, it is entirely possible to create
M3 code that calls C or C code that calls M3. In fact, much of the runtime
includes underlying calls to Unix, Win32, or OS/2 APIs. As with
any other language, interoperability comes at a cost of slight
complication, but that is to be expected, and we've found that
it's well worth the support you get from the language.

> The answer to your question is that developers "voted with their feet"
> and chose C++.  Your opionion of "better quality" seems not to be
> shared by the majority of developers.

I disagree--developers choose from the subset of available tools
which they know about. In many cases, they simply are not aware
of other tools, or that there is a perception that such a tool
is not appropriate for what they are doing. (Sometime this perception
is correct, and sometime it is not.) Of course, buzzword compliance 
doesn't hurt.

-- Farshad

-- 
Farshad Nayeri
Critical Mass, Inc.
http://www.cmass.com/

Disclaimer: I am biased!
From: David Thornley
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5lcfoj$1n4$1@darla.visi.com>
In article <·················@cmass.com>,
Farshad Nayeri  <·······@cmass.com> wrote:
>Daniel J. Salomon wrote:
>> 
>> In article <·····················@lyapunov.ucsd.edu>,
>> Matt Kennel (Remove 'nospam' to reply) <······@nospam.lyapunov.ucsd.edu> wrote:
>> |>
>> |> There are lots of good languages with free compilers whose implementation
>> |> quality exceeds the early C++ compilers.  And yet, what happened?
>> 
>> Modula-3 falls into this category.  I had high hopes for it at one

>> The answer to your question is that developers "voted with their feet"
>> and chose C++.  Your opionion of "better quality" seems not to be
>> shared by the majority of developers.
>
>I disagree--developers choose from the subset of available tools
>which they know about. In many cases, they simply are not aware
>of other tools, or that there is a perception that such a tool
>is not appropriate for what they are doing. (Sometime this perception
>is correct, and sometime it is not.) Of course, buzzword compliance 
>doesn't hurt.
>
This is certainly true.

Thing is, C++ took off before the hype, and before it was buzzword-
compatible.  It became popular by word of mouth, and Modula 3
didn't.

The fact that C++ is (mostly) upward compatible with C didn't hurt,
but I don't see that it helped all that much at first.  In Unix,
plugging in something like CFront isn't all that big a deal, but
it's still a cost.  C++ had to provide something valuable over and
above C to be seen as worthwhile, and therefore you have to
consider "significantly better C" vs. "possibly significantly
better language".

Nowadays, most Mac/Windows C compilers are also C++ compilers,
C++ is blessed by Microsoft, it complies with many of the buzzwords
in the latest ISO standard, and you can't open a computer magazine
without at least one company trying to sell you C++.  It wasn't
always that way.  Learn from it.

David Thornley
(who can't see what this is doing in comp.lang.lisp)
From: Peter da Silva
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5m1pd0$cmn@web.nmti.com>
In article <·················@cmass.com>,
Farshad Nayeri  <·······@cmass.com> wrote:
> > In addition, Modula-3 has lately turned into a lifestyle choice:
> > if you choose Modula-3, you have to use their whole
> > developement environment.

> This is certainly *not* true. You can get standalone compilers
> for M3, and you can easily link in C code with it. In fact, you can
> download our CM3 compiler today from http://www.cmass.com/cm3/ 
> which comes with examples of linking your code with C on Unix and M3.

If I do that, and I write some code, who will I be able to share it
with? How easy is it to write portable M3 code?

I had a horrible time trying to get M2 code that would work cross-platform.

-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: mark carroll
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5m21vo$3ei$1@news.cis.ohio-state.edu>
In article <··········@web.nmti.com>, Peter da Silva <·····@nmti.com> wrote:
>In article <·················@cmass.com>,
>Farshad Nayeri  <·······@cmass.com> wrote:
(snip)
>> This is certainly *not* true. You can get standalone compilers
>> for M3, and you can easily link in C code with it. In fact, you can
>> download our CM3 compiler today from http://www.cmass.com/cm3/ 
>> which comes with examples of linking your code with C on Unix and M3.
>
>If I do that, and I write some code, who will I be able to share it
>with? How easy is it to write portable M3 code?
>
>I had a horrible time trying to get M2 code that would work cross-platform.

Modula-3 code is extremely portable. Not only can you get compilers
for Win95, WinNT, OS/2, and a large range of Unices (work is being
done on a Mac one), but even GUI and network object applications
usually work without any change in your code. This is one reason why
an increasing number of businesses are coding in M3 - their GUI
applications work on both WinNT and Unix without modification.

-- Mark (see followups)
From: Matt Kennel (Remove 'nospam' to reply)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5nl10j.cvo.kennel@lyapunov.ucsd.edu>
On 13 May 1997 20:59:21 GMT, Daniel J. Salomon <·······@nickel.cs.umanitoba.ca> wrote:
:In article <·····················@lyapunov.ucsd.edu>,
:Matt Kennel (Remove 'nospam' to reply) <······@nospam.lyapunov.ucsd.edu> wrote:
:|> 
:|> There are lots of good languages with free compilers whose implementation
:|> quality exceeds the early C++ compilers.  And yet, what happened?
:
:Modula-3 falls into this category.  I had high hopes for it at one
:time.  It is safer to use than C++ and has a nicer syntax.  I found
:that when I used it, I spent my effort on debugging my algorithms, and
:not just my code, as compared to C++.  Nevertheless, I don't use it
:anymore.  I found that it fell short in features and efficiency.  For
:instance, Modula-3 does not have function and operator overloading, and
:because of fundamental design decisions, this feature cannot be added
:to the language.  In addition, Modula-3 has lately turned into a
:lifestyle choice:  if you choose Modula-3, you have to use their whole
:developement environment.

I use a language with a free compiler which

   * does have function and operator overloading
   * a very nice typesystem, with working genericity, and full separate
     MI of both implementation and subtype.
   * generates high performance numerical code competitive with
     hand-rolled C, and significantly faster than nearly all C++ matrix
     classes
   * interfaces quite well with C (e.g. you can have a FILE * as an
     object attribute or variable)
   * even works with Fortran arrays.
   * runs just fine with Emacs (with color-highlighting) and make.

and has had nearly all of this for five years.  And I didn't even mention
all the cool langauge things it does. 

:The answer to your question is that developers "voted with their feet"
:and chose C++.  Your opionion of "better quality" seems not to be
:shared by the majority of developers.

I don't think most ever chose C++ over Modula-3, Sather or Ada95; they
chose C++ over C and Fortran and didn't consider anything else. 

:Daniel J. Salomon -- ·······@cs.UManitoba.CA
:       Dept. of Computer Science / University of Manitoba
:       Winnipeg, Manitoba, Canada  R3T 2N2 / (204) 474-8687


-- 
Matthew B. Kennel/Institute for Nonlinear Science, UCSD/
Don't blame me, I voted for Emperor Mollari. 
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <BITMEADC.97May13155636@Alcatel.com.au>
In article <············@canopus.cc.umanitoba.ca> ·······@silver.cs.umanitoba.ca (Daniel J. Salomon) writes:

>C++ is not a pretty language, and its is not a safe language, but you
>have to use it for a couple of advanced projects before you fully
>appreciate its contribution to language design.  

ROTFL.

Well, the last two big projects I've been on, edit/compile/debug times
have blown out to about 3 hours, so you get plenty of time to
contemplate this amazing contribution. It may not be positive however.

Seriously though, the battle I always fight with C++ is practically
zero prodictivity. It's like wading neck deep in molassas.

It doesn't matter too much about how clever STL is or is not. The only
tactic that wins against the C++ compiler is minimising the number of
compiles. That doesn't give me much scope to experiment with clever
template thingys, even ignoring the fact that more templates will blow
out compile times even more.

>In short, there are solid reasons for the success of C++.  It is not
>just a fluke, or some kind of industry conspiracy.  Critics should try
>to include some solid facts in their attacks, instead of just throwing
>out wild accusations or ridicule.

Solid fact: If I wasn't using C++, I wouldn't have time to read this
news group... I'd be doing actual work instead of waiting for
compiles.
From: Dean Roddey
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <33794730.5691@ng.netgate.net>
Chris Bitmead uid(x22068) wrote:
 
> Well, the last two big projects I've been on, edit/compile/debug times
> have blown out to about 3 hours, so you get plenty of time to
> contemplate this amazing contribution. It may not be positive however.
> 

What compiler do you use? I have a non-trivial amount of code and it
compiles very fast. I use precompiled headers and incremental compile
and link. Are you sure you fully understand how to set up your
development system, or perhaps you are not using the right one? I'm not
asking in a derogatory way, just asking. I find that most people never
take the time to step back and learn new ways to take advantage of the
capabilities of most modern compilers. I have always made it a point to
do so, and the results speak for themselves (though not to you of course
because you've never come to one of my 'Compilation Concerts' where I
compile and link in the round backed by the London Philharmonic.)

Seriously though, if you have not done so, either buy a new development
system or take the time to fully learn the one you have.

-- 
Dean Roddey
The CIDLib Class Libraries
'CIDCorp
·······@ng.netgate.net
http://ng.netgate.net/~droddey/

"Software engineers are, in many ways, similar to normal people"
From: Thant Tessman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3379E911.2781@nospam.acm.org>
Dean Roddey wrote in response to Chris Bitmead:

> [...]  I have a non-trivial amount of code and it compiles very fast. I 
> use precompiled headers and incremental compile and link. Are you sure 
> you fully understand how to set up your development system, or perhaps 
> you are not using the right one?  [...]

The project I'm working on also has a non-trivial amount of code (although
in our case it only takes a half-an-hour to compile from scratch).  Our
system takes full advantage of the incremental compilation capabilities
of our compiler and I've managed to get best case compiles down to a 
minute and a half.  But getting all the compile dependencies right 
required a weeks worth of work and some butt-ugly makefile and shell
script hacking.  And if you change a header in a library (which is 
the part I work on), or delete a file referenced by some makedepend
you're back to half-hour compiles.

(I actually put all that work into setting up the dependencies not to
speed up the compiles, but to avoid bugs caused by out-of-synch libraries.)

But after having worked in at least two languages that compile expressions
as you enter them, I resent having to wait at all.  True incremental 
compilation is a completely different, thorougly more pleasant, thoroughly 
more productive way to work, and unless you've tried it yourself you
can't compare.

-thant
From: Dean Roddey
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <337A8955.154@ng.netgate.net>
Thant Tessman wrote:
> 
> Dean Roddey wrote in response to Chris Bitmead:
> 
> > [...]  I have a non-trivial amount of code and it compiles very fast. I
> > use precompiled headers and incremental compile and link. Are you sure
> > you fully understand how to set up your development system, or perhaps
> > you are not using the right one?  [...]
> 
> The project I'm working on also has a non-trivial amount of code (although
> in our case it only takes a half-an-hour to compile from scratch).  Our
> system takes full advantage of the incremental compilation capabilities
> of our compiler and I've managed to get best case compiles down to a
> minute and a half.  But getting all the compile dependencies right
> required a weeks worth of work and some butt-ugly makefile and shell
> script hacking.  And if you change a header in a library (which is
> the part I work on), or delete a file referenced by some makedepend
> you're back to half-hour compiles.
>

What compiler do you use? If you use precompiled headers correctly, this
is not an issue either. I don't have to manage make files or worry about
dependencies or anything else and removing or modifying a fundamental
header does not make a lot of difference. Once the precompiled header
phase finishes, the rest of the files don't really care about it because
they use that one binary file for all header info.

> But after having worked in at least two languages that compile expressions
> as you enter them, I resent having to wait at all.  True incremental
> compilation is a completely different, thorougly more pleasant, thoroughly
> more productive way to work, and unless you've tried it yourself you
> can't compare.
> 

I dunno. I have serious doubts about that kind of language when you do
really big work, which I do. Once it gets to the point where LOTS of
things have to be evaluated just to make typed in expression X do what
it does, I'm not sure its a win in the end. And most large scale systems
have an 'environment' in which they run, which cannot just be started
and stopped on a dime (such as network connections, global/static object
states,  interlocked threads on various shared resources, etc...) I fail
to understand how such a language would make these things magically
start and stop very quickly in order to allow you to evaluate over and
over an expression that might modify these things in some way, such as
kick off threads or network transations, modify those globa/static
objects, etc...

------------------------
Dean Roddey
The CIDLib Class Libraries
'CIDCorp
·······@ng.netgate.net
http://ng.netgate.net/~droddey/

"Software engineers are, in many ways, similar to normal people"
From: Thant Tessman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3380869D.41C6@nospam.acm.org>
Dean Roddey wrote:

> What compiler do you use?   [...]

The one supported by SGI which doesn't support precompiled headers.


> > But after having worked in at least two languages that compile expressions
> > as you enter them, I resent having to wait at all.  True incremental
> > compilation is a completely different, thorougly more pleasant, thoroughly
> > more productive way to work, and unless you've tried it yourself you
> > can't compare.
> >
> 
> I dunno. I have serious doubts about that kind of language when you do
> really big work, which I do. Once it gets to the point where LOTS of
> things have to be evaluated just to make typed in expression X do what
> it does, I'm not sure its a win in the end.  [...]

Yeah, in the worst case it might almost be as bad as C++.

-thant
From: Thant Tessman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3380AF88.41C6@nospam.acm.org>
[...followups trimmed...]


I wrote:

> Dean Roddey wrote:
> 
> > What compiler do you use?   [...]
> 
> The one supported by SGI which doesn't support precompiled headers.

I lied.  SGI's C++ 7.1 supports precompiled headers.  And it cut 
recompilation time due to a change to a library header roughly in half
in exchange for large amounts of disk space.

-thant
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <BITMEADC.97May15113124@Alcatel.com.au>
In article <·············@ng.netgate.net> Dean Roddey <·······@ng.netgate.net> writes:

>> Well, the last two big projects I've been on, edit/compile/debug times
>> have blown out to about 3 hours, so you get plenty of time to
>> contemplate this amazing contribution. It may not be positive however.
>> 
>
>What compiler do you use? 

UNIX compilers, which I believe are derivitives of cfront, but you
would have to ask Sun and HP that. Currently I am doing HP.

>I have a non-trivial amount of code and it
>compiles very fast. I use precompiled headers and incremental compile
>and link. Are you sure you fully understand how to set up your
>development system, 

I had/have confidence in the large number of expert people we have/had
to set up our environment optimally. (And believe me, you need to be
some sort of guru to get the best performance out of templates).

>or perhaps you are not using the right one? 

Possibly, but I have no choice in that.

>I'm not
>asking in a derogatory way, just asking. I find that most people never
>take the time to step back and learn new ways to take advantage of the
>capabilities of most modern compilers. 

If they were any good, the compiler would figure it out for you.

>I have always made it a point to
>do so, and the results speak for themselves (though not to you of course
>because you've never come to one of my 'Compilation Concerts' where I
>compile and link in the round backed by the London Philharmonic.)
>
>Seriously though, if you have not done so, either buy a new development
>system or take the time to fully learn the one you have.

Buy a new one? I suggest you talk to our budgeting people. They
wouldn't spend $10,000 even if you could prove a saving of $100,000.

(If they did understand these things we wouldn't even be using C++ now
would we ?).
From: Anthony Shipman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kmrhg$6bt@ephor.tusc.com.au>
In <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

>Imagine trying to write a sort routine that worked not on just
>arrays, but any data structure that supported a specific set of 
>operations, like get_next_item.  The beauty of the STL is that you
>can mix and match algorithms and data structures.  This is hard
>to do in a purely traditional message-based object-oriented 
>framework.


My viewpoint is that a design based on adding operations like
get_next_item() to a data structure is at too low a level.

First boost your technology to the level of a lazy functional language like
Haskell.

Then view a list as not just a data type but an abstract interface for
linear operations.  

To add linear operations to a data structure add a function that maps
the data structure to a list of the members of the structure.  For
example to a tree data structure add a function that builds a list of
the members in depth first order.  Another function could be written to
build a list in breadth first order.  These adaptor functions can be
quite small, being little more than a mathematical specification of
depth-first or breadth-first or whatever traversal.

Then any function that operates on a list can operate on the data
structure.  Careful use of type classes will let the syntax be quite
neat.

It is important that lazy evaluation be used.  This lets a search
function terminate the search early which will terminate the traversal
of the data structure early as you would expect.  The low-level
implementation will be equivalent to what you would write with a
get_next_item() function but it's all generated automatically.  

The only minuses that I can think of are that

*  there may be dynamic dispatching on each member operation.  Recent
   developments in optimising dynamic dispatching to be static will help
   here.

*  memory allocation issues will give higher peak memory usage but also
   quite possibly greater speed since there is no overhead due to the
   reference counting a C++ iterator would use as it passes over the
   data structure.  Deforestation optimisations could eliminate the
   memory allocation issues completely.

The big plus of this functional approach is that the linear operations
and the data structures are completely decoupled.  You can compose any
data structure and linear operation using an appropriate adaptor
function that describes the traversal order.

Other pluses are that improvements in optimisations in compilers will
result in all existing code being improved.  Whereas hand-written code
for the interaction of operations and data structures in lower-level
languages tend to become frozen.  For example a parallelising compiler
will let you run multiple concurrent iterations on parallel hardware
with no extra effort.

-- 
Anthony Shipman                 "You've got to be taught before it's too late,
TUSC Computer Systems Pty Ltd    Before you are six or seven or eight,
                                 To hate all the people your relatives hate,
E-mail:  ···@tusc.com.au         You've got to be carefully taught."  R&H
From: Fergus Henderson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kneho$87v@mulga.cs.mu.OZ.AU>
···@tusc.com.au (Anthony Shipman) writes:

>My viewpoint is that a design based on adding operations like
>get_next_item() to a data structure is at too low a level.
>
>First boost your technology to the level of a lazy functional language like
>Haskell.
[...]
>The low-level
>implementation will be equivalent to what you would write with a
>get_next_item() function but it's all generated automatically.  

Well, hopefully.  But you are assuming quite a bit.  My guess is that
in practice for most current Haskell and C++ implementations, C++ and
STL will beat this style of Haskell code by a significant constant factor.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Matt Austern
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <fxtwwpdd2vo.fsf@isolde.mti.sgi.com>
·····@usa.net.delete_me (Darin Johnson) writes:

> In article <·············@mti.sgi.com>, Alexander Stepanov wrote:
> >Being responsible for the standard template library, I could assure you that 
> >C++ does have merits. I tried to implement STL in a variety of languages 
> >and failed. I had a very modest goal - to be able to express linear search
> >in a such way that it would work for any data structure for which it makes
> >sense. C++ was the only language in which I could do it.
> 
> Really?  How odd.  Why couldn't this be done in Smalltalk, Eiffel, or Java?

Alex and I tried to implement the STL in Java; you can see our attempt
at http://reality.sgi.com/austern/java/index.html.  For a number of
reasons, though, the attempt wasn't all that successful.  The most
obvious problem is that Java doesn't have any sort of genericity at
all (polymorphism is not a substitute), but there were actually some
other issues as well.

The main reason that Alex never tried to implement the STL in Eiffel
is that he doesn't know Eiffel.  I do, though, so I'll take the
liberty of responding for him.

(Caveat: my Eiffel experience is a year or two old.  It's possible
that the language has changed since then, and that my comments are no
longer applicable.)

The general problem is that the whole goal of writing a library of
generic algorithms is to separate algorithms from data structures: you
want to write a partition algorithm, for example, that can work for
arrays, doubly-linked lists, and any other data structure that users
might create.  This separation is difficult in Eiffel, though, because
Eiffel was designed with precisely the opposite goal in mind: it
encourages a very close association between algorithms and data
structures.  This shows up in a number of small details, which turn
out to be more important than they initially appear.

It might be possible to write something like the STL in Eiffel; I
don't really see how, though.  The main problems that I see are 
(1) The lack of genericity at the level of functions, as opposed to
the level of classes; (2) The lack of nested type declarations; 
(3) The lack of typedef---it's surprisingly important; and (4) A
constrained genericity mechanism that relies on inheritance.

The constrained genericity problem is probably the worst of them.  The
STL does impose requirements on generic parameters, but the
requirements involve rather complicated relationships between types; I
don't see how to capture those relationships in terms of inheritance.
From: Alexander Stepanov
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336E824D.237C@mti.sgi.com>
Matt Austern wrote:
> 
> The main reason that Alex never tried to implement the STL in Eiffel
> is that he doesn't know Eiffel.  I do, though, so I'll take the
> liberty of responding for him.
> 

This statement is only partially correct. I do not know Eiffel. I never
tried to implement STL in Eiffel. I do not believe, however, that these
statements are causally connected.

I considered several langages which I did not know as possible
instruments for building a library of generic software components: CLU,
Modula 3, Oberon, SML, Eiffel. I always sought the best advice from the
experts available to me to assertain if such a task would be possible.
For all of these languages I came to the conclusion that I would not be
able to accomplish my task. 

To put it simply: I was trying to develop a systematic organization of
algorithms, data structures and other software components. I was not
trying to produce a C++ library. I discovered that C++ was the best
available tool for the job. It is clearly possible to argue that I
failed and the organization of software components in STL is
fundamentally flawed. But if I was succesful, it was only because
Bjarne Stroustrup provided me with the right tool.

-- 
Alexander Stepanov
········@sgi.com

Silicon Graphics
2011 N. Shorline Boulevard
Mountain View, CA 94043-1389

tel.: (415)933-6121
From: Thant Tessman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336F5950.3F54@nospam.acm.org>
Alexander Stepanov wrote:

> [...]  It is clearly possible to argue that I
> failed and the organization of software components in STL is
> fundamentally flawed.

I haven't seen anybody argue this.  Given the context, the
STL is a thing of beauty.

(Of course, as with everything related to C++, practice falls
far short of what little even theory promises, and as expected,
my implementation of the STL from SGI sucks.  For one thing, 
some very peculiar errors in my code turned out to be caused
by a "PAUSE" macro defined in "alloc.h".)


> But if I was succesful, it was only because
> Bjarne Stroustrup provided me with the right tool.

This is the claim I reject.  It doesn't surprise me at all
that the STL couldn't be done in Eifel or Java.  But SML or
CLOS or...you're gonna have to substantiate that one.

-thant
From: Alexander Stepanov
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336FDF31.6201@mti.sgi.com>
Thant Tessman wrote:
> 
> Alexander Stepanov wrote:
> 
> > [...]  It is clearly possible to argue that I
> > failed and the organization of software components in STL is
> > fundamentally flawed.
> 
> I haven't seen anybody argue this.  Given the context, the
> STL is a thing of beauty.
> 
> (Of course, as with everything related to C++, practice falls
> far short of what little even theory promises, and as expected,
> my implementation of the STL from SGI sucks.  For one thing,
> some very peculiar errors in my code turned out to be caused
> by a "PAUSE" macro defined in "alloc.h".)

Please sent us (···@sgi.com) a detailed report. We will try to fix it
as fast as possible. This bug has never been reported.
Interestingly, you are the first disgrunted customer we had. Most people
are very happy with our implementation.

> 
> > But if I was succesful, it was only because
> > Bjarne Stroustrup provided me with the right tool.
> 
> This is the claim I reject.  It doesn't surprise me at all
> that the STL couldn't be done in Eifel or Java.  But SML or
> CLOS or...you're gonna have to substantiate that one.

1. Addresses.

STL is based on the fundamental assumption that addresses are
good. The memory model of the C machine is the right base for the
abstraction. Neither Lisp nor ML allow a natural address/location
abstraction. You can implement address like thingies in them, but
the built-in data strucutres do not based on the needed abstraction.
Note that in Lisp one tends to stick to the built-in data-structures. 
I never seen a serious impementation of a doubly-linked lists in Lisp. 
(Yes, yes, I had done one myself too, but it was not serious.) As far
as I know, the same holds true for SML. Arrays and lists can not
be easily unified. Or at least, they are not usually unified.
Take a look at list->vector, vector->list pair in Scheme and compare it
with generic constructor in STL containers. They have to provide
2N new conversion functions for every new data structure in the library.
Clearly, they do not bother to extend the number of data structures. 

One of the things I am trying to do now is to extend the iterator
classification to handle non-uniform memory references. (One of
my collegues, Fred Chow, proposes to call them NUMA-iterators.) It is
quite remarkable how the existing STL framework could be extended to
deal with MP, cache behaviour, parallelism. But it all relies on
addresses. Abstract addresses, but addresses nevertheless.

2. Container vs. iterator

Lisp also brought a conceptual confusion of list as an iterator and list
as a data structure. There is no way to distiguish between the two uses.
It is a subtle point, but I am sure you can see it. It also makes it
impossible to have an ownership or whole-part semantics for data
structures and makes it impossible to survive without
garbage collection. (I like garbage collection as an option, but
Lisp and ML make a virtue out of necessity.)

3. Type system

It is possible to define swap in C++. And you can use partial
specialization to choose the right swap. 

template <class T>
inline void swap(T& x, T& y) {
	T tmp = x;
	x = y;
	y = tmp;
}

and

template <class T>
inline void swap(vector<T>& x, vector<T>& y) {
	x.swap(y);
}

And you should see amazing things you can do with types using
partial specialization. (Look at the description of iterator_traits
in the standard.) It is very easy to specify very complicated
relations among type categories.

It is so easy to use the type system to carry semantic information
and to use types for selecting correct algorithms. Somebody once
remarked that STL shows how much can be accomplished by passing empty
structures around.

I do not know any other language where I can easily say:

1. Normally, reduce returns an identity element of its operation.

template <class InputIterator, class BinaryOperation>
iterator_traits<InputIterator>::value_type
reduce(InputIterator first, InputIterator last, BinaryOperation op) {
	if (first == last) return identity_element(op);

	iterator_traits<InputIterator>::value_type result = *first;

	while (++first != last) result = op(result, *first);

	return result;
}



2. The default operation of reduce is plus.

template <class InputIterator>
iterator_traits<InputIterator>::value_type
inline reduce(InputIterator first, InputIterator last) {
	return reduce(first, last,
	 	plus<iterator_traits<InputIterator>::value_type());
}


3. The default identity element of plus is 0

template <class T>
inline T identity_element(const plus<T>&) {
	return T(0);
}

4. The default identity element of multiply is 1

template <class T>
inline T identity_element(const multiply<T>&) {
	return T(1);
}

Note, that if I want to add a bunch of doubles I just say:

vector<double> v;

// fill v with doubles

cout << reduce(v.begin(), v.end());

// now print the product:

cout << reduce(v.begin(), v.end(), multiply<double>());

I do not need to pass ++, *, ==, = for iterators as our ML experts
suggest that we do. Types are good. Compiler will find the right
operations.

And if tomorrow I put my doubles into a set (does SML have sets?),
I can just say:

set<double> v;

// fill v with doubles

cout << reduce(v.begin(), v.end());


// now print the product:

cout << reduce(v.begin(), v.end(), multiply<double>());

And if, tomorrow, you define sets that use skip lists you just do:

skip_set<double> v;

// fill v with doubles

cout << reduce(v.begin(), v.end());


// now print the product:

cout << reduce(v.begin(), v.end(), multiply<double>());


Now, take Common Lisp reduce. It is not generic. (If you define your own
doubly linked list, their reduce is not going to do anything reasonable
for it.) It is hard making it generic, or they would have done it.

Using these techniques, is quite easy to define algorithms affiliated
with different algebraic structures, say, Euclidian domains. It is quite
easy to state that, say, all polynomial rings over a field are
Euclidian domains. It is also possible to state when to use Euclid's
algorithm and when to use binary gcd algorithm. That is, it is possible
to describe algorithms over theories - and that's what generic
programming is all about. Yes, there are languages other than C++, that
allow one to do this, Axiom and A# by Richard Jenks et al. is one which
needs to get far greater recognition. (I would use them as a proof that
it is much more important for a language designer to know their van der
Waerden, than to read lambda calculus books. As a matter of fact, many
would benifit greatly if they worked carefully through George Chrystal's
great textbook.) Ada 95 is much, much better for generic programming
than Ada 83. SML and CLOS? I do not think so. 

> 
> -thant


Alex

-- 
Alexander Stepanov
········@sgi.com

Silicon Graphics
2011 N. Shorline Boulevard
Mountain View, CA 94043-1389

tel.: (415)933-6121
From: Marco Antoniotti
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <scf4tcfqjp8.fsf@infiniti.PATH.Berkeley.EDU>
This is a very interesting and informative posting.  I learned a lot
from it.  However, being the hard-line Commonist Lisper I cannot help
to comment on the following. :)

In article <·············@mti.sgi.com> Alexander Stepanov <········@mti.sgi.com> writes:

   From: Alexander Stepanov <········@mti.sgi.com>
   Newsgroups: comp.lang.scheme,comp.lang.lisp,comp.lang.misc,comp.lang.functional,comp.lang.c++
   Date: Tue, 06 May 1997 18:47:29 -0700
   Organization: SGI/MIPS

... much cut.

   Now, take Common Lisp reduce. It is not generic. (If you define your own
   doubly linked list, their reduce is not going to do anything reasonable
   for it.) It is hard making it generic, or they would have done it.

Doubly linked lists in Common Lisp are easily implemented (the fact
that they are not in the language and that maybe lisp programmers do
not use them as much may be the reason for the lack of
implementations)

However, about REDUCE...

------------------------------------------------------------------------------

(defpackage "STL" ; just a name
   (:use "COMMON-LISP")
   (:shadow "REDUCE"))

(in-package "STL")

(defmethod reduce ((s sequence) f &key from-end start end initial-value)
   (common-lisp:reduce f s
                       :from-end from-end
                       :start start
                       :end end
                       :initial-value initial-value))

(defmethod reduce ((s dll:dll) f &key from-end start end initial-value)
   (dll:reduce f s
               :from-end from-end
               :start start
               :end end
               :initial-value initial-value))

(defmethod reduce ((s hash-table) f &key from-end start end initial-value)
   ;; You got the hang of it.
   )

------------------------------------------------------------------------------

Where I will pardoned the swap of arguments (nobody said that CL is
perfect) and the assumption of existence of a DLL package with a DLL
class defined in it as well as a specialized dll:reduce.

Happy Lisping
-- 
Marco Antoniotti
==============================================================================
California Path Program - UCB
Richmond Field Station
tel. +1 - 510 - 231 9472
From: Marco Antoniotti
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <scfn2q63sak.fsf@infiniti.PATH.Berkeley.EDU>
In article <·····················@massif.brightware.com> ·····@brightware.COM (Jeff Greif) writes:

   From: ·····@brightware.COM (Jeff Greif)
   Newsgroups: comp.lang.scheme
   Cc: ······@mc.lcs.mit.edu
   Date: 8 May 1997 01:37:15 -0400
   Organization: Brightware Inc
   Reply-To: <···@brightware.com>
   Lines: 94
   Sender: ··············@bloom-beacon.mit.edu
   Distribution: world
   References: <···············@infiniti.PATH.Berkeley.EDU>
   Xref: agate comp.lang.scheme:20525

   This is perfectly reasonable, but it is not what the STL is about.
   The aim of the STL is to express the algorithm  of the REDUCE function
   just once.  It's roughly of this form (if your lisp optimizes tail calls):

   (defun stl:reduce (coll fun &key (start (begin coll)) (end (end coll)) (initial-value  (funcall fun)))
     (if (eq start end)
	 initial-value
	 (let ((val (funcall fun initial-value (element coll start)))) 
	   (stl:reduce coll fun :start (next coll start) :end end :initial-value val))))

   where BEGIN, END, NEXT and ELEMENT are the generic functions to traverse
   any collection in the forward direction (I've left out the :from-end keyword
   which requires reverse order) and access its contents.  BEGIN, END and NEXT might be
   implemented universally in terms of locf's if they were defined in CL -- this
   is more or less what's done in the C++ STL -- or they might return some kind
   of struct or closure which contains the state variables of the iteration (a
   bucketed hash table would need two variables, for instance).
   The start and end arguments are thus iteration state objects of some sort.

   This is supposed to produce an efficient computation (O(n) for collections of
   size n for this algorithm, and constant space) regardless of what form of
   collection (list, vector, hashtable, linked or doubly-linked structs or CLOS
   instances, trees, etc) is used and what kind of elements appear in it.  All
   the details of the collection behavior are hidden in the iteration generic
   functions.

Whatever!  You can define a set of "iterators" in CL (the SERIES
package is an example in this direction) and then rewrite REDUCE using
that form of abstraction.

The claim that Alexander Stepanov made:

    "Now, take Common Lisp reduce. It is not generic. (If you define your own
    doubly linked list, their reduce is not going to do anything reasonable
    for it.) It is hard making it generic, or they would have done it."

does not stand.

Cheers
-- 
Marco Antoniotti
==============================================================================
California Path Program - UCB
Richmond Field Station
tel. +1 - 510 - 231 9472
From: Thant Tessman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <33712808.41C6@nospam.acm.org>
Alexander Stepanov wrote:

> But if I was succesful, it was only because
> Bjarne Stroustrup provided me with the right tool.

I wrote:

> This is the claim I reject.  It doesn't surprise me at all
> that the STL couldn't be done in Eifel or Java.  But SML or
> CLOS or...you're gonna have to substantiate that one.

[...stuff...]

At the end of this post is an implementation of doubly-linked lists 
implemented in SML but in the style of the STL.  There's also
a "replace" function like the one in the STL just to show
how it would work.

I think it satisfies all your criteria for a genericity.

  1) You can mutate what you find in the data structure

Iterators are separate from containers so that:

  2) You can restart searches

  3) You can have multiple search paths

  4) You can consider subranges

  5) You can compare two positions for equality

Also, this is fully generic, with no run-time type dispatching.

This implementation took me about two hours and I am not an SML
expert by any stretch of the imagination.  But it's still more
succinct than the equivalent C++ code.  And doing things in the
spirit of SML using higher-order functions to build your data 
accessor functions would produce still more succinct code than 
what I have here (as Greg Morrisett has already demonstrated).

The only advantage to programming this way in C++ is that templates
support partial specialization.  I mentioned earlier that I thought
this was pretty neat.  But the STL only uses it as a replacement
for what using higher-order functions buys you anyway.  And believe
me, I use partial specialization all the time.  I'd still rather
be programming in SML.

> [...reduce...]
>
> I do not need to pass ++, *, ==, = for iterators as our ML experts
> suggest that we do. Types are good. Compiler will find the right
> operations.

First, not wanting to pass in these functions is a long way from 
"can't do a generic linear search".  Second, CLOS generic functions
allow you to specialize functions in exactly the same way that templates
allow partial specialization (except that the dispatch is done 
dynamically).  So I don't buy for a moment that it's hard making a
generic "reduce" in Common Lisp simply because no one's done it.
I think it's more likely that no one has seen the need since it's
so easy just to create and pass around functions directly.

(BTW, things like "reduce" is what I was talking about when I said
that the STL came off as merely an attempt to make it easier to
do things in C++ that were already easy in other languages.)

The whole trick to the STL is separating containers from iterators and
getting all the properties of both consistent enough to make it easy
to write generic algorithms.  This is a very cool thing.  Your 
implementation of the STL plays C++'s strengths well (were it that
we all had so much influence with the language creator), but there
is NOTHING inherent about this problem that makes C++ particularly
suited to solving it.

Please, please, please just let C++ die.

-thant


(**************)


signature DATASTRUCTURE = 
  sig 
    exception MemoryFault
    eqtype ''a iterator
    eqtype ''a container
    val null : ''a iterator
    val new : unit -> ''a container
    val push_back : ''a container * ''a -> unit
    val push_front : ''a container * ''a -> unit
    val first : ''a container -> ''a iterator
    val last : ''a container -> ''a iterator
    val prev : ''a iterator -> ''a iterator
    val next : ''a iterator -> ''a iterator
    val set : ''a iterator * ''a -> unit
    val get : ''a iterator -> ''a
  end


structure Chain : DATASTRUCTURE = 
  struct 

    exception MemoryFault

    datatype ''a iterator = 
      LNull
    | Link of ''a ref * {prev: ''a iterator ref, next: ''a iterator ref}


    datatype ''a container = Chain of {head: ''a iterator ref,
				       tail: ''a iterator ref}

    fun new () = Chain {head = ref LNull, tail = ref LNull}

    fun push_back (Chain {head, tail}, item) =
      case tail of 
	ref LNull => let
		       val link = Link (ref item, {prev=ref LNull, 
						   next=ref LNull})
		     in
		       tail := link;
		       head := link
		     end
      | ref (Link (_, {next, ...})) => let
				      val link = Link(ref item, 
						      {prev = ref (!tail),
						       next = ref LNull})
				     in
				       next := link;
				       tail := link
				     end

    fun push_front (Chain {head, tail}, item) =
      case head of 
	ref LNull => let
		       val link = Link (ref item, {prev=ref LNull, 
						   next=ref LNull})
		     in
		       tail := link;
		       head := link
		     end
      | ref (Link (_, {prev, ...})) => let
				      val link = Link(ref item, 
						      {prev = ref LNull,
						       next = ref (!head)})
				     in
				       prev := link;
				       head := link
				     end

    fun first (Chain {head as ref link, ...}) = link
    fun last (Chain {tail as ref link, ...}) = link

    fun next LNull = raise MemoryFault
      | next (Link (_, {next as ref n, ...})) = n

    fun prev LNull = raise MemoryFault
      | prev (Link (_, {prev as ref p, ...})) = p

    fun set (LNull, _) = raise MemoryFault
      | set (Link (item, _), newValue) = (item := newValue)

    fun get LNull = raise MemoryFault
      | get (Link (item, _)) = !item

    val null = LNull

  end
      


functor SomeAlgos(DataStructure:DATASTRUCTURE) = 
  struct

    (* for now all we have is replace, but you get the point *)

    fun replace(first, last, oldValue, newValue) =
      let 
	fun f i =
	  if (i=DataStructure.null) then ()
	  else
	    (if ((DataStructure.get i) = oldValue)
	       then (DataStructure.set (i, newValue)) 
	     else ();
	     if (i<>last) then f(DataStructure.next i) else ())
      in
	f(first)
      end

  end

(*  an example of their use *)


open Chain;


val chain : int container = new ();

push_back(chain, 1);
push_back(chain, 2);
push_front(chain, ~1);

val i = first chain;

(* specialize the algorithm to chains, like instantiating a template *)

structure SomeChainAlgos = SomeAlgos(Chain);

SomeChainAlgos.replace(first chain, last chain, 1, 99);

(* here's polymorphic swap in SML *)

fun swap (a, b) = 
  let
    val tmp = !a
  in
    a := !b;
    b := tmp
  end
From: Lyman S. Taylor
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kr31d$e7k@pravda.cc.gatech.edu>
In article <·············@mti.sgi.com>,
Alexander Stepanov  <········@mti.sgi.com> wrote:
>> that the STL couldn't be done in Eifel or Java.  But SML or
>> CLOS or...you're gonna have to substantiate that one.

  I, for one, am still waiting......  "impossible" "cannot" 
  deserve some justification. 


>1. Addresses.
>
>STL is based on the fundamental assumption that addresses are
>good. The memory model of the C machine is the right base for the
>abstraction. Neither Lisp nor ML allow a natural address/location
>abstraction. 

  Eh??  Admittedly Lisp nor ML allow one to point to internal structure
  of "entities" ( i.e. you can't do arbitrary pointer manipulation). 
  However, constrained to the boundaries of "entities" what exaclty is
  inexpressible? 

  
> You can implement address like thingies in them, but

   Oh. let's see. It acts like a adress, hence "address like". 
   So here were have  an address/location abstraction. 

>the built-in data strucutres do not based on the needed abstraction.

   And what praytell stops you from layering/adding this abstraction onto the
   built-in data structures? 

   [ Remeber the postulation stipulated several messages back was that it was
     "impossible" to do.  In my book "impossible" is a relatively strong
      stipulation. ] 

>Note that in Lisp one tends to stick to the built-in data-structures. 
>I never seen a serious impementation of a doubly-linked lists in Lisp. 

  I haven't seen one... therefore it doesn't exist and therefore impossible. 
  Yeah right.  Or could it possibly be that most folks, if they need one,
  just independently "reinvent the wheel"?  How likely is that if it isn't
  in the "standard library"?  If the folks a Harlequin/Lucid, Franz, Symbolics,
  etc. ( i.e. a large group of lisp programmers with some legacy of code 
  behind them.. ) chime in and say there is NO doubly-linked lists in any
  of their code... then I might fell inclined revisit this argument. 

 
>as I know, the same holds true for SML. Arrays and lists can not
>be easily unified. Or at least, they are not usually unified.
>Take a look at list->vector, vector->list pair in Scheme and compare it
>with generic constructor in STL containers.

    And if you added a generic constructor abstraction in Common Lisp utilizing
    macros you couldn't get the STL functionality??

    I asked this before and didn't really get a response. So I'll rephrase it.
    C++ templates are essentailly "syntactic sugar".  There's little templates
    do that a programmer couldn't do by just typing approximately the same 
    code over and over again. Fortunately the C++ compiler does some 
    bookkeeping for him/her and does alot of code writing and substitution 
    "automagically".

    Likewise the macro system of Common Lisp can be used to add "syntactic 
    sugar" to Common Lisp code.  It can be used to do bookeeping (i.e. execute
    arbitrary pieces of code at compile time) in conjunction with writing 
    code. 

    So what stops a STL-like implementor from 
		i. adding a template-like mechanism to "raw" CL. 
                ii. implementing the STL using this mechanism. 

    [ Again discounting compile time checks on "correctness" of the code 
      given that Common Lisp is a dynamic language and isn't overly pressed
      about static type checking.  ]  While not a CL macro "guru", offhand
    I do not see what the "show stopper" is in implementing this.

    Code refering to these generic may have to be incased in macro body but
    that seems about as "different"/"onerous" as suffixing "<data_type>" after 
    STL type/function references. 

    [ throw in the use of CLOS for overloading function names and I definately 
      do not.]

    Something along the lines of.... 
    
    (with-generics ( (generic-type1 param ) 
                     (generic-type2 param param ) 
		     ( (generic-fcn1  (generic-arg param )
				     (generic-arg param )  param param ) )
		     ( (generic-fcn2  (generic-arg param param) param ) ))

        ;; if pressed about speed.. some declarations.. 
	(declare (..... (var10  generic-type1 )  (var11 generic-type2) ... ))
	

	  ...  (generic-fcn1   var10  (generic-fcn2 var11 ) .... ) ...  )



    the macroexpansion of the above could be just as name-mangled as anything
    a C++ compilier might generate... ;-)   


    [ I'm not too familiar with Scheme macros to affirm/discount there
	ability to do this task. I wouldn't dismiss it though. ] 

    In Essence, in the case of lisp I think that if it is syntactic sugar
    you are in seach of, then you criticism should appeal to the deficiencies
    of the syntactic sugar making capabilities of the language.  Otherwise
    this debate is "stuck on 'stupid' and not getting off". 


>One of the things I am trying to do now is to extend the iterator
>classification to handle non-uniform memory references. (One of
>my collegues, Fred Chow, proposes to call them NUMA-iterators.) It is
>quite remarkable how the existing STL framework could be extended to
>deal with MP, cache behaviour, parallelism. But it all relies on
>addresses. Abstract addresses, but addresses nevertheless.
>
>2. Container vs. iterator
>
>Lisp also brought a conceptual confusion of list as an iterator and list
>as a data structure. There is no way to distiguish between the two uses.
>It is a subtle point, but I am sure you can see it. 

  Errr, you seemed to have lost me on this one... 

   C/C++					Lisp

   int a[4] = { 1, 2, 3, 4};
   int *p = a;                                 (setf p '( 1 2 3 4 ))
  
   printf("%d \n", *p);			       (format t "%d ~%" (first  p ))
   p = p + 1 ;				       (setf p (rest p))
   printf("%d \n", *p):                        (format t "%d ~%" (first p ))

  Exactly what is the subtle difference in the way C/C++ treats "p"
  and how Lisp treats "p"?


>3. Type system
>
>It is possible to define swap in C++. And you can use partial
>specialization to choose the right swap. 

  The unstated implication that in Scheme/Common Lisp you cannot
  define swap?????    Surely you jest....  

  for CL see ( slightly more than the same functionality..)

http://www.harlequin.com/books/HyperSpec/Body/mac_rotatef.html#rotatef




>I do not know any other language where I can easily say:

  [ template reduce code deleted... ] 

>3. The default identity element of plus is 0

  Oh like 
		(+) ==> 0 


>4. The default identity element of multiply is 1

  Oh like 
		(*) ==> 1

>
>Now, take Common Lisp reduce. It is not generic. (If you define your own
>doubly linked list, their reduce is not going to do anything reasonable
>for it.) It is hard making it generic, or they would have done it.

 
   This is akin to saying C++ isn't good because printf isn't generic 
   enough... 


   1. In Common Lisp reduce is a function.  So yeah it is a tad difficult to
	expand to other datastructures.  You can't overload the name ( actually
        not quite true but could involve implementation dependent gyrations)
       It has also been around "forever" too. 

http://www.harlequin.com/books/HyperSpec/Body/fun_reduce.html#reduce
     
      However, I'm going to use a simplified argument list that matches 
      the reduce that is there..       
		
      (defgeneric my-reduce  ( fcn seq )  ) 

      ;; if just any prefdefined sequence and a function...
      (defmethod  my-reduce  ( (fcn function) (seq sequence ) )
        (reduce fcn seq ))

      (defmethod  my-reduce  ( (fcn function) (seq T ) )
        ... here define insanely great generic algorithm to 
	    do reduce....  )

      (defmethod my-reduce   ( (fcn function) (seq whiz-bang) )
         ... here define even more insanely great generic alogirtm 
	     to do reduce specialized for the whiz-bang data structure)


    [ NOTE:  I could if I made explicit the full lambda list...
		i.  assign the current REDUCE to a new symbol.
		      OLD-REDUCE ( so I could use the predefined code).

		ii. define my defgeneric on the name REDUCE.
			and say yes the warning message "do you really want
			do this, I'm about to redefine reduce as a generic
			function and potentiall blow away the previous 
                        definition". 
		iii. define my new reduce with the same name, but old
			argument set-up.   Albeit for slightly slower
			overall performance... since now a generic function
			instead of a function.      ]


   2. The default reduction function for reduce is + ... Gee that's gotta
             be hard to do in Lisp, huh??? :-) 

      If the lambda list for reduce looked list STL's would this be 
	"impossible". 

       (defgeneric stl-reduce ( begin-iter  end-iter 
				  &optional (fcn function stl-plus)) )

	[ again + is a function in CL. If you want to overload with abandon
		you'll need your own name. ]

       (defmethod  stl-reduce ( (being-iter iterator) (end-iter iterator)
				  &optional (fcn function stl-plus ))
	  .... insanely great generic stl-reduce code goes here... )


       ..... 

-- 
Lyman S. Taylor           Comment by a professor observing two students 
(·····@cc.gatech.edu)     unconscious at their keyboards:
				"That's the trouble with graduate students.
				 Every couple of days, they fall asleep."
From: Alexander Stepanov
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <337121CD.52BF@mti.sgi.com>
I got several dosen private messages containing code in Scheme that
purports to demonstrate the error of my ways. And now we do get CL
code that puts me into my proper place.

I tried to explain something. I might have failed. I might be wrong. But
I have spent 10 years writing code in these languages, and it is a
matter of common courtesy to assume that I do know something before
sending me angry personal messages accusing me of all kinds of
monstrous things.  

To demonstrate that I heard of higher order functions I include a
hand-out I wrote in 1985 (note, that I do define a "generic" reduce)
plus few relevant manpages from a large algorithmic library that I wrote
in 84-85. I apologize for sending such a large post, but it might calm
some people. 
(I even have two papers that deal with reduce in functional languages
setting, but I do not have them handy to post on the net, nor are they
are really worth reading, but for the fact that I been there done that.)


;;; Iterators

;;; one of the central ideas of higher order programming
;;; is the idea of using higher order functional forms
;;; (functions that produce functions) instead of using
;;; recursion (tail or otherwise)

;;; we can implement a function that adds square roots of all even
;;; numbers in an interval (a, b); but if we want to add square roots
;;; of all numbers in a list we shall need another program; and
;;; another one for vectors; and another one for heaps ...

;;; we can simplify our life by introducing iterators, that are
;;; somewhat like universal quantifiers on data structures

;;; simpliest class of functional forms are iterators
;;; iterator is a function that takes a structure and
;;; returns a function that takes a function f of one
;;; argument as its argument and applies f to every
;;; element of the structure

;;; most primitive kind of iterators can be produced with

(define (primitive-iterator initial-value transform)
  (lambda (function)
    (define (loop x)
      (function x)
      (loop (transform x)))
    (loop initial-value)))

;;; sometimes the function we pass to the iterator is destructive
;;; and can affect x; to handle cases like that we define

(define (primitive-iterator! initial-value transform)
  (lambda (function)
    (define (loop x)
      ((lambda (next) (function x) (loop next))
       (transform x)))
    (loop initial-value)))

;;; For example, we can iterate through natural numbers with

(define for-each-natural-number
  (primitive-iterator 1 1+))

;;; Problem:

;;; what will happen if you say

;;; (for-each-natural-number print)

;; ? (before you try it find out Ctrl-Break on your keyboard)

;;; here you can ask what good does it do to have a non-terminating
;;; iterators.
;;; but we can make functions that
;;; starting with any iterator can produce other iterators
;;; out of it

;;; for example, restrict-iterator takes a predicate and
;;; an iterator and returns a new iterator which applies
;;; function only to those elements that satisfy the predicate

(define (restrict-iterator predicate iterator)
  (lambda (function)
    (iterator (when-combinator predicate function))))

;;; and we can compose an iterator with a function

(define ((compose-iterator f iterator) g)
  (iterator (compose g f)))

;;; and we can terminate the iteration with the following two
;;; iterator-manipulating functions:

(define (iterator-until predicate iterator marker)
  (lambda (function)
    (call-with-current-continuation
      (lambda (exit)
        (iterator (if-combinator predicate exit function))
        marker))))

(define (iterator-while predicate iterator marker)
  (lambda (function)
    (call-with-current-continuation
      (lambda (exit)
        (iterator (if-combinator predicate function exit))
        marker))))

;;; where call-with-current-continuation (or call/cc) is a
;;; function that ...

;;; there is an "extra" feature in iterators created with
;;; iterator-until and iterator-while: in case
;;; of "unnatural" termination they return a value that caused it
;;; otherwise they return a marker

;;; we can define a product of iterators

(define (product-of-iterators operation iterator1 iterator2)
  (lambda (function)
    (iterator1
      (lambda (x)
        (iterator2
          (lambda (y)
            (function (operation x y))))))))

;;; first class continuations allow us to step through an iterator

(define (make-step-iterator function iterator)
  (lambda (return)
    (iterator
      (lambda (x)
        (set! return
              (call-with-current-continuation
                (lambda (rest) (function x) (return rest))))))
    #!false))

(define (step-iterator iterator)
  (call-with-current-continuation
    (lambda (here)
      (iterator here))))

(define (sum-of-iterators operation iterator1 iterator2)
  (lambda (function)
    (let ((value1 '())
          (value2 '()))
      (let loop ((step1 (step-iterator
                          (make-step-iterator
                            (lambda (x) (set! value1 x))
                            iterator1)))
                 (step2 (step-iterator
                          (make-step-iterator
                            (lambda (x) (set! value2 x))
                            iterator2))))
        (cond ((and step1 step2)
               (function (operation value1 value2))
               (loop (step-iterator step1)
                     (step-iterator step2)))
              (step1 step1)
              (step2 step2)
              (else #!false))))))

(define (for-each-in-interval first last)
  (iterator-until
    (bind-1-of-2 < last)
    (primitive-iterator first 1+)
    'will-never-use-this-marker))

;;; it would also be nice
;;; to implement reduction (reduction operator was introduced by
;;; Kenneth Iverson in APL)

(define (reduce iterator)
  (lambda (function . initial-value)
    (define (add-to x)
      (set! initial-value (function initial-value x)))
    (cond (initial-value
            (set! initial-value (car initial-value))
            (iterator add-to)
            initial-value)
          (else
            (let ((marker #!false))
              (define (first-time x)
                (set! initial-value x)
                (set! marker #!true)
                (set! first-time add-to))
              (iterator (lambda (x) (first-time x)))
              (if marker initial-value (function)))))))

;;; where set! is a special form that changes a value of a binding

;;; with all that we can give a new definition of factorial

(define (factorial n)
  ((reduce (for-each-in-interval 1 n)) *))

;;; Problem

;;; what does this function do:

(define (foo n)
  ((reduce
     (compose-iterator (compose / factorial) (for-each-in-interval 0
n)))
   +))

;;; ?

;;; Problem

;;; implement a function that takes an iterator and computes a mean of
;;; elements through which iteration is done


;;; functional forms on lists

;;; <cons, car and stuff>

(define (for-each-cdr list)
  (iterator-while pair? (primitive-iterator list cdr) '()))

;;; (define for-each-cdr
;;;   (compose (bind-1-of-2 iterator-while pair?)
;;;            (bind-2-of-2 primitive-iterator cdr)))

(define (for-each-cdr! list)
  (iterator-while pair? (primitive-iterator! list cdr) '()))

(define (for-each list)
  (compose-iterator car (for-each-cdr list)))

(define (map! list)
  (lambda (function)
    ((for-each-cdr list) (lambda (x) (set-car! x (function (car x)))))))

(define (reverse-append a b)
  ((reduce (for-each a)) (T-combinator cons) b))

(define (reverse-append! a b)
  ((reduce (for-each-cdr! a))
   (lambda (x y) (set-cdr! y x) y)
   b))


(define (vector-for-each-index v)
  (for-each-in-interval 0 (-1+ (vector-length v))))

(define (vector-for-each v)
  (compose-iterator (lambda (x) (vector-ref v x))
                    (vector-for-each-index v)))

(define (vector-map! v)
  (lambda (function)
    ((vector-for-each-index v)
     (lambda (i) (vector-set! v i (function (vector-ref v i)))))))

(define (rcons pair value)
  (let ((temp (cons value '())))
    (set-cdr! pair temp)
    temp))

(define ((collect-cons iterator) function)
  (let ((header (cons 9 9))) ;9 is as good as anithing
    ((reduce iterator)
     rcons
     header)
    (cdr header)))

(define (map list)
  (collect-cons (for-each list)))

(define (list-copy list) ((map list) identity))

(define ((collect-append! iterator) function)
  (reverse!
    ((reduce iterator)
     (lambda (x y) (reverse-append! (function y) x))
     '())))

(define (map-append! list) (collect-append! (for-each list)))


(define (member-if predicate? list)
  ((iterate-until
     (compose predicate? car)
     (for-each-cdr list)
     '())
   identity))

(define (filter predicate list)
  ((collect-cons (restrict-iterator predicate (for-each list)))
   identity))

(define (filter! predicate list)
  ((collect-append! (restrict-iterator (compose predicate car)
                                       (for-each-cdr! list)))
   identity))

The library that I created (a Scheme precurser to STL) did contain:

MAKE-ACCUMULATE

Format: ((MAKE-ACCUMULATE iterator) 
           function 
           initial-value 
           structure)

Parameters: 
iterator - An iterator
function - A function of two variables.
initial-value - A value suitable as the first argument to the
function. 
structure - A structure containing values suitable as the second
argument to the function.

Explanation: Make-accumulate creates an accumulating function;
i.e., a function which accumulates the results of another
function applied to a structure. An accumulating function takes
three arguments. The first is an initial value to start the
accumulation process. This initial value is used both as a
starting value for the result to be returned and as an initial
argument to function. The second argument to an accumulating
function is a function to be applied. The third argument is a
structure to which the function is to be applied. Make-accumulate
itself takes an iterator as an argument. This describes how the
function is to be applied to the structure. Thus, the function
returned by make-accumulate is specific to the iterator and can
be called with various functions and structures. It is, of
course, necessary that the iterator be compatible with the
structure and that the function be compatible both with the
structure and initial value. Accumulate-for-each is an
accumulating function created by calling make-accumulate with the
iterator for-each.

Implementation:

(define ((make-accumulate iterator) 
           function 
           initial-value 
           structure) 
  (iterator 
    (lambda (x) 
      (set! initial-value (function initial-value x))) 
    structure) 
  initial-value) 

and

AKE-REDUCE

Format: (MAKE-REDUCE predicate reduction)

Parameters: 
predicate - A predicate which returns true iff the structure
passed to it is non-empty; e.g., if a list is not null.
reduction - A reduction operator.
function - A function of two variables.
structure - A structure.
identity - (optional argument) Result to return if the structure
is empty.

Explanation: Make-reduce creates a reduction operator which works
on empty data structures as well as non-empty ones given a
predicate which works on non-empty structures. A reduction
operator is one which applies a function to all the elements of a
structure and returns the result. It may or may not be
destructive of the structure. Make-reduce returns a function of
two arguments with an optional third argument. If the structure
is non-empty, the reduction returned by make-reduce is the same
as the reduction passed to it. If the structure is empty, the
reduction returned will return the identity argument passed to
make-reduce (if such an argument is present) or the empty list
(if no identity argument is present.) For more information, see
the description of REDUCE below.

Usage: (see the definition of REDUCE, below)

Implementation: 
 
(define ((make-reduce non-empty-predicate? non-empty-reduction) 
         operation structure . identity) 
  (cond ((non-empty-predicate? structure) 
         (non-empty-reduction operation structure)) 
        ((pair? identity) (car identity)) 
        (else (operation)))) 

and

REDUCE

Format: (REDUCE operation list)

Parameters: 
operation - A function of two variables. The function should
return a value suitable as an argument to it.
list - A list containing elements suitable as arguments to the
operation. 

Explanation: Reduce applies the operation to all elements of the
list and returns the result. The operation should be associative.
Reduce returns the empty list if called with an empty list,
regardless of what the operation itself would return if it were
called with an empty list.

Usage: (define (mag+ x y) (+ (abs x) (abs y)))  ==> mag+
       (reduce mag+ '(1 -5 -4 7))               ==> 17
       (reduce mag+ '())                                           ==>
'()
       (+)                                                         ==> 0

Implementation: 

(define reduce 
  (make-reduce 
    pair? 
    (lambda (operation list) 
      (accumulate-for-each 
         operation 
         (car list) 
         (cdr list)))) 

and

PARALLEL-REDUCE!

PAIRWISE-REDUCE!

Format: (PAIRWISE-REDUCE-NON-EMPTY-LIST! operation list)

        (PAIRWISE-REDUCE operation list)

        (PARALLEL-REDUCE operation list)
        
Parameters: 
operation - A function of two variables. The list should contain
elements suitable as arguments to this function and the function
should itself return a value suitable as an argument to itself.
The function should be associative.
list - A list, possibly empty.

Explanation: Parallel-reduce! is a reduction operation. It
applies an operation on the elements of a list in parallel in a
pairwise fashion; i.e., it applies the operation to the first two
elements in the list, then to the next two elements in the list,
etc. This leaves a list with half as many elements. Parallel-
reduce! then works on the halved list, halving its size again.
This is continued until a single element remains containing the
value to be returned. Parallel-reduce! modifies the list it is
passed and returns the result of the operation. After its
invocation, the list passed as input contains a single element
whose value is the result of applying the operation to all the
elements of the original list (or is an empty list if the
original list was empty.) On a single processor and for
operations without side-effects, parallel reduction is similar to
ordinary (sequential) reduction. However, for operations with
side effects, in particular when intermediate results are saved,
parallel reduction can give rise to much more efficient
algorithms. Pairwise-reduce! carries out one round of parallel-
reduce!, halving the list. 

Usage: (define a '(2 5 8 11 13))          ==> a
       (pairwise-reduce! - a)             ==> (-3 -3 13)
       a                                                       ==> (-3
-3 13)
       (define b '("ex" "c" "elle" "nt")) ==> b
       (parallel-reduce! string-append b) ==> "excellent"
       (car b)  


Implementation: 

(define (pairwise-reduce-non-empty-list! operation list) 
  (for-each-cdr 
    (lambda (x) 
      (when (pair? (cdr x)) 
            (set-car! x (operation (car x) (cadr x))) 
            (set-cdr! x (cddr x)))) 
    list) 
  list) 

(define pairwise-reduce! 
  (make-reduce pair? pairwise-reduce-non-empty-list!)) 

(define parallel-reduce! 
  (make-reduce 
    pair? 
    (lambda (operation list) 
      (apply-until 
        (lambda (x) (null? (cdr x))) 
        (lambda (x) 
          (pairwise-reduce-non-empty-list! operation x)) 
        list) 
      (car list))))




Lyman S. Taylor wrote:
> 
> In article <·············@mti.sgi.com>,
> Alexander Stepanov  <········@mti.sgi.com> wrote:
> >> that the STL couldn't be done in Eifel or Java.  But SML or
> >> CLOS or...you're gonna have to substantiate that one.
> 
>   I, for one, am still waiting......  "impossible" "cannot"
>   deserve some justification.
> 
> >1. Addresses.
> >
> >STL is based on the fundamental assumption that addresses are
> >good. The memory model of the C machine is the right base for the
> >abstraction. Neither Lisp nor ML allow a natural address/location
> >abstraction.
> 
>   Eh??  Admittedly Lisp nor ML allow one to point to internal structure
>   of "entities" ( i.e. you can't do arbitrary pointer manipulation).
>   However, constrained to the boundaries of "entities" what exaclty is
>   inexpressible?
> 
> 
> > You can implement address like thingies in them, but
> 
>    Oh. let's see. It acts like a adress, hence "address like".
>    So here were have  an address/location abstraction.
> 
> >the built-in data strucutres do not based on the needed abstraction.
> 
>    And what praytell stops you from layering/adding this abstraction onto the
>    built-in data structures?
> 
>    [ Remeber the postulation stipulated several messages back was that it was
>      "impossible" to do.  In my book "impossible" is a relatively strong
>       stipulation. ]
> 
> >Note that in Lisp one tends to stick to the built-in data-structures.
> >I never seen a serious impementation of a doubly-linked lists in Lisp.
> 
>   I haven't seen one... therefore it doesn't exist and therefore impossible.
>   Yeah right.  Or could it possibly be that most folks, if they need one,
>   just independently "reinvent the wheel"?  How likely is that if it isn't
>   in the "standard library"?  If the folks a Harlequin/Lucid, Franz, Symbolics,
>   etc. ( i.e. a large group of lisp programmers with some legacy of code
>   behind them.. ) chime in and say there is NO doubly-linked lists in any
>   of their code... then I might fell inclined revisit this argument.
> 
> 
> >as I know, the same holds true for SML. Arrays and lists can not
> >be easily unified. Or at least, they are not usually unified.
> >Take a look at list->vector, vector->list pair in Scheme and compare it
> >with generic constructor in STL containers.
> 
>     And if you added a generic constructor abstraction in Common Lisp utilizing
>     macros you couldn't get the STL functionality??
> 
>     I asked this before and didn't really get a response. So I'll rephrase it.
>     C++ templates are essentailly "syntactic sugar".  There's little templates
>     do that a programmer couldn't do by just typing approximately the same
>     code over and over again. Fortunately the C++ compiler does some
>     bookkeeping for him/her and does alot of code writing and substitution
>     "automagically".
> 
>     Likewise the macro system of Common Lisp can be used to add "syntactic
>     sugar" to Common Lisp code.  It can be used to do bookeeping (i.e. execute
>     arbitrary pieces of code at compile time) in conjunction with writing
>     code.
> 
>     So what stops a STL-like implementor from
>                 i. adding a template-like mechanism to "raw" CL.
>                 ii. implementing the STL using this mechanism.
> 
>     [ Again discounting compile time checks on "correctness" of the code
>       given that Common Lisp is a dynamic language and isn't overly pressed
>       about static type checking.  ]  While not a CL macro "guru", offhand
>     I do not see what the "show stopper" is in implementing this.
> 
>     Code refering to these generic may have to be incased in macro body but
>     that seems about as "different"/"onerous" as suffixing "<data_type>" after
>     STL type/function references.
> 
>     [ throw in the use of CLOS for overloading function names and I definately
>       do not.]
> 
>     Something along the lines of....
> 
>     (with-generics ( (generic-type1 param )
>                      (generic-type2 param param )
>                      ( (generic-fcn1  (generic-arg param )
>                                      (generic-arg param )  param param ) )
>                      ( (generic-fcn2  (generic-arg param param) param ) ))
> 
>         ;; if pressed about speed.. some declarations..
>         (declare (..... (var10  generic-type1 )  (var11 generic-type2) ... ))
> 
> 
>           ...  (generic-fcn1   var10  (generic-fcn2 var11 ) .... ) ...  )
> 
>     the macroexpansion of the above could be just as name-mangled as anything
>     a C++ compilier might generate... ;-)
> 
>     [ I'm not too familiar with Scheme macros to affirm/discount there
>         ability to do this task. I wouldn't dismiss it though. ]
> 
>     In Essence, in the case of lisp I think that if it is syntactic sugar
>     you are in seach of, then you criticism should appeal to the deficiencies
>     of the syntactic sugar making capabilities of the language.  Otherwise
>     this debate is "stuck on 'stupid' and not getting off".
> 
> >One of the things I am trying to do now is to extend the iterator
> >classification to handle non-uniform memory references. (One of
> >my collegues, Fred Chow, proposes to call them NUMA-iterators.) It is
> >quite remarkable how the existing STL framework could be extended to
> >deal with MP, cache behaviour, parallelism. But it all relies on
> >addresses. Abstract addresses, but addresses nevertheless.
> >
> >2. Container vs. iterator
> >
> >Lisp also brought a conceptual confusion of list as an iterator and list
> >as a data structure. There is no way to distiguish between the two uses.
> >It is a subtle point, but I am sure you can see it.
> 
>   Errr, you seemed to have lost me on this one...
> 
>    C/C++                                        Lisp
> 
>    int a[4] = { 1, 2, 3, 4};
>    int *p = a;                                 (setf p '( 1 2 3 4 ))
> 
>    printf("%d \n", *p);                        (format t "%d ~%" (first  p ))
>    p = p + 1 ;                                 (setf p (rest p))
>    printf("%d \n", *p):                        (format t "%d ~%" (first p ))
> 
>   Exactly what is the subtle difference in the way C/C++ treats "p"
>   and how Lisp treats "p"?
> 
> >3. Type system
> >
> >It is possible to define swap in C++. And you can use partial
> >specialization to choose the right swap.
> 
>   The unstated implication that in Scheme/Common Lisp you cannot
>   define swap?????    Surely you jest....
> 
>   for CL see ( slightly more than the same functionality..)
> 
> http://www.harlequin.com/books/HyperSpec/Body/mac_rotatef.html#rotatef
> 
> >I do not know any other language where I can easily say:
> 
>   [ template reduce code deleted... ]
> 
> >3. The default identity element of plus is 0
> 
>   Oh like
>                 (+) ==> 0
> 
> >4. The default identity element of multiply is 1
> 
>   Oh like
>                 (*) ==> 1
> 
> >
> >Now, take Common Lisp reduce. It is not generic. (If you define your own
> >doubly linked list, their reduce is not going to do anything reasonable
> >for it.) It is hard making it generic, or they would have done it.
> 
> 
>    This is akin to saying C++ isn't good because printf isn't generic
>    enough...
> 
>    1. In Common Lisp reduce is a function.  So yeah it is a tad difficult to
>         expand to other datastructures.  You can't overload the name ( actually
>         not quite true but could involve implementation dependent gyrations)
>        It has also been around "forever" too.
> 
> http://www.harlequin.com/books/HyperSpec/Body/fun_reduce.html#reduce
> 
>       However, I'm going to use a simplified argument list that matches
>       the reduce that is there..
> 
>       (defgeneric my-reduce  ( fcn seq )  )
> 
>       ;; if just any prefdefined sequence and a function...
>       (defmethod  my-reduce  ( (fcn function) (seq sequence ) )
>         (reduce fcn seq ))
> 
>       (defmethod  my-reduce  ( (fcn function) (seq T ) )
>         ... here define insanely great generic algorithm to
>             do reduce....  )
> 
>       (defmethod my-reduce   ( (fcn function) (seq whiz-bang) )
>          ... here define even more insanely great generic alogirtm
>              to do reduce specialized for the whiz-bang data structure)
> 
>     [ NOTE:  I could if I made explicit the full lambda list...
>                 i.  assign the current REDUCE to a new symbol.
>                       OLD-REDUCE ( so I could use the predefined code).
> 
>                 ii. define my defgeneric on the name REDUCE.
>                         and say yes the warning message "do you really want
>                         do this, I'm about to redefine reduce as a generic
>                         function and potentiall blow away the previous
>                         definition".
>                 iii. define my new reduce with the same name, but old
>                         argument set-up.   Albeit for slightly slower
>                         overall performance... since now a generic function
>                         instead of a function.      ]
> 
>    2. The default reduction function for reduce is + ... Gee that's gotta
>              be hard to do in Lisp, huh??? :-)
> 
>       If the lambda list for reduce looked list STL's would this be
>         "impossible".
> 
>        (defgeneric stl-reduce ( begin-iter  end-iter
>                                   &optional (fcn function stl-plus)) )
> 
>         [ again + is a function in CL. If you want to overload with abandon
>                 you'll need your own name. ]
> 
>        (defmethod  stl-reduce ( (being-iter iterator) (end-iter iterator)
>                                   &optional (fcn function stl-plus ))
>           .... insanely great generic stl-reduce code goes here... )
> 
>        .....
> 
> --
> Lyman S. Taylor           Comment by a professor observing two students
> (·····@cc.gatech.edu)     unconscious at their keyboards:
>                                 "That's the trouble with graduate students.
>                                  Every couple of days, they fall asleep."

-- 
Alexander Stepanov
········@mti.sgi.com

Silicon Graphics
2011 N. Shorline Boulevard
Mountain View, CA 94043-1389

tel.: (415)933-6121
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <s6y7mhamsqp.fsf@aalh02.alcatel.com.au>
Alexander Stepanov <········@mti.sgi.com> writes:

> > This is the claim I reject.  It doesn't surprise me at all
> > that the STL couldn't be done in Eifel or Java.  But SML or
> > CLOS or...you're gonna have to substantiate that one.
> 
> 1. Addresses.
> 
> STL is based on the fundamental assumption that addresses are
> good. The memory model of the C machine is the right base for the
> abstraction. Neither Lisp nor ML allow a natural address/location
> abstraction. 

I'm really confused about this statement. How does a reference to a
Lisp object differ to a pointer to a C++ object. I just can't see what
the distinction is.

> You can implement address like thingies in them, but
> the built-in data strucutres do not based on the needed abstraction.

Huh? STL was not built using the "built-in data structures" of
C++. STL *IS* a collection of data structures. 

The question is, could you write some CLOS sets, vectors, lists, and a
set of algorithms that work over all of them.

> Note that in Lisp one tends to stick to the built-in data-structures. 
> I never seen a serious impementation of a doubly-linked lists in Lisp. 

I had never seen an implementation of doubly linked lists in C++
either until I actually went to the trouble of writing my own.

> (Yes, yes, I had done one myself too, but it was not serious.) As far
> as I know, the same holds true for SML. Arrays and lists can not
> be easily unified. Or at least, they are not usually unified.

Surely we are discussing what can be done, rather than what is usually
done? Arrays and lists in C++ were never unified until STL came along
right?

> 2. Container vs. iterator
> 
> Lisp also brought a conceptual confusion of list as an iterator and list
> as a data structure. There is no way to distiguish between the two uses.

Well, that is only one way of using lisp. You can do the same in C++
if you want.

> It is a subtle point, but I am sure you can see it. It also makes it
> impossible to have an ownership or whole-part semantics for data
> structures and makes it impossible to survive without
> garbage collection. (I like garbage collection as an option, but
> Lisp and ML make a virtue out of necessity.)

Well certainly no functional language could survive without GC. 

Hey, if you admit it's a necessity, it might as well be a virtue eh?
 
> 3. Type system
> 
> It is possible to define swap in C++. And you can use partial
> specialization to choose the right swap. 

<snip>

Well I didn't think this was a debate about static vs dynamic
typing. Of course, implementing swap in lisp is even more trivial than
C++, although most lispers consider assignment (which swap is a form
of), unnecessary and bad style.

> And you should see amazing things you can do with types using
> partial specialization. (Look at the description of iterator_traits
> in the standard.) It is very easy to specify very complicated
> relations among type categories.

A static typing argument, which I don't want to get into.

(Of course it's easy to use the type system in CLOS to do
specialisation as well, and IMHO much more powerful as well.)
 
> It is so easy to use the type system to carry semantic information
> and to use types for selecting correct algorithms. 

Same goes for CLOS.

> Note, that if I want to add a bunch of doubles I just say:
> 
> vector<double> v;
> 
> // fill v with doubles
> 
> cout << reduce(v.begin(), v.end());
> 
> // now print the product:
> 
> cout << reduce(v.begin(), v.end(), multiply<double>());

Yes, nice but easier in CLOS. Following is an implementation of reduce
in Scheme. To make it do what you want in CLOS to work on generic
types, all one has to do is to substitute "car" "cdr" and "null?" for
some suitable iterator generic functions, with suitable data structure
iterators which define these generic features. You would probably pass
an iterator rather than the data structure itself.

BTW, you'll also notice that the Lisp version is something that your
average programmer would actually write in real life. All that STL
code you wrote, while terribly clever, is probably too complex for
your average programmer to go to the effort of writing in real life.

First up, the list only version...

(define (reduce op list)
  (if (null? (cdr list))
	  (car list)
	  (op (car list) (reduce op (cdr list)))))

(define v (make-vector))

;; fill with doubles

(reduce + v)

;; now print the product:

(reduce * v)

Now to make it work with different data structures... you would
probably have data structures have a method called "get-iterator" or
something and the code would look something like:

(define (reduce op iter)
  (if (at-end? iter)
	  (obj iter)
	  (op (next iter) (reduce op (next iter)))))

(define v (make-vector))

;; fill with doubles

(reduce + (get-iterator v))

Still very easy to write. Much easier than C++.

> I do not need to pass ++, *, ==, = for iterators as our ML experts
> suggest that we do. Types are good. Compiler will find the right
> operations.

Not passing iter methods is easy to achieve in all OO languages I
think, including eiffel.

> And if tomorrow I put my doubles into a set (does SML have sets?),
> I can just say:
> 
> set<double> v;
> 
> // fill v with doubles
> 
> cout << reduce(v.begin(), v.end());

Just a result of having nice consistent data structures and iterators.

> Now, take Common Lisp reduce. It is not generic. (If you define your own
> doubly linked list, their reduce is not going to do anything reasonable
> for it.) It is hard making it generic, or they would have done it.

I'm not expert in CL, so I havn't really used it's version of
reduce. I suppose it only works for lists, but there is nothing
stopping you writing a set of consistent data structures with a reduce
function that works over all of them.
 
>SML and CLOS? I do not think so. 

While it is common in lisp to do most of your work with lists, I can't
see why that is a problem with the language. Perhaps it is just time
you implemented STL in Lisp.
From: M. Prasad
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3371D642.3A5B@polaroid.com>
Chris Bitmead uid(x22068) wrote:

[snip]
> C++, although most lispers consider assignment (which swap is a form
> of), unnecessary and bad style.

This is theory (promulgated by advocates of "Functional
Programming",) but in practice, I doubt any large
scale production quality Lisp code exists which does
not use assignment.  For large and complicated
multiple-module tasks, it is simply not practical to live
with this rule, though it is good for small textbook
examples.  (Of course, I would be very interested in
counter-examples if they exist and comments on how it
was done, what was the experience like...)
From: Jeffrey Mark Siskind
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <xohzpu52465.fsf@ai.emba.uvm.edu>
To: ·······@polaroid.com
Subject: Re: C++ briar patch (Was: Object IDs are bad)
References: <·············@nospam.acm.org> <··········@research.att.com>
	<·············@nospam.acm.org> <··········@research.att.com>
	<················@naggum.no> <·············@mti.sgi.com>
	<····················@connectnet1.connectnet.com>
	<···············@isolde.mti.sgi.com> <·············@mti.sgi.com>
	<·············@nospam.acm.org> <·············@mti.sgi.com>
	<···············@aalh02.alcatel.com.au> <·············@polaroid.com>
--text follows this line--
"M. Prasad" <·······@polaroid.com> writes:

> Chris Bitmead uid(x22068) wrote:
> 
> [snip]
> > C++, although most lispers consider assignment (which swap is a form
> > of), unnecessary and bad style.
> 
> This is theory (promulgated by advocates of "Functional
> Programming",) but in practice, I doubt any large
> scale production quality Lisp code exists which does
> not use assignment.  For large and complicated
> multiple-module tasks, it is simply not practical to live
> with this rule, though it is good for small textbook
> examples.  (Of course, I would be very interested in
> counter-examples if they exist and comments on how it
> was done, what was the experience like...)

Back in 1981, my colleagues Ken Crouch and Jay Southard and I wrote MacPitts,
a silicon compiler that took behavioural system descriptions as input and
produced full-custom VLSI layouts as output. MacPitts was about 50,000 lines
of Franz-Lisp code. It was written in a purely functional style. On a VAX
11/750, with 8M of memory, running 4.1 BSD, it could compile a four-page
description of a 32-bit microprocessor to a layout with 10,000 transistors, in
about 4 hours.

    Jeff (home page http://www.emba.uvm.edu/~qobi)
From: Lyman S. Taylor
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kterj$foa@pravda.cc.gatech.edu>
In article <···············@aalh02.alcatel.com.au>,
Chris Bitmead uid(x22068) <·············@alcatel.com.au> wrote:
>
>I'm not expert in CL, so I havn't really used it's version of
>reduce. I suppose it only works for lists, but there is nothing

   Actually it works on any of the "built-in" sequences.  But isn't
   exactly the epitome generic design either. It's largely crafted to
   work well with the math ops and correct input. :-) 
   The "identity" value must be embedded in the function applied ...
   ( the  STL does decouple these... ) And admittedly some of the 
   hackery in the string-accum function wouldn't be needed if the
   initial accumulation value was the identity value... i.e. application
   to a list of 1 is special cased to just return the original single
   element,  kind of "penny wise and pound foolish". [ only in the
   default behaviour though. go figure.. ] 


(defun integer-accum (&rest args ) 
  "add up the value of the numeric values of the arguments." 
  (print args ) 
  (if args 
      (+ (first args ) (second args ))
      0))

(defun string-accum (&rest args )
  "add up the value of the integer values of the arguments. 
   NOTE: The first pair will be two characters. After that it will be
         the sum so far and character." 
   (print args )
   (if args
       (+ (if (typep (first args ) 'number)   
              (first args)
              (char-int (first args)))
              (char-int (second args)))
       0))

 
 (reduce #'integer-accum   '( 1 2 3 4)) ==> 10    ;; list of ints 
 (reduce #'integer-accum   '()          ==> 0 
 (reduce #'integer-accum  '#(1 2 3 4))  ==> 10    ;; vector of ints
 (reduce #'string-accum     "defh")  ==> 510      ;; a string 
 (reduce #'string-accum     "")      ==> 0        ;; the empty string
 ;; dubious examples
 (reduce #'+ '( "hello world" )) ==>  "hello world" 

 (reduce #'string-accum "a" )    ==>  #\a   
 (reduce #'string-acum  "a" :intial-value 0 ) ==> 97
 

http://www.harlequin.com/books/HyperSpec/Body/fun_reduce.html#reduce

[although, all the examples in the above use lists... ditto on Steele's CLtL2] 


 
 
-- 
Lyman S. Taylor           Comment by a professor observing two students 
(·····@cc.gatech.edu)     unconscious at their keyboards:
				"That's the trouble with graduate students.
				 Every couple of days, they fall asleep."
From: Eli Barzilay
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <33718C00.34DD@cs.cornell.edu>
Whow, man - now you got me - please don't insult Lisp if you havn't used
it
(and reading your mail I see that you DON'T know it too good).

So we have C and we have C++, this is the same as Lisp and CLOS - saying
that
the Lisp reduce function is not generic is very true - it works only for
Lisp
lists - but try doing something similar with C - where you don't even
have any
container primitive data structure except for arrays.

So the rules should be that if you use C++ to show how beautiful it is -
then
you must let me use CLOS for the same thing!  And here is a possible
translation of what you've shown in Lisp using CLOS (not that I think
that
this is the best way of doing this -- you do have some questionable
points in
your code).  This is based on some definitions for the "iter" class, and
the
operation class with plus as an instance.

;;; 1. Normally, reduce returns an identity element of its operation.
;;; 2. The default operation of reduce is plus.

(defmethod GREDUCE ((first iter) (last iter) &optional (op plus))
  (if (iter-equal first last)
    (identity-element op)
    (let ((result (iter-value first)))
      (loop while (not (iter-equal (advance first) last))
            do (setf result (apply-op op result (iter-value first))))
      result)))

;;; 3. The default identity element of plus is 0

(defmethod IDENTITY-ELEMENT ((op plus-op))
  0)

;;; 4. The default identity element of multiply is 1

(defmethod IDENTITY-ELEMENT ((op multiply-op))
  1)

;;; add a bunch of doubles - based on implementation for a vect class

(let ((v (make-instance 'vect)))
  ;; fill v with doubles
  (print-object (greduce (get-first v) (get-last v)) t)
  ;; now print the product:
  (print-object (greduce (get-first v) (get-last v) multiply) t)
  )

;; And if tomorrow I put my doubles into a set

(let ((v (make-instance 'set)))
  ;; fill v with doubles
  (print-object (greduce (get-first v) (get-last v)) t)
  ;; now print the product:
  (print-object (greduce (get-first v) (get-last v) multiply) t)
  )

;; And if, tomorrow, you define sets that use skip lists you just do

(let ((v (make-instance 'skip-set)))
  ;; fill v with doubles
  (print-object (greduce (get-first v) (get-last v)) t)
  ;; now print the product:
  (print-object (greduce (get-first v) (get-last v) multiply) t)
  )


Now I'm sure that you will see something up there and say that this is
not
what you need, or I didnt make something, etc.  Just remember that
modifying
the above for any kind of behavior you want is VERY easy.  So will be an
implementation for the container classes and iterator - and guess what -
I can
even do that with DOUBLY-LINKED list implementation (I guess that using
two
pointers and really using them will mean that this will be a `serious'
implementation?)

-- 
                                                                  Eli
Barzilay:
                                                                  Maze
is Life!
From: Alexander Stepanov
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <33728FD4.4287@mti.sgi.com>
Eli Barzilay wrote:
> 
> Whow, man - now you got me - please don't insult Lisp if you havn't 
> used it (and reading your mail I see that you DON'T know it too good).
> 

This seems to be a common sentiment. I keep getting little Lisp, Scheme,
and SML programs showing my amazing ignorance.

It is, however, unlikely to effect me. You see, I tried. I used
Symbolics, I used Common Lisp, I taught a course on implementing Common
Lisp. I implemented THE LOOP macro. (As a matter of fact, I probably
impemented every single macro in Common Lisp - I am looking for my
lecture notes from my CL class, but cannot find them yet.) I know what
locatives were. I do know about SETF. I read the lambda papers in the
seventies. I read a very large portion of MIT Scheme code - and forced
many innocent students to do the same. (As a matter of fact, my last
large project in Scheme - a VLIW simulator - was done in 1994.) While I
never seriously programmed in ML, I did seriously read one ML book and
many ML papers. One possible explanation is that I am just stupid and
cannot appreciate the thing of beauty.

If you are satisfied with this explanation, STOP READING NOW, and,
please, please, do not send me mail expressing you opinion about my
mental abilities and moral qualities of my ancestors.

There some of you, who express genuine interest and I would try to
explain some of my points. What follows is a sort of an Apologia pro
vita sua. It is rumbling and unclear, but it is difficult to explain the
motivations of a lifetime of research, especially when one is lead to
conclusions contrary to the accepted academic wisdom. 

I started working on what I now call generic programming in the mid
seventies. I was thinking about parallelizing transformations of simple
loops, summation for example. a + (b + (c + d)) = (a + b) + (c + d). I
noticed that this transformation depended on the associativity of +. I
concluded that this transformation is affiliated with an algebraic
theory of semigroups. The natural conclusion was that it is important to
be able to express in the programming language tha fact that certain
operations are associative. While it is true that any reasonable
compiler knows about associativity of + for built-in types, it is
impossible to inform it that other operations, say max, are associative,
and it is impossible to express properties of even + for non-built in
types, quaternions for example. At the same time I noticed that
transforming sequential reduction to parallel reduction makes sense even
for sequential computations. For example, it is always better to merge
four lists of the same size with the parallel reduction than with the
left-most reduction. And then, to my great surprise, I realized that
while it is true for merge, it is not true in general. For example,
parallel reduction does not help at all if you multiply many polynomials
After a while, I discovered that the same operations benefit from
parallel reduction as benefit from Russian peasant algorithm for power
and the other way around. Both reduction and power are associated with
the same theory of monoids and the algorithmic selection for both
depends on complexity properties of the monoid operation. It took me a
while to realize that the property in question is a simple bilinear
inequality for the cost function.

So by 1980, I realized that there is a natural way to describe
algorithms in terms of multisorted algebras with complexity requirements
associated with them. One of the difficulties of explaining what I
wanted to do to other people was the fact that algorithms people did not
want to hear about multisorted algebras, multisorted algebras people did
not want to hear about adding non-algebraic complexity axioms and
clearly wanted to leave Russian peasant algorithms to Russian peasants.
(As one of my good friends, who is a very multisorted person, says, -
Knuth is just hacking.)

When John Backus made his famous Turing award speech, I saw the light. I
decided that I had to combine my ideas about associating operations with
semantical and complexity properties with FFP. I realized that Backus
was somewhat mistaken when he tried to restrict the number of functional
forms, but I tried to express a large body of algorithms in FFP-like
form. I spent several years trying to represent heaps, or to do Prim's
algorithm in a functional way. At some point it became clear to me that
I was doing something quite silly. I saw that addresses were good. There
are different theories of address operations that allow me to group
algorithms together and express them in the most abstract form. I saw
that data structures are models of different address algebras. I saw
that I can use morphisms of these address operations as a way to provide
an encapsulation of different traversal methods. I would say that by
1984 I had a fairly good idea of the taxonomy of different software
components. The only thing that I needed was a programming language to
express my ideas. 

Let us see what I wanted to say. I wanted a language that would allow me
to write programs in terms of what I call a concept. There are two ways
of describing what a concept is. First, model theoretic, namely, a
concept is a set of types with similar interfaces. (The notion of
"similar" is actually quite lax. It is a free combination of structural
and named equivalence for signature groups.) Second, proof theoretic
(or, more exactly, code theoretic), a concept is a collection of all the
valid and efficient programs written in terms of it.

I needed types to hang semantical and complexity information onto. I
needed overloading, to be able to use different algorithms on different
subtheories. I became more and more convinced that an address is a
fundamental component kind. I found Lisp more and more inadequate from a
very metaphysical point of view. It equates an object and its address. I
wanted to be able to talk about address as quite different than the
object it names. ( I knew that: "A name means an object. The object is
its meaning." Wittgenstein, Tractatus 3.203, but I wanted "meaning",
"denotation" to be an explicit function since I wanted to define it
differently for different models of the same address concept.) I also
came to the realization that I wanted a language with copy and equality
defined quite differently from Lisp. That is, I realized that I could
build a very useful theory of containers (data strucutres with
ownership) based on a philosophically sound notion of whole and part;
something along the lines of:

1.If two objects share a part, then one object is a part of the other
(no sharing, objects are disjoint).

2. No circularity among objects - an object cannot be a part of itself
and, therefore, cannot be part of any of its parts.

3. When an object is destroyed all its parts are destroyed.

4. Two objects are equal iff their essential parts are equal.


And then in 1987 I discovered C. That is, I discovered C++, but the part
that I was really impressed was C. C treatment of pointers and the
semantics of built-in types were much closer to my theory than anything
I have seen before. There were some big disappointments - the language
did not provide == operator for structs and my theory demanded that
	T x = y; assert(x == y);

Unfortunately, at that point C++ was not at all usable. It took me
several years to discover the reasons why I could not use inheritance.
But I got really impressed with the underlying C machine and with the
way Bjarne added function and operator overloading, and with the notions
of copy constructor and desctructor. (I do not, of course, like the fact
that they are member functions. I could do really better things if they
could be globally defined and templatized.)

And then Bjarne added templates. I was quite astonsihed with what I
could do with them. I could express very complex relations between
concepts, I could carry a lot of information with types. Aren't C++
templates just glorified macros? I do not thing so. I think that they
are very powerful type generating mechanisms. The ability to nest
templates together with partial specialization allowed me to express a
complex relations between types.

Is C++ pefect for generic programming? No. After all, the central things
for this style of programming is a notion of concept. Things like input
iterator. You cannot express them in C++. STL relies very havily on
extra-linguistic specifications. While I do like C model of memory very
much, it is too specific. I do believe that parameterization by memory
models, different pointer types if you like, is very important. There
are hundreds of little glitches. But it is much better than anything
else I know of for expressing what I have been trying to express. 




-- 
Alexander Stepanov
········@mti.sgi.com

Silicon Graphics
2011 N. Shorline Boulevard
Mountain View, CA 94043-1389

tel.: (415)933-6121
From: M. Prasad
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <33731627.7FCD@polaroid.com>
Alexander Stepanov wrote:
> 
> Eli Barzilay wrote:
> >
> > Whow, man - now you got me - please don't insult Lisp if you havn't
> > used it (and reading your mail I see that you DON'T know it too good).
> >
> 
> This seems to be a common sentiment. I keep getting little Lisp, Scheme,
> and SML programs showing my amazing ignorance.
> 

Please ignore the nuts...

I see from one of your earlier messages that
you were also disappointed with CLU.  Did you
find the template features in CLU inadquate,
or was it the treatment of object equality/similarity?
One would think the built-in iterator concepts would
make generic programming for data structures easier?
Did this turn out not to be the case in your
experimentation?
From: Alexander Stepanov
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3373E0DB.3359@mti.sgi.com>
M. Prasad wrote:
> 
> Alexander Stepanov wrote:
> >
> > Eli Barzilay wrote:
> > >
> > > Whow, man - now you got me - please don't insult Lisp if you havn't
> > > used it (and reading your mail I see that you DON'T know it too good).
> > >
> >
> > This seems to be a common sentiment. I keep getting little Lisp, Scheme,
> > and SML programs showing my amazing ignorance.
> >
> 
> Please ignore the nuts...
> 
> I see from one of your earlier messages that
> you were also disappointed with CLU.  Did you
> find the template features in CLU inadquate,
> or was it the treatment of object equality/similarity?

You got it just right. CLU has Ada like genericity. You have to
do explicit instantiation. But the second one is much more
important. CLU has a Lisp-like machine model. (See my recent
post in comp.lang.scheme where I tried to explain the machine
model aspects of why I stopped using Lisp.)

> One would think the built-in iterator concepts would
> make generic programming for data structures easier?

No. You see, iterators in STL are a much more elaborate
things than iterators in CLU or series in Common Lisp.
It did take me a long time to figure out a semantic 
difference between input iterators and forward iterators,
and to see the algorithmic classes that require one or the
other. (One-pass, one-direcitonal vs. Multi-pass,
one-direcitonal.) But I did learn a from CLU. It helped me to
realize the importance of types. I am also indebted to Barbara
for the initial explanation why inheritance is weaker than
genericity. My understanding did develop since that time (1987,
if I remember correctly), but she did a remarkable job,
explaining it to me while riding in a car from Newark airport to
Bell Labs. Her explanation did save me years.

I did learn from OBJ work of Goguen and Meseguer. But I
couldn't do STL in OBJ 3 or FOOPS or MOD.

The only language from which I did not learn anything is Java. I
spent 6 months writing code in it and came back empty handed.
Again, I am not saying that there is nothing marvelous in Java,
but only that I personally did not get any insights. I clearly
failed in my task to do STL in Java, but you should realize that
there are at least 3 different implementations of STL in Java,
and one of them (JGL) is, I was told, shipped with Microsoft
Java product. So, when I say that it is not possible, I clearly
have different criteria than Microsoft. The same is true in
Scheme. There are pieces of code in STL which are just
translations of my very old Scheme code. And I could clearly 
translate the entire STL into Scheme - after all, I did build
an architecture simulator in Scheme and if I can simulate a
modern VLIW computer, I clearly can simulate an abstract C
machine. 

So, restating my point again, I was looking for a certain
abstract machine model. The model for which I had been looking
happened to be an abstraction of an existing C/C++ machine model
and quite different from Lisp/CLU machine model.  When I found
it, I was exceedingly happy. That is, I was not starting from
C++, but from some rather philosophical set of requirements. 
(As an amusing aside: my project on generic programming at
General Electric Research was terminated after a new lab manager
attended my talk on logic of whole/parts; he put it quite
nicely: General Electric does not need philosophers.) 

> Did this turn out not to be the case in your
> experimentation?

-- 
Alexander Stepanov
········@mti.sgi.com

Silicon Graphics
2011 N. Shorline Boulevard
Mountain View, CA 94043-1389

tel.: (415)933-6121
From: Thant Tessman
Subject: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <3374B0B9.41C6@nospam.acm.org>
Alexander Stepanov wrote:

> [...]  But I did learn a from CLU. It helped me to
> realize the importance of types. I am also indebted to Barbara
> for the initial explanation why inheritance is weaker than
> genericity.  [...]


(If the following starts out stating the obvious, bare with me.
There's an important point I want to make.)

A type "B" is a subtype of "A" if an instance of "B" can be used 
any place an instance of "A" is expected.  One way to acieve this 
in practice is to make "B" inherit from "A".  But this is only one 
way, and a very limited way at that.  A much more powerful way to 
get subtyping polymorphism is to use CLOS-style generic functions.  

(The ambiguous use of the word "generic" is unfortunate.  
Disclaimer: I've never used CLOS itself, but I've used and 
even built systems inspired by it.  When I say CLOS-style 
genericity, I'm just distinguishing it from Ada-style 
genericity.  (I've never used Ada either.))  

One way to think of generic functions is as a set of different
functions all with the same name, but each taking a different
number and type of arguments.  (The "+" operator is an 
obvious example in that in many languages the "+" operator 
works on both integers and floating-point values.)

The difference between overloaded functions in C++ and generic 
functions in CLOS is that generic functions dispatch dynamically
--that is, the correct version of the function is selected while 
the program is running based on the run-time argument types.

This ability to dispatch dynamically is extremely powerful.
And in fact the whole point of virtual member functions in 
C++ is to provide the ability to select an object's member 
function at run-time based on the object's "real" type as 
opposed to its "base" type.

So CLOS generic functions can be thought of as virtual member 
functions, but on the 'outside' of the object, and with the 
object being the first argument to the function.  And instead
of dispatching merely on the object (i.e. the first argument),
generic functions take into account the types of *all* the 
arguments.

Now remember that the important point is not "inheritance" but
"subtyping".  And in fact, C++ provides *two* mechanisms 
for achieving subtyping.  Inheritance is only the first 
mechanism.  The second mechanism is (hold your breath)
TEMPLATE PARTIAL SPECIALIZATION which is NOTHING MORE than
statically-typed CLOS-style generic functions.

If I were asked to characterize the difference between object
oriented languages and functional languages in the broadest
terms possible, I would say that object oriented languages
emphasize subtyping polymorphism and functional languages
emphasize generic polymorphism.

Having lived in both worlds, I think both kinds of polymorphism 
are important, and my ideal language would have both (but I think
combining them is hard to do well in a statically-typed language).

More significantly, I think that higher-order functions (although 
more associated with functional languages) are an orthogonal concept 
to polymorphism and in fact supercede both in importance.  This is 
why I think SML is far more expressive than C++ despite SML's lack of 
subtyping polymorphism (which I mentioned way way back at the 
beginning of this thread).

(As for this abstract machine model of Stepanov's, its relationship
to genericity escapes me, leaving his original flame-inducing 
claims still unaddressed.)

-thant
From: Charles Fiterman
Subject: Inheritance versus reflexivity.
Date: 
Message-ID: <EA2q2y.HCq@midway.uchicago.edu>
Objects are described by classes and one very useful way to build
classes in inheritance. Given class point give me colored_point which
differs from point by adding a field and some methods. Another way
is generics. Given class point give me integer_point which differs
from point in that position must be integer.

But there are lots of ways to specify classes. Suppose you want to
build a new class like an old class except it keeps the time-stamp
of its last modification. Thats not inheritance or generics but
its very systematic. If you can read a class definition and write
one you can have a function that produces time stamped classes
out of non time stamped classes.

Consider a property I call is_transaction. If a function has this
property it either completes leaving side effects or has an exception
and leaves no side effects. Giving this property to functions is 
cumbersome and they can become broken by program changes on other
functions that they use indirectly.

But if functions are objects and you can read and write them you
can have a function make_transaction that reads a function and
writes a function having the desired property. You can apply a
function to a class and give all its methods the desired property.

As useful as inheritance is it should only be regarded as one
way of building class descriptions.

This also demonstrates that building class herarchies doesn't
always proceed by adding subclasses and new root classes. A
class built by make_transaction is more general than the 
input class and should be its superclass. Or it may replace
it on the herarchy because the other class was never meant
for any use but as input to make_transaction. Further this
shows classes may not need names just like functions.
From: Chris Bitmead uid(x22068)
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <s6yn2pymvn9.fsf@aalh02.alcatel.com.au>
Thant Tessman <·····@nospam.acm.org> writes:

> Now remember that the important point is not "inheritance" but
> "subtyping".  And in fact, C++ provides *two* mechanisms 
> for achieving subtyping.  Inheritance is only the first 
> mechanism.  The second mechanism is (hold your breath)
> TEMPLATE PARTIAL SPECIALIZATION which is NOTHING MORE than
> statically-typed CLOS-style generic functions.

You're dead right. You don't need inheritance to have OO or
polymorphism. It so happens that inheritance models a common pattern
of using polymorphism, but generic functions are a much more
generalised and therefore more powerful concept than the subset
thereof which is C++ style inheritance.

It's also much cleaner and easier to use CLOS style generic functions
as a replacement for C++ style templates, although I can appreciate
that templates are always done statically. (Although I can only wonder
what would happen if the same amount of money spent on developing C++
compilers were spent on optimising Lisp compilers, if most of these
could be compiled staticly in CLOS anyway.)
 
> (As for this abstract machine model of Stepanov's, its relationship
> to genericity escapes me, leaving his original flame-inducing 
> claims still unaddressed.)

It escapes me so far too. I'm hoping he will try explaining what he
means further.
From: Bjarne Stroustrup
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <EA68MJ.L4t@research.att.com>
·············@alcatel.com.au (Chris Bitmead uid(x22068)) writes:

 > It's also much cleaner and easier to use CLOS style generic functions
 > as a replacement for C++ style templates, although I can appreciate
 > that templates are always done statically. (Although I can only wonder
 > what would happen if the same amount of money spent on developing C++
 > compilers were spent on optimising Lisp compilers, if most of these
 > could be compiled staticly in CLOS anyway.)

Given the time that Lisp has been around (and CLOS), and given the number
of organizations that has been involved in Lisp-related research, I do not
think that it is obvious that more money has been spent on C++ compilers.
I suspect that it is not the case.

One problem with C++ is exactly that the PC compiler suppliers spends FAR
more on windows-related GUI flash than on their compilers (i.e. on the part
of the software development environment that is devoted to getting the source
text correctly translated into efficient object code).

	- Bjarne

Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html
From: Alasdair Johnson
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <01bc6082$2215cbc0$58148d82@ayj>
>windows-related GUI flash

This seems to imply that GUI building is not important? I wish Microsoft
for one would spend *more* time on this issue, not less. Object oriented
language should speed development time & in windows this means doing things
visually!

BTW Do you think that Borland (or Microsoft) could have done C++ Builder
(ie a visual-component based tool) with standard (draft ANSI) C++?

-- 
Get PR-Tracker -- tracks problem reports, defects, bugs
INFORMATION:  http://www.halcyon.com/softwise/prtracker.html
DOWNLOAD:     http://www.halcyon.com/softwise/download.html
From: Chris Bitmead uid(x22068)
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <BITMEADC.97May15121720@Alcatel.com.au>
In article <··········@research.att.com> ··@research.att.com (Bjarne Stroustrup) writes:

> > It's also much cleaner and easier to use CLOS style generic functions
> > as a replacement for C++ style templates, although I can appreciate
> > that templates are always done statically. (Although I can only wonder
> > what would happen if the same amount of money spent on developing C++
> > compilers were spent on optimising Lisp compilers, if most of these
> > could be compiled staticly in CLOS anyway.)
>
>Given the time that Lisp has been around (and CLOS), and given the number
>of organizations that has been involved in Lisp-related research, I do not
>think that it is obvious that more money has been spent on C++ compilers.
>I suspect that it is not the case.

I don't buy this at all. Look at the current situation. We've got all
the big software companies writing compilers (Microsoft, Borland,
Symantic), and we've got all the big hardware companies writing
compilers (Sun, HP, IBM, etcetera).

Add to that the fact that a lot of the work that was done on C code
optimisation also can apply to C++.

That just doesn't compare with what was ever spent on lisp compilers.

Although I do note that the Franz compiler appears to produce code
which is often faster than C/C++.

>One problem with C++ is exactly that the PC compiler suppliers spends FAR
>more on windows-related GUI flash than on their compilers (i.e. on the part
>of the software development environment that is devoted to getting the source
>text correctly translated into efficient object code).

They may spend more on GUI flash, but they clearly spend enormous
amounts on the compiler too. Even the early Borland compilers had an
enormous number of optimisation switches, and clever schemes like
pre-compiled headers.
From: M. Prasad
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <337B064A.7733@polaroid.com>
Chris Bitmead uid(x22068) wrote:
> amounts on the compiler too. Even the early Borland compilers had an
> enormous number of optimisation switches, and clever schemes like
> pre-compiled headers.

This may be a little backward reasoning -- private
companies in the US do not spend time and money with
the goal of making something in the public domain popular.
If something in the public domain *is* already
popular or fast gaining popularity, then they will
spend time and money in an attempt to benefit from
the popularity.
From: Jeffrey Mark Siskind
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <xohsozp1g1l.fsf@ai.emba.uvm.edu>
Harley Davis <·····@laura.ilog.com> writes:

> Therefore, you can't simply lay the blame for poor Lisp performance on
> a lack of investment in compilers.  Rather, I think there are inherent
> features of the Lisp runtime that makes it very difficult to optimize
> Lisp for the key parameter: memory usage.  The C++ runtime model means
> that even simple compilers can generate pretty efficient code.

I think that it has nothing to do with the runtime model or the language. It
has to do with the fact that garbage collection enables functional composition
which in turn enables modular programming. And current compilers can't fold
modules together. Let me give you an example to be more precise. Suppose that
Scheme didn't have a builtin LAST procedure and you wanted to write one. You
could either write:

(define (last l) (first (reverse l)))

or:

(define (last l)
 (if (null? (rest l))
     (first l)
     (last (rest l))))

The former is less efficient than the latter. But the latter is more difficult
to write, debug, and prove correct (whether formally or informally). More
importantly, while the latter can be written in either Lisp or C, in a
practical sense, because of garbage collection, the former can only be written
in Lisp.

The former uses a library module, namely REVERSE. The later is written totally
with primitives. While one can write REVERSE in C, one cannot compose
REVERSE with FIRST as easy as one can do in Lisp. Because of the need to
negotiate storage management. And this breaks modularity.

Functional composition allows a much greater level of code modularity and
reuse. Typical Lisp programs build higher and higher levels of abstractions
around black boxes. Typical C programs have a high percentage of primitive
operators throughout all levels of the hierarchy that pierce through the
abstraction boundaries. (That is one reason why C programmers prefer infix and
Lisp programmers don't care. If C programs could use functional composition to
eliminate the primitive operators from the higher levels of abstraction, those
higher levels would not have any infix operators at all. They would look like
Lisp code, with just as many parentheses, just in different places.)

It is not the languages that differ in efficiency. Rather it is the
programming styles that they enable and encourage that differ in efficiency.
Functional composition allows Lisp to support an inherently higher-level
programming style. (Note that I didn't say functional programming. This has
nothing to do with recursion, higher-order functions, or side-effect free
programming. One can still avail onseself of functional composition even
without recursion or higher-order functions and even when there are side
effects.)

Now this has nothing to do with Lisp vs. C. Functional composition is such a
seductive programming style, because it is so much higher-level, that I
predict that if you add garbage collection to C (a.k.a Java) it is only a
matter of time before the entire world starts writing things like:

int last(struct list {int f; struct list *r} *l){return (reverse(l))->f;}

instead of:

int last(struct list {int f; struct list *r} *l)
{ for (; l->r==NULL; l = l->r);
  return l->f;}

The problem is that even when you add a garbage collector to C, the former is
much less efficient than the latter. And to automatically generate the latter
from the former, in the general case, requires partial evaluation and program
transformations like unfold-fold, something which, in the general case, is way
beyond the state of the art. So the functional-composition style is going to
remain less efficient than the atomic-primitive style for a long time to come.
Independent of the programming language and runtime model. But I predict that,
even so, the entire world will get so addicted to the functional-composition
style that they won't care. It is such a compelling force that Resistance is
Futile (TM).

In the end, not only will Lisp survive, it will be the only survivor. Not its
syntax, not its semantics, not its implementations, but its programming style.
Those of us who are still around will say `I told you so' and `What took you
so long'.

    Jeff (home page http://www.emba.uvm.edu/~qobi)
From: Hamilton Richards Jr.
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <ham-1505970856200001@ham.dialin.cs.utexas.edu>
In article <···············@ai.emba.uvm.edu>, Jeffrey Mark Siskind
<····@ai.emba.uvm.edu> wrote:

>... You could either write:
> 
> (define (last l) (first (reverse l)))
> 
> or:
> 
> (define (last l)
>  (if (null? (rest l))
>      (first l)
>      (last (rest l))))
> 
> The former is less efficient than the latter. 

It's not less efficient if your evaluator is lazy.

--Ham

------------------------------------------------------------------
Hamilton Richards Jr.            Department of Computer Sciences
Senior Lecturer                  Mail Code C0500
512-471-9525                     The University of Texas at Austin
Taylor Hall 5.116                Austin, Texas 78712-1188
------------------------------------------------------------------
From: Gary D. Duzan
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <5lhhbm$l8n@news-central.tiac.net>
In article <····················@ham.dialin.cs.utexas.edu>,
Hamilton Richards Jr. <···@cs.utexas.edu> wrote:
=>In article <···············@ai.emba.uvm.edu>, Jeffrey Mark Siskind
=><····@ai.emba.uvm.edu> wrote:
=>
=>>... You could either write:
=>> 
=>> (define (last l) (first (reverse l)))
=>> 
=>> or:
=>> 
=>> (define (last l)
=>>  (if (null? (rest l))
=>>      (first l)
=>>      (last (rest l))))
=>> 
=>> The former is less efficient than the latter. 
=>
=>It's not less efficient if your evaluator is lazy.

   Not as inefficient, perhaps, but presumably there is some overhead in
maintaining the state of the expressions not evaluated.

                                      Gary D. Duzan
                         Humble Practitioner of the Computing Arts
From: Patrick Logan
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <5lnesn$sqh$2@nadine.teleport.com>
In comp.lang.functional Gary D. Duzan <····@wheel.tiac.net> wrote:
: In article <····················@ham.dialin.cs.utexas.edu>,
: Hamilton Richards Jr. <···@cs.utexas.edu> wrote:
: >In article <···············@ai.emba.uvm.edu>, Jeffrey Mark Siskind
: ><····@ai.emba.uvm.edu> wrote:
: >
: >>... You could either write:
: >> 
: >> (define (last l) (first (reverse l)))
: >> 
: >> or:
: >> 
: >> (define (last l)
: >>  (if (null? (rest l))
: >>      (first l)
: >>      (last (rest l))))
: >> 
: >> The former is less efficient than the latter. 
: >
: >It's not less efficient if your evaluator is lazy.

How does lazy evaluation help here? (I am just learning Haskell,
which is the first time I've really struggled with lazy evaluation).

It looks to me as if the function FIRST forces the evaluation of
REVERSE over the entire list. Both definitions will be O(n), so
the difference in efficiency is a difference in constant factors.
REVERSE requires a CONS, so it is less efficient, even in a lazy
language.

Am I missing something?

-- 
Patrick Logan ·············@teleport.com
From: Hamilton Richards Jr.
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <ham-1905971638210001@ham.dialin.cs.utexas.edu>
In article <············@nadine.teleport.com>, Patrick Logan
<······@teleport.com> wrote:

 > In comp.lang.functional Gary D. Duzan <····@wheel.tiac.net> wrote:
 > : In article <····················@ham.dialin.cs.utexas.edu>,
 > : Hamilton Richards Jr. <···@cs.utexas.edu> wrote:
 > : >In article <···············@ai.emba.uvm.edu>, Jeffrey Mark Siskind
 > : ><····@ai.emba.uvm.edu> wrote:
 > : >
 > : >>... You could either write:
 > : >> 
 > : >> (define (last l) (first (reverse l)))
 > : >> 
 > : >> or:
 > : >> 
 > : >> (define (last l)
 > : >>  (if (null? (rest l))
 > : >>      (first l)
 > : >>      (last (rest l))))
 > : >> 
 > : >> The former is less efficient than the latter. 
 > : >
 > : >It's not less efficient if your evaluator is lazy.
 > 
 > How does lazy evaluation help here? (I am just learning Haskell,
 > which is the first time I've really struggled with lazy evaluation).
 > 
 > It looks to me as if the function FIRST forces the evaluation of
 > REVERSE over the entire list. Both definitions will be O(n), so
 > the difference in efficiency is a difference in constant factors.

Quite right. I was mistaken.

 > REVERSE requires a CONS, so it is less efficient, even in a lazy
 > language.
 > 
 > Am I missing something?

No, I was thinking (sloppily) of sorting a sequence to find its first (or
k-th) element. There, laziness helps; in using `reverse` to find the last
element, laziness doesn't help.

Thanks for the correction.

--Ham

------------------------------------------------------------------
Hamilton Richards Jr.            Department of Computer Sciences
Senior Lecturer                  Mail Code C0500
512-471-9525                     The University of Texas at Austin
Taylor Hall 5.116                Austin, Texas 78712-1188
------------------------------------------------------------------
From: Erik Naggum
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <3072645194255534@naggum.no>
* Bjarne Stroustrup
| Given the time that Lisp has been around (and CLOS), and given the number
| of organizations that has been involved in Lisp-related research, I do
| not think that it is obvious that more money has been spent on C++
| compilers.  I suspect that it is not the case.

hm.  how long do you think CLOS has been around?  IIRC, you started on C++
before 1980.  the first widely available CLOS "user guide" was published in
1989, and a specification in 1990, although a lot of experiments with other
object-oriented languages had been going on in the Lisp community.

the Lisp family has one easily identifiable problem that other language
families have avoided: Fortran has had version numbers or years added to
it all along its developmental route, and Ada83 is not Ada95.  however,
"Common Lisp" is the name of two languages, possibly three (Common Lisp the
Language, 1st (CLtL1, 1984) and 2nd (CLtL2, 1990) edition, and the final
ANSI standard (ANSI-CL 1994)).  "Lisp" is moreover the rightful name of
_lots_ of languages.  C and ANSI/ISO C are close enough that "C" is now
largely synonymous with "ANSI C", but C++ is as different from C as ANSI
Common Lisp is from Common Lisp the Language, 1st edition.  however, people
who were dissatisfied with Lisp in 1965 can still proclaim to be talking
about "Lisp" as if nothing had happened since then, albeit with limited
credibility.

so, how much money has been spent on Common Lisp and CLOS compared to C++?
note that you have to subtract all the money on C from C++ and all the
money on Lisp from Common Lisp and CLOS.  do you still think you have a
case?  I don't.

last time I heard, Borland and Microsoft spent more than a billion dollars
each on their C++ environments, and that nearly killed Borland.  a similar
stunt to produce a C++ environment _did_ kill Lucid, Inc, a very successful
Lisp vendor.  (it's Lisp product survived, the C++ efforts didn't.)

| One problem with C++ is exactly that the PC compiler suppliers spends FAR
| more on windows-related GUI flash than on their compilers (i.e. on the
| part of the software development environment that is devoted to getting
| the source text correctly translated into efficient object code).

isn't this true for _all_ products in the PC world?  PC programmers don't
seem to care about compiler or language conformance at all.  it needs to
"look cool" and "run fast" and if it works correctly most of the time, too,
hey, that's great, but no real requirement.  such programmers seem content
to test their code against the compiler and see if the machine does what
they expect it to do.  they write code that behaves as they want in testing
instead of code that follows the specification of the language.  in fact,
they write code for the specific machine, operating system and compiler
_instance_, not _any_ specification, and nobody in their right mind would
want to port PC software to a _real computer_, so who cares if all the
programmers there really program in assembly, anyway?  (although it looks
like a high-level language to the untrained observer.)  whatever comes
after Bill Gates' multi-billion-dollar fraud operation is exposed sure
isn't going to be written by people who have this mindset, however many
millions they number today.

if there is any justice in this world at all, the mechanisms that caused
people to shy away from Lisp because of perceived problems in the past
related to hype and delivered products will hit C++ with even more force.
I derive some peace of mind from this.

#\Erik
-- 
C++ is an object-oriented assembly-line programming language.
From: Bengt Kleberg
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <bengtk-1605972330070001@sl72.modempool.kth.se>
In article <················@naggum.no>, Erik Naggum <····@naggum.no> wrote:

...deleted well thought out writings
> 
> if there is any justice in this world at all, the mechanisms that caused

TANJ (There Aint No Justice)

-- 
Best Wishes, Bengt

Email: ······@damek.kth.se
From: Darin Johnson
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <slrn5npv49.h34.darin@connectnet1.connectnet.com>
In article <················@naggum.no>, Erik Naggum wrote:
>hm.  how long do you think CLOS has been around?  IIRC, you started on C++
>before 1980.  the first widely available CLOS "user guide" was published in
>1989, and a specification in 1990, although a lot of experiments with other
>object-oriented languages had been going on in the Lisp community.

Actually, PCL was around earlier than that, and CLOS is very much like
a "standardized" PCL.

>isn't this true for _all_ products in the PC world?  PC programmers don't
>seem to care about compiler or language conformance at all.  it needs to
>"look cool" and "run fast" and if it works correctly most of the time, too,
>hey, that's great, but no real requirement.

Amen there.  Portability in the PC world is synonymous with <fnord>.

The attitude seems to be "if it gets the job done, it's great", with
no thought that a little effort might find something better or more
suitable, or that a little criticism might encourage the vendors to
improve things beyond the "good enough" stage.

-- 
Darin Johnson
·····@usa.net.delete_me
From: Hrvoje Niksic
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <kigu3k58pcp.fsf@jagor.srce.hr>
Harley Davis <·····@laura.ilog.com> writes:

> I agree with Bjarne.  Lisp is easy to parse and the intermediate
> forms are extremely tractable, so one or two people working in a
> compiler can do as much as many more people working on a C++
> compiler, where the parsing and intermediate code forms are so
> complex as to render lots of optimization very difficult.  The fact
> that Microsoft needs over 100 people on the Visual C++ team may thus
> be more indicative of the complexity of the language than a
> particularly strong investment in improving the development system.

This is hardly what Bjarne was trying to say.  He said that typical
Windows developers were not interested in improving their compilers
*at all*, not that the language was more difficult to improve.

You have raised a valid issue, which I may agree with, but it has
nothing to do with what Bjarne said.

-- 
Hrvoje Niksic <·······@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
Contrary to popular belief, Unix is user friendly.  
It just happens to be selective about who it makes friends with.
From: Chris Bitmead uid(x22068)
Subject: Re: inheritance versus genericity (Was: C++ briar patch)
Date: 
Message-ID: <BITMEADC.97May19121852@Alcatel.com.au>
In article <··············@laura.ilog.com> Harley Davis <·····@laura.ilog.com> writes:

>··@research.att.com (Bjarne Stroustrup) writes:
>
>> ·············@alcatel.com.au (Chris Bitmead uid(x22068)) writes:
>> 
>>  > It's also much cleaner and easier to use CLOS style generic functions
>>  > as a replacement for C++ style templates, although I can appreciate
>>  > that templates are always done statically. (Although I can only wonder
>>  > what would happen if the same amount of money spent on developing C++
>>  > compilers were spent on optimising Lisp compilers, if most of these
>>  > could be compiled staticly in CLOS anyway.)
>> 
>> Given the time that Lisp has been around (and CLOS), and given the number
>> of organizations that has been involved in Lisp-related research, I do not
>> think that it is obvious that more money has been spent on C++ compilers.
>> I suspect that it is not the case.
>> 
>> One problem with C++ is exactly that the PC compiler suppliers spends FAR
>> more on windows-related GUI flash than on their compilers (i.e. on the part
>> of the software development environment that is devoted to getting the source
>> text correctly translated into efficient object code).
>
>I agree with Bjarne.  Lisp is easy to parse and the intermediate forms
>are extremely tractable, so one or two people working in a compiler
>can do as much as many more people working on a C++ compiler, where
>the parsing and intermediate code forms are so complex as to render
>lots of optimization very difficult.  The fact that Microsoft needs
>over 100 people on the Visual C++ team may thus be more indicative of
>the complexity of the language than a particularly strong investment
>in improving the development system.
>
>Therefore, you can't simply lay the blame for poor Lisp performance on
>a lack of investment in compilers.  

I never said that Lisp had "poor performance". What I said was that,
imagine what could have been done had the same money been spent. In
fact several Lisp compilers are at least as fast as C++ compilers.

>Rather, I think there are inherent
>features of the Lisp runtime that makes it very difficult to optimize
>Lisp for the key parameter: memory usage.  The C++ runtime model means
>that even simple compilers can generate pretty efficient code.


ROTFL.

There is no such thing as a "simple C++ compiler".
From: Helmut Zeisel
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5leclq$1en1@lnzx08.vai.co.at>
In article <·············@mti.sgi.com>, Alexander Stepanov <········@mti.sgi.com> writes:
 
> I am also indebted to Barbara
> for the initial explanation why inheritance is weaker than
> genericity. My understanding did develop since that time (1987,
> if I remember correctly), but she did a remarkable job,
> explaining it to me while riding in a car from Newark airport to
> Bell Labs. Her explanation did save me years.
> 
Maybe I missed a previous post, but I thought
genericity is weaker than inheritance;
at least this is was Bertrand Meyer writes
(at least as I understand it).
Can someone explain the details?

By the way, who is Barbara?

Helmut Zeisel



-- 
From: Matt Austern
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <fxthgg4d8b8.fsf@isolde.mti.sgi.com>
······@vai.co.at (Helmut Zeisel) writes:

> > I am also indebted to Barbara
> > for the initial explanation why inheritance is weaker than
> > genericity. My understanding did develop since that time (1987,
> > if I remember correctly), but she did a remarkable job,
> > explaining it to me while riding in a car from Newark airport to
> > Bell Labs. Her explanation did save me years.
> > 
> Maybe I missed a previous post, but I thought
> genericity is weaker than inheritance;
> at least this is was Bertrand Meyer writes
> (at least as I understand it).
> Can someone explain the details?

Genericity in Eiffel is very restricted; this is probably related
to the fact that Bertrand Meyer thinks that genericity is a weak
concept.  You might want to look at languages where genericity is
less restricitive, though, such as Ada 95, C++, and ML.

> By the way, who is Barbara?

Barbara Liskov, the designer of CLU.
From: Marco Antoniotti
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <scfiv0sphes.fsf@infiniti.PATH.Berkeley.EDU>
In article <·············@mti.sgi.com> Alexander Stepanov <········@mti.sgi.com> writes:

   From: Alexander Stepanov <········@mti.sgi.com>
   Newsgroups: comp.lang.scheme,comp.lang.lisp,comp.lang.misc,comp.lang.functional,comp.lang.c++
   CC: ········@sgi.com
   Date: Thu, 08 May 1997 19:45:40 -0700
   Organization: SGI/MIPS
   Path: agate!usenet.INS.CWRU.Edu!kira.cc.uakron.edu!neoucom.edu!news.ysu.edu!news.radio.cz!cam-news-hub1.bbnplanet.com!su-news-hub1.bbnplanet.com!news.bbnplanet.com!zdc!super.zippo.com!enews.sgi.com!chronicle.mti.sgi.com!news
   Lines: 165
   References: <·············@nospam.acm.org> <··········@research.att.com>
						   <·············@nospam.acm.org> <··········@research.att.com>
						   <················@naggum.no> <·············@mti.sgi.com>
						   <····················@connectnet1.connectnet.com> <···············@isolde.mti.sgi.com> <·············@mti.sgi.com> <·············@nospam.acm.org> <·············@mti.sgi.com> <·············@cs.cornell.edu>
   Mime-Version: 1.0
   Content-Type: text/plain; charset=iso-2022-jp
   Content-Transfer-Encoding: 7bit
   X-Mailer: Mozilla 2.0S (X11; I; IRIX 6.2 IP22)
   Xref: agate comp.lang.scheme:20567 comp.lang.lisp:27868 comp.lang.misc:29356 comp.lang.functional:9467 comp.lang.c++:268343

   Eli Barzilay wrote:
   > 
   > Whow, man - now you got me - please don't insult Lisp if you havn't 
   > used it (and reading your mail I see that you DON'T know it too good).
   > 

   This seems to be a common sentiment. I keep getting little Lisp, Scheme,
   and SML programs showing my amazing ignorance.

   It is, however, unlikely to effect me. You see, I tried. I used
   Symbolics, I used Common Lisp, I taught a course on implementing Common
   Lisp. I implemented THE LOOP macro. (As a matter of fact, I probably
   impemented every single macro in Common Lisp - I am looking for my
   lecture notes from my CL class, but cannot find them yet.) I know what
   locatives were. I do know about SETF. I read the lambda papers in the
   seventies. I read a very large portion of MIT Scheme code - and forced
   many innocent students to do the same. (As a matter of fact, my last
   large project in Scheme - a VLIW simulator - was done in 1994.) While I
   never seriously programmed in ML, I did seriously read one ML book and
   many ML papers. One possible explanation is that I am just stupid and
   cannot appreciate the thing of beauty.

   If you are satisfied with this explanation, STOP READING NOW, and,
   please, please, do not send me mail expressing you opinion about my
   mental abilities and moral qualities of my ancestors.

   There some of you, who express genuine interest and I would try to
   explain some of my points. What follows is a sort of an Apologia pro
   vita sua. It is rumbling and unclear, but it is difficult to explain the
   motivations of a lifetime of research, especially when one is lead to
   conclusions contrary to the accepted academic wisdom. 

	... much deleted.

I was not satisfied at all with the explanation and kept on reading.
The account is fascinating, very interesting and very informative.
Yet, it still does not convince me that you could not replicate the
STL (or some "equivalent") in Common Lisp.  But then again I do not
have time and resources to put in the effort, so, that's it :)

Cheers
-- 
Marco Antoniotti
==============================================================================
California Path Program - UCB
Richmond Field Station
tel. +1 - 510 - 231 9472
From: David Hanley
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3373A1B1.7135@nospan.netright.com>
Alexander Stepanov wrote:
> 
> Eli Barzilay wrote:
> >
> > Whow, man - now you got me - please don't insult Lisp if you havn't
> > used it (and reading your mail I see that you DON'T know it too good).
> >
> 
> This seems to be a common sentiment. I keep getting little Lisp, Scheme,
> and SML programs showing my amazing ignorance.
> 

	Well, I, for one, was not posting code in order to show ignorance.
I was posting code in order to understand what it did not do that
you were, in fact, looking for.  The reason for _that_ is my lack of
understanding as to what in these languages was insifficent.

	So far, the only issue I've been able to really understand
has been the speed issue-- C++ will do a lot of things pretty fast. 
Some of the others I've not been able to quite figure out. 
C++ lets you use addresses naturally.  Ok. Why is that the 'right way'
for an algorithms library... etc...  I think it would help a bit
if you could explain why some of these lisp or ML bits aren't
quite right for what you want.

	I read your posting several times, but there's some point in it
I'm somehow missing.  Do you have any papers, perhaps?  Maybe something
that is longer will make some of the points clearer. 

dave
From: Richard A. O'Keefe
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5l9q0j$ig5$1@goanna.cs.rmit.edu.au>
David Hanley <·····@nospan.netright.com> writes:
>	Well, I, for one, was not posting code in order to show ignorance.
>I was posting code in order to understand what it did not do that
>you were, in fact, looking for.  The reason for _that_ is my lack of
>understanding as to what in these languages was insifficent.

My little Scheme example, ditto.
I am carefully saving Stepanov's postings, because I think there's a
paper in replying to them, and if not, a lot of understanding nevertheless.

The place where we start to part company is his insistence that
a data structure is a collection of *locations*.  If that's the
view he wants, then clearly any value-oriented language like Haskell
or Clean is not going to do what he wants, and that's _why_ I want
to use such languages.  I was just trying to help a student debug a
C program today, and the problem was that the bug symptom showed up
long after the bug bit; it was clobbering a location it had no
business clobbering.

Stepanov says that it if you take vectors out of Common Lisp, it is
hard to put them back.  Of *course* it is, that's why they are there.
If Stepanov wants to be able to define vector-like things for himself
from the ground up, that _automatically_ rules out everything except
languages like PL/360, PL-11, Bliss (-36, -16, -32), ESPL, C, and C++.
It guarantees that _any_ programming language that tries to provide a
high level model, hiding the hardware, like Smalltalk, or Eiffel, is
not going to do what he wants.  That's fine, but it's not because of
a defect in the languages, it's because the designers have accomplished
their _goal_.

I will have to study his list of algorithmic desiderata very careully.
It seems to me that he is placing extremely strong demands on what the
'generalised linear search' ought to be able to do; basically, he wants
every sequence to look like an array.  But there are a lot of sequences
that aren't good at looking like arrays, and I believe there are
useful collections that can usefully be viewed as sequences that cannot
support his interface efficiently.  I also deny that his intuition about
what 'generalised linear search' _ought_ to be able to do matches mine;
he has stretched the concept beyond what I am comfortable with.  Again,
that's fine.  We don't _have_ to agree about that, except I don't want
to pay the associated price.

As far as I can see, there are two basic advantages of C++ over Lisp,
ML, &c:

(1) It is a wide spectrum language offering some extremely low level
    features, so such high level features as it has don't get in the
    way of implementing things very differently.

(2) The template sublanguage is computation-universal, which makes
    it possible to express arbitrarily complex polyalgorithm selection
    code as compile-time computations, and the information needed for
    this can be attached to the base collection types quite naturally.

Is that a fair summary?

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: William Clodius
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3378FC87.1CFB@lanl.gov>
Richard A. O'Keefe wrote:
> <snip>
> I will have to study his list of algorithmic desiderata very careully.
> It seems to me that he is placing extremely strong demands on what the
> 'generalised linear search' ought to be able to do; basically, he wants
> every sequence to look like an array.  But there are a lot of sequences
> that aren't good at looking like arrays, and I believe there are
> useful collections that can usefully be viewed as sequences that cannot
> support his interface efficiently.

I am not sure I understand your point here. I try to maintain a
distinction in my mind between the interface and the implementation. The
implementation has a straightforward mapping to efficiency, but
syntactically similar interfaces can map to very different
implementations and need not impact efficiency for a "sufficiently"
smart optimizing compiler given sufficient time. (Whether the
implementation is easilly written in a form that can be optimized with
near linear resources in code size is a different but significant
issue.)

I am under the impression that Stepanov is claiming that C++ templates
allow him to use the most efficient underlying implementation for any
arbitrary algorithm, i.e., while the interface for a 'generalised linear
search' is that of a search through an array, the sequence need not be
an array and the underlying implementation need not be at all that used
for arrays.

> <snip>
> As far as I can see, there are two basic advantages of C++ over Lisp,
> ML, &c:
> 
> (1) It is a wide spectrum language offering some extremely low level
>     features, so such high level features as it has don't get in the
>     way of implementing things very differently.
> 
> (2) The template sublanguage is computation-universal, which makes
>     it possible to express arbitrarily complex polyalgorithm selection
>     code as compile-time computations, and the information needed for
>     this can be attached to the base collection types quite naturally.
> 
> Is that a fair summary?

I think so. In particular the capabilities of templates are critical as
they allow a sufficiently smart and knowledgeable programmer to write
code so that the mapping of the interface to the underlying
implementation can be perfomed at compile time.

-- 

William B. Clodius		Phone: (505)-665-9370
Los Alamos Nat. Lab., NIS-2     FAX: (505)-667-3815
PO Box 1663, MS-C323    	Group office: (505)-667-5776
Los Alamos, NM 87545            Email: ········@lanl.gov
From: Fred Gilham
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <u7lo5iayiq.fsf@japonica.csl.sri.com>
William Clodius writes:

>I think so. In particular the capabilities of templates are critical as
>they allow a sufficiently smart and knowledgeable programmer to write
>code so that the mapping of the interface to the underlying
>implementation can be perfomed at compile time.

Can someone comment on template metaprogramming (see
http://monet.uwaterloo.ca/~tveldhui/papers/Template-Metaprograms/meta-art.html
for example) from a lisp perspective?  This seems to be something that
lisp should be good at.  What would be the lisp equivalent of template
metaprogramming and is this a recognized style of lisp programming?

-- 
-Fred Gilham    ······@csl.sri.com
From: Shriram Krishnamurthi
Subject: template metaprogramming (was Re: C++ briar patch)
Date: 
Message-ID: <j7vpvutx0tb.fsf_-_@new-world.cs.rice.edu>
Fred Gilham <······@japonica.csl.sri.com> writes:

> Can someone comment on template metaprogramming (see
> http://monet.uwaterloo.ca/~tveldhui/papers/Template-Metaprograms/meta-art.html
> for example) from a lisp perspective?

I read this and, from what I can tell, it's nothing more than
programming with a reasonable macro system.  You can't do this in
something like C/C++'s macro system because of how limited that
(macro) language is.  However, in Lisp, you have the entire language
available at the macro level, so it's quite easy.

Some of Scheme's macro systems push the envelope even further by
providing hygiene and "referential transparency", which make it easier
to write error-free macros.

>			   What would be the lisp equivalent of template
> metaprogramming and is this a recognized style of lisp programming?

The Lisp equivalent would be to use macros and yes, it is very much a
part of the "Lisp style" of programming.

'shriram
From: Harley Davis
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <wkraf9imps.fsf@laura.ilog.com>
Fred Gilham <······@japonica.csl.sri.com> writes:

> Can someone comment on template metaprogramming (see
> http://monet.uwaterloo.ca/~tveldhui/papers/Template-Metaprograms/meta-art.html
> for example) from a lisp perspective?  This seems to be something that
> lisp should be good at.  What would be the lisp equivalent of template
> metaprogramming and is this a recognized style of lisp programming?

Macros.  You can write a macro that lets the user declare whatever
information will allow the macro code to generate appropriately
efficient runtime code.  In fact, I would say that it is merely a
matter of tradition rather than anything fundamental which lets C++ do
more analysis at compile-time than Lisp to generate efficient code.

-- Harley

-------------------------------------------------------------------
Harley Davis                            net: ·····@ilog.com
Ilog, Inc.                              tel: (415) 944-7130
1901 Landings Dr.                       fax: (415) 390-0946
Mountain View, CA, 94043                url: http://www.ilog.com/
From: M. Prasad
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <337A1DCB.335D@polaroid.com>
Richard A. O'Keefe wrote:
> (1) It is a wide spectrum language offering some extremely low level
>     features, so such high level features as it has don't get in the
>     way of implementing things very differently.
> 
> (2) The template sublanguage is computation-universal, which makes
>     it possible to express arbitrarily complex polyalgorithm selection
>     code as compile-time computations, and the information needed for
>     this can be attached to the base collection types quite naturally.
> 
> Is that a fair summary?

Quite good, I would say.  However, the "high level" vs
"low level" thinking perhaps should be abandoned in this
context, if "locations" are admitted to be a legitimately
useful asbtraction and not just a dressing up of
the machine.
From: David Chase
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EA5JM0.AFL@world.std.com>
Richard A. O'Keefe wrote:

> I will have to study his list of algorithmic desiderata very careully.

I think it is also necessary to explore the solution space.  It's
unclear
to me if aggressive (perhaps programmer-guided) constant propagation and
inlining (remember that procedure-typed parameters can also be
constants)
might not also produce a similarly efficient result in an otherwise
"less
efficient" language.  Of course, this requires a sufficiently capable
compiler, but so does STL itself (not all C++ compilers seem to swallow
it,
at least not the last time that I looked).

Yet another point in the solution space is the use of tools.  C++ is
damnably hard
to parse, and even harder to re-emit after modification (I speak from
painful
experience here), so it is not easy to write
program-modifying/generating
tools for it.

For other, more parseable languages, it is possible to write
extralingual
tools with some of the power of C++'s templates.  One example is
Modula-3,
whose first pickle generator had the same "instantiate unless user has
specialized" trick that C++ templates have.  The first "generics" for
M-3
were also done with a tool, instead of embedding them in the language.
There are drawbacks to tools, to be sure, but they can still solve many
problems.  It seems to me that in cases where the transformation being
applied is capable of arbitrary computation, that you might want it run
separately from the compiler, if only to give you something to debug
when
the magic goes awry.

David Chase
From: Thant Tessman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <33734C8F.794B@nospam.acm.org>
Alexander Stepanov wrote:

[...deep thoughts...]

I have respect for the cleverness of the design of the STL even if 
I do consider the effort misplaced.  So in the spirit of giving you 
the benefit of the doubt, I've read your post three times desparatetly 
looking for some kernel of an idea worth hanging on to (let alone one 
that is useful in the "real world" or one that somehow emphasizes the 
alleged singluar strengths of C++), but all I can say is:  Huh?

-thant
From: Anthony Shipman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5ljnin$s3u@ephor.tusc.com.au>
In <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

>Alexander Stepanov wrote:

>[...deep thoughts...]

>I have respect for the cleverness of the design of the STL even if 
>I do consider the effort misplaced.  So in the spirit of giving you 
>the benefit of the doubt, I've read your post three times desparatetly 
>looking for some kernel of an idea worth hanging on to (let alone one 
>that is useful in the "real world" or one that somehow emphasizes the 
>alleged singluar strengths of C++), but all I can say is:  Huh?

>-thant


I think what I have gleaned from Alexander's article containing the
reduce function demonstrates the ability of C++ to

    overload operations
    overload with optional arguments

Then on top of that templates can be used to organise the many
combinations of operations and types that reduce is overloaded over.
This makes it possible to write generic code.  (I think that many other
people use the word generic to just mean "can be parameterised by types
and operations").

Overloading is available in OO languages in general but it is usually
implemented by dynamic dispatching.  Other OO languages that allow
optional arguments might include CLOS, incrTcl or Python but I'm not
familiar with these.

Overloading is not available in ML even though it has powerful generic
facilities.  Haskell does overloading, either by dynamic or static
dispatch but no arguments can be optional.  (This means something
different from currying).  You would have to use different function
names e.g.  sum for a reduce with plus but I think that that would be an
improvement.

This combination of overloading and optional arguments and templates is
a singular strength of C++ but I wouldn't call it overwhelming.  I'd
still choose another language (almost) all of the time.
-- 
Anthony Shipman                 "You've got to be taught before it's too late,
TUSC Computer Systems Pty Ltd    Before you are six or seven or eight,
                                 To hate all the people your relatives hate,
E-mail:  ···@tusc.com.au         You've got to be carefully taught."  R&H
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <BITMEADC.97May13154101@Alcatel.com.au>
In article <·············@mti.sgi.com> Alexander Stepanov <········@mti.sgi.com> writes:

Hi

I'm still a bit vague on why you couldn't do what you wanted in Lisp,
efficiency issues put aside for a moment...

>I also
>came to the realization that I wanted a language with copy and equality
>defined quite differently from Lisp. That is, I realized that I could
>build a very useful theory of containers (data strucutres with
>ownership) based on a philosophically sound notion of whole and part;
>something along the lines of:
>
>1.If two objects share a part, then one object is a part of the other
>(no sharing, objects are disjoint).

Of course you don't have to share objects in Lisp.

>2. No circularity among objects - an object cannot be a part of itself
>and, therefore, cannot be part of any of its parts.

Surely you didn't need a language did _not_ allow something to
implement what you want?

>3. When an object is destroyed all its parts are destroyed.

Well, in the context of a GC you don't worry too much about when
things are destroyed. Is there some reason why this is important?

>4. Two objects are equal iff their essential parts are equal.

Is the lisp equal function no good?
From: Scott Schwartz
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <8gzptzkq7q.fsf@galapagos.cse.psu.edu>
·············@Alcatel.com.au (Chris Bitmead uid(x22068)) writes:
| I'm still a bit vague on why you couldn't do what you wanted in Lisp,
| efficiency issues put aside for a moment...

Bzzzzt.  Efficiency is everything.  You can't put it aside.
From: Darin Johnson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5nhr92.ag4.darin@connectnet1.connectnet.com>
>| I'm still a bit vague on why you couldn't do what you wanted in Lisp,
>| efficiency issues put aside for a moment...
>
>Bzzzzt.  Efficiency is everything.  You can't put it aside.

You can put it aside; because there are many different facets to
efficiency.  Efficient can mean fast running, low memory usage, easy
maintenance, etc.  As far as cpu speed, this is *easily* put aside for
many programs (and Lisp isn't that bad as far as speed anyway, since
you can and usually do compile it).

Efficiency only matters as far as the end user cares about it.  If
the end user doesn't care, then efficiency isn't important.  The
end user may be more interested that the product be usable in one
week but slow and bulky than a product due in 2 months but fast and
small.  And no, what suits one person as an end user does not suit
all users (so no arguing about what you personally like).

-- 
Darin Johnson
·····@usa.net.delete_me
From: Fergus Henderson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kmg6h$fih@mulga.cs.mu.OZ.AU>
Matt Austern <·······@isolde.mti.sgi.com> writes:

>Alex and I tried to implement the STL in Java; you can see our attempt
>at http://reality.sgi.com/austern/java/index.html.  For a number of
>reasons, though, the attempt wasn't all that successful.  The most
>obvious problem is that Java doesn't have any sort of genericity at
>all (polymorphism is not a substitute), but there were actually some
>other issues as well.

Why isn't polymorphism an adequate substitute?

Clearly polymorphism isn't an _ideal_ substitute, because of the
need for lots of downcasts.  That's unfortunate, but doing type checking
at run time rather than at compile time isn't going to make the sky fall
in.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Matt Austern
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <fxtpvv4cynz.fsf@isolde.mti.sgi.com>
···@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

> >Alex and I tried to implement the STL in Java; you can see our attempt
> >at http://reality.sgi.com/austern/java/index.html.  For a number of
> >reasons, though, the attempt wasn't all that successful.  The most
> >obvious problem is that Java doesn't have any sort of genericity at
> >all (polymorphism is not a substitute), but there were actually some
> >other issues as well.
> 
> Why isn't polymorphism an adequate substitute?
> 
> Clearly polymorphism isn't an _ideal_ substitute, because of the
> need for lots of downcasts.  That's unfortunate, but doing type checking
> at run time rather than at compile time isn't going to make the sky fall
> in.

Polymorphism isn't an adequate substitute for genericity because it
doesn't do the same thing; it's not primarily an issue of efficiency
(although that matters too), but of semantics.

Note that it's generic algorithms I'm concerned with, not just
container classes.  If the only tool I have at hand is polymorphism,
then I don't see a way of writing a single algorithm that can be used
for vectors, singly linked lists, double linked lists, and binary
search trees.
From: Francois-Rene Rideau
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <xgmlo5s32zz.fsf@Kadath.ens.fr>
Matt Austern <·······@isolde.mti.sgi.com> writes:

> Polymorphism isn't an adequate substitute for genericity because it
> doesn't do the same thing; it's not primarily an issue of efficiency
> (although that matters too), but of semantics.
> 
> Note that it's generic algorithms I'm concerned with, not just
> container classes.  If the only tool I have at hand is polymorphism,
> then I don't see a way of writing a single algorithm that can be used
> for vectors, singly linked lists, double linked lists, and binary
> search trees.
>
Use functors!
The functor would take as argument a module with the types and primitives
needed by your generic algorithm, and return a module that returns
your generic functions.

Alternatively, you could use the object system from OCAML.
[Note that OCAML also has functors, and that its standard library
never needed do anything that required objects, only functors]

== Fare' -- ······@ens.fr -- Franc,ois-Rene' Rideau -- DDa(.ng-Vu~ Ba^n ==
Join the TUNES project for a computing system based on computing freedom !
                TUNES is a Useful, Not Expedient System
URL: "http://www.eleves.ens.fr:8080/home/rideau/Tunes/"
From: Fergus Henderson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5ko8v0$m8c@mulga.cs.mu.OZ.AU>
Matt Austern <·······@isolde.mti.sgi.com> writes:

>···@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
>
>> Why isn't polymorphism an adequate substitute?
>> 
>> Clearly polymorphism isn't an _ideal_ substitute, because of the
>> need for lots of downcasts.  That's unfortunate, but doing type checking
>> at run time rather than at compile time isn't going to make the sky fall
>> in.
>
>Polymorphism isn't an adequate substitute for genericity because it
>doesn't do the same thing; it's not primarily an issue of efficiency
>(although that matters too), but of semantics.

Well, I'm still missing the difference.  I don't see why polymorphism
plus downcasting doesn't give you the same semantics as genericity.

Note that genericity can be implemented with shared code, just like
polymorphism is -- for example, some Ada compilers implement Ada
generics that way, and so do all Haskell compilers.  The only semantis
differences that I can see are that (a) with genericity, you get
homogenous collections, whereas with polymorphism you get heterogenous
collections -- but fortunately it is easy to use the latter to
implement the former; and (b) you're going to need some explicit
downcasts.

>Note that it's generic algorithms I'm concerned with, not just
>container classes.  If the only tool I have at hand is polymorphism,
>then I don't see a way of writing a single algorithm that can be used
>for vectors, singly linked lists, double linked lists, and binary
>search trees.

You could just use the same design embodied in the STL: your single
algorithm works on Iterators (or more specifically InputIterators,
ForwardIterators, etc.), and each Container provides begin() and end()
methods that return Iterators.

Why is that so hard??

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Graham C. Hughes
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <87iv0w17nk.fsf@A-abe.resnet.ucsb.edu>
-----BEGIN PGP SIGNED MESSAGE-----

···@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

> Well, I'm still missing the difference.  I don't see why polymorphism
> plus downcasting doesn't give you the same semantics as genericity.

The C rule regarding casts bears repeating, and in fact is relevant to
every statically typed language; a cast tells the compiler you know
much more about the happenings then it does.  Don't do it if you can
possibly help it.  Casts are a sledgehammer, designed to subvert the
type system.

In the days predating templates in C++, collection classes had to be
done using polymorphism & downcasting.  This was error prone and type
unsafe, and the primary reason I didn't do much C++ programming at the
time.  Element extraction was tedious, and ensuring that the element
had the type you thought it did was worse.  Java is in this situation
now, and (modulo Pizza) it doesn't look to be getting any better.

Using polymorphism plus downcasting as a substitute for genericity is
the clearest indicator I can possibly find that the author is used to
a dynamically typed language.  This works fine for CLOS, Python,
Smalltalk, what have you, but is inappropriate for statically typed
languages such as C++, Ada, Eiffel, and others.

Note that (with some care) an STL vector can be made into a
pseudo-heterogeneous container by storing pointers.  The care is
necessary due to memory allocation issues.
- -- 
Graham Hughes    http://A-abe.resnet.ucsb.edu/~graham/     MIME & PGP mail OK.
const int PGP_fingerprint = "E9 B7 5F A0 F8 88 9E 1E  7C 62 D9 88 E1 03 29 5B";
   #include <stddisclaim.h>

-----BEGIN PGP SIGNATURE-----
Version: 2.6.3
Charset: noconv
Comment: Processed by Mailcrypt 3.4, an Emacs/PGP interface

iQCVAwUBM2/D+yqNPSINiVE5AQH8+wP9F+p2M6T1+wEuq02LRm9YphEtUmFqS1XH
iO70tZoovXhIyq0eehpYYdc9fnoonOcZPyKvTfqp+KqnIPk1Di1Lv+1+Mvg9zD69
Se5g5UZ9d54vJXyXoLp+4ArKUsmcmiVE8Y1yiRbZ0q38smKixGbr5y7+wVMSCGhZ
ew+KluYLvTQ=
=h9jn
-----END PGP SIGNATURE-----
From: Fergus Henderson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kp2d9$c35@mulga.cs.mu.OZ.AU>
"Graham C. Hughes" <·············@resnet.ucsb.edu> writes:

>···@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
>
>> Well, I'm still missing the difference.  I don't see why polymorphism
>> plus downcasting doesn't give you the same semantics as genericity.
>
>[... lots of stuff about why casts are evil ...]
>Using polymorphism plus downcasting as a substitute for genericity is
>the clearest indicator I can possibly find that the author is used to
>a dynamically typed language.

Sure.  I was thinking of implementing something like STL in Java,
and when it comes to genericity, Java is a dynamically typed language.

In C, casts are certainly something you want to avoid whenever
possible.  In Java, casts are not nearly as unsafe as they are in C,
because they are checked at runtime.  Sure, something like Pizza would
be better, but I don't think the need to downcast in Java is a
show-stopper.  I think you could write a version of STL in Java
without resorting to preprocessing hacks, and apart from issues of
efficiency that could be solved by a sufficiently smart compiler,
and apart from the need to downcast, I think it could be just as
powerful as the C++ STL.  In fact, it would have some advantages over
the C++ STL: the interfaces would be explicit in the code, and the
compiler would check them, whereas in C++ the interfaces for
things like ForwardIterator or Assignable are present only in the
documentation, not in the code, and are not checked by the compiler.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Fergus Henderson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kp7q9$g15@mulga.cs.mu.OZ.AU>
I wrote:

>I think you could write a version of STL in Java
>without resorting to preprocessing hacks, and apart from issues of
>efficiency that could be solved by a sufficiently smart compiler,
>and apart from the need to downcast, I think it could be just as
>powerful as the C++ STL.

Actually on further reflection I see that the Java version would have
another disadvantage compared to the C++ version.  As Alexander Stepanov
has pointed, in C++ you can do nifty things with template specialization.
In Java you could still special-case the algorithms, e.g.

	foo(InputIterator i) {
		if ((RandomAccessIterator) i) {
			// use random access algorithm
			random_access_foo((RandomAccessIterator) i);
		} else if ((SomeOtherSpecialIterator) i) {
			// use some other special case
			some_other_foo_algorithm((SomeOtherSpecialIterator) i);
		} else {
			// if none of the special cases apply, just
			// use a single-pass algorithm
			single_pass_foo(i);
		}
	}

and a smart compiler could inline foo() and optimize away the if-then-else
and the type tests.  (Of course, relying on compiler optimization is not
always a good thing.  It might be a good idea to add pragmas or something
to give the compiler a hints that it should always specialize foo();
it could then issue a warning if for some reason it wasn't able to do so.)

However, the disadvantage of this Java solution is that all the special
cases must be listed in a single function; adding a new specialization
requires modifying that function.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Darin Johnson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5n1f4u.l25.darin@connectnet1.connectnet.com>
>In the days predating templates in C++, collection classes had to be
>done using polymorphism & downcasting.  This was error prone and type
>unsafe, and the primary reason I didn't do much C++ programming at the
>time.

Yes, but now we have templates, and we can do polymorphism+downcasting
inside the template!  Thus, type safety, few errors, ease of use, and
elegance, without all that ugly inefficiency of actually *duplicating*
code, which is what the vast majority of templated collection classes
do.

Why don't people do this??  I'm honestly baffled.  Why not an array,
list, bag, set, etc, that operate on pointers to void, with templates
to create concrete type-safe classes?  And this easily lets you have
precompiled collection classes, whereas even the best C++ compiler
today still has problems with precompiling templates, especially
monstrosities like STL.

>Using polymorphism plus downcasting as a substitute for genericity is
>the clearest indicator I can possibly find that the author is used to
>a dynamically typed language.  This works fine for CLOS, Python,
>Smalltalk, what have you, but is inappropriate for statically typed
>languages such as C++, Ada, Eiffel, and others.

Yes, but static typing is also opposed to object orientedness (IMHO,
and depending upon how you were raised).  That is, object oriented
fundamentals treats data as an amorphous object - you can perform
operations on the data *without* knowing the type.

Yes, I know static typing is a good thing, but that doesn't mean it's
not in opposition to OO at the same time.  Languages achieve different
tradeoffs as they have different goals.  Smalltalk wants to be a pure
OO language, to enable pure OO programs to be written, so static
typing has to go or take a severely diminished role.  C++ has the goal
of being efficient for low level programming at the same time it has
OO concepts, so static typing has to stay while being loosened, and OO
has to be added while being restricted.

Also, by saying "substitute for genericity", I think the logic is a
bit backwards.  Genericity implies typing, and thus is not necessarily
needed in languages with no typing or weak typing.  (even downcasting
is undefinable, you can't downcast in Smalltalk...)

>Note that (with some care) an STL vector can be made into a
>pseudo-heterogeneous container by storing pointers.  The care is
>necessary due to memory allocation issues.

If C++ had garbage collection, all these odd little rules and things
to remember about memory/constructors/destructors would have been
designed much differently.

But I consider this "care" to be obvious.  STL advocates love to warn
about never storing pointers, as you might accidentally lose memory.
Gack, what a horrible argument.  I might as well never call "new" as I
might lose memory.  Obviously if someone is storing pointers in an STL
collection, they will need to take care that memory isn't lost,
*exactly* as if they were using the pointers anywhere else.  Yes, I
know destructors won't get called on the objects that are pointed to
when the collection is destructed, that's obvious.  Good programming
would imply that I destruct the objects before destructing the
collection anyway, regardless of if I store the objects themselves or
the pointers.  It's *sloppy* programming to rely upon having
everything cleaned up just because you go out of scope.

Yes, memory leaks are a major headache; but I think the proposed
solution of having bloated slow code isn't perfect either (ie, bloated
because of immense duplication from templates, and slow because
objects are copied instead of pointers).  Sadly, a large chunk of the
C++ community doesn't want to admit there was a tradeoff involved.

-- 
Darin Johnson
·····@usa.net.delete_me
From: Matt Austern
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <fxtbu6mdfc0.fsf@isolde.mti.sgi.com>
·····@usa.net.delete_me (Darin Johnson) writes:

> >Note that (with some care) an STL vector can be made into a
> >pseudo-heterogeneous container by storing pointers.  The care is
> >necessary due to memory allocation issues.
> 
> If C++ had garbage collection, all these odd little rules and things
> to remember about memory/constructors/destructors would have been
> designed much differently.
> 
> But I consider this "care" to be obvious.  STL advocates love to warn
> about never storing pointers, as you might accidentally lose memory.

Which STL developers say that you should never store pointers in
containers?  Not Alex Stepanov, certainly, and not Bjarne Stroustrup.
Not the C++ standardization committee either, for that matter: the
standard C++ library contains an adaptor, mem_fun, which is
specifically intended for the case when an STL container contains
pointers.

It is absolutely not true that there's anything wrong with storing
pointers in STL containers.  STL containers contain objects, and
pointers, in C++, are perfectly good objects.  My automated tests
specifically test storing pointers in STL containers.
From: Daniel F. Higgins
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <33700694.14B7@fresgisvr.fsu.umd.edu>
> Polymorphism isn't an adequate substitute for genericity because it
> doesn't do the same thing; it's not primarily an issue of efficiency
> (although that matters too), but of semantics.
> 
> Note that it's generic algorithms I'm concerned with, not just
> container classes.  If the only tool I have at hand is polymorphism,
> then I don't see a way of writing a single algorithm that can be used
> for vectors, singly linked lists, double linked lists, and binary
> search trees.

I've been tossing around the idea of making wrapper classes for all the
types, and modeling some of the polymorphic design of these classes
after java.. I did it to write a database engine, constructing a record
from a bunch of base fields (of certain types).

What is the down side of polymorphism? Is run-time typing is going to be
included in the next C++, and when is it coming out!


-- 
Daniel F. Higgins
//////////////////////////
http://www.fsu.umd.edu/students/dhiggins/index.html
········@netbiz.net
From: Peter Ludemann
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <wujbu6nfe9b.fsf@wistaria.i-have-a-misconfigured-system-so-shoot-me>
Matt Austern <·······@isolde.mti.sgi.com> writes:

> Alex and I tried to implement the STL in Java; you can see our attempt
> at http://reality.sgi.com/austern/java/index.html.  For a number of
> reasons, though, the attempt wasn't all that successful.  The most
> obvious problem is that Java doesn't have any sort of genericity at
> all (polymorphism is not a substitute), but there were actually some
> other issues as well.

What's wrong with using "interfaces" to describe the interesting usage
properties of the data structures?  That would avoid the need for
polymorphistic downcasting.  Of course, people would need to wrap
their data-structures in interface declarations, e.g.:

class SimpleList implements LeftToRightTraversal, PositionIndexing {
  // LeftToRightTraversal interface methods are First(), Next()
  // PositionIndexing interface method is Get(int i)
  //   (note that list.First() == list.Get(0))
}

but that could be done with a downcast in the library.

It's hard to get such interface designs right.  Back in the old days,
when we didn't call these things "objects" (one project I worked on
had "agents" and "aspects"), we mis-designed a RDBMS interface to have
only the methods "First", "Last", "Next", "Previous", with horrible
performance for positioning to the i'th result).

-- 
Peter Ludemann		+1.415.813.6806  (fax: +1.415.813.7499)
Software Architect	········@inxight.com
InXight Software, Inc.	http://www.inxight.com
PAHV 105, 3400 Hillview Ave., Palo Alto, CA 94304 
From: Matt Austern
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <fxtenb8d84o.fsf@isolde.mti.sgi.com>
Peter Ludemann <········@inxight.com> writes:

> Matt Austern <·······@isolde.mti.sgi.com> writes:
> 
> > Alex and I tried to implement the STL in Java; you can see our attempt
> > at http://reality.sgi.com/austern/java/index.html.  For a number of
> > reasons, though, the attempt wasn't all that successful.  The most
> > obvious problem is that Java doesn't have any sort of genericity at
> > all (polymorphism is not a substitute), but there were actually some
> > other issues as well.
> 
> What's wrong with using "interfaces" to describe the interesting usage
> properties of the data structures?  

The first thing to remember: the STL is primarily a library of
algorithms.  Data structures are interesting, yes, but the
real issue that's at stake is whether or not inheritance is
a good way to express generic algorithms.

The problem is that the semantics of interfaces is that of
polymorphism; interfaces are unable to encapsulate the sorts of type
relationship that you get with genericity.

Consider, for example, the following generic algorithm written in
C++.

template <class InputIterator, class T, class BinaryOperation>
T accumulate(InputIterator first, InputIterator last, T init,
             BinaryOperation binary_op) {
  for ( ; first != last; ++first)
    init = binary_op(init, *first);
  return init;
}

This is a very simple algorithm, but even something this simple
involves some very complicated relationships between types.

(1) first and last are of the same type, InputIterator.  
(2) InputIterator satisfies the input iterator axioms.  
(3) The type T is the same as InputIterator's value type.
(4) The type BinaryOperation satisfies the binary function axioms.
(5) BinaryFunction's first argument type, second argument type, 
    and return type, are all the same as InputIterator's value
    type.

It's these type relationships that can't be modelled by inheritance:
inheritance only involves one very stylized form of type
transformation.  It doesn't have any notion of two types that always
have to transform together.

Note, by the way, that some of these type relationships can't be
expressed within C++ either: C++ is not an ideal language for writing
generic algorithms.  At least C++ doesn't get in the way, though.  A
language with static typing and inheritance, but without genericity,
would get in the way.

(Java also has one other limitation that makes this sort of thing
difficult: the basic types, like int, double, and char, aren't part of
its type hierarchy.  So if you come up with a solution that relies on
inheritance, that solution automatically excludes the basic types.
That's unfortunate: I find that vectors of int, for example, are
useful.  However, this limitation is just an accidental quirk of one
particular language; Eiffel and Smalltalk, for example, don't have
this problem.)
From: Thant Tessman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336B72C8.41C6@nospam.acm.org>
Alexander Stepanov wrote:

> Being responsible for the standard template library, I could assure you 
> that C++ does have merits. I tried to implement STL in a variety of 
> languages and failed. I had a very modest goal - to be able to express 
> linear search in a such way that it would work for any data structure for 
> which it makes sense. C++ was the only language in which I could do it.  
> [...]  And, yes, I tried Scheme, ML, Ada, Java...  And I tried them quite 
> seriously, spending years on every fad that comes out of POPL.

I will admit that templates and the STL are utterly amazing creations 
given the fact that it's C++, but I find the above VERY hard to believe.

Here's why: I've implemented function overloading in Scheme using 
macros.  This, plus Scheme's dynamic type system gives the programmer 
just as much genericity (if not more genericity) in Scheme as in C++.  
My implementation was of course slower than C++'s templates (because 
dispatching on overloaded functions was done dynamically), but believe 
me it was far easier to implement than the STL (let alone templates).  
And the programming language Dylan provides this expressiveness at the 
language level giving the compiler the chance to statically dispatch 
when possible in order to provide good performance.

As for SML, C++'s template functions are a pale imitation of SML's 
support for generic polymorphism, and C++'s template classes are 
a pale imitation of SML's functors.  There are differences, some 
possibly in C++'s favor.  For example, SML doesn't allow overloaded 
functions.  But to the degree that overloaded functions are resolved 
statically, overloading is merely syntactic sugar.  And to the degree 
that they are resolved dynamically (via virtual member functions in
the case of C++), we're talking OO, which you said you don't like.

Another difference between SML's functors and C++' templates is that 
templates are generiated automatically in pieces as needed.  Although
some people hate this, I happen to think this is cool, and I suspect 
that this is at the heart of any advantage you may think C++ has over 
SML.  This latter property of templates has allowed me to do some truly 
scary things with templates that I don't think I could do using functors.  
But the template tricks I've come up with are UNIVERSALLY used to get 
around the other problems of C++.

As for the STL itself, as cool as it is, it really comes off as being
an attempt to make it easier to do the kind of things in C++ that have 
always been easy in other languages.  I welcome examples to the contrary
if they exist.

***

Alexander Stepanov's dissillusionment with OO reminds me of something
I've been thinking about for a while.  Object-oriented methodology
is a collection of techniques for managing program complexity.  A
very large "a-ha" for me was that higher-order functions could be
used to build OO systems.  Therefore, higher-order functions are
a more fundamental/powerful concept than OO.

(The only reason to build OO into the language (as opposed to 
providing it in a library) is to give the compiler the chance to 
optimize on those techniques, which is why Dylan, for example, 
provides both higher-order functions and OO.)

The strange thing is that I've never seen a defender of C++ 
acknowledge the power of higher-order functions.  Higher-order
functions are simply functions that build other functions.  But 
I can't help but get the impression that the defenders of C++ just 
don't get it.  This would explain why they feel it is necessary to 
build all this other complex machinery.

-thant
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <E9MFtx.2An@research.att.com>
In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

> I will admit that templates and the STL are utterly amazing creations 
> given the fact that it's C++, but I find the above VERY hard to believe.

It's easy to toss gratuitous insults into what you say,
but that doesn't make your statements any more or less valid.

> Here's why: I've implemented function overloading in Scheme using 
> macros.  This, plus Scheme's dynamic type system gives the programmer 
> just as much genericity (if not more genericity) in Scheme as in C++.  
> My implementation was of course slower than C++'s templates (because 
> dispatching on overloaded functions was done dynamically), but believe 
> me it was far easier to implement than the STL (let alone templates).  
> And the programming language Dylan provides this expressiveness at the 
> language level giving the compiler the chance to statically dispatch 
> when possible in order to provide good performance.

Perhaps Alex will confirm the following:  He said that C++ was the only
language in which he could implement linear search so that it would work
on any reasonable data structure, but I suspect he may have omitted to
add ``without substantial run-time overhead compared to a straightforward
hand-coded solution.''

I do not think it's particularly difficult to write a generic linear
search in any of a number of languages, but it invariably runs much more
slowly than the same algorithm recoded for the particular data structure
being searched.

> As for SML, C++'s template functions are a pale imitation of SML's 
> support for generic polymorphism, and C++'s template classes are 
> a pale imitation of SML's functors.  There are differences, some 
> possibly in C++'s favor.  For example, SML doesn't allow overloaded 
> functions.  But to the degree that overloaded functions are resolved 
> statically, overloading is merely syntactic sugar.  And to the degree 
> that they are resolved dynamically (via virtual member functions in
> the case of C++), we're talking OO, which you said you don't like.

C++ template functions aren't an imitation of SML, because Bjarne was
unfamiliar with SML when he designed templates.  Moreover, there are
significant differences between the two notions.  See, for example,
my article ``An Example of Language-Sensitive Design'', in the Journal
of Object-Oriented Programming, Vol. 8, no. 4.  The gist of that article
is to show a C++ program that, translated directly into SML, yields a
lousy SML program.  If we redesign the program to fit well with SML,
and then try to translate it to C++, we get a lousy C++ program.  The
point is that the two languages have different enough views of the world
that the same techniques just don't apply.

> Another difference between SML's functors and C++' templates is that 
> templates are generiated automatically in pieces as needed.  Although
> some people hate this, I happen to think this is cool, and I suspect 
> that this is at the heart of any advantage you may think C++ has over 
> SML.  This latter property of templates has allowed me to do some truly 
> scary things with templates that I don't think I could do using functors.  
> But the template tricks I've come up with are UNIVERSALLY used to get 
> around the other problems of C++.

Well, if you start with the attitude that the language is full of problems
to be overcome, you'll certainly find them.  That's true of any language.

> As for the STL itself, as cool as it is, it really comes off as being
> an attempt to make it easier to do the kind of things in C++ that have 
> always been easy in other languages.  I welcome examples to the contrary
> if they exist.

The thing I find particularly interesting about STL is not that it makes
it easier to do things in C++ that I could already do in other languages.
Rather, STL makes it easier to do things EFFICIENTLY in C++ that I could
not do efficiently in ANY other language readily available to me.

It is very easy to write a library in any of a number of languages that
will sort a generic data structure, but that library will probably do a
dynamic type dispatch for every comparison.  What's nice about C++ templates
is that that dynamic type dispatch is done at compile time, and is used as
a way of getting the compiler to lay down appropriate code at run time.
Other languages I have seen either don't do that at all, or make it substantially
harder.  Of course a counterexample may exist, but if it does, it doesn't
seem to be a widespread part of current practice.

> Alexander Stepanov's dissillusionment with OO reminds me of something
> I've been thinking about for a while.  Object-oriented methodology
> is a collection of techniques for managing program complexity.  A
> very large "a-ha" for me was that higher-order functions could be
> used to build OO systems.  Therefore, higher-order functions are
> a more fundamental/powerful concept than OO.

I suspect that they are a dual, in the logical sense.
OO: `Everything is data, even programs'
FP: `Everything is program, even data'

> (The only reason to build OO into the language (as opposed to 
> providing it in a library) is to give the compiler the chance to 
> optimize on those techniques, which is why Dylan, for example, 
> provides both higher-order functions and OO.)

I think there are other reasons as well.  OOP is particularly useful
for simulations, and lots of commercial applications involve
simulation in one way or another.

> The strange thing is that I've never seen a defender of C++ 
> acknowledge the power of higher-order functions.  Higher-order
> functions are simply functions that build other functions.  But 
> I can't help but get the impression that the defenders of C++ just 
> don't get it.  This would explain why they feel it is necessary to 
> build all this other complex machinery.

Perhaps you haven't looked hard enough.  You might start with STL
function adaptors, which are nothing more or less than higher-order
functios, or come to my Usenix tutorial at the COOTS conference this
June, which will talk a good bit about how to use templates to simulate
higher-order functions in C++.  I will completely agree with you that
it would be nice if C++ had a more direct way of supporting higher-order
functions, but that desire is mostly abstract -- in practice I don't see
it getting in the way of using C++ to solve problems that arise for real.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Alexander Stepanov
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336BE05A.15FB@mti.sgi.com>
Andrew Koenig wrote:
> 
> In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:
> 
> > I will admit that templates and the STL are utterly amazing creations
> > given the fact that it's C++, but I find the above VERY hard to believe.
> 
> It's easy to toss gratuitous insults into what you say,
> but that doesn't make your statements any more or less valid.
> 
> > Here's why: I've implemented function overloading in Scheme using
> > macros.  This, plus Scheme's dynamic type system gives the programmer
> > just as much genericity (if not more genericity) in Scheme as in C++.
> > My implementation was of course slower than C++'s templates (because
> > dispatching on overloaded functions was done dynamically), but believe
> > me it was far easier to implement than the STL (let alone templates).
> > And the programming language Dylan provides this expressiveness at the
> > language level giving the compiler the chance to statically dispatch
> > when possible in order to provide good performance.
> 
> Perhaps Alex will confirm the following:  He said that C++ was the only
> language in which he could implement linear search so that it would work
> on any reasonable data structure, but I suspect he may have omitted to
> add ``without substantial run-time overhead compared to a straightforward
> hand-coded solution.''

While what you are saying is true, the amazing fact is that I could not even
do a slow generic linear search in Scheme. I taught a graduate course in 
algorithm design based on Scheme for 10 consequitive semesters. (There are
almost 500 students who had been exposed to my ridiculous attempts to express
complex algorithms in a language that hides memory, - I have been fortunate,
however, since none of them had taken me to court.) Time after time, I tried
to generalize over vectors and lists, and failed. Common Lisp is an example of
the similar attempt: the position function returns an integer index for both list
and vector if an element is found and nil otherwise. It is a not very useful
result for lists - using integers as iterator for all the sequence types is
plainly not what one needs. It is equaly important to see how subranges are
dealt with: keyword arguments :start and :end are integers - not a very useful
choice for lists.

> 
> I do not think it's particularly difficult to write a generic linear
> search in any of a number of languages, but it invariably runs much more
> slowly than the same algorithm recoded for the particular data structure
> being searched.
> 
> > As for SML, C++'s template functions are a pale imitation of SML's
> > support for generic polymorphism, and C++'s template classes are
> > a pale imitation of SML's functors.  There are differences, some
> > possibly in C++'s favor.  For example, SML doesn't allow overloaded
> > functions.  But to the degree that overloaded functions are resolved
> > statically, overloading is merely syntactic sugar.  And to the degree
> > that they are resolved dynamically (via virtual member functions in
> > the case of C++), we're talking OO, which you said you don't like.
> 
> C++ template functions aren't an imitation of SML, because Bjarne was
> unfamiliar with SML when he designed templates.  Moreover, there are
> significant differences between the two notions.  See, for example,
> my article ``An Example of Language-Sensitive Design'', in the Journal
> of Object-Oriented Programming, Vol. 8, no. 4.  The gist of that article
> is to show a C++ program that, translated directly into SML, yields a
> lousy SML program.  If we redesign the program to fit well with SML,
> and then try to translate it to C++, we get a lousy C++ program.  The
> point is that the two languages have different enough views of the world
> that the same techniques just don't apply.

Well, a world recognized ML authority spent some time working with me
on - guess what - expressing linear search. I still have a long message from
him explaining why it could not be done. I would gladly switch to ML if
somebody can show me how I can express what I want to express in it. I have
no personal stake in C++. I use it as a tool. And both Bjarne and Andy could
attest to my long standing criticism of some of its main features. 

> 
> > Another difference between SML's functors and C++' templates is that
> > templates are generiated automatically in pieces as needed.  Although
> > some people hate this, I happen to think this is cool, and I suspect
> > that this is at the heart of any advantage you may think C++ has over
> > SML.  This latter property of templates has allowed me to do some truly
> > scary things with templates that I don't think I could do using functors.
> > But the template tricks I've come up with are UNIVERSALLY used to get
> > around the other problems of C++.
> 
> Well, if you start with the attitude that the language is full of problems
> to be overcome, you'll certainly find them.  That's true of any language.
> 
> > As for the STL itself, as cool as it is, it really comes off as being
> > an attempt to make it easier to do the kind of things in C++ that have
> > always been easy in other languages.  I welcome examples to the contrary
> > if they exist.


I guess you are a much better programmer than I am, since you find that it
is easy to do what I find totally impossible. If you ever come to the Bay 
Area, please stop by and give a talk on library design to our group.
(The remark is addressed to Thant Tessman, and not to Andy Koenig. Andy, 
however, is always welcome too, and I hope that he knows it.)

> 
> The thing I find particularly interesting about STL is not that it makes
> it easier to do things in C++ that I could already do in other languages.
> Rather, STL makes it easier to do things EFFICIENTLY in C++ that I could
> not do efficiently in ANY other language readily available to me.
> 
> It is very easy to write a library in any of a number of languages that
> will sort a generic data structure, but that library will probably do a
> dynamic type dispatch for every comparison.  What's nice about C++ templates
> is that that dynamic type dispatch is done at compile time, and is used as
> a way of getting the compiler to lay down appropriate code at run time.
> Other languages I have seen either don't do that at all, or make it substantially
> harder.  Of course a counterexample may exist, but if it does, it doesn't
> seem to be a widespread part of current practice.
> 
> > Alexander Stepanov's dissillusionment with OO reminds me of something
> > I've been thinking about for a while.  Object-oriented methodology
> > is a collection of techniques for managing program complexity.  A
> > very large "a-ha" for me was that higher-order functions could be
> > used to build OO systems.  Therefore, higher-order functions are
> > a more fundamental/powerful concept than OO.
> 
> I suspect that they are a dual, in the logical sense.
> OO: `Everything is data, even programs'
> FP: `Everything is program, even data'

Hear, hear. One of them tells us that binary search is an object, while the
other insists that stack is a function. 

> 
> > (The only reason to build OO into the language (as opposed to
> > providing it in a library) is to give the compiler the chance to
> > optimize on those techniques, which is why Dylan, for example,
> > provides both higher-order functions and OO.)
> 
> I think there are other reasons as well.  OOP is particularly useful
> for simulations, and lots of commercial applications involve
> simulation in one way or another.
> 
> > The strange thing is that I've never seen a defender of C++
> > acknowledge the power of higher-order functions.  Higher-order
> > functions are simply functions that build other functions.  But
> > I can't help but get the impression that the defenders of C++ just
> > don't get it.  This would explain why they feel it is necessary to
> > build all this other complex machinery.
> 
> Perhaps you haven't looked hard enough.  You might start with STL
> function adaptors, which are nothing more or less than higher-order
> functios, or come to my Usenix tutorial at the COOTS conference this
> June, which will talk a good bit about how to use templates to simulate
> higher-order functions in C++.  I will completely agree with you that
> it would be nice if C++ had a more direct way of supporting higher-order
> functions, but that desire is mostly abstract -- in practice I don't see
> it getting in the way of using C++ to solve problems that arise for real.

I should add that I had been a proponent of functional programming for 
more than a decade - one of my first papers was presented at the First
Functional Programming Conference. I have acknowledged the power of higher
order functions. My problem was that I was not interested in doing tail
recursive factorials or memoizing Fibonacci numbers - I wanted to implement
algorithms that people could use when they build their systems. And that
forced me to use C++.

And, believe me, my life would have been much easier if I stayed with 
one of the officially approved religions. In the circles where I circulate,
it is not politically acceptable to defend C++, especially if you like
C and not ++. I wish I could love Java...

> --
>                                 --Andrew Koenig
>                                   ···@research.att.com
>                                   http://www.research.att.com/info/ark

-- 
Alexander Stepanov
········@mti.sgi.com

Silicon Graphics
2011 N. Shorline Boulevard
Mountain View, CA 94043-1389

tel.: (415)933-6121
From: Marnix Klooster
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336D8E6E.17BA@research.baan.nl>
Alexander Stepanov wrote, among other things:

> I should add that I had been a proponent of functional programming for
> more than a decade - one of my first papers was presented at the First
> Functional Programming Conference. I have acknowledged the power of higher
> order functions. My problem was that I was not interested in doing tail
> recursive factorials or memoizing Fibonacci numbers - I wanted to implement
> algorithms that people could use when they build their systems. And that
> forced me to use C++.
> 
> And, believe me, my life would have been much easier if I stayed with
> one of the officially approved religions. In the circles where I circulate,
> it is not politically acceptable to defend C++, especially if you like
> C and not ++. I wish I could love Java...

You might want to look at Pizza (http://www.cis.unisa.edu.au/~pizza). 
That's Java plus higher-order functions, parametric polymorphism (nice
for sorting!) and algebraic datatypes.  If it doesn't make Java lovable,
it certainly makes it usable.

[Followups adapted.]

> Alexander Stepanov
> ········@mti.sgi.com

Groetjes,
 <><
Marnix
--
Marnix Klooster              |   If you post a reply to a
·········@research.baan.nl   |   News article of mine, please
······@worldonline.nl        |   send me a copy by e-mail.
From: Lyman S. Taylor
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kka3u$cdg@pravda.cc.gatech.edu>
In article <·············@mti.sgi.com>,
Alexander Stepanov  <········@mti.sgi.com> wrote:
>Andrew Koenig wrote:
>> 
...
>> on any reasonable data structure, but I suspect he may have omitted to
>> add ``without substantial run-time overhead compared to a straightforward
>> hand-coded solution.''
>
>While what you are saying is true, the amazing fact is that I could not even
>do a slow generic linear search in Scheme 
...
>algorithm design based on Scheme for 10 consequitive semesters. (There are
...

  Hmmm, I suppose by generic linear search you mean something analogous
  to Common Lisp's FIND.  If so, then the following seems to generically
  do the job. It is a tad crude, but I only spent but an little over 
  an hour and a half developing it. :-)  [ And a less times coming
  up with the examples and doing some testing... ]  It tried not to 
  use anything that didn't have simple Scheme translation. Or most
  other functional languages....  ( e.g. there no dependence on 
  CLOS  and multiple values can be mimiced by returning a list/structure ). 
  
  [ More comments after the code... ] 

------------------------8< generic_find.lisp >8-------------------------

(defun make-list-iterator ( some-list &optional  start end )
 "Return a list iterator.  This iterator can be queried about it's 
  value, forward, end?, and interface functions. The optional start 
  and end should be a sublist of the argument. WARNING the current
  implementation doesn't confirm this." 
  (unless start 
    (setq start some-list))
  (labels ((forward () (if (eql end start )
                         (error "At end of sequence")
                         (setq start (rest start))))
           (backward () (error "No backward protocol on this type"))
           (value    () (if (eql end start )
                            (error "At end of sequence")
                            (first start)))

           (end? ()  (eql end start)) 
           (interface () (values #'forward #'value  #'end?  #'backward )))
    #'(lambda (action )
        (case  action 
          (interface (interface) )
          (value     (value))
          (forward   (forward))
          (end?      (end?))
          (otherwise (error "unknown action"))))))

#| 
   Usage Examples:

   Prints all of the elements of the list and returns ALL-DONE. 

   (multiple-value-bind ( forward value end?  ) 
                        (funcall (make-list-iterator '( a b c )) 'interface)
     (labels ((demo-loop () 
                (cond ((funcall end?) 'all-done)
                      (t (print (funcall value)) 
                         (funcall forward) 
                         (demo-loop)))))
       (demo-loop)))

   Same as above with slightly different approach. 

   (let ((iter  (make-list-iterator '(a b c))))
     (labels ((demo-loop () 
                (cond ((funcall iter 'end?) 'all-done)
                      (t (print (funcall iter 'value))
                         (funcall iter 'forward)
                         (demo-loop)))))
      (demo-loop)))

    Prints B through D then returns ALL-DONE. 

   (let* ((demo-list '(a b c d e f ))
          (iter  (make-list-iterator demo-list 
                                     (nthcdr 1 demo-list) 
                                     (nthcdr 4 demo-list )) ) )
     (labels ((demo-loop () 
                (cond ((funcall iter 'end?) 'all-done)
                      (t (print (funcall iter 'value))
                         (funcall iter 'forward)
                         (demo-loop)))))
      (demo-loop)))

|#



(defun make-vector-iterator ( some-vector &optional (start 0)  end  )
 "Return a vector iterator.  This iterator can be queried about it's 
  value, forward, end?, and interface functions. The optional start and
  end must be numbers and start < end. WARNING the current implementation
  doesn't confirm this." 
  (unless end 
    (setq end (length some-vector)))
  (labels ((forward () (if (eql end start )
                           (error "At end of sequence")
                           (setq start (1+ start))))
           (backward () (if (eql end start )
                            (error "At start of sequence")
                            (setq end (1- end ))))
           (value    () (if (eql end start )
                            (error "At end of sequence")
                            (svref some-vector start)))
           (end? ()  (eql end start))
           (interface () (values #'forward #'value  #'end?  #'backward )))
    #'(lambda (action )
        (case  action 
          (interface (interface) )
          (value     (value))
          (forward   (forward))
          (end?      (end?))
          (backward  (backward))
          (otherwise (error "unknown action"))))))


#| 
  Usage Examples: 

   Prints all of the elements and returns the symbol ALL-DONE

   (multiple-value-bind ( forward value end?  ) 
                        (funcall (make-vector-iterator '#( a b c )) 'interface)
     (labels ((demo-loop () 
                (cond ((funcall end?) 'all-done)
                      (t (print (funcall value)) 
                         (funcall forward) 
                         (demo-loop)))))
       (demo-loop)))

    Same thing as above slightly different interface 

 (let ((iter  (make-vector-iterator '#(a b c))))
     (labels ((demo-loop () 
                (cond ((funcall iter 'end?) 'all-done)
                      (t (print (funcall iter 'value))
                         (funcall iter 'forward)
                         (demo-loop)))))
      (demo-loop)))

     Prints only  B through D then returns ALL-DONE

   (let* ((demo-vector '#(a b c d e f ))
          (iter  (make-vector-iterator demo-vector  1 4 )))
     (labels ((demo-loop () 
                (cond ((funcall iter 'end?) 'all-done)
                      (t (print (funcall iter 'value))
                         (funcall iter 'forward)
                         (demo-loop)))))
      (demo-loop)))

|#


(defun make-iterator ( object ) 
 "Return the appropriate iterator based upon the type of the given object. 
  At present this should either be a list or a vector." 
  (cond ((typep object 'list) (make-list-iterator object ))
        ((typep object 'vector ) (make-vector-iterator object))
        (t (error "No iterator for this type: ~A" (type-of object)))))



;;; The following version takes advantage of the multivalued INTERFACE 
;;; function. It binds the specific iterator state changing functions
;;; to their "generic" names. 

(defun generic-find1 ( item sequence )
 "Return an iterator at the first occurance of item in the sequence.
  Otherwise invokes an error [ Admittedly a bit drastic, could be rewritten
  to return NIL. FUNCTIONP would distinguish the results.]."

 (let ( (iter (make-iterator sequence )) )
   (multiple-value-bind ( forward value end?  ) (funcall iter 'interface)
     (labels ((find-loop () 
                (cond ((funcall end?) (error "not found"))
                      ((eql item (funcall value)) iter)
                      (t (funcall forward) 
                         (find-loop)))))
       (find-loop)))))


;;; The following version requires a dispatch through the iterator's 
;;; case statement. Doesn't require a call to interface. And allows
;;; multiple iterators to be used together without confusion over
;;; the interace functions. ( a tad slower due to the indirection though).

(defun generic-find2 ( item sequence )
 "Return an iterator at the first occurance of item in the sequence.
  Otherwise invokes an error [ Admittedly a bit drastic, could be rewritten
  to return NIL. FUNCTIONP would distinguish the results.]."

  (let ( (iter (make-iterator sequence )) )
    (labels ((find-loop () 
               (cond ((funcall iter 'end?) (error "not found"))
                     ((eql item (funcall iter 'value)) iter )
                     (t (funcall iter 'forward)
                        (find-loop)))))
      (find-loop))))

(defmacro with-iterator ( iter-sequence &rest body )
 "Any of the iterator's interface functions may be call/funcalled within
  the body. Additionally the iterator is bound the named specified by the 
   iterartor sequence list." 
  `( let (( ,(first iter-sequence) (make-iterator ,(second iter-sequence))))
         (multiple-value-bind (forward value end? backward ) 
                              (funcall ,(first iter-sequence) 'interface)
           ,@body )))

;;; The following is a rehash of find1, but using a macro to "hide" some
;;; of the overhead of extracting the iterator's interface functions. 
;;;

(defun generic-find3 ( item sequence )
 "Return an iterator at the first occurance of item in the sequence.
  Otherwise invokes an error [ Admittedly a bit drastic, could be rewritten
  to return NIL. FUNCTIONP would distinguish the results.]."
 (with-iterator (iter sequence )
   (labels ((find-loop () 
                (cond ((funcall end?) (error "not found"))
                      ((eql item (funcall value)) iter)
                      (t (funcall forward) 
                         (find-loop)))))
       (find-loop))))

              

#|
  Usage Examples..

  (funcall (generic-find1 'b '(a b c)) 'value)
  (funcall (generic-find2 'b '(a b c)) 'value)
  (funcall (generic-find3 'b '(a b c)) 'value)

  (funcall (generic-find1 'b '#(a b c)) 'value)
  (funcall (generic-find2 'b '#(a b c)) 'value)
  (funcall (generic-find3 'b '#(a b c)) 'value)

|#

---------------------------8< end of generic_find.lisp >8-----------------

Collections in Dylan have an iteration protocol that allows one to 
"generically iterate" with collections, but allowing collection subtype
specific iteration functions to be defined for efficiency. 

http://www.harlequin.com/books/DRM/drm-102.html#MARKER-9-268


The other thing I find curious is that, in admittedly simplified viewpoint,
templates simply are a "code writing" mechanism.  But so are Common Lisp
macros.  It seems like most of the functionality of C++'s templates 
could be implemented as CL macro(s). Maybe seriously non trival macros 
but none the less, where's the "show stopper"??  This discounts the
the functionality of causing a compile time error if interface isn't
completely implemented ( since CL is dynamic that doesn't "matter" 
so much in it's context. ). And also any of the "value semantics"
cruft that doesn't matter either in "reference semantics" languages. 

Along the lines of with-iterator macro above, create generic functions
bodies and fill in the details later. The calls to the template functions
are customized at compile time by placing bodies with calls to them
inside of a macro.
 
    i.  define the generic template functions with a macro. 

	(define-template-fcn  generic-find ( T ) ( item  ( sequence T )) 
	   .... body of the function using the generic iterator
		names ... ) 

      Puts the body of the function and substutuion information into
      a repository for later retrieval, copying, customization. 

    ii. add the type as part of specification. 

          (using-generics  ( sequence sequence-type )
              ....
	      (generic-find  item sequence )
               ...  ) 

         which writes a context specific version of the generic-find, given 
         sequence specfic functions ( with possibly name-mangled identifiers).
          
         [ With more booking overhead could keep track if the had been 
		instantiated before and just reuse that version. ]
-- 

Lyman S. Taylor			"Because no matter where you go,
(·····@cc.gatech.edu)			there you are."
						Buckaroo Banzai
From: Thant Tessman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336E151B.41C6@nospam.acm.org>
Alexander Stepanov wrote:

> [...] the amazing fact is that I could not even do a slow 
> generic linear search in Scheme.  [...] Time after time, I 
> tried to generalize over vectors and lists, and failed. 
> Common Lisp is an example of the similar attempt: the position 
> function returns an integer index for both list and vector if an 
> element is found and nil otherwise. It is a not very useful
> result for lists - using integers as iterator for all the 
> sequence types is plainly not what one needs. It is equaly 
> important to see how subranges are dealt with: keyword 
> arguments :start and :end are integers - not a very useful
> choice for lists.

Yeah, integers make crummy iterators.  So what?  I still don't
understand why you couldn't use CLOS generic functions to do
*exactly* the same kind of thing you did in the STL.  Now that
I think about it, the biggest trick behind the STL is getting the iterator 
behavior worked out.  

Help me 
out here with an example if you could.


Andrew Koenig wrote:

> I suspect that they are a dual, in the logical sense.
> OO: `Everything is data, even programs'
> FP: `Everything is program, even data'

I've considered this view myself.  It might be true if OO made 
it easy to treat programs as data, but this typically isn't the 
case.  Besides, higher-order functions are useful even in OO 
languages.



> Perhaps you haven't looked hard enough.  [...to find a defender
> of C++ acknowledge higher-order functions...]  You might start with 
> STL function adaptors, which are nothing more or less than higher-
> order functios, or come to my Usenix tutorial at the COOTS conference 
> this  June, which will talk a good bit about how to use templates 
> to simulate higher-order functions in C++.

I've done it myself even before knowing anything about the STL.  I was 
really proud of myself for figuring out that this could be done in C++ 
until I thought about how much effort it took to get what really
was a cheesy technique to work at all.

Besides, this doesn't sound so much like an acknowledgement of the 
power of higher-order functions as much as it sounds like yet another
in a long history of desparate attempts to defend C++ from 
clearly superior alternatives.  (Yes C++ supports higher-order
functions.  Well, actually it doesn't, but you can build these
things that you can use sort of like you would use higher-order
functions in certain situations.  Yeah they're a pain-in-the-ass
to build, and yeah, your compiler may not handle it yet, but at 
least you can keep using C++, which after all, is a very successful 
language.)


Alexander Stepanov wrote:

> I should add that I had been a proponent of functional programming 
> for more than a decade - one of my first papers was presented at the 
> First Functional Programming Conference. I have acknowledged the power 
> of higher order functions. My problem was that I was not interested 
> in doing tail recursive factorials or memoizing Fibonacci numbers - 
> I wanted to implement algorithms that people could use when they 
> build their systems. And that forced me to use C++.

Gee, my hatred for C++ was fostered by doing real-time 3D graphics on
SGI machines.  The only help I want building systems on this machine 
is an alternative to C++.  And as soon as I have time to get the 
OpenGL working under something else (most likely SML), I'm going to 
drop C++ as fast as I can.  In the mean-time I'm going to bitch and 
moan about C++ because it makes me feel a little better.

-thant

--
Philosophy is the search for the set of principles 
that will finally free us from the need to think.
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <E9qIFI.AB1@research.att.com>
In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

> Andrew Koenig wrote:

> > I suspect that they are a dual, in the logical sense.
> > OO: `Everything is data, even programs'
> > FP: `Everything is program, even data'

> I've considered this view myself.  It might be true if OO made 
> it easy to treat programs as data, but this typically isn't the 
> case.  Besides, higher-order functions are useful even in OO 
> languages.

Sure, but function objects are just objects and can be manipulated
like other objects.

> Besides, this doesn't sound so much like an acknowledgement of the 
> power of higher-order functions as much as it sounds like yet another
> in a long history of desparate attempts to defend C++ from 
> clearly superior alternatives.

Desparate?  Hardly.  It's an expression of the pragmatic observation
that an awful lot of programs -- and programmers -- don't make a great
deal of use of higher-order functions.  If they're important to you,
then by all means choose a language that supports them the way you like.
But don't assume that your taste is universal.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <s6yenbkm28e.fsf@aalh02.alcatel.com.au>
···@research.att.com (Andrew Koenig) writes:

> > Besides, this doesn't sound so much like an acknowledgement of the 
> > power of higher-order functions as much as it sounds like yet another
> > in a long history of desparate attempts to defend C++ from 
> > clearly superior alternatives.
> 
> Desparate?  Hardly.  It's an expression of the pragmatic observation
> that an awful lot of programs -- and programmers -- don't make a great
> deal of use of higher-order functions.  

Huh? I'm sure hardly any programmers use higher-order
functions. Perhaps that's because hardly any main stream languages
support it? It's a bit hard to write functional COBOL you know.

When did you observe a group of programmers using a higher-order
functional language that did not use them?
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <E9t7or.6tD@research.att.com>
In article <···············@aalh02.alcatel.com.au> ·············@alcatel.com.au (Chris Bitmead uid(x22068)) writes:

> Huh? I'm sure hardly any programmers use higher-order
> functions. Perhaps that's because hardly any main stream languages
> support it? It's a bit hard to write functional COBOL you know.

Agreed.

> When did you observe a group of programmers using a higher-order
> functional language that did not use them?

Never -- but it doesn't matter, because the higher-order functional
languages do not support -- and their communities consider irrelevant --
other key aspects of programming languages that most commercial
programmers consider indispensible.

For example, a good chunk of commercial programming practice today
is related in some way to object-oriented design.  A key notion in
object-oriented design is the use of objects to represent concepts
in the program being designed.  An important characteristic of objects
is their ability to store mutable state information.

The higher-order functional languages generally do not support mutable
state, because doing so would compromise referential transparency.  In
particular, higher-order functions seem to be the most useful when
combined with lazy evaluation, which in turn does not seem to combine
well with the idea of mutable state.  So these well known and widely
used design techniques simply do not apply in such languages.

That means, in turn, that if you wish to program in functional style,
you really have to change almost everything about how you think
about programming.  It's not just a matter of using higher-order
functions or not using them.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: David Monniaux
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kq8jp$3l0@cri.ens-lyon.fr>
Andrew Koenig (···@research.att.com) wrote:
: In article <···············@aalh02.alcatel.com.au> ·············@alcatel.com.au (Chris Bitmead uid(x22068)) writes:
: Never -- but it doesn't matter, because the higher-order functional
: languages do not support -- and their communities consider irrelevant --
: other key aspects of programming languages that most commercial
: programmers consider indispensible.

This argument, which is basically that academic people design pretty languages
that are unuseable in "real" environments is somewhat flawed (see below).

: For example, a good chunk of commercial programming practice today
: is related in some way to object-oriented design.  A key notion in
: object-oriented design is the use of objects to represent concepts
: in the program being designed.  An important characteristic of objects
: is their ability to store mutable state information.

You should perhaps try "semi functional" languages like ML, especially
Objective CAML. It seems to have what most people here want:
- functional features
- imperative features
- objects (not very used, since the functors seem more powerful for
  most purposes)
- functors and modules

When it comes to implementing structures and having generic algorithms,
I think modules and functors are very powerful. You can, for instance,
write a whole module using, say, a priority queue. You test it with,
say, a heap for that queue. Then you feel that more appropriate
structures may be better (say, you want to have a disk-cached queue).
You then abstract the queue, making it a parameter. You can use your
module, by simply instanciating it with your heap or your nifty
disk-cached system.
The standard library features Map's, Set's etc..., and more structures
are easily coded. I've myself added Heap's etc...

http://pauillac.inria.fr/ocaml

When it comes to efficiency, O'Caml features both a bytecode compiler,
for quick compiles during development, and a native code compiler.
It is the implementation language for production-stage projects such
as Coq (a theorem prover which is used to prototype critical systems,
such as embedded airplane systems) and Ensemble. The O'Caml compiler
is itself written in O'Caml.

-- 
"If computers worked, it'd be known."
Computer science student at ENS, Lyon, France
http://www.ens-lyon.fr/~dmonniau

PS: As for the general tone of the discussion, I'm somehow disgusted.
Many people here seem to argue that their way is the only way, and
that people who don't agree have obviously never done "serious"
programming. The quality of the talk would certainly improve if
we spent less time accusing each other of, basically, incompetency,
and more time actually working on design.
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <E9v3o5.66@research.att.com>
In article <··········@cri.ens-lyon.fr> ········@ens-lyon.fr (David Monniaux) writes:

> Andrew Koenig (···@research.att.com) wrote:

> : Never -- but it doesn't matter, because the higher-order functional
> : languages do not support -- and their communities consider irrelevant --
> : other key aspects of programming languages that most commercial
> : programmers consider indispensible.

> This argument, which is basically that academic people design pretty languages
> that are unuseable in "real" environments is somewhat flawed (see below).

That's not my argument.  Rather, it is that there several schools of
language design, each of whose adherents considers irrelevant some things
that other schools' adherents consider essential.  Each school believes
its favorite environments and problems to be the only `real' ones.

> You should perhaps try "semi functional" languages like ML, especially
> Objective CAML. It seems to have what most people here want:
> - functional features
> - imperative features
> - objects (not very used, since the functors seem more powerful for
>   most purposes)
> - functors and modules

I have used ML a good bit, but I would have a very hard time convincing
my colleagues on the business side of the house to use it, if only
because the first prerequisite is the widespread availability of a
commercially supported compiler on each of several platforms and
corresponding commercial training courses.  Plus a significant commercial
user community -- no one wants to be the first to bet part of their
business on something.

Incidentally, the ML that I've used has neither inheritance nor
overloading, nor is it likely to acquire them any time soon.

> When it comes to implementing structures and having generic algorithms,
> I think modules and functors are very powerful. You can, for instance,
> write a whole module using, say, a priority queue. You test it with,
> say, a heap for that queue. Then you feel that more appropriate
> structures may be better (say, you want to have a disk-cached queue).
> You then abstract the queue, making it a parameter. You can use your
> module, by simply instanciating it with your heap or your nifty
> disk-cached system.
> The standard library features Map's, Set's etc..., and more structures
> are easily coded. I've myself added Heap's etc...

Modules and functors are very powerful indeed, for similar reasons to
the ones that make C++ templates powerful.

> PS: As for the general tone of the discussion, I'm somehow disgusted.
> Many people here seem to argue that their way is the only way, and
> that people who don't agree have obviously never done "serious"
> programming. The quality of the talk would certainly improve if
> we spent less time accusing each other of, basically, incompetency,
> and more time actually working on design.

I think we're in violent agreement.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: David Monniaux
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5ksm5n$v8@cri.ens-lyon.fr>
Andrew Koenig (···@research.att.com) wrote:
: In article <··········@cri.ens-lyon.fr> ········@ens-lyon.fr (David Monniaux) writes:
: I have used ML a good bit, but I would have a very hard time convincing
: my colleagues on the business side of the house to use it, if only
: because the first prerequisite is the widespread availability of a
: commercially supported compiler on each of several platforms and
: corresponding commercial training courses. Plus a significant commercial
: user community -- no one wants to be the first to bet part of their
: business on something.

In a nutshell: ML won't be used commercially because there's no commercial
compiler for it, and surely people won't start making a commercial compiler
for it if nobody uses it in the commercial world.
:-)

The situation may be different here, as Caml has become one of the commonly
taught languages at college level. However, the main problem is that the
industry, as you said, is very conservative, and it takes tons of resources
(think of all the hype Sun had to build around Java, which is not even
"new" technology, since it's basically a scaled-down C++ with a GC) to
have it accept things it is not used to.

However, I can tell you that O'Caml has begun to catch on. It is, for
instance, used to prototype airplane embedded systems (if it is not a
"serious" application, I don't see what is "serious" :-) ).
The question is whether it will remain a teaching language, used only
in niche applications such as prototyping and proofs on safety-critical
systems, or whether it'll come mainstream.

: Incidentally, the ML that I've used has neither inheritance nor
: overloading, nor is it likely to acquire them any time soon.

O'Caml has those but, as I said, few people actually use its OO features.

-- 
Computer science student at ENS, Lyon, France
http://www.ens-lyon.fr/~dmonniau
From: Thant Tessman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3371EECE.41C6@nospam.acm.org>
David Monniaux wrote:


> In a nutshell: ML won't be used commercially because there's no 
> commercial compiler for it, and surely people won't start making 
> a commercial compiler for it if nobody uses it in the commercial 
> world.
>
> :-)
> 
> [...]


  http://www.harlequin.com/mlworks/Welcome.html
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <E9vG44.Cpq@research.att.com>
In article <·········@cri.ens-lyon.fr> ········@ens-lyon.fr (David Monniaux) writes:

> In a nutshell: ML won't be used commercially because there's no commercial
> compiler for it, and surely people won't start making a commercial compiler
> for it if nobody uses it in the commercial world.
> :-)

Absolutely correct, unfortunately.

There is a superb compiler available -- for free -- but its authors
don't seem to be interested in turning it into something that
would be useful for real work.  Among the things missing is accurate
documentation of the run-time libraries, a stable way of interfacing
with the underlying operating system, and a way of creating
stand-alone executables without undue space overhead.

The compiler folks could easily solve these problems if they wanted to.
But it doesn't seem to be important to them.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Erik Naggum
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3072118514546808@naggum.no>
* David Monniaux
| In a nutshell: ML won't be used commercially because there's no
| commercial compiler for it, and surely people won't start making a
| commercial compiler for it if nobody uses it in the commercial world.
| :-)

* Andrew Koenig
| Absolutely correct, unfortunately.

The Harlequin Group made MLWorks available for beta testing last fall.  the
beta license expired 1997-01-01, after which I received a questionnaire and
some notes on how to get the commercial product.  I elected not to buy it.
well over 100 people got a copy of this product (and some of the mailings,
hence I know the numbers).

take a look at <URL:http://www.harlequin.com/full/products/sp/mlworks.html>

you can even download an evaluation version.  yes, this products exists is
available on a large number of platforms.

I hope you're better informed in other cases where you use "absolutely
correct" about something, Andrew.

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: Richard A. O'Keefe
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kupq4$6nj$1@goanna.cs.rmit.edu.au>
>* David Monniaux
>| In a nutshell: ML won't be used commercially because there's no
>| commercial compiler for it,...

>* Andrew Koenig
>| Absolutely correct, unfortunately.

Erik Naggum <····@naggum.no> writes:
>The Harlequin Group made MLWorks available for beta testing last fall.

It's also worth noting that the Poplog system (Common Lisp, Prolog, Pop-11,
powerful editor VED, more documentation than a strong man can lift ...)
has included ML for several years.  I had a student who was using it
several years back.  It worked pretty well.  All the Poplog languages
interoperate quite smoothly, and you have been able to mix in dynamically
loaded C, Fortran, &c since the earliest days.

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Dave MacQueen
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <yr01n2q45ndy.fsf@slocum.cs.bell-labs.com>
···@research.att.com (Andrew Koenig) writes:

> In article <·········@cri.ens-lyon.fr> ········@ens-lyon.fr (David Monniaux) writes:
> 
> > In a nutshell: ML won't be used commercially because there's no commercial
> > compiler for it, and surely people won't start making a commercial compiler
> > for it if nobody uses it in the commercial world.
> > :-)
> 
> Absolutely correct, unfortunately.
> 
> There is a superb compiler available -- for free -- but its authors
> don't seem to be interested in turning it into something that
> would be useful for real work.  Among the things missing is accurate
> documentation of the run-time libraries, a stable way of interfacing
> with the underlying operating system, and a way of creating
> stand-alone executables without undue space overhead.
> 
> The compiler folks could easily solve these problems if they wanted to.
> But it doesn't seem to be important to them.
> -- 
> 				--Andrew Koenig
> 				  ···@research.att.com
> 				  http://www.research.att.com/info/ark

I infer that this barb is directed at SML/NJ.  In fact, these points
are being addressed, and a major new release will be announced before
too long.  Regarding documentation of the library, see

  http://www.research.att.com/~jhr/sml/basis/sml-std-basis.html

There are a considerable number of modules in this new Basis library
that are there to support "real work", including a number of modules
that provide interfaces to the underlying operating system, be it
Unix or Windows.  

Watch for news in the next couple of months at our web site:

  http://cm.bell-labs.com/cm/cs/what/smlnj/index.html

-- 
Dave MacQueen
········@research.bell-labs.com
Room 2A-431, Bell Labs, 700 Mountain Ave, Murray Hill, NJ 07974
From: Matt Kennel (Remove 'nospam' to reply)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5nd19u.fv.kennel@lyapunov.ucsd.edu>
On Thu, 8 May 1997 16:50:28 GMT, Andrew Koenig <···@research.att.com> wrote:
:In article <·········@cri.ens-lyon.fr> ········@ens-lyon.fr (David Monniaux) writes:
:
:> In a nutshell: ML won't be used commercially because there's no commercial
:> compiler for it, and surely people won't start making a commercial compiler
:> for it if nobody uses it in the commercial world.
:> :-)
:
:Absolutely correct, unfortunately.
:
:There is a superb compiler available -- for free -- but its authors
:don't seem to be interested in turning it into something that
:would be useful for real work.  
: Among the things missing is accurate
:documentation of the run-time libraries, a stable way of interfacing
:with the underlying operating system, and a way of creating
:stand-alone executables without undue space overhead.
:
:The compiler folks could easily solve these problems if they wanted to.
:But it doesn't seem to be important to them.

There are two problems:

   1) researchers get funded to do research, not production, and many of
      the commercially important requirements do not advance research.
      It's not a question of having "no interest" 
      
   2) 'commercial people' often seem to have an anti-intellectual attitude
      towards the products of research and in fact resarchers themselves,
      which is often derived from a mistaken impression of the results of
      tendency #1.
      
      For example, if they decided otherwise, and hired former students and
      postdocs of the research group I'm sure lots of progress could
      be made. 

:				--Andrew Koenig
:				  ···@research.att.com

-- 
Matthew B. Kennel/Institute for Nonlinear Science, UCSD/
Don't blame me, I voted for Emperor Mollari. 
From: Daniel Wang
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <r8td8r16drq.fsf@atomic.CS.Princeton.EDU>
>>>>> "David" == David Monniaux <········@ens-lyon.fr> writes:

    David> In a nutshell: ML won't be used commercially because there's no
    David> commercial compiler for it, and surely people won't start making
    David> a commercial compiler for it if nobody uses it in the commercial
    David> world.  :-)

Bzzt see
http://www.harlequin.com/mlworks/Welcome.html
From: Daniel Wang
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <r8tk9lb5qlk.fsf@trek.CS.Princeton.EDU>
>>>>> "Andrew" == Andrew Koenig <···@research.att.com> writes:

    Andrew> Never -- but it doesn't matter, because the higher-order
    Andrew> functional languages do not support -- and their communities
    Andrew> consider irrelevant -- other key aspects of programming
    Andrew> languages that most commercial programmers consider
    Andrew> indispensible.

{stuff deleted}
    Andrew> For example, a good chunk of commercial programming practice
    Andrew> today is related in some way to object-oriented design. 
{stuff deleted}

Objective CAML

    Andrew> The higher-order functional languages generally do not support
    Andrew> mutable state, because doing so would compromise referential
    Andrew> transparency.  
{stuff deleted}
    Andrew> In particular, higher-order functions seem to be
    Andrew> the most useful when combined with lazy evaluation, which in
    Andrew> turn does not seem to combine well with the idea of mutable
    Andrew> state.  So these well known and widely used design techniques
    Andrew> simply do not apply in such languages.

Not all of the functional language community is tied to the idea of
referential transperency. The ML family of langauges have always had eager
evaluation, exceptions, references, and higher-order functions. Not to
mention the Scheme/Lisp community.

    Andrew> That means, in turn, that if you wish to program in functional
    Andrew> style, you really have to change almost everything about how you
    Andrew> think about programming.  It's not just a matter of using
    Andrew> higher-order functions or not using them.  

Assuming you toss the ML family of languages into the functional style, the
above statements are just wrong. Though, I have to agree programing in ML
has changed my way of thinking about programming. It's encouraged me to
write clear and correct code. 

There's functional and *purely* functional. Just like there's OO and
*purely* OO. (C++ as opposed to Smalltalk). I'd wager that any programing
style taken to an extreme is bad because it assumes there is one true way to
do something and tries to shoe horn everything into that style. Taking
things to extreme's is worth the research effort though, since you get to
learn what fits and what doesn't. Giving langauge designers a better feel
for the design space by pushing the envelop of the explored design space.

Functional languages haven't caught on commercially because they have been
primiarly used as vehicles for doing research. The parties doing the
langauge work don't have any motive to force their ideas sell their ideas to
the commerical world. Most of the functional languages are pretty new in
comparison to langues like Simula which begot C++. I'd wager that in 20 or
so years everyone will be hacking languages that look like some of the
research languages today. It's taken about the long for simple ideas like
garbage collection to get pushed into the comercial world by languages like
Java, which builds on a lot of old research.
From: Seth LaForge
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5n1s1m.d0u.sethml@agora.ugcs.caltech.edu>
On Wed, 7 May 1997 11:53:15 GMT, Andrew Koenig <···@research.att.com> wrote:
>In article <···············@aalh02.alcatel.com.au> ·············@alcatel.com.au (Chris Bitmead uid(x22068)) writes:
>> Huh? I'm sure hardly any programmers use higher-order
>> functions. Perhaps that's because hardly any main stream languages
>> support it? It's a bit hard to write functional COBOL you know.
>
>Agreed.
>
>> When did you observe a group of programmers using a higher-order
>> functional language that did not use them?
>
>Never -- but it doesn't matter, because the higher-order functional
>languages do not support -- and their communities consider irrelevant --
>other key aspects of programming languages that most commercial
>programmers consider indispensible.

I think that in context what Chris meant by "higher-order functional
language" is any language which supports higher-order functions, i.e.
supports functions and continuations as first-class objects.
Languages which support higher-order functions need not be side-effect
free, or lazy.  I've always thought that using the term "functional"
to refer to side-effect free, possibly lazy languages was a rather bad
choice of terms...

>For example, a good chunk of commercial programming practice today
>is related in some way to object-oriented design.  A key notion in
>object-oriented design is the use of objects to represent concepts
>in the program being designed.  An important characteristic of objects
>is their ability to store mutable state information.
>
>The higher-order functional languages generally do not support mutable
>state, because doing so would compromise referential transparency.  In
>particular, higher-order functions seem to be the most useful when
>combined with lazy evaluation, which in turn does not seem to combine
>well with the idea of mutable state.  So these well known and widely
>used design techniques simply do not apply in such languages.

This is simply not true.  There is nothing which ties closures to lazy
nonmutating languages.  I have found closures to be very useful in
lazy languages (Haskell), strict nonmutating languages (ML), and
side-effecting languages.  In particular, Pizza (a superset of Java;
see http://www.cis.unisa.edu.au/~pizza/) supports closures and
anonymous functions quite nicely, and Sather
(http://www.icsi.berkeley.edu/~sather/) likewise supports closures in
a rather unique way.  Note that both of these are OO langauges which
rely on side effects all the time.

I have found the closures in these languages to be really useful.  In
writing a ray tracer in Sather, I used closures in the parser to
represent partially-evaluated portions of the parse tree for later
evaluation (the reason this was necessary has to do with grotty
details of OpenInventor syntax which I won't go into here).  I used
closures and anonymous functions extensively in implementing a fractal
image compression algorithm in Pizza.

>That means, in turn, that if you wish to program in functional style,
>you really have to change almost everything about how you think
>about programming.  It's not just a matter of using higher-order
>functions or not using them.

It's true that using higher-order functions effectively requires a
slight change in thinking, but it certainly doesn't require you change
everything, and it doesn't require that you use lazy side-effect free
languages.  In my experience, closures simplify many programming
tasks, no matter what language you're working in.  They are by no
means necessary, but they're really nice.

Seth
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-0905971803390001@10.0.2.1>
In article <··········@research.att.com>, ···@research.att.com (Andrew
Koenig) wrote:

> Never -- but it doesn't matter, because the higher-order functional
> languages do not support -- and their communities consider irrelevant --
> other key aspects of programming languages that most commercial
> programmers consider indispensible.
> 
> For example, a good chunk of commercial programming practice today
> is related in some way to object-oriented design.  A key notion in
> object-oriented design is the use of objects to represent concepts
> in the program being designed.  An important characteristic of objects
> is their ability to store mutable state information.

This is the most circular argument I have seen in a while.
You come up with a language L that has a property P.
You set up an entire industry that spends $billions to convince
people that they need P, whether they do or not.
And then you turn around and complain that language M doesn't have property P,
which you claim people want because you told them that they needed it.

I'm not complaining here about whether property P is good or not good.  But
one can hardly convince me based on these silly arguments for P.

This circular argument is essentially the root of this 'Show me the STL'
thread.  Who cares about STL?  If objectified, iteratified loops are the
best that OO can do, then stop wasting my time.  This is one h*ll of a lot
of machinery for such a small payback.
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EA2o32.HB5@research.att.com>
In article <·······················@10.0.2.1> ······@netcom.com (Henry Baker) writes:

> This is the most circular argument I have seen in a while.
> You come up with a language L that has a property P.
> You set up an entire industry that spends $billions to convince
> people that they need P, whether they do or not.
> And then you turn around and complain that language M doesn't have property P,
> which you claim people want because you told them that they needed it.

This summary, while interesting, is factually incorrect.

Neither I, nor Bjarne, nor AT&T `set up an entire industry.'
C++ was successful because it catered to the tastes that
lots of programmers had already formed, instead of trying
to change those tastes dramatically.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Bjarne Stroustrup
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EA2yDu.683@research.att.com>
···@research.att.com (Andrew Koenig) writes:

 > Neither I, nor Bjarne, nor AT&T `set up an entire industry.'
 > C++ was successful because it catered to the tastes that
 > lots of programmers had already formed, instead of trying
 > to change those tastes dramatically.

I suspect that this could be confusing. The key is the word "dramatically."

We certainly do try to change programmers' tastes. That is why we
teach new styles and techniques to make programmers more effective.
We try to convince programmers to adopt these techniques where
appropriate and as fast as the individuals and organizations can
absorb the changes while remaining effective.

Where Andy and I and many others in the C++ community differ from
many proponents of new languages and new techniques is in our concern
for the transition and in our respect for other people's taste and
experiences - even in cases where we don't share them. In particular,
I do not subscribe to the popular theory that it is essential to force
people to change and that a language should be designed to be a key part
of an effort to enforce a style/paradigm/philosophy.

I feel that C++ has contributed significantly to the much wider acceptance
of data abstraction, object-oriented programming, and generic programming
that we see today (compared to, say, ten years ago). I think it will continue
to contribute significantly and positively for years to come.

I think most people in the continuing language debates/wars agree that we
want to use better programming and design techniques. Many also agree that
better languages can help. However, there are widely differing opinions on
how best to achieve this (and which of the diverging schools of thinking
about languages is the right one).

I do not believe that for most people and organizations a radical break
with the past is the best or fastest way to progress. Sometimes and for
some people a radical break works. However, when enthusiasm outstrips
caution and experience it is easy to trigger a backlash. Lasting change
on a large scale is far harder to achieve than most people seem willing
to believe.

As always, you can find more extensive dicussions of these issues in my
writings. In particular, "The Design and Evolution of C++" addresses these
points and their practical effects on the C++ Language features. Chapters
11 and 12 of "The C++ Programming Language (2nd Edition)" also touch upon
some of these issues.

	- Bjarne

Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-1305970849160001@10.0.2.1>
In article <··········@research.att.com>, ··@research.att.com (Bjarne
Stroustrup) wrote:

> I do not believe that for most people and organizations a radical break
> with the past is the best or fastest way to progress.

There's a big difference between a 'radical break with the past', and
a 'regression into the past'.  I have a very difficult time understanding
how you can put 'progress' and 'C++' in the same sentence.

(Those who don't understand this comment should first learn about Algol-68,
Simula, Smalltalk and Lisp, before replying.)
From: Bjarne Stroustrup
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EA6F85.4tE@research.att.com>
······@netcom.com (Henry Baker) writes

 > In article <··········@research.att.com>, ··@research.att.com (Bjarne
 > Stroustrup) wrote:
 > 
 > > I do not believe that for most people and organizations a radical break
 > > with the past is the best or fastest way to progress.
 > 
 > There's a big difference between a 'radical break with the past', and
 > a 'regression into the past'.  I have a very difficult time understanding
 > how you can put 'progress' and 'C++' in the same sentence.
 > 
 > (Those who don't understand this comment should first learn about Algol-68,
 > Simula, Smalltalk and Lisp, before replying.)

All of these languages existed well before C++. I for one learned a lot
from them. We should probably also add Modula-2 and Ada to the list of
languages available for study and use before C++ became available.

All of these languages were available at the time C++ started to become
popular, and several - notably Lisp - had many vocal proponents. However,
C++ succeeded on a large scale, and most alternatives at the time didn't.
Maybe people who have only a vague idea of how this came to be should
hesitate before replying.

It is my opinion - based on significant personal experience - that the
individuals, groups, and organizations that chose C++ over its many
alternatives were on average no more or less capable than those who chose
alternatives and were on average no less successful afterwards.


In some other thread, ······@netcom.com (Henry Baker) writes

 > As to the assumption that one can turn a C programmer into a C++ programmer --
 > good luck!  I doubt that 6 months will suffice, and in the mean-time, you'd
 > better just kiss off the programmer (and all of his code that he writes
 > during that period).

This conjecture doesn't square with our experience at Bell Labs. In the early
years, we carefully monitored and measured several projects converting from C
to C++. The least improvement we found over the first half year (measured from
the start of C++ training) was 15%. Most projects and individuals did much
better according to most measures. We considered productivity according to
several measures and tracked the projects later to consider maintenance costs
and defect reports (on average the costs were halved). And no, the people
measuring were not a bunch of C++ fanatics. It was people responsible for
the quality of the delivered product. And no, the projects were not staffed
by specially selected ace programmers.

	- Bjarne

Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html
From: Francois-Rene Rideau
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <xgmlo5h9akt.fsf@Kadath.ens.fr>
>: ··@research.att.com (Bjarne Stroustrup)

> All of these languages were available at the time C++ started to become
> popular, and several - notably Lisp - had many vocal proponents. However,
> C++ succeeded on a large scale, and most alternatives at the time didn't.
> Maybe people who have only a vague idea of how this came to be should
> hesitate before replying.
>
I have more than vague ideas, and I see no reason to hesitate before replying:


Firstly, there were economic reasons to C++ success:
* C++ had free/cheap compilers, other languages not. Particularly,
 people buying C compilers have been given a C++ compiler bundled with it
* There was Turbo C++ and Microsoft C++, not Turbo Lisp or Microsoft Lisp;
* All in all, people could purchase/pirate C++ easily/for free, and get
 lots of docs and integrated development environment. No such thing for
 any other language.
* All this almost free C++ was available on standard cheap PC hardware.

Secondly, there were legacy reasons:
* C++ promised to leverage C software and proficiencies
* C++ was adapted to the low-level architecture of existing,
 cheap/free operating systems.

Thirdly, there were marketing reasons:
* C++ promised a new world of OO programming and launched the OO hype.
* C++ marketing hype has kept promising more features
 (templates, exceptions, GC, etc), so people have been waiting for them
 instead of migrating, even though the C++ result is unusable/costly.

Lastly, there were technical reasons:
* C++ has always had an obvious advantage over C: // comments-to-end-of-line


The same can be said for the success of
the Intel architectures since the 8080, 8086, 80386,
as well as CPM, MSDOS, UNIX, Windows, etc:
inferior bloated braindead and/or slow designs,
but the *marginal* cost for getting it is very low,
so they all became standards.
That's purely economical and political reasons, not technical reasons.

No competing language/operating-system had such advantages.
RISC architectures are superior to Intel for cheaper? Who cares!
MacOS, AmigaOS, NeXTStep, RISCOS, Genera are better? Who cares!
Languages like Eiffel, Modula-3, ML, Lisp, etc,
would be better to build upon than C/C++? Who cares!
The *marginal cost* of getting them is high.
They are not given as standard programming tools,
you can't have them for free, you can't even pirate them,
you can't even get them to work on the hardware you have!
And if it were only for you!? It's the same for everyone!
   So people vote with they purse (not their feet, as ark said),
and only in as much as their purse allow them. They choose the obvious,
cheap solution (both in money and in time). They get C++ on Windows.
And of course, because high volumes and competition help reduce cost,
this all is an autocatalytic phenomenon.
   Again, it's a matter of basic economics, not technics.


The solution to put C++ back to the garbage can of computer history
where it belongs?
   Provide free (no cost) software that runs on any hardware,
written in superior languages.
Of course, because it need be free (no cost) to win,
no proprietary software vendor can afford developing it,
so it must also be free (liberty).
And because the industry is controlled by *vendors* on marketing grounds,
rather than service providers and users on technical grounds,
there's little funding of such projects.
   Hence, fighting all these wrong things about the world of computer software
is definitely a long-term project. Yet it shall eventually succeed,
for the very same reason that market economy shall succeed against planism
and protectionism, and that democracy shall succeed against tyranny:
just because a better system will always, *in the long run* succeed better,
by definition of a better system.
   I invite all sensible people to contribute to help making these
better days happen sooner, to everyone's long-term benefit.


Regards,

== Fare' -- ······@ens.fr -- Franc,ois-Rene' Rideau -- DDa(.ng-Vu~ Ba^n ==
Join the TUNES project for a computing system based on computing freedom !
                TUNES is a Useful, Not Expedient System
URL: "http://www.eleves.ens.fr:8080/home/rideau/Tunes/"
From: Francois-Rene Rideau
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <xgmohad9b0d.fsf@Kadath.ens.fr>
>: ··@research.att.com (Bjarne Stroustrup)

> In the early years,
> we carefully monitored and measured several projects converting from C
> to C++. The least improvement we found over the first half year
> (measured from
> the start of C++ training) was 15%. Most projects and individuals did much
> better according to most measures. We considered productivity according to
> several measures and tracked the projects later to consider maintenance costs
> and defect reports (on average the costs were halved). And no, the people
> measuring were not a bunch of C++ fanatics. It was people responsible for
> the quality of the delivered product. And no, the projects were not staffed
> by specially selected ace programmers.
>
Dear Bjarne,

Did you try any comparative study?
What about giving the same money to teach programming
in another language, and compare productivity/maintenance results
on similarly featured development environments?
Now, *THAT* would give meaningful results.
i.e. I'm happy that you training periods would increase productivity,
but a training period in any language would.
Was C++ particularly good at that?

And what about experiments with fresh programmers without any C background?
What if C++ did increase productivity of the fixed number of people
having already learnt C, but decreased productivity of the ever
increasing number of people who have not learnt it yet?
Would it be worth it?
What if the short-term value of C++ was good,
but its long-term effect disastrous?

#f
From: Bjarne Stroustrup
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EA7AF1.9rC@research.att.com>
Francois-Rene Rideau <······@ens.fr> writes:
 
 > >: ··@research.att.com (Bjarne Stroustrup)
 > 
 > > In the early years,
 > > we carefully monitored and measured several projects converting from C
 > > to C++. The least improvement we found over the first half year
 > > (measured from
 > > the start of C++ training) was 15%. Most projects and individuals did much
 > > better according to most measures. We considered productivity according to
 > > several measures and tracked the projects later to consider maintenance costs
 > > and defect reports (on average the costs were halved). And no, the people
 > > measuring were not a bunch of C++ fanatics. It was people responsible for
 > > the quality of the delivered product. And no, the projects were not staffed
 > > by specially selected ace programmers.
 > >
 > Dear Bjarne,
 > 
 > Did you try any comparative study?
 > What about giving the same money to teach programming
 > in another language, and compare productivity/maintenance results
 > on similarly featured development environments?
 > Now, *THAT* would give meaningful results.

Genuine scientific multiway comparative studies are hard and expensive.
We (meaning a group in AT&T Bell Labs not including me) compared groups
of people (the smallest group I know of had seven people) that used to
write in C, before, during, and after conversion to using C++. This was
done for several groups.

My main interest was to improve the quality of the systems produced based
on the assumption that this could be done using a better language (C++)
without undesirable sideefects on productivity or the quality of life
for the individuals involved. The organizations letting groups convert
and monitoring the conversions were - I think - more interested to see
whether productivity could be improvements without lowering quality.

There were, over the years, other groups that tried converting to other
languages - modula-2, CHILL, and Lisp - springs to mind, but I have less
knowledge of those, I have not seen data from those that could be used
for comparison. My impression is that these experiements were abandoned
because of unsatisfatory results rather than politics. However, I'm sure
other people will have different opinions. But, no, I don't have solid
comparative data. One data point is that several C++ projects succeeded
in an environment that was hostile to all new languages (including C++)
where projects that chose other languages failed (for a variety of reasons).

Remember, the purpose of these measurements were simply to determine
cost effective tools and techniques in a particular industrial setting.
The purpose was not to isolate exactly what in the development process
yielded the observed results.


 > i.e. I'm happy that you training periods would increase productivity,
 > but a training period in any language would.
 > Was C++ particularly good at that?

Thanks to the Hawthorne effect, any genuine show of interest in a group
will increase productivity. However, this effect was both large and
sustained. Productivity and quality improved over an initial half year
and were sustained and increased over the releases over the next few
years. This was done several times and with reasonably average programmers
and reasonably average turnover of programmers.

The "training period" was typically a single week! The training was
usually done by a professional training organization rather than by
researchers.

I think that for people with a C or Pascal background plus the usual
assortment of other skills that professional software developers have
C++ is pretty good at keeping people productive during the learning
period.


 > And what about experiments with fresh programmers without any C background?

We did not have many groups with a non-C background and a group of new
people fresh out of college wouldn't have the domain knowledge necessary
to complete the project in a reasonable time. The groups received new
people - some of whom were "fresh programmers" - because of normal turnover.
However, no measurements were made relating to that.

Furthermore, in the US at least it is hard to find someone who wants
to become a software developer who has not manages to acquire at least
some familiarity with C (or - these days - with C++).


 > What if C++ did increase productivity of the fixed number of people
 > having already learnt C, but decreased productivity of the ever
 > increasing number of people who have not learnt it yet?

I don't see the number of people who does not know C increasing.


 > Would it be worth it?

Yes it would. I have never seen long-term differences in the performance
of C and Pascal programmers learning and using C++. I have not seen enough
programmers with a different background to have an opinion. However, I am
not among those who consider knowing C a prerequisite for learning C++.
Previously knowing C isn't much of an advantage after the first few weeks.
Being a decent programmer in any language is more important.


 > What if the short-term value of C++ was good,
 > but its long-term effect disastrous?

But they weren't. The projects improved over time (yeasr) compared to
expectation and compared to similar C projects.

Wouldn't it be nice if I could actually prove this? I can't. There are
some numbers published by Denis Mancl, more numbers that are not released
(corporations do not like to give hard numbers on their development
projects), and some studies by James Coplien (in the "Pattern Languages
of Programming" book), but they don't add up to scientific proof.

On the other hand, I don't think there is scientific proof that workstations
give better results than timesharing yet. People tend to vote with their
feet (and money) before hard evidence can be gathered - and they won't
go back to become a control group either.

I have no doubt, that compared to C, proper use of C++ can give a major
and lasting advantage in both productivity and quality. Comparing to
other languages is harder. What little data I have is so soft that it
is little better than heresay and large restricted to individuals and
small groups of enthusiasts. However, - as I mentioned in an earlier
posting I see no systematic disadvantage to C++ programmers compared
to any other language in the fields I know of.

Naturally, tools, libraries, etc. can greatly enhance the positive
effects of a good language (among which I include C++). However, the
results I mention was done relying on only the most basic libraries
and relatively early C++ compilers and tools.

	- Bjarne

Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-1505970804070001@10.0.2.1>
In article <··········@research.att.com>, ··@research.att.com (Bjarne
Stroustrup) wrote:

> Thanks to the Hawthorne effect, any genuine show of interest in a group
> will increase productivity.

Thanks for the reference.  I hope that you knew about Hawthorne _before_
you did your study.

> The "training period" was typically a single week! The training was
> usually done by a professional training organization rather than by
> researchers.

This is complete garbage!  There is _no way_ that C programmers will be
programming C++ templates and classes in one week, unless they had had
previous training/experience in another OO language -- e.g., Simula,
Smalltalk, CLOS.  I don't care what 'professional training organization' or
'methodology' was used.  If you mean that they were able to operate the compiler
without training wheels, then that might be true.  But the ability to produce
useful code that takes advantage of the differences between C++ and C in a
single week is beyond belief.

It is precisely comments like this that destroy your credibility.
From: ········@bayou.uh.edu
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5lg42l$dc9$2@Masala.CC.UH.EDU>
Henry Baker (······@netcom.com) wrote:
: In article <··········@research.att.com>, ··@research.att.com (Bjarne
: Stroustrup) wrote:

[Snip]

: > The "training period" was typically a single week! The training was
: > usually done by a professional training organization rather than by
: > researchers.

: This is complete garbage!  There is _no way_ that C programmers will be
: programming C++ templates and classes in one week, unless they had had
: previous training/experience in another OO language -- e.g., Simula,
: Smalltalk, CLOS.  

I agree wholeheartedly.  I cannot see how on Earth a single week
would turn a C programmer into a C++ programmer.  A single week
could let them use C++ as a better C, but NOT as an OO language.


[Snip]


--
Cya,
Ahmed

Here's a present just for you,
When you open it you'll be through
	"Letter Bomb" by the Circle Jerks
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-1505971937460001@10.0.2.1>
In article <··········@research.att.com>, ··@research.att.com (Bjarne
Stroustrup) wrote:

>  > > The "training period" was typically a single week! The training was
>  > > usually done by a professional training organization rather than by
>  > > researchers.
> 
>  > This is complete garbage!
> 
> No. It's a fact.
> 
>  > There is _no way_ that C programmers will be
>  > programming C++ templates and classes in one week, unless they had had
>  > previous training/experience in another OO language -- e.g., Simula,
>  > Smalltalk, CLOS.
> 
> I didn't claim that the C programmers was "taught all of C++ in a week."
> That can be done, but not to the point where people would be effective
using it.

OK.  Since your assertion that all of C++ can be taught in a week meets with
universal skepticism, 'show me the code!'

Post the code right here on these newsgroups that these neophytes
programmed after
exactly 1 week of exposure to C++.

I'd like to see what wonders these people programmed after 5-7 days, and we
can all judge for ourselves whether the code would be useful, or would have
to be thrown away.

----

I'm man enough to admit that it took me considerably longer than 7 days of
exposure to C++ before I was willing for anyone to even see my code, because
it was so hopeless.  And this was with the help of the very good and very
fast Metrowerks C++ compiler, which enabled me to quickly try out the
hundreds of
cases that weren't covered in your book.

Could I do 'hello world' in C++ after a week?  Sure, so long as I used
printf!  ;-)

Could I write 'factorial' in C++ after a week?  Sure.

Could I do what is suggested and replace macros by templates after a week?  No
way.  I'm not sure that even now I know all there is to know about templates --
(those that do seem to comprise a very small group indeed!)  And even today,
I might have to waste 2-3 days to prove to myself that something _can't_ be
done using a template, at which point I go back to using a macro (and curse the
whole time!).

Could I overload "+" to do string concatenation after a week?  Sure, but who
would care?

Could I figure out how to build up an algebraic 'tower' like that found in
Common Lisp or Scheme after a week?  No way.

-----

The major problem with C++ is similar to that which sets most graduate students
back about a whole semester -- how to hack TeX (or its equivalents) into
producing your thesis not just in a readable font, but using every conceivable
font!  The result of that semester of hard work is a thesis that looks like a
ransom note (perhaps it is!).  Likewise, the C++ program that one sees from the
3-6 month C++'er looks like a ransom note, because while he 'learned the
language',
he hasn't acquired any taste in how to use it.

Like I said, C++ learning time without any previous OO experience: minimum 6
months.
From: Bjarne Stroustrup
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EAC7IC.33B@research.att.com>
······@netcom.com (Henry Baker) writes:

 > In article <··········@research.att.com>, ··@research.att.com (Bjarne
 > Stroustrup) wrote:
 > 
 > >  > > The "training period" was typically a single week! The training was
 > >  > > usually done by a professional training organization rather than by
 > >  > > researchers.
 > > 
 > >  > This is complete garbage!
 > > 
 > > No. It's a fact.
 > > 
 > >  > There is _no way_ that C programmers will be
 > >  > programming C++ templates and classes in one week, unless they had had
 > >  > previous training/experience in another OO language -- e.g., Simula,
 > >  > Smalltalk, CLOS.
 > > 
 > > I didn't claim that the C programmers was "taught all of C++ in a week."
 > > That can be done, but not to the point where people would be effective
 > using it.

Note the "but not to the point where people would be effective using it."
and I continued

	``Trying to teach all of any unfamiliar language in a week and then
	trying to apply it in a major project immediatly would be an almost
	certain disaster. In fact, there has been noticeable disasters where
	 people - using a variety of languages - has gone overboard with OO
	and language features that were new to them.

	I recommend a gradual approach to learning and applying C++ in most
	 cases. My homepages have information on learning C++ and so has
	"The Design and Evolution of C++."''

and later in the same note:

	``I estimate that it on average takes between one and two years to
	become fully comfortable with C++ and the main techiques it supports
	(assuming you don't start with C++ already comfortable with abstraction 	techniques).''

I have personally taught all the major facilities of C++ and the key
techniques they support in a week - or less - and so have many others.
I do however consistently stressed that it takes a long time to internalize
those ideas and that a much longer time to become comfortable using even
a large subset of those techniques. In C++ as in any other language.


 > OK.  Since your assertion that all of C++ can be taught in a week meets with
 > universal skepticism, 'show me the code!'

I don't think "all of C++ can be taught in a week" is a fair summary of
what I said. Furthermore, my points were supported by several poster in
this thread so "universal skeptisism" doesn't seem to be an accurate summary
of the reaction.


 > Post the code right here on these newsgroups that these neophytes
 > programmed after
 > exactly 1 week of exposure to C++.
 > 
 > I'd like to see what wonders these people programmed after 5-7 days, and we
 > can all judge for ourselves whether the code would be useful, or would have
 > to be thrown away.

I described the experience with several groups of programmers building
industrial applications over years. The smallest of these groups had seven
people. We are talking of several hundred thousand lines of code built and
maintained over years. That is not the type of code one posts on the net
- even if the systems hadn't been the basis of multi-billion-dollars-a-year
businesses. 

The programmers weren't "neophytes." They were experienced C programmers and
most were experts in the domain they were programming in. Even the most
brilliant programmer with the world's best tools would have been at a
complete loss without that domain expertice.

What we saw repeatedly was that such programmers could - after a training
period of a week - be more productive and write more maintainable code
using C++ than they could in C. The improvements started to appear
almost immediately and increased over the years. The initial improvements
(measured after half a year) were modest (I mentioned that the least
improvement we ever saw was 15%, the average was about 45%) but fairly
consistent, sustained, and increasing as the programmers became more
comfortable with C++.


 > I'm man enough to admit that it took me considerably longer than 7 days of
 > exposure to C++ before I was willing for anyone to even see my code, because
 > it was so hopeless.  And this was with the help of the very good and very
 > fast Metrowerks C++ compiler, which enabled me to quickly try out the
 > hundreds of
 > cases that weren't covered in your book.
 > 
 > Could I do 'hello world' in C++ after a week?  Sure, so long as I used
 > printf!  ;-)
 > 
 > Could I write 'factorial' in C++ after a week?  Sure.
 > 
 > Could I do what is suggested and replace macros by templates after a week?  No
 > way.  I'm not sure that even now I know all there is to know about templates --
 > (those that do seem to comprise a very small group indeed!)  And even today,
 > I might have to waste 2-3 days to prove to myself that something _can't_ be
 > done using a template, at which point I go back to using a macro (and curse the
 > whole time!).
 > 
 > Could I overload "+" to do string concatenation after a week?  Sure, but who
 > would care?
 > 
 > Could I figure out how to build up an algebraic 'tower' like that found in
 > Common Lisp or Scheme after a week?  No way.

This may or may not be true, but it is hardly relevant. What matters to me
is not what student exercises a programmer can complete or what particular
language features a programmer understand every detail of.

What matters is that the programmer working together with colleagues can
produce code that is better and more maintainable than he/she could before,
and that this code can be produced faster and with less pain than before.

Understanding how this was done is important to me, and I think interesting
in general. What we have is a large-scale experiement that worked. I'm sure
that we can do even better today. 


 > The major problem with C++ is similar to that which sets most graduate students
 > back about a whole semester -- how to hack TeX (or its equivalents) into
 > producing your thesis not just in a readable font, but using every conceivable
 > font!  The result of that semester of hard work is a thesis that looks like a
 > ransom note (perhaps it is!).

I'm not talking about graduate students or "lone cowboy types" trying to
revolutionize a field single-handedly overnight. I'm relaying experiences
of competent industrial programmers working in teams producing systems that
last many years and evolve.


 > Likewise, the C++ program that one sees from the
 > 3-6 month C++'er looks like a ransom note, because while he 'learned the
 > language',
 > he hasn't acquired any taste in how to use it.

Not if the language has been well introduced and cautiosly applied.


 > Like I said, C++ learning time without any previous OO experience: minimum 6
 > months.

Compared with what I have been saying consistently over a decade or so,
you seem to be an optimist. Maybe my approach is after all the more cautious.
I ascribe a lot of the success of C++ in the kind of demanding projects I'm
describing to a cautious and gradual approach.

	- Bjarne

Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-1705971809200001@10.0.2.1>
In article <··········@research.att.com>, ··@research.att.com (Bjarne
Stroustrup) wrote:

> I have personally taught all the major facilities of C++ and the key
> techniques they support in a week - or less - and so have many others.

Show us the C++ code that they produced after a week in class.

> I described the experience with several groups of programmers building
> industrial applications over years. The smallest of these groups had seven
> people. We are talking of several hundred thousand lines of code built and
> maintained over years. That is not the type of code one posts on the net
> - even if the systems hadn't been the basis of multi-billion-dollars-a-year
> businesses. 

Why should we believe you?  Show us 10 examples of where these people used
C++ constructs after 1 week in class.

> The programmers weren't "neophytes." They were experienced C programmers and
> most were experts in the domain they were programming in. Even the most
> brilliant programmer with the world's best tools would have been at a
> complete loss without that domain expertice.

I agree.  But these people still had to learn a whole new language.
Show us the code.

> What we saw repeatedly was that such programmers could - after a training
> period of a week - be more productive and write more maintainable code
> using C++ than they could in C.

Show us some examples of this.  Show us a piece of code that they produced
after your 1-week training course.  We will judge for ourselves whether this
is 'more maintainable' code.

> The improvements started to appear
> almost immediately and increased over the years. The initial improvements
> (measured after half a year) were modest (I mentioned that the least
> improvement we ever saw was 15%, the average was about 45%) but fairly
> consistent, sustained, and increasing as the programmers became more
> comfortable with C++.

OK, show us code that was produced 1 week, 1 month, 6 months, 1 year, and
2 years after this 1-week course (no further 'training' allowed).

> What matters is that the programmer working together with colleagues can
> produce code that is better and more maintainable than he/she could before,
> and that this code can be produced faster and with less pain than before.

OK, show us some of this code, both before and after, so we can see how it
is 'better and more maintainable' than it was before.  Unless you also
post the timecards, I guess it would be difficult to tell whether this
code was 'produced faster', so we'll focus primarily on 'better and more
maintainable' for the moment.

> Understanding how this was done is important to me, and I think interesting
> in general. What we have is a large-scale experiement that worked. I'm sure
> that we can do even better today. 

What you have is a large-scale experiment that would be laughed out of any
peer-reviewed journal in a real _science_ like medicine.  Where is your
control?  Where is your blind?  Did you then put these people back onto a
C program to compare their productivity in C afterwards?

> I'm not talking about graduate students or "lone cowboy types" trying to
> revolutionize a field single-handedly overnight. I'm relaying experiences
> of competent industrial programmers working in teams producing systems that
> last many years and evolve.

I don't care who you are talking about.  Show me the code.
From: Tuomo Takkula
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <sfjzptslwqh.fsf@muppet17.cs.chalmers.se>
······@netcom.com (Henry Baker) writes:


> ...
> Show us the C++ code that they produced after a week in class.
> ... 
> Why should we believe you?  Show us 10 examples of where these people used
> C++ constructs after 1 week in class.
> ...
> I agree.  But these people still had to learn a whole new language.
> Show us the code.
> ...
> Show us some examples of this.  Show us a piece of code that they produced
> after your 1-week training course.  We will judge for ourselves whether this
> is 'more maintainable' code.
> ...
> OK, show us code that was produced 1 week, 1 month, 6 months, 1 year, and
> 2 years after this 1-week course (no further 'training' allowed).
> ...
> OK, show us some of this code, both before and after, so we can see how it
> is 'better and more maintainable' than it was before.  Unless you also
> post the timecards, I guess it would be difficult to tell whether this
> code was 'produced faster', so we'll focus primarily on 'better and more
> maintainable' for the moment.
> ...
> What you have is a large-scale experiment that would be laughed out of any
> peer-reviewed journal in a real _science_ like medicine.  Where is your
> control?  Where is your blind?  Did you then put these people back onto a
> C program to compare their productivity in C afterwards?
> ...
> I don't care who you are talking about.  Show me the code.



You are starting to 'nudd'.

Tuomo
From: ozan s. yigit
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <x6raf77az1.fsf@ds9.rnd.border.com>
······@netcom.com (Henry Baker) in response to Stroustroup:


> > The "training period" was typically a single week! The training was
> > usually done by a professional training organization rather than by
> > researchers.
> 
> This is complete garbage!  There is _no way_ that C programmers will be
> programming C++ templates and classes in one week, unless they had had
> previous training/experience in another OO language -- e.g., Simula,
> Smalltalk, CLOS. 

i think not. i have been with developers using C++ classes in one week too
and we did not have the templates at the time. C++ is a large language, but
you do not have to dump it on people's head all at once. you want people
to get going without getting stuck in trickier corners. this would
be true for common lipthth too, for instance. 

> It is precisely comments like this that destroy your credibility.

thankfully, hard earned credibility is not lost with armchair commentary
in this medium, and should be of considerable relief for almost all
contributors this discussion...

oz
---
The bullets inside are very hot. Why do i feel so cold?
                -- [subtitle fracture in Lethal Panther]
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-1605970928130001@10.0.2.1>
In article <··············@ds9.rnd.border.com>, ··@ds9.rnd.border.com
(ozan s. yigit) wrote:

> i think not. i have been with developers using C++ classes in one week too
> and we did not have the templates at the time. C++ is a large language, but
> you do not have to dump it on people's head all at once. you want people
> to get going without getting stuck in trickier corners. this would
> be true for common lipthth too, for instance. 

I agree, but Bjarne made the specific claim that it was possible to teach
the entire C++ language in just one week, and then have the students make
immediate substantive contributions to a C++ projects.  He then reiterated
this claim.  So he did 'dump it on people's head(s) all at once', and he
must have included templates, since they are part of the C++ language.  I
pointed out several times 'trickier corners', and he brushed it off.

So I will reiterate my previous request.  Bjarne, 'show me the code!'
From: Darin Johnson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5npqub.5s5.darin@connectnet1.connectnet.com>
>I agree, but Bjarne made the specific claim that it was possible to teach
>the entire C++ language in just one week, and then have the students make
>immediate substantive contributions to a C++ projects.  He then reiterated
>this claim.  So he did 'dump it on people's head(s) all at once', and he
>must have included templates, since they are part of the C++ language.  I
>pointed out several times 'trickier corners', and he brushed it off.
>
>So I will reiterate my previous request.  Bjarne, 'show me the code!'

But you don't need to know the dustier corners to make effective use
of C++ and help out on C++ projects!  Sure, some die hards insist that
you can't do C++ without templates and other late features to the
language, but such insistance rarely matches reality.

I learned C++ in a week.  Sure, it was 1985, and C++ was a heck of a
lot smaller.  But there was nothing "new" in it, it was just new
syntax is all.  OO is an old concept, better defined by languages
other than C++ anyway; so learning classes and inheritance is trivial
if you know OO and C already.  Learning C++ oddities like virtual
versus non-virtual is a bit harder, so you take another day to
experiment with it.  And don't worry about MI, it's supposed to be
rarely used anyway.  Exceptions aren't new, just new syntax, and so
forth for just about everything Oh, and learn on your own, I've always
found that I learn about 3 hours worth of stuff in a week long class.

A week, no problem.  Why should it be?  Am I overestimating the competence
or experience of today's programmers?

-- 
Darin Johnson
·····@usa.net.delete_me
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-1605971704070001@10.0.2.1>
In article <····················@connectnet1.connectnet.com>,
·····@usa.net.delete_me (Darin Johnson) wrote:
> I learned C++ in a week.  Sure, it was 1985, and C++ was a heck of a
> lot smaller.  But there was nothing "new" in it, it was just new
> syntax is all.  OO is an old concept, better defined by languages
> other than C++ anyway; so learning classes and inheritance is trivial
> if you know OO and C already.  Learning C++ oddities like virtual
> versus non-virtual is a bit harder, so you take another day to
> experiment with it.  And don't worry about MI, it's supposed to be
> rarely used anyway.  Exceptions aren't new, just new syntax, and so
> forth for just about everything Oh, and learn on your own, I've always
> found that I learn about 3 hours worth of stuff in a week long class.
> 
> A week, no problem.  Why should it be?  Am I overestimating the competence
> or experience of today's programmers?

Stroustrup claimed 1 week for all of C++ for people with C experience, but
_no_ OO experience, and _no_ Lisp experience.  So your previous OO experience
put you well ahead of his team.  I still think that 1 week, even with previous
OO experience, is probably 4 sigmas from the mean.

Even if you already know some OO, some exceptions, some templates, etc., from
another language, there is an awful lot to learn about the _differences_
between the way that C++ does it and the way that your previous languages
do it.  There is a certain minimum amount of time required to go through and
find (or trip over) these differences, and if you start coding right away,
then you should be prepared for some major rude awakenings when you start
debugging.  I happen not to like major rude awakenings, so I am happy to
do as much learning as possible with 'toy' programs that compile fast and
can be readily debugged.

If you try to push through this learning stage too fast, you will find yourself
learning the same lessons, but _much_ more expensively, as you attempt
to find bugs in a much larger system.

Alternatively, if you have been
pushed through this stage too fast, but still code conservatively
with constructs you understand very well and are completely comfortable
with, you will probably fall into a large class of programmers who never
really learn to take advantage of the language.  I saw this happen with
programmers who learned an 'early' version of a language, but never really
spent much time later keeping up.  When the 'full' language later came out,
their programming style never took advantage of 95% of the new features, even
though the features were sorely needed, and would have reduced their efforts
substantially.

So I think that trying to push people too fast through the C -> C++
transition can backfire in a major way.
From: Bjarne Stroustrup
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EAC7Jw.38y@research.att.com>
······@netcom.com (Henry Baker) writes:

 > Stroustrup claimed 1 week for all of C++ for people with C experience, but
 > _no_ OO experience, and _no_ Lisp experience.

As I have pointed out before ``1 week for all of C++ for people with C
experience, but  _no_ OO experience'' is a misrepresentation of what I
have said. Have a look at "The Design and Evolution of C++" or my homepages
to see what I actually claim.

	- Bjarne

Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-1705971810470001@10.0.2.1>
In article <··········@research.att.com>, ··@research.att.com (Bjarne
Stroustrup) wrote:

> ······@netcom.com (Henry Baker) writes:
> 
>  > Stroustrup claimed 1 week for all of C++ for people with C experience, but
>  > _no_ OO experience, and _no_ Lisp experience.
> 
> As I have pointed out before ``1 week for all of C++ for people with C
> experience, but  _no_ OO experience'' is a misrepresentation of what I
> have said. Have a look at "The Design and Evolution of C++" or my homepages
> to see what I actually claim.
> 
>         - Bjarne

Exactly.  Me thinks you doth claim too much.  Show me the code.
From: Peter da Silva
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5m2mfl$493@web.nmti.com>
In article <·······················@10.0.2.1>,
Henry Baker <······@netcom.com> wrote:
> I agree, but Bjarne made the specific claim that it was possible to teach
> the entire C++ language in just one week, and then have the students make
> immediate substantive contributions to a C++ projects.

Where? I didn't see any such claim.
-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-2305970649320001@10.0.2.1>
In article <··········@web.nmti.com>, ·····@nmti.com (Peter da Silva) wrote:

> In article <·······················@10.0.2.1>,
> Henry Baker <······@netcom.com> wrote:
> > I agree, but Bjarne made the specific claim that it was possible to teach
> > the entire C++ language in just one week, and then have the students make
> > immediate substantive contributions to a C++ projects.
> 
> Where? I didn't see any such claim.

See below:

In article <··········@research.att.com>, ··@research.att.com (Bjarne
Stroustrup) wrote:

> I have personally taught all the major facilities of C++ and the key
> techniques they support in a week - or less - and so have many others.
From: Gareth McCaughan
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <86vi4adylg.fsf@g.pet.cam.ac.uk>
Henry Baker wrote:

> > > I agree, but Bjarne made the specific claim that it was possible to teach
> > > the entire C++ language in just one week, and then have the students make
> > > immediate substantive contributions to a C++ projects.
> > 
> > Where? I didn't see any such claim.
> 
> See below:
...
> > I have personally taught all the major facilities of C++ and the key
> > techniques they support in a week - or less - and so have many others.

We know that B.S. claimed

  (1) that he has taught "all the major facilities of C++"
      in a week

and

  (2) that he has taught some people C++ for a week and they
      have then made immediate substantive contributions to
      C++ projects.

But those are not at all the same as claiming

  (3) that he has taught "all the major facilities" in a week
      to people who have then made immediate substantive
      contributions.

I'm willing to believe (1) and (2), but not (3); I think B.S.
was claiming (1) and (2) but not (3).

(For the record, I can't stand C++ myself.)

-- 
Gareth McCaughan       Dept. of Pure Mathematics & Mathematical Statistics,
·····@dpmms.cam.ac.uk  Cambridge University, England.
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-2305971154310001@10.0.2.1>
In article <··············@g.pet.cam.ac.uk>, Gareth McCaughan
<·····@dpmms.cam.ac.uk> wrote:

> Henry Baker wrote:
> 
> > > > I agree, but Bjarne made the specific claim that it was possible
to teach
> > > > the entire C++ language in just one week, and then have the
students make
> > > > immediate substantive contributions to a C++ projects.
> > > 
> > > Where? I didn't see any such claim.
> > 
> > See below:
> ...
> > > I have personally taught all the major facilities of C++ and the key
> > > techniques they support in a week - or less - and so have many others.
> 
> We know that B.S. claimed
> 
>   (1) that he has taught "all the major facilities of C++"
>       in a week
> 
> and
> 
>   (2) that he has taught some people C++ for a week and they
>       have then made immediate substantive contributions to
>       C++ projects.
> 
> But those are not at all the same as claiming
> 
>   (3) that he has taught "all the major facilities" in a week
>       to people who have then made immediate substantive
>       contributions.
> 
> I'm willing to believe (1) and (2), but not (3); I think B.S.
> was claiming (1) and (2) but not (3).

From bs ··········@research.att.com 5/14/97:

> This conjecture doesn't square with our experience at Bell Labs. In the early
> years, we carefully monitored and measured several projects converting from C
> to C++. The least improvement we found over the first half year (measured from
> the start of C++ training) was 15%. Most projects and individuals did much
> better according to most measures.

'bs' says a _minimum_ of 15% improvement _over_ the first half year (i.e.,
not 'by the end of').

This was in his response to my statement:

 > As to the assumption that one can turn a C programmer into a C++ programmer:
 > good luck!  I doubt that 6 months will suffice, and in the mean-time, you'd
 > better just kiss off the programmer (and all of his code that he writes
 > during that period).

As far as I can tell, 'bs' was referring to the same project.  It's difficult
to know, because he refuses to give any dates or any other details about his
projects in order that we can better assess what he is claiming.
From: Matthias Blume
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <izwwoqdsal.fsf@rant.cs.princeton.edu>
In article <··············@g.pet.cam.ac.uk> Gareth McCaughan <·····@dpmms.cam.ac.uk> writes:

   We know that B.S. claimed

     (1) that he has taught "all the major facilities of C++"
	 in a week

   and

     (2) that he has taught some people C++ for a week and they
	 have then made immediate substantive contributions to
	 C++ projects.

   But those are not at all the same as claiming

     (3) that he has taught "all the major facilities" in a week
	 to people who have then made immediate substantive
	 contributions.

   I'm willing to believe (1) and (2), but not (3); I think B.S.
   was claiming (1) and (2) but not (3).

Very well.  But then, what relevance do statements (1) and (2) have
wrt. the ongoing discussion?

-- 
-Matthias
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-2505971114380001@10.0.2.1>
In article <··············@rant.cs.princeton.edu>,
·····@rant.cs.princeton.edu (Matthias Blume) wrote:
> In article <··············@g.pet.cam.ac.uk> Gareth McCaughan
<·····@dpmms.cam.ac.uk> writes:
>    We know that B.S. claimed
>      (1) that he has taught "all the major facilities of C++"
>          in a week
>    and
>      (2) that he has taught some people C++ for a week and they
>          have then made immediate substantive contributions to
>          C++ projects.
>    But those are not at all the same as claiming
>      (3) that he has taught "all the major facilities" in a week
>          to people who have then made immediate substantive
>          contributions.
> 
>    I'm willing to believe (1) and (2), but not (3); I think B.S.
>    was claiming (1) and (2) but not (3).
> Very well.  But then, what relevance do statements (1) and (2) have
> wrt. the ongoing discussion?

I don't understand your question.  B.S. made certain claims.  I asked him to
back them up.  He simply repeated the claims word for word, with no new
information.

To summarize what I think we have learned from B.S.:

1.  He performed at least one 1-week training course on 7 professional C
programmers who had no previous OO or Lisp experience.  No other details
about what was taught or what was learned in this 1-week course were given.
Other than that this was the 'early years', B.S. has steadfastly refused to
give the dates of this course, so it is impossible to know what a 'C programmer'
of whatever era this is already knows, except that he alluded to the possibility
that this might be K&R C with lint.

2.  B.S. "carefully monitored and measured" groups of programmers.  Their
'productivity' improved a _minimum_ of 15% over the next 6 months 'according to
most measures'.  B.S. has steadfastly refused to elaborate on what 'carefully
monitored' and 'measured' mean.  This wording has the presumption that
August Science Was Performed, and invites questions about exactly what
was done.

3.  We have no details whatsoever on how 'maintenance costs' or 'defect
reports' are measured.

4.  Since B.S. refuses to give any details about the code produced by these
programmers, _we have no assurance that this C++ training had anything other
than a 'Hawthorne Effect' on these programmers_.

If B.S. would simply claim "I personally _like_ C++ more than C and _feel_
that I am more productive using, and furthermore, all the people I have taught
C++ to _feel_ the same way", I would have no problem with that.  (I personally
feel the same way about other things.)  But B.S. is making a much stronger
claim: that some independent notions of 'productivity' and 'maintainability'
have been 'measured' by some 3rd party and produced some numerically significant
results.  If B.S. claims this and uses it repeatedly in defense of C++, then
I think that any Computer _Scientist_ deserves to have a more in-depth
explanation of exactly what 'productivity', 'maintainability', and 'measured'
mean in this context.  So far, all B.S. does is simply continue repeating
himself, but gives no new information relevant to this issue of exactly what
in C++ is 'more productive' than in ANSI C.

---

B.S.:
"In the early
years, we carefully monitored and measured several projects converting from C
to C++. The least improvement we found over the first half year (measured from
the start of C++ training) was 15%. Most projects and individuals did much
better according to most measures. We considered productivity according to
several measures and tracked the projects later to consider maintenance costs
and defect reports (on average the costs were halved)."

"We (meaning a group in AT&T Bell Labs not including me) compared groups
of people (the smallest group I know of had seven people) that used to
write in C, before, during, and after conversion to using C++. This was
done for several groups."

"Productivity and quality improved over an initial half year
and were sustained and increased over the releases over the next few
years. This was done several times and with reasonably average programmers
and reasonably average turnover of programmers."

"What little data I have is so soft that it
is little better than heresay and large restricted to individuals and
small groups of enthusiasts."

(This is a far cry from "_carefully_ monitored" and "measured".)
From: ozan s. yigit
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <x667wautbe.fsf@ds9.rnd.border.com>
Henry Baker writes:

> See below:
> 
> In article <··········@research.att.com>, ··@research.att.com (Bjarne
> Stroustrup) wrote:
> 
> > I have personally taught all the major facilities of C++ and the key
> > techniques they support in a week - or less - and so have many others.

you know, in polite communication between adults, there /is/ such a thing
as granting others the imprecision of the english language as we take it for
granted; noone should have to suffer a public flogging for not supplementing
a statement with a dissertation on its exact domain.

oz
---
Civilization is expensive.     -- John Kenneth Galbraith
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-2305971157400001@10.0.2.1>
In article <··············@ds9.rnd.border.com>, ··@ds9.rnd.border.com
(ozan s. yigit) wrote:
> Henry Baker writes:
> > See below:
> > In article <··········@research.att.com>, ··@research.att.com (Bjarne
> > Stroustrup) wrote:
> > > I have personally taught all the major facilities of C++ and the key
> > > techniques they support in a week - or less - and so have many others.
> 
> you know, in polite communication between adults, there /is/ such a thing
> as granting others the imprecision of the english language as we take it for
> granted; noone should have to suffer a public flogging for not supplementing
> a statement with a dissertation on its exact domain.

'bs' didn't say it just once (··········@research.att.com 5/15/97):

> The "training period" was typically a single week! The training was
> usually done by a professional training organization rather than by
> researchers.
From: Bjarne Stroustrup
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EAn76v.Dx7@research.att.com>
······@netcom3.netcom.com writes:

 > In article <··········@web.nmti.com>, ·····@nmti.com (Peter da Silva) wrote:
 > 
 > > In article <·······················@10.0.2.1>,
 > > Henry Baker <······@netcom.com> wrote:
 > > > I agree, but Bjarne made the specific claim that it was possible to teach
 > > > the entire C++ language in just one week, and then have the students make
 > > > immediate substantive contributions to a C++ projects.
 > > 
 > > Where? I didn't see any such claim.
 > 
 > See below:
 > 
 > In article <··········@research.att.com>, ··@research.att.com (Bjarne
 > Stroustrup) wrote:
 > 
 > > I have personally taught all the major facilities of C++ and the key
 > > techniques they support in a week - or less - and so have many others.

The UNCUT quote is 

	I have personally taught all the major facilities of C++ and the key
	techniques they support in a week - or less - and so have many others.
	I do however consistently stressed that it takes a long time to internalize
	those ideas and that a much longer time to become comfortable using even
	a large subset of those techniques. In C++ as in any other language.

This was (immediately) preceded by:

	······@netcom.com (Henry Baker) writes:

	 > In article <··········@research.att.com>, ··@research.att.com (Bjarne
	 > Stroustrup) wrote:
	 > 
	 > >  > > The "training period" was typically a single week! The training was
	 > >  > > usually done by a professional training organization rather than by
	 > >  > > researchers.
	 > > 
	 > >  > This is complete garbage!
	 > > 
	 > > No. It's a fact.
	 > > 
	 > >  > There is _no way_ that C programmers will be
	 > >  > programming C++ templates and classes in one week, unless they had had
	 > >  > previous training/experience in another OO language -- e.g., Simula,
	 > >  > Smalltalk, CLOS.
	 > > 
	 > > I didn't claim that the C programmers was "taught all of C++ in a week."
	 > > That can be done, but not to the point where people would be effective
	 > using it.
	
	Note the "but not to the point where people would be effective using it."
	and I continued

		``Trying to teach all of any unfamiliar language in a week and then
		trying to apply it in a major project immediatly would be an almost
		certain disaster. In fact, there has been noticeable disasters where
		 people - using a variety of languages - has gone overboard with OO
		and language features that were new to them.

		I recommend a gradual approach to learning and applying C++ in most
		 cases. My homepages have information on learning C++ and so has
		"The Design and Evolution of C++."''

	and later in the same note:

		``I estimate that it on average takes between one and two years to
		become fully comfortable with C++ and the main techiques it supports
		(assuming you don't start with C++ already comfortable with abstraction 	techniques).''


Context can be very important when you want to understand a sentence.
 
	- Bjarne

Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EAnAxL.I2A@research.att.com>
In article <·······················@10.0.2.1> ······@netcom.com (Henry Baker) writes:
> In article <··········@web.nmti.com>, ·····@nmti.com (Peter da Silva) wrote:

> > In article <·······················@10.0.2.1>,
> > Henry Baker <······@netcom.com> wrote:
> > > I agree, but Bjarne made the specific claim that it was possible to teach
> > > the entire C++ language in just one week, and then have the students make
> > > immediate substantive contributions to a C++ projects.

> > Where? I didn't see any such claim.

> See below:

> In article <··········@research.att.com>, ··@research.att.com (Bjarne
> Stroustrup) wrote:

> > I have personally taught all the major facilities of C++ and the key
> > techniques they support in a week - or less - and so have many others.

I still don't see any such claim.  In particular, I don't see the
`and then have the students make immediate substantive contributions
to a [sic] C++ projects' part.

It is definitely possible to cover the whole language in a week --
I do it every summer in the course I teach at Stanford.  I do not,
however, expect all my students to go home and immediately apply
everything they have learned.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-2305971206340001@10.0.2.1>
In article <··········@research.att.com>, ···@research.att.com (Andrew
Koenig) wrote:
> > In article <··········@research.att.com>, ··@research.att.com (Bjarne
> > Stroustrup) wrote:
> > > I have personally taught all the major facilities of C++ and the key
> > > techniques they support in a week - or less - and so have many others.
> 
> I still don't see any such claim.  In particular, I don't see the
> `and then have the students make immediate substantive contributions
> to a [sic] C++ projects' part.
> 
> It is definitely possible to cover the whole language in a week --
> I do it every summer in the course I teach at Stanford.  I do not,
> however, expect all my students to go home and immediately apply
> everything they have learned.

From 'bs' (··········@research.att.com 5/14/97):
> In the early
> years, we carefully monitored and measured several projects converting from C
> to C++. The least improvement we found over the first half year (measured from
> the start of C++ training) was 15%. Most projects and individuals did much
> better according to most measures.

This sounds to me like an immediate (_over_ the first half year, not just
'by the end of' the first half year) improvement of a _minimum_ of 15%, with
'most' doing 'much better'.  I think that that qualifies as 'substantive
contributions', since this is the _increase_ over the baseline
contribution, and the baseline contribution continued.

Now if this statement refers to a different experience than the one from
the first quote, it is up to 'bs' to make this clear.
From: Reginald Perry
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <sxlenb4rzkl.fsf@yakko.zso.dec.com>
··@research.att.com (Bjarne Stroustrup) writes:

> ······@netcom.netcom.com (Henry Baker) writes:
> 
>  > In article <··········@research.att.com>, ··@research.att.com (Bjarne
>  > Stroustrup) wrote:
>  > 
>  > > Thanks to the Hawthorne effect, any genuine show of interest in a group
>  > > will increase productivity.
>  > 
>  > Thanks for the reference.  I hope that you knew about Hawthorne _before_
>  > you did your study.
> 
> Of course. I knew of the Hawthorne effect 20 years ago. It is especially widely
> known within AT&T Bell Labs because the original study was done by Bell Labs'
> people in the old AT&T Hawthorne plant.
> 
> Also, you shouldn't have the people trying to effect a change also measure its
> effectiveness, so I had nothing to do with the data gathering and analysis.
> 
> 
>  > > The "training period" was typically a single week! The training was
>  > > usually done by a professional training organization rather than by
>  > > researchers.
> 
>  > This is complete garbage!
> 
> No. It's a fact.
> 
> 
>  > There is _no way_ that C programmers will be
>  > programming C++ templates and classes in one week, unless they had had
>  > previous training/experience in another OO language -- e.g., Simula,
>  > Smalltalk, CLOS.
> 
> I didn't claim that the C programmers was "taught all of C++ in a week."
> That can be done, but not to the point where people would be effective using it.
> Trying to teach all of any unfamiliar language in a week and then trying to apply
> it in a major project immediatly would be an almost certain disaster. In fact, there
> has been noticeable disasters where people - using a variety of languages - has gone
> overboard with OO and language features that were new to them.
> 
> I recommend a gradual approach to learning and applying C++ in most cases. My homepages
> have information on learning C++ and so has "The Design and Evolution of C++."
> 

This is a very important statement in these discussions. I wouldn't
believe anyone who told me that with a one week course under the
team's belt, they were able to write code that took full advantage of
C++. I bet that a lot of the projects that failed did just that.

No one seems to mention the failures. Thats too bad. There are some
good lessons in failure.

Fortunately, I can count our project as a success of transitioning
from C to C++. The key to our success is that we had two people who
did all of the grunt work of setting up the abstractions and
infrastructure that allowed the inexperienced people to write simple
code that just used the abstractions presented. My colleague and I
ported STL implemented smart pointers and RTTI and designed the
interfaces to the infrastructure. We then presented these interfaces
and their usage to the group.

As a result we were able to eliminate those pesky wild pointer and
memory leak problems in the C++ portion of the code. Those errors did
show up in the legacy code written in C that we had to use but we were
fortunate that by using a combination of Insight and Atom (a tool in
Digital Unix), we found them. This meant that when we released the
product to the public, we got more problems with licensing issues than
the program crashing. Now as we know, there is no way to declare a
complex program completely bug free, but the product has been out for over
a year and I haven't had to chase down a crash in the C++ portion of
the code.

We are working on writing up these experiences. When we are done maybe
we will try to submit it for publication somewhere. I don't know who
would be interested now since Java is the "hot" language now :-).

Even through all of the work we did, I am still not a C++ advocate. I
felt that the power of the language compelled me, but the associated
complexity is not for everyone. In fact I believe that 70% or more of
the teams using it probably should have been using something with a
cleaner object model. When I first was learning OO programming, I left
C++ alone and used Sather on SGI machines Objective-C on NeXT to
understand the concept. Only then could I come to C++ and use the
language as an OO language. I then discovered Lisp and it seems to
have very interesting depths which I will have to spend some time
exploring, but my thoughts seem to map to Lisp cleaner than C++. I
have since seen a lot of "competent" programmers who told me they
were using C++, but when I looked at their code, they were using it as
either a better C or as C with classes.

It seems to me that the failure of the software industry to have
programs grow in power, efficiency, and ease of use at the rate that
hardware has grown is due to a couple of interesting factors. First
the most popular languages have made it very tough (for me) to cleanly
map my abstract concepts to clean code to run on a machine. Second,
the languages that come closest to being able to do that have had
shitty implementations. This is because the goals of each camp come
from different points on the map. The C/C++ camp of programmers wanted
efficiency and integration with the OS. This makes perfect sense at
the System Application level. For example our product Performance
Manager is what I would call a System Application. It needs intimate
knowledge of the internals of the operating system, but it also needs
a nice face to help the user wade through the massive amount of
detail. This is the sort of application I thought Bjarne was alluding
to when I read The Design and Evolution of C++. The Lisp camp seems to
come from more of a research camp. This meant that the users of the
language had different requirements which were not necessarily that
close to the OS and while some implementations were designed with
efficiency in mind, they were not the rule. This may not be completely
true, but just take a look at what you have now. Three major vendors,
four implementations with only MCL seeming to have a nice following
and seemingly only CMUCL being able to be made to run as fast as C/C++
consistently. The other implementations, including MCL, have strengths
and weaknesses in their compilers that have limited broad use. For
example I come from a physics background and would like to (in my
copious spare time) write apps that do interesting numerical stuff
underneath, but have a nice front end on them since the numerical
calculation is just the end result of my interaction with the
system. CMU does not have an interface builder and the other lisp
systems costed a small fortune which I did not have. So IMNSHO both
sides have problems that they need to work out.

This seems to be changing in that the complex languages, mainly C++,
are getting better environments that make it easier to map ideas to
code, and the lisp vendors are making nicer implementations that
interface to the lower levels and have nice interface builders (at
least LispWorks does). The Lisp vendors are also seem to be doing a
lot of work to compile to better code. And maybe vendors will compile
Java to native code so that the programmers who should have been using
something like smalltalk will use Java instead. Those guys are pretty
much lost to the Lisp camp since they were pretty much poisoned as
undergrads.

Anyway, sorry for the long-winded discussion, but there seems to be
all of this argument about what is the best language and the answer
for me is that each camp needs to get its act together. I want to be
able to easily map the ideas in my head to clean code. I then want to
be able to experiment with that code in an easy fashion and easily fix
it while its running so that I can see it in action now not 2 hours
later when I have forgotten the bug I was working on. I then want to
be able to easily find the hotspots in the code and have those
hotspots compile to code that is so close to the hand coded assembly
language, that I wont waste my time going to assembly language. I want
to be able to interface to the OS at at least the system call level
when I need to and be able to use all of the processors I have on my
machine. 

So while C++ takes care of some of this list, the mapping and the
compile-run-debug cycle is such a pain for large projects that I waste
a lot of time waiting for a compile. The Lisp camp needs to make it
dog simple to interface to the OS. For example in LispWorks I can just
evaluate a C/C++ header file and the foreign interfaces are generated
for me automagically. I don't want to have to write all of the foreign
interface code so this is a good thing. The nature of C++ pretty much
prevents a NeXTStep like interface builder, but they have been
trying. The Lisp vendors need to buy a used NeXTCube and take a real
close look. This should be a no-brainer for Lisp.

Thanks for your time. I am now going back to lurking and learning to
hack Lisp effectively :-).
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-1905970702390001@10.0.2.1>
In article <·············@cristie.co.uk>, ····@cristie.co.uk wrote:

> Henry Baker wrote:
> <snip> 
> But the ability to produce
> > useful code that takes advantage of the differences between C++ and C in a
> > single week is beyond belief.
> > 
> > It is precisely comments like this that destroy your credibility.
> 
> Calm down!  I'm sure you're worth every penny!!!  :-)
> 
> Regards
> 
> Ben

I'll calm down when I see the details of bs's study.  I'd like to know the
actual calendar dates of this training, the number of people involved, the
educational backgrounds of the people involved, the work experience (including
computer languages used) of the people involved, the type of software involved,
the nature of the productivity measurements, the number of people measuring,
the controls utilized during this measurement, etc.  Without these and other
details of this experiment, the results are worthless, and shouldn't be
quoted in support of any productivity 'gains'.

This isn't Tijuana Medical Clinic, this is Bell Labs.  We deserve better.
From: David Hanley
Subject: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3380A5F6.53A8@nospan.netright.com>
Henry Baker wrote:
> 
> 
> I'll calm down when I see the details of bs's study.  I'd like to know the
> actual calendar dates of this training, the number of people involved, the
> educational backgrounds of the people involved, the work experience (including
> computer languages used) of the people involved, the type of software involved,
> the nature of the productivity measurements, the number of people measuring,
> the controls utilized during this measurement, etc.  Without these and other
> details of this experiment, the results are worthless, and shouldn't be
> quoted in support of any productivity 'gains'.

	Despite the fact that I don't like C++ too much as a language, I can
somewhat buy the fact that Mr Strosups studies may be valid when taken
in the 
proper context, i.e. moving C based projects to C++ ones.  At the very
least,
feeding the old C code to the C++ compiler may uncover type errors and
prevent new ones.  

	I agree that turning regular C programmers to C++ powerhouses in a week
is not going to happen.  I think you're reading a little bit much into
what he 
said in his earlier notes.  He only climed a productivity increase, not
language
mastery.

	I'm not a fan of C++, but I don't beleive that Mr Strosup had the 
power to move a large section of the industry to an 'inferior'
language.  

	I think this points out the reason for C++'s success.  C++ was based
on a language that was sucessful and pervasive (C).  C++ allowed C users
to
take advantage of newer compiler technology without much 'downtime'. 
C++
users could use the 'better' typechecking right away.  If there was a
string
class they could get their hands on and sucessfully use, bingo--a
reduction
in development time, because string handling was now easier.  Objects
and destructors make automatic cleanup a little easier.  

	The key thing is that users could learn and apply new principles
very quickly and remain productive.  This mirrors my own introduction to
C++.
I picked up the basic class idea pretty quickly, and my code got a
little bit
better.  Later when I leaned and grokked 'virtual' it got better yet. :)
It took ~1 year to get the whole thing in my head( I wasn't learning it
aggressively )
but at each point I was able to use the new feature, and build upon
what I knew. 

	How does this apply to functional languages?  Well, for whatever reason
functional languages are not the 'norm' in the software community. 
Sorry,
that's the fact.  If I were to start a project and decide 'let's do it
in LISP' 
i'd have a pretty hard time finding enough qualified lisp programmers,
and
a hard time convincing management it was a good idea to use lisp.  

	What if had a 'lispy C'--A C compiler with a few lisp features thrown
in.  It would be easier to pitch to maangement ( it's c with more
features! ) 
and I could find C programmers by shaking a stick in the dark.
Then, I could take this group of C programmers , spend a little time
instructing
then to use, say, garbage collection, and let them go.  I bet
productivity would
increase.  Periodically, 'lispy C' could add another lisp feature 
( Continuations? Higher order functions? ) and this could be introduced
to
the programmers.  More productivity increases ( as compared to C, mind
you ).

	Note that this is essentially the route C++ used.  It even compiled to
C
at first so that it would be easially avaialbe on many platforms.  Lispy
C could do that as well.  Would such an approach be sucessful?  I
dunno.  It 
worked for C++.  

	Now, you may argue that C++ is not good in the 'long run', but that 
is not how such decisions are usually made.  A company with ( too ) many
programmers
could write 1 project in lisp, and a mirror project in C++ for
comparison, with
the appropriate maintenence over the years, then compare quality and
costs.
No one really wants to do that.  If C++ can get us increased
productivity in
the next quarter, great.  Let's use it.  It would probably take more
time 
than that to teach the whole staff passable LISP. 

	We might surmise that a small software company could use LISP 
and be sucessful because of higher productivity.  Unfortunately, this 
evidence is mysteriously lacking.  


dave

P.S. I think lispy C would be a mess too.  :) :)
From: Henry Baker
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <hbaker-1905971321050001@10.0.2.1>
In article <·············@nospan.netright.com>, ·····@nospam.netright.com wrote:

>         Despite the fact that I don't like C++ too much as a language, I can
> somewhat buy the fact that Mr Strosups studies may be valid when taken
> in the 
> proper context, i.e. moving C based projects to C++ ones.  At the very
> least,
> feeding the old C code to the C++ compiler may uncover type errors and
> prevent new ones.  

That's also done by ANSI C.

>         I agree that turning regular C programmers to C++ powerhouses in
a week
> is not going to happen.  I think you're reading a little bit much into
> what he 
> said in his earlier notes.  He only climed a productivity increase, not
> language
> mastery.

Substantial productivity increase means more 'stuff' (however measured)
per unit person per unit time, so there has to be some mechanism for this
increase.  Either they are typing faster, or typing fewer characters, or
making fewer mistakes or something.  Since this study was a formal study,
this information must be available.  Let's see it.
From: ········@wat.hookup.net
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5lsrg4$r3p$1@nic.wat.hookup.net>
In <·······················@10.0.2.1>, ······@netcom.com (Henry Baker) writes:
> ...
>> feeding the old C code to the C++ compiler may uncover type errors and
>> prevent new ones.  
>
>That's also done by ANSI C.

Weren't most of ANSI C's changes from K&R C directly based on C++?  At the
time of its introduction, C++, even without using the OO features, was a
vast improvement over C.  The fact that most of these improvements get fed
back into C with the ANSI standardization tends to obscure this fact
somewhat. 

>> ...
>Substantial productivity increase means more 'stuff' (however measured)
>per unit person per unit time, so there has to be some mechanism for this
>increase.  Either they are typing faster, or typing fewer characters, or
>making fewer mistakes or something.  Since this study was a formal study,
>this information must be available.  Let's see it.

Don't bother.  It is my experience that these measurements to measure
something that can be measured.  I still have my doubts how much this
relates to real productivity.

Hartmann Schaffer
From: David Chase
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <EAHJqq.4nK@world.std.com>
Henry Baker wrote:
> 
> In article <·············@nospan.netright.com>, ·····@nospam.netright.com wrote:

> > proper context, i.e. moving C based projects to C++ ones.  At the very
> > least, feeding the old C code to the C++ compiler may uncover type errors
> > and prevent new ones.

> That's also done by ANSI C.

Henry, I think you are missing an important point, that nobody seems to
be making plain.  People are lazy slobs, and can only occasionally be
troubled to remember to do all the right things.  If your compiler
requires prototypes (you can use then in Ansi C, but they are not
required) then you MUST provide them.  If your compiler enforces
public/private, then if you, or someone, can once be troubled to
say what you intend when writing down a header file, then a little
roadblock has been thrown in the way of subverting that interface down
the road.  One of my major epiphanies along these lines was using
one of those C++ advisory tools (sold by HP, Parasoft, and CenterLine,
my former employer) to develop a little bit of software.  The first
reaction is "shut up stupid, don't tell me how to write code", but
lo-and-behold, if you follow the rules, you get more maintainable
code that surprises you less in the future.  And these are rules
that I would surely forget if I had to rely on myself to check them,
and even if I did, it would take up my time to remember it.  Much
easier to drop the code into the compiler, see where it complains,
fix it.  Of course, I'd prefer to get this by working a different
language altogether, but the general rule holds -- let me worry
about the problem, let the compiler or checker worry about all the
rules that will make the code easier to deal with in the future.
You can do many good things in Ansi C, but you have to think about
them.

I've been a big fan of "if you want someone to do something, make it
easy for them to do it" for years now.  A corollary of this is that I
think C++ has all the wrong defaults (Java inherited a couple, too,
all in the name of C-compatibility), but that's another story.

Of course, another corollary of this is that if there are language
features that lead to unmaintainable code, perhaps they should be
eliminated from the language, or given discouraging names.  For
instance, if you don't want people to do unchecked casts, make
them use funny syntax to get the unchecked casts.  C++ gets this
backwards, of course -- the funny syntax is used for the safe
casts.

> Substantial productivity increase means more 'stuff' (however measured)
> per unit person per unit time, so there has to be some mechanism for this
> increase.  Either they are typing faster, or typing fewer characters, or
> making fewer mistakes or something.  Since this study was a formal study,
> this information must be available.  Let's see it.

Here I agree.  References?  If this was a statistical study, let's see
the numbers.  I suppose the information could be proprietary, but it's
a little odd that the final result would not be (perhaps there is an
advantage in encouraging your competition to adopt C++, while keeping
the effective training methods a secret :-).

David Chase
From: Henry Baker
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <hbaker-2005970914550001@10.0.2.1>
In article <··········@world.std.com>, mylastname, @, world, dot, std, .,
com wrote:
> Henry, I think you are missing an important point, that nobody seems to
> be making plain.  People are lazy slobs, and can only occasionally be
> troubled to remember to do all the right things.
[lots of stuff that I agree with deleted]

Enforcing type constraints (or any other constraints) _may_ be a 'good thing',
depending upon the context.  When I have 'ANSI' checked on my C compiler,
it does require prototypes, so -- within the simpler type system of C -- it
is as picky as the C++ compiler.

But the real issue here is: where is the source of increased productivity of
C++ over C (assuming that the increase is real, which we have very little hard
evidence for) ??  Does it come from writing less code (generativity,
inheritance), making fewer errors (typing, reuse of previously debugged stuff),
making programming more fun (trips to exotic places to learn exotic languages),
getting paid more (C++ programmers get more $$$ than C programmers),
faster compilers (shorter edit-compile-debug cycle), less work to do (we used
to be able to program that in C, but since we can't program that in C++ you'll
have to do without or get someone else), or what?
From: John DiCamillo
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <milodEAHooo.s2@netcom.com>
······@netcom.com (Henry Baker) writes:

>But the real issue here is: where is the source of increased productivity of
>C++ over C (assuming that the increase is real, which we have very little hard
>evidence for) ??  Does it come from 

[snip several plausible reasons]

>faster compilers (shorter edit-compile-debug cycle),

As a C++ programmer who also uses C on occasion, I can *assure* you
that it's not faster compilers. ;-)

-- 
    ciao,
    milo
================================================================
    John DiCamillo                         Fiery the Angels Fell 
    ·····@netcom.com       Deep thunder rode around their shores
From: William Paul Vrotney
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <vrotneyEAHtDo.Lp4@netcom.com>
In article <··············@netcom.com> ·····@netcom.com (John DiCamillo)
writes:

> ······@netcom.com (Henry Baker) writes:
> 
> >But the real issue here is: where is the source of increased productivity of
> >C++ over C (assuming that the increase is real, which we have very little hard
> >evidence for) ??  Does it come from 
> 
> [snip several plausible reasons]
> 
> >faster compilers (shorter edit-compile-debug cycle),
> 
> As a C++ programmer who also uses C on occasion, I can *assure* you
> that it's not faster compilers. ;-)
> 
> -- 
>     ciao,
>     milo

Although interesting this thread sure seems to have evolved into a hard core
C/C++ discussion.  It is not even the good old "Great Lisp versus C debate".

Perhaps it is time for respondents to remove the comp.lang.scheme and
comp.lang.lisp newsgroups before posting?


-- 

William P. Vrotney - ·······@netcom.com
From: Mukesh Prasad
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3381E2A5.7977@polaroid.com>
······@netcom.com (Henry Baker) writes:

>But the real issue here is: where is the source of increased productivity of
>C++ over C (assuming that the increase is real, which we have very little hard
>evidence for) ??  Does it come from

In my experience, the most useful things so far have been:

1)  Prototypes, which helped reduce bugs by
    comparison (when C didn't have them)
2)  Default functions and function overloading
    make life easier.
3)  Class encapsulation, constructors, destructors
    help in modular development
4)  Polymorphism is very helpful for writing
    framework classes which users can modify
    without necessarily understanding much
    of the internals.

I think 4 is particularly significant -- once the novice C++ user
has gotten past the mechanisms for using virtual functions,
he/she can take advantage of the ability to customize
expert-written code.  With C's interfaces involving
functions and occasional function pointers, it was much
more difficult to have so easily customizable code.
From: Darin Johnson
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <slrn5o3oo4.i3o.darin@connectnet1.connectnet.com>
>> > proper context, i.e. moving C based projects to C++ ones.  At the very
>> > least, feeding the old C code to the C++ compiler may uncover type errors
>> > and prevent new ones.
>
>> That's also done by ANSI C.

Remember, C++ was introduced *before* ANSI C.  Maybe these experiments
were done way back then, before you could do good type checking in
normal C...

-- 
Darin Johnson
·····@usa.net.delete_me
From: David Hanley
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3381C517.1DBD@nospan.netright.com>
Henry Baker wrote:
> 
> In article <·············@nospan.netright.com>, ·····@nospam.netright.com wrote:
> 
> >         Despite the fact that I don't like C++ too much as a language, I can
> > somewhat buy the fact that Mr Strosups studies may be valid when taken
> > in the
> > proper context, i.e. moving C based projects to C++ ones.  At the very
> > least,
> > feeding the old C code to the C++ compiler may uncover type errors and
> > prevent new ones.
> 
> That's also done by ANSI C.

	True.  But the study did not claim to compare increases in 
productivity moving from C to ANSI C and C++, just moving from C to C++.

> 
> >         I agree that turning regular C programmers to C++ powerhouses in
> a week
> > is not going to happen.  I think you're reading a little bit much into
> > what he
> > said in his earlier notes.  He only climed a productivity increase, not
> > language
> > mastery.
> 
> Substantial productivity increase means more 'stuff' (however measured)
> per unit person per unit time, so there has to be some mechanism for this
> increase.  Either they are typing faster, or typing fewer characters, or
> making fewer mistakes or something.  Since this study was a formal study,
> this information must be available.  Let's see it.

	Probably typing fewer characters.  You know-- /* */ to //

	:)
From: Henry Baker
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <hbaker-2005971557090001@10.0.2.1>
In article <·············@nospan.netright.com>, ·····@nospam.netright.com wrote:
> Henry Baker wrote:
> > That's also done by ANSI C.
> 
>         True.  But the study did not claim to compare increases in 
> productivity moving from C to ANSI C and C++, just moving from C to C++.

OK, I'm confused.  As I said before, I have no idea when this test was
performed, so I don't know if ANSI C existed at that time.  However, the goal of
the discussion is to tell whether C++ _today_ is more productive than C
_today_, and C today is ANSI C.  If competition from C++ forced C to become
ANSI C, then that was a good thing.  However, we still need to know what
features of C++ that don't appear in ANSI C are _good things_, and we won't
find that out by comparing C++ with K&R C.
From: Ben Hanson
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3382F5A6.1740@cristie.co.uk>
Henry Baker wrote:
> OK, I'm confused.  As I said before, I have no idea when this test was
> performed, so I don't know if ANSI C existed at that time.  However, the goal of
> the discussion is to tell whether C++ _today_ is more productive than C
> _today_, and C today is ANSI C.  If competition from C++ forced C to become
> ANSI C, then that was a good thing.  However, we still need to know what
> features of C++ that don't appear in ANSI C are _good things_, and we won't
> find that out by comparing C++ with K&R C.

Surely though, the modern computing industry is driven (nearly) wholly
by fashion these days and constantly re-invents istself selling olld
technology as new (look at the way Microsoft dress up 1960's technology
as New Technology).

I may not be anywhere as experienced as you Henry, but isn't 90% of
computing pure hype?

If not I'd love to hear the reasons!  I may be a cynic, but that doesn't
mean I don't look for the good things in this industry.

Regards,

Ben
From: Chris Bitmead uid(x22068)
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <BITMEADC.97May20111552@Alcatel.com.au>
In article <·············@nospan.netright.com> David Hanley <·····@nospan.netright.com> writes:

>	I'm not a fan of C++, but I don't beleive that Mr Strosup had the 
>power to move a large section of the industry to an 'inferior'
>language.  

Actually, Mr BS did stumble across a way to get the industry to
move to something inferior.

People with a "C" headache thought they would try out the "C++"
aspirin on some of their minor headaches to see what happened, and
found their headache went away.

Trouble is they then went and prescribed the same pill for a brain
tumour, and found that it let the cancer grow instead of reduced.

Unfortunately, now most research is spent on the C++ "aspirin", and
the real large project cancer cures are forgotten about.

>How does this apply to functional languages?  Well, for whatever
>reason functional languages are not the 'norm' in the software
>community.  Sorry, that's the fact.  If I were to start a project and
>decide 'let's do it in LISP' i'd have a pretty hard time finding
>enough qualified lisp programmers, and

You'd have so many lisp programmers beating down your door to do real
high quality development that you wouldn't know what to do.

>Now, you may argue that C++ is not good in the 'long run', but that is
>not how such decisions are usually made.  

Yes, it's a tradgedy isn't it. This attitude wouldn't be tolerated in
any other profession. Can you imagine it? "Yeah the bridge will
probably fall down next year, but in the mean time you will get a lot
of cars across it". "Don't worry about the cancer, you've got 6 months
of healthy life ahead of you", "They'll sue you for all your money
next year, but don't worry because we'll delay it in the courts for 6
more months"

>A company with ( too ) many
>programmers could write 1 project in lisp, and a mirror project in C++
>for comparison, with the appropriate maintenence over the years, then
>compare quality and costs.  No one really wants to do that.  If C++
>can get us increased productivity in the next quarter, great.  Let's
>use it.  It would probably take more time than that to teach the whole
>staff passable LISP.
>	We might surmise that a small software company could use LISP 
>and be sucessful because of higher productivity.  Unfortunately, this 
>evidence is mysteriously lacking.  

Well, the research papers give the evidence. What more do you want?
From: Rainer Joswig
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <joswig-ya023180002505971214260001@news.lavielle.com>
In article <······················@Alcatel.com.au>,
·············@Alcatel.com.au wrote:

> >A company with ( too ) many
> >programmers could write 1 project in lisp, and a mirror project in C++
> >for comparison, with the appropriate maintenence over the years, then
> >compare quality and costs.  No one really wants to do that.  If C++
> >can get us increased productivity in the next quarter, great.  Let's
> >use it.  It would probably take more time than that to teach the whole
> >staff passable LISP.
> >       We might surmise that a small software company could use LISP 
> >and be sucessful because of higher productivity.  Unfortunately, this 
> >evidence is mysteriously lacking.  
> 
> Well, the research papers give the evidence. What more do you want?

Well, AT&T was doing a switching system in Lisp and another one
in C++. The C++ system did take a lot more resources (it was
done as a production system). The Lisp version was more
like a research project (let's see what we can do). As it
turned out the Lisp version did have more functionality
at comparable speed and was *much* cheaper to built.

This was a large project (if I remember correct, up to 100 people were
working on the switch based on Lisp). It did touch areas like real-time GC,
OODBMs, fault tolerance, the system should be down in the
range of a minute per year, etc.

The group has reported about that publicly and they seemed a bit
frustrated that despite the clear superiority of their switch,
the company still wanted to market the system based on C++.

-- 
http://www.lavielle.com/~joswig/
From: Jay Martin
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5maer6$ghg@uni.library.ucla.edu>
······@lavielle.com (Rainer Joswig) writes:

>In article <······················@Alcatel.com.au>,
>·············@Alcatel.com.au wrote:

>> >A company with ( too ) many
>> >programmers could write 1 project in lisp, and a mirror project in C++
>> >for comparison, with the appropriate maintenence over the years, then
>> >compare quality and costs.  No one really wants to do that.  If C++
>> >can get us increased productivity in the next quarter, great.  Let's
>> >use it.  It would probably take more time than that to teach the whole
>> >staff passable LISP.
>> >       We might surmise that a small software company could use LISP 
>> >and be sucessful because of higher productivity.  Unfortunately, this 
>> >evidence is mysteriously lacking.  
>> 
>> Well, the research papers give the evidence. What more do you want?

There are no such research papers.

>Well, AT&T was doing a switching system in Lisp and another one
>in C++. The C++ system did take a lot more resources (it was
>done as a production system). The Lisp version was more
>like a research project (let's see what we can do). As it
>turned out the Lisp version did have more functionality
>at comparable speed and was *much* cheaper to built.

This is total heresay and of course is pointless as it says nothing
about the the long term maintanance which usually consists of like 80%
of the project costs.  If it was a research project, then it was
highly likely that it was a poorly designed piece of crap.  Most
researchers just don't have the discipline to be good software
engineers.

>This was a large project (if I remember correct, up to 100 people were
>working on the switch based on Lisp). It did touch areas like real-time GC,
>OODBMs, fault tolerance, the system should be down in the
>range of a minute per year, etc.

Well it actually "touched" them, wow!

>The group has reported about that publicly and they seemed a bit
>frustrated that despite the clear superiority of their switch,
>the company still wanted to market the system based on C++.

Do to that software is a incredibly incompetent and religious field, we 
have to wonder wether the group was the usual bunch zealot crackpots.

Jay
From: Chris Bitmead uid(x22068)
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <BITMEADC.97May26170843@Alcatel.com.au>
In article <··········@uni.library.ucla.edu> ·······@cs.ucla.edu (Jay Martin) writes:

>>> >       We might surmise that a small software company could use LISP 
>>> >and be sucessful because of higher productivity.  Unfortunately, this 
>>> >evidence is mysteriously lacking.  
>>> 
>>> Well, the research papers give the evidence. What more do you want?
>
>There are no such research papers.

There are research papers that show Lisp giving much higher
productivity than C++.

>>Well, AT&T was doing a switching system in Lisp and another one
>>in C++. The C++ system did take a lot more resources (it was
>>done as a production system). The Lisp version was more
>>like a research project (let's see what we can do). As it
>>turned out the Lisp version did have more functionality
>>at comparable speed and was *much* cheaper to built.
>
>This is total heresay and of course is pointless as it says nothing
>about the the long term maintanance which usually consists of like 80%
>of the project costs.  If it was a research project, then it was
>highly likely that it was a poorly designed piece of crap.  Most
>researchers just don't have the discipline to be good software
>engineers.

Really? I find that most software engineers don't have the discipline
to be good software engineers. Most researchers actually do take the
time to do it right.
From: Jay Martin
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5mbkt8$19im@uni.library.ucla.edu>
·············@Alcatel.com.au (Chris Bitmead uid(x22068)) writes:

>In article <··········@uni.library.ucla.edu> ·······@cs.ucla.edu (Jay Martin) writes:

>>>> >       We might surmise that a small software company could use LISP 
>>>> >and be sucessful because of higher productivity.  Unfortunately, this 
>>>> >evidence is mysteriously lacking.  
>>>> 
>>>> Well, the research papers give the evidence. What more do you want?
>>
>>There are no such research papers.

>There are research papers that show Lisp giving much higher
>productivity than C++.

Then kindly someone point me to a web site with this glorious
evidence.  I have never seen serious language productivity research
and it was my opinion that CS academia was not going to do it anytime
soon.  Of course, I am talking about serious software engineering
efforts not prototyping.  So such comparison should be based on a
reasonably large and long projects where long term maintanance is of
central concern and with programmers that not at some the extreme part
of the bell curve.  Of course, C/C++ is the weakest of all modern
strongly typed languages, so such research is already cherry-picking.

Jay
From: Darin Johnson
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <slrn5ojoes.e74.darin@connectnet1.connectnet.com>
In article <···········@uni.library.ucla.edu>, Jay Martin wrote:
>So such comparison should be based on a
>reasonably large and long projects where long term maintanance is of
>central concern and with programmers that not at some the extreme part
>of the bell curve.

I will first admit that I have only worked at (and am working) one
site that sold commercial software.  Long term maintenance is
important - but it is not practiced!  There more of a feeling of
"rush it out the door" here than when I was in academia or at a
commercial research environment.  Some programmers want to have more
discipline, but can't.

As far as your earlier assertion that research programmers are bad at
maintenance and aren't disciplined; bullshit.  You just slapped them
all in the face, and perpetuated this idioitic myth that can prevent
them from getting hired.  I ran into this situation with interviewers,
some who came flat out and said they did not believe I could maintain
code.  I've spent three years "maintaining" code now, and it's nothing
special or magical, and involves no skills that research programmers
lack.  Maintenance may be time consuming and expensive, but it's not
rocket science (excepting NASA code maintenance).  Maintenance is
usually given to entry level or junior programmers; to imply that
research programmers are worse at it than those fresh from school with
no experience is malicious.  The code I maintain (but didn't write) is
horrible, but I can only clean it up or make it more maintainable when
I have free time.  I spent lots of time in grad school making sure my
programs were clean and maintainable by whoever picked them up; and
many of my fellows were equally conscientious, we are not anomalies.
Research programming takes incredible discipline (which is why I'm now
maintaining code instead), you need accurate measurements,
documentation, record keeping, and lots of patience.

-- 
Darin Johnson
·····@usa.net.delete_me
From: Dean Roddey
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <338A78F8.11C4@ng.netgate.net>
Darin Johnson wrote:
> 
> In article <···········@uni.library.ucla.edu>, Jay Martin wrote:
> >So such comparison should be based on a
> >reasonably large and long projects where long term maintanance is of
> >central concern and with programmers that not at some the extreme part
> >of the bell curve.
> 
> I will first admit that I have only worked at (and am working) one
> site that sold commercial software.  Long term maintenance is
> important - but it is not practiced!  There more of a feeling of
> "rush it out the door" here than when I was in academia or at a
> commercial research environment.  Some programmers want to have more
> discipline, but can't.
> 

The reasons are pretty obvious, just to start another long, drawn out,
and meaningless argument ... :-0

The reason is that you cannot sell quality to most customers of
software. Quality is not quantifiable in such a way as to be externally
verifiable. And customers are generally incapable of verifying it
themselves, since (if they had that skill) they could right it
themselves probably and make the money for themselves.

Without this ability to sell the quality of one's architecture, what is
the likely outcome? Basically its exactly what we see, where the
internal architecture and the quality of the software is forced to take
a distant second or third or fourth to features, political strategic
decisions from on high, and so forth.

I think it sucks too, but I'm not sure what to do about it. There are
obviously some customers who you can sell quality to, but the shrink
wrapped market certainly ain't among them as far as I can tell. To the
end user, it can be band-aided and glued together internally as long as
it looks pretty and does not crash too often. So ad hoc fixes are
generally done instead of fundamental improvement, every one of which
degrades the overall quality and stability of the product.

Just my opinion, of course.

------------------
Dean Roddey
The CIDLib Class Libraries
'CIDCorp
·······@ng.netgate.net
http://ng.netgate.net/~droddey/

"Software engineers are, in many ways, similar to normal people"
From: Ulf Wiger
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <338AA4B5.6F25@etxb.ericsson.se>
Darin Johnson wrote:
> 
> In article <···········@uni.library.ucla.edu>, Jay Martin wrote:
> >So such comparison should be based on a
> >reasonably large and long projects where long term maintanance is of
> >central concern and with programmers that not at some the extreme part
> >of the bell curve.

Long-term maintenance is primarily a matter of careful planning and 
structuring - it can be supported in many different languages.

At Ericsson, we have plenty of evidence to support the claim that
The Erlang language supports and encourages the writing of maintainable 
code. If you want specific data, contact <·····@erlang.ericsson.se>.
For obvious reasons, not all information on our product development is 
available to the public.

If you believe our 300+ Erlang programmers are all at the extreme end 
of the bell curve, you should buy lots of Ericsson stock!
(well... you _should_ buy lots of Ericsson stock.) 

> I will first admit that I have only worked at (and am working) one
> site that sold commercial software.  Long term maintenance is
> important - but it is not practiced!  There more of a feeling of
> "rush it out the door" here than when I was in academia or at a
> commercial research environment.  [rest deleted]

The importance of maintainable software varies in different fields.
In a product with an expected shelf life of a few months to a few 
years, maintenance is not a vital factor - code reuse probably still is.

When building a telephone switch, which might be supported for decades
(e.g. the Ericsson AXE switch), maintenance is essential.
It would surprise me to learn that the researchers at AT&T didn't 
factor in maintenance as a vital design parameter when prototyping 
a switch in LISP.

-- 
Ulf Wiger, Chief Designer ETX/DN/XBS    <·······@etxb.ericsson.se>
Ericsson Telecom AB                          tfn: +46  8 719 81 95
Varuv�gen 9, �lvsj�                          mob: +46 70 519 81 95
S-126 25 Stockholm, Sweden                   fax: +46  8 719 43 44
From: Christopher Stacy
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <uaflg2kli.fsf@pilgrim.com>
Does this need to be cross-posted to all these lists,
or is that just to fully enflame all the religous sects?

Ulf Wiger <·······@etxb.ericsson.se> writes:
> When building a telephone switch, which might be supported for decades
> (e.g. the Ericsson AXE switch), maintenance is essential.
> It would surprise me to learn that the researchers at AT&T didn't 
> factor in maintenance as a vital design parameter when prototyping 
> a switch in LISP.

Actually, I believe that high software maintenance costs was the
primary reason that they chose to use LISP.  I recall them explaining
how they had armies of people struggling to maintain the 5ESS code.
The other reason was the ability to rapidly develop new, highly
reliable switch features and deploy them in a dynamic environment
(eg. downloading them into a running Lisp.)

Why would you imagine that LISP code is not maintainable?

Chris
From: Marco Antoniotti
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <scfraeqdk76.fsf@infiniti.PATH.Berkeley.EDU>
In article <·············@pilgrim.com> Christopher Stacy <······@pilgrim.com> writes:

   From: Christopher Stacy <······@pilgrim.com>
   Date: 28 May 1997 02:10:01 -0400
   Organization: Pilgrim Telephone
   Lines: 20
   References: <·······················@10.0.2.1> <··········@research.att.com>
	   <···············@Kadath.ens.fr> <··········@research.att.com>
	   <·······················@10.0.2.1> <·············@cristie.co.uk>
	   <·······················@10.0.2.1> <·············@nospan.netright.com>
	   <······················@Alcatel.com.au>
	   <·································@news.lavielle.com>
	   <··········@uni.library.ucla.edu>
	   <······················@Alcatel.com.au>
	   <···········@uni.library.ucla.edu>
	   <····················@connectnet1.connectnet.com>
	   <·············@etxb.ericsson.se>
   X-Newsreader: Gnus v5.3/Emacs 19.34
   Xref: agate comp.lang.scheme:21338 comp.lang.lisp:28486 comp.lang.misc:29900 comp.lang.functional:10022 comp.lang.c++:272752

   Does this need to be cross-posted to all these lists,
   or is that just to fully enflame all the religous sects?

   Ulf Wiger <·······@etxb.ericsson.se> writes:
   > When building a telephone switch, which might be supported for decades
   > (e.g. the Ericsson AXE switch), maintenance is essential.
   > It would surprise me to learn that the researchers at AT&T didn't 
   > factor in maintenance as a vital design parameter when prototyping 
   > a switch in LISP.

   Actually, I believe that high software maintenance costs was the
   primary reason that they chose to use LISP.  I recall them explaining
   how they had armies of people struggling to maintain the 5ESS code.
   The other reason was the ability to rapidly develop new, highly
   reliable switch features and deploy them in a dynamic environment
   (eg. downloading them into a running Lisp.)

   Why would you imagine that LISP code is not maintainable?

There is a very big problem with Lisp.  There are not very many
experienced Lisp programmers around (as posts on comp.lang.lisp tend
to suggest).

The main problem being that (Common) Lisp is not being taught in
schools as much as C/C++ (and now Java) is.  This is the harsh
reality.

Cheers
-- 
Marco Antoniotti
==============================================================================
California Path Program - UCB
Richmond Field Station
tel. +1 - 510 - 231 9472
From: Michael Sperber [Mr. Preprocessor]
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <y9ln2pii9o0.fsf@modas.informatik.uni-tuebingen.de>
>>>>> "Jay" =3D=3D Jay Martin <·······@cs.ucla.edu> writes:

Jay> Then kindly someone point me to a web site with this glorious
Jay> evidence.

I hope an ftp address does as well:

/nebula.systemsz.cs.yale.edu:/pub/yale-fp/papers/NSWC

This was a study conducted by the DoD.

Jay> [ ... ] Of course, I am talking about serious software engineering
Jay> efforts not prototyping.

Of course, that allows you to claim that pretty much any serious
software engineering effort done with functional languages or Lisp is
merely prototyping.

Jay> So such comparison should be based on a reasonably large and long
Jay> projects where long term maintanance is of central concern and
Jay> with programmers that not at some the extreme part of the bell
Jay> curve.

There, Ericsson's experience is bound to me more significant than the
above reference.  Someone just posted on this.  The above reference
reports on experience (albeit in Haskell) with both expert and novice
programmers.  Interestingly, there was almost no difference in
productivity.

There *is* evidence however on what takes up the most time in software
maintenance in C/C++ projects.  Around 35% of all bugs in C/C++
development come from memory problems that can't arise in safe
languages.  The follow-up costs seems to be even higher in proportion.
We haven't even started talking about other factors, such as decent,
expressive type systems, proper polymorpism, higher-order abstraction
or modularization.  The above data is from a '95 PLDI tutorial by John
Ellis.  I could probably dig up a reference if necessary.

-- 
Cheers =3D8-} Mike
Friede, V=F6lkerverst=E4ndigung und =FCberhaupt blabla
From: Chris Bitmead uid(x22068)
Subject: Language productivity (was C++'s success)
Date: 
Message-ID: <BITMEADC.97May27111042@Alcatel.com.au>
>>There are research papers that show Lisp giving much higher
>>productivity than C++.
>
>Then kindly someone point me to a web site with this glorious
>evidence.  I have never seen serious language productivity research
>and it was my opinion that CS academia was not going to do it anytime
>soon.  

Here is one example of such research.  Of course no one research paper
is going to satisfy everyone's questions or concerns. I think there is
enough information in this paper though to draw *some* fairly
significant conclusions, or at least provides the beginning of some
hard empirical evidence. Certainly much more than anything put forward
in this debate so far.

There is a link in here to the language comparison paper...
http://www.cs.yale.edu/users/hudak.html
From: Jay Martin
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5mqisg$1ln2@uni.library.ucla.edu>
·····@usa.net.delete_me (Darin Johnson) writes:

>In article <···········@uni.library.ucla.edu>, Jay Martin wrote:
>>So such comparison should be based on a
>>reasonably large and long projects where long term maintanance is of
>>central concern and with programmers that not at some the extreme part
>>of the bell curve.

>I will first admit that I have only worked at (and am working) one
>site that sold commercial software.  Long term maintenance is
>important - but it is not practiced!  There more of a feeling of
>"rush it out the door" here than when I was in academia or at a
>commercial research environment.  Some programmers want to have more
>discipline, but can't.

You are confusing competent software engineering with what is
practiced.  Maybe if computer science academia wasn't so rotten with
respect to software, the industry wouldn't be so screwed up.

>As far as your earlier assertion that research programmers are bad at
>maintenance and aren't disciplined; bullshit.  You just slapped them
>all in the face, and perpetuated this idioitic myth that can prevent
>them from getting hired.  

In academic research, the purpose is to produce papers.  Since no
"gold stars" are given on papers whose supporting software is
excellent, there is little reason to produce good quality software in
academic research and in fact most academics don't really care about
good quality software..  Take my institution UCLA, they have declared
the software subject as "unworthy of study" (as has most of computer
science) and there is pretty much no professors who are good software
engineers or care about SE.  The result is poorly software educated
students and research project software in past years that looks like
sewage.

>I ran into this situation with interviewers,
>some who came flat out and said they did not believe I could maintain
>code.  I've spent three years "maintaining" code now, and it's nothing
>special or magical, and involves no skills that research programmers
>lack.  Maintenance may be time consuming and expensive, but it's not
>rocket science (excepting NASA code maintenance).  Maintenance is
>usually given to entry level or junior programmers; to imply that
>research programmers are worse at it than those fresh from school with
>no experience is malicious. 

The problem with researcher types with respect to software is not
intelligence.  The problem is temperment and practicality.  Also
whether you will be happy in the position.  As a more researchy type,
I don't think I could tolerate maintaining badly written code for a
long period of time.  I have done it for years in the past and it is
not fun.  The interviewers obviously have been burned by research
types and thus they are pretty much justified.  Plus so much of
academic research software has been unrealistic and of poor quality
over the last 20 years, its hard to blame them for coming to their
conclusion.

>The code I maintain (but didn't write) is
>horrible, but I can only clean it up or make it more maintainable when
>I have free time. 

Well gee doesn't this make you want shoot Computer Science academia
for screwing the industry with incompetent graduates.  

>I spent lots of time in grad school making sure my
>programs were clean and maintainable by whoever picked them up; and
>many of my fellows were equally conscientious, we are not anomalies.
>Research programming takes incredible discipline (which is why I'm now
>maintaining code instead), you need accurate measurements,
>documentation, record keeping, and lots of patience.

Why did you waste your time?  It doesn't really do much for publishing
papers you know.  Only the "numbers" count.  Most research prototypes
are just thrown away, so why do all that boring documentation and
clean evolvable structure stuff.  Besides if you really hack it you
could get better performance numbers.  Heh, were doing SCIENCE
dammmit!  Software is just unscientific trivia which is equivalent to
wiping your butt.  If you really cared about software quality, then
obviously don't understand real "academic computer science research".
Seriously, I really don't know why you think research programming
takes alot software engineering discipline.  I personally don't see
alot of researchers/students who are really excited about building
quality software.  Most seem just to want to hack everything in K&R C.
Even if some wierdos in research do care, endlessly polishing software
is not exactly conductive to "real world" behaviour (real deadlines).
What project from academic research is recognized as excellent quality
software created from a practical process?

All of the above is commenting on academic research, industry research
software may be excellent though these practical software skills
didn't come from any PHD program I have seen.


Jay
From: Bill Gooch
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <339199B4.2705@flash.net>
Jay Martin wrote:
> 
> ....
> All of the above is commenting on academic research, industry research
> software may be excellent though these practical software skills
> didn't come from any PHD program I have seen.

Thank you for clarifying the thrust of your comments.
It wasn't previously clear that you were talking about
academic research, which in my experience is quite
a bit different from commercial research.

It might help to recognize that PhD programs are pre-
dominantly oriented toward training academics, whereas
Bachelor's and Master's programs often have a more 
practical orientation.  This of course varies from one
institution to another, but the whole structure of 
most PhD programs almost invites abuse by the faculty, 
whereas achieving other degrees is typically much more
under the control of the student.

-- 
Bill Gooch			······@flash.net
From: David Chase
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <33942F2E.6E82@world.std.com>
Jay Martin wrote:

> You are confusing competent software engineering with what is
> practiced.  Maybe if computer science academia wasn't so rotten with
> respect to software, the industry wouldn't be so screwed up.

I figure one cause of the industry being screwed up is incompetent
research on productivity and software engineering.  There was some
study just published in the CACM, based (as near as I can tell) on
self-reported data with no control.  No way to tell (from reading
the study) if all this TQM and CMM stuff is worth a penny, or if
they're just doing it all with the Hawthorne effect.  It's entirely
possible that it does work; I've worked with and without "process",
(small-p-process, I think)  and I know what feels saner and more
productive, but that's just my anecdote.

My father is a mechanical engineer.  I got some feel for how they
deal with producivity and process when he had a Big Problem
to solve.  He spent a very long time going over all sorts of 
production records, chasing several false leads, and finally
narrowed the problem down to a different process in a supplier's
production of one of the raw materials.

I don't know much about process and productivity, but it was
pretty clear to me how important getting reproducible and consistent
production results was to his work.  One wonders, given a chance
to use computer languages with completed, non-wiggling standards,
(e.g., Ada, C, Scheme, Fortran) why anyone who worried about
software quality would use a language with an unfinished
standard and notoriously inconsistent implementations, some of
which are not even build-to-build consistent with themselves.
(What, you thought I might be talking about C++?  Why do you
think that?)

This, by-the-way, is one of the reasons why I am so interested
in Java.  I was one of the reviewers for the JLS, and one thing
that was very obvious was that there were going to be very few
gratuitous ambiguities, much tighter than the standards for C,
Scheme, or Fortran (though maybe not tighter than the Ada standard).
(And, once I figured out that this was what they wanted, I pointed
out any ambiguities that I could find.)  Division has a definition.
So does the evaluation order of side-effects in expressions,
and parameters to subroutines.  Harder for the optimizer-writer,
but not impossible.  As near as I could tell, the intention really
is to get as close to write-once-run-anywhere as is feasible.
I know, from years ago when I worked at Sun, that reproducible
behavior was one of Bill Joy's pet peeves.

Another difficulty, at least as I perceive it, is that the
people buying the productivity tools are not the same as the
people using the productivity tools, and some of the purchasers
may have missed the single management skill that I know -- if
you want people to do something, make it easy for them to do
it.  For instance, there's a bug tracking system out there
that is really awful; to quote a colleague, "my ***hole could
write a better bug tracker".  Yet, this is sold, for money,
and I've heard that it generates "great statistics", and that
this is why people buy it, and keep on using it.  I'm sure
that my bug-fixing "statistics" using this tool looked
pretty strange, because I would only use it when I had
absolutely nothing else left to do, because it was so
unpleasant.  I know it is possible to do better, because
I've seen better -- Sun's internal bug tracking tool is
far better than this thing that I used in two other jobs
(I know, right now, that any Sun employees reading this
have dropped their jaws in amazement, but it is true).

-- 
David Chase, ·····@world.std.com
Note: Mail filters automatically and silently discard mail from
······@bigfoot.com, ······@hotmail.com, ······@olg.com.
From: Richard A. O'Keefe
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5n89ie$ihf$1@goanna.cs.rmit.edu.au>
·······@cs.ucla.edu (Jay Martin) writes:
>In academic research, the purpose is to produce papers.  Since no
>"gold stars" are given on papers whose supporting software is
>excellent, there is little reason to produce good quality software in
>academic research and in fact most academics don't really care about
>good quality software..  Take my institution UCLA, they have declared
>the software subject as "unworthy of study" (as has most of computer
>science) and there is pretty much no professors who are good software
>engineers or care about SE.  The result is poorly software educated
>students and research project software in past years that looks like
>sewage.

Don't judge all of academia by UCLA.  RMIT is probably about the number
3 University in the state of Victoria.  (Melbourne Uni and Monash Uni
are numbers 1 and 2, not sure which order.)  I teach a "software
creation and maintenance" subject.  Our highest ranking staff member
is the Professor of Software Engineering.  I cannot recall our
organisational goal statement verbatim, but it goes something like
"We want to produce graduates who will be able to function well as
junior team members in real software work."  (Of course _wanting_ this
is no guarantee that we _achieve_ it...)  This is one reason we chose
Ada as our first year language, not C.

>>The code I maintain (but didn't write) is
>>horrible, but I can only clean it up or make it more maintainable when
>>I have free time. 

>Well gee doesn't this make you want shoot Computer Science academia
>for screwing the industry with incompetent graduates.  

On what did you base your imaginative leap to the conclusion that
the "horrible code" was written by Computer Science graduates?
There's no shortage of TAFEs, community colleges, "tech schools",
whatever, that pump out people with programming certificates.

Industry screws *us*. They want us to teach students absolutely
*everything* (as in, most Australian industry doesn't want to teach its
new IT workers anything).  But they won't pay people more for having a
Masters.  In fact, there is a tendency to be suspicious of people who
have studied a bit more, too academic.  It's already ruinously expensive
to study for 3 or 4 years.  To teach what industry wants, it would have
to be 5, which would put it out of economic range for many of our
students.  And much of "industry" doesn't _want_ people who know how to
write good code.  In deadly earnest, I tell you that I have had a phone
call from a "head-hunter" saying "we can place _anyone_ you greaduate if
they know Microsoft Windows internals; we don't care if they know
anything else."  (That was 3.1.1, not W95 or WNT.)  We are also screwed
by the schools.  How are we supposed to produce skilled IT graduates
when they have trouble reading and writing?  I am no longer surprised by
students who can't take log to the base 2 of 32 (mainly because they
don't know what logarithms _are_), although I was rather startled by the
student who couldn't divide 1000 by 100.  I am still dismayed when an
assignment question says "draw _an_ ER diagram to represent this
information" and N students pipe up "how many diagrams should we draw?"



-- 
Four policemen playing jazz on an up escalator in the railway station.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Darin Johnson
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <slrn5ph6g5.4at.darin@connectnet1.connectnet.com>
>>>The code I maintain (but didn't write) is
>>>horrible, but I can only clean it up or make it more maintainable when
>>>I have free time. 
>
>>Well gee doesn't this make you want shoot Computer Science academia
>>for screwing the industry with incompetent graduates.

No, because it wasn't written by a graduate in computer science.
The author is in his 60's, and most schools didn't have computer
science programs until the 1980's.  And we still have quite a few
programmers here employed who don't have cs degrees.

-- 
Darin Johnson
·····@usa.net.delete_me
From: Darin Johnson
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <slrn5ph818.4at.darin@connectnet1.connectnet.com>
In article <············@goanna.cs.rmit.edu.au>, Richard A. O'Keefe wrote:
>Industry screws *us*. They want us to teach students absolutely
>*everything* (as in, most Australian industry doesn't want to teach its
>new IT workers anything).

I get the impression that they want students taught *one* thing.  It's
just that every company wants a different thing taught.  General
knowledge and ability to adapt is not desired; what's desired is if
someone knows the particular skills already.  Ie, some companies
insist students need to learn "C++ and Win32", and that schools are
shirking their responsibility if they don't; others want AI, numerical
analysis, cobol, unix, CICS, java, networking, or something else.
And everyone of them, when asking for these skills, say "the industry"
wants them, as if every company is exactly the same.

>But they won't pay people more for having a
>Masters.  In fact, there is a tendency to be suspicious of people who
>have studied a bit more, too academic.

Gack, how true.  I had lots of fun being 31 years old, with
a masters and 3 years towards a phd, competing for entry level
jobs with fresh BA CS people.

And I *did* run across several people that were indeed put off by
the fact that I had an advanced education.  Some thought I was
looking too low and wouldn't want the job they had (sheesh, I'm
getting hungry, of course I want your job).  One person amazingly
stated (to others, not to my face) that he thought I would not do
my job but would spend my time doing research instead...

I do think things would have been easier if I went *immediately*
to a Masters after getting my BS, and then immediately gone out
and looked for a job.

-- 
Darin Johnson
·····@usa.net.delete_me
From: David Sharp
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <339D95A7.C0FD4A04@kmos.cmsu.edu>
Jay Martin wrote:
[munch]
> All of the above is commenting on academic research, industry research
> software may be excellent though these practical software skills
> didn't come from any PHD program I have seen.

There is a certain truth to what you say.  However, I know from personal
experience that maintainable code makes doing further research easier. 
If you hack the program, then you have to hack it again if you alter the
experiment.  If you carefully design the software, then modifying it to
fit a new experiment is much easier.

David Sharp
From: Rainer Joswig
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <joswig-ya023180002605970813070001@news.lavielle.com>
In article <··········@uni.library.ucla.edu>, ·······@cs.ucla.edu (Jay
Martin) wrote:

> >Well, AT&T was doing a switching system in Lisp and another one
> >in C++. The C++ system did take a lot more resources (it was
> >done as a production system). The Lisp version was more
> >like a research project (let's see what we can do). As it
> >turned out the Lisp version did have more functionality
> >at comparable speed and was *much* cheaper to built.
> 
> This is total heresay

I was in the audience where the project leader gave a talk
about that and I talked to some of the members of the team.

> and of course is pointless as it says nothing
> about the the long term maintanance which usually consists of like 80%
> of the project costs.

This was running over many years.

>  If it was a research project, then it was
> highly likely that it was a poorly designed piece of crap.  Most
> researchers just don't have the discipline to be good software
> engineers.

The Lisp system worked. One person
told me that he phoned home to France using the switch.

> >This was a large project (if I remember correct, up to 100 people were
> >working on the switch based on Lisp). It did touch areas like real-time GC,
> >OODBMs, fault tolerance, the system should be down in the
> >range of a minute per year, etc.
> 
> Well it actually "touched" them, wow!

The architecture of the Lisp-based switch consists (all from memory):

- An administrative Lisp system with an OODMS.
- a number of special purpose processors doing the switching
- a number of Lisp systems running on separate nodes communicating
  via message passing. These were doing the computations
  and they controlled the special purpose processors

One of the architecture problems they solved was the maintainability
of a system that should have no down time at all. So you could
reprogram the switch on the fly.


Jay, making various insults doesn't help your credibility.

-- 
http://www.lavielle.com/~joswig/
From: Todd Hoff
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <338BA992.697B@possibility.com>
Rainer Joswig wrote:
> 
> In article <··········@uni.library.ucla.edu>, ·······@cs.ucla.edu (Jay
> Martin) wrote:
> The Lisp system worked. One person
> told me that he phoned home to France using the switch.

Working means it works under full load, not for a call. Is
there any experience under these conditions?

> - a number of special purpose processors doing the switching

Ok, so hardware did all the fast stuff and Lisp was the glue.
There's no reason this could not work i'd imagine. I take it
all the drivers, which a switch would have a lot of were not
in lisp.

> One of the architecture problems they solved was the maintainability
> of a system that should have no down time at all. So you could
> reprogram the switch on the fly.

There would have to be some unavailabilty because of
actively running code referencing changing code. In C++ you can 
download new programs and do a reboot, other parts of the system
have to handle the load while this happens. Or you can download scripts
which puts you back at lisp i'd guess.

Question 1: was the lisp  used commerically 
available or was it home spun? If so it would be very
difficult for your average shop to reproduce the results.

Question 2: how would it work in small memory footprint and
anemic processor environments?
A switch is going to have all the memory and processor
it needs, an embedded toaster won't.

thanx

------------------------------------------------------------------
···@possibility.com         | I have no interest in any ship that
http://www.possibility.com  | does not sail fast, for I plan to go
http://www.sendmecoffee.com | in harm's way. -- J.P. Jones
From: Rainer Joswig
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <joswig-ya023180002805972218050001@news.lavielle.com>
In article <·············@possibility.com>, ···@possibility.com wrote:

> Rainer Joswig wrote:
> > 
> > In article <··········@uni.library.ucla.edu>, ·······@cs.ucla.edu (Jay
> > Martin) wrote:
> > The Lisp system worked. One person
> > told me that he phoned home to France using the switch.
> 
> Working means it works under full load, not for a call. Is
> there any experience under these conditions?

What kind of a question is this? Do you really think they
are building an ATM switch that does not perform well in the
real world?

From the Franz, Inc. web site:

 Lucent Technologies, formerly AT&T Network Systems
 and Bell Labs Research, has licensed Allegro CL products
 for the past 10 years. Lucent's various projects involving
 Allegro CL development have included a distributed
 service workbench for video on demand applications over
 ATM, ATM switching, and interfaces to various database
 systems. 

 A switching application known as the Globeview-2000
 Broadband System was developed to accommodate new or
 custom services such as routing by call origin, call
 forwarding, universal telephone numbers, voice mail and
 other services. These services could be updated on-the-fly
 to a running switch because of Allegro CL's Dynamic
 Objects technology. 


> 
> > - a number of special purpose processors doing the switching
> 
> Ok, so hardware did all the fast stuff and Lisp was the glue.

Oh guys... What do think how a switching system in the
>10 Gbps range works? 

> Question 1: was the lisp  used commerically 
> available or was it home spun? If so it would be very
> difficult for your average shop to reproduce the results.

Ask Symbolics, Harlequin and Franz.


> Question 2: how would it work in small memory footprint and
> anemic processor environments?
> A switch is going to have all the memory and processor
> it needs, an embedded toaster won't.

Have a look at http://www.isr.com/L.html .

-- 
http://www.lavielle.com/~joswig/
From: Olivier Lefevre
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3389EDD0.2C00@ny.ubs.com>
Jay Martin wrote:
 
> ······@lavielle.com (Rainer Joswig) writes:
>>
>> Well, AT&T was doing a switching system in Lisp and another one
>> in C++. The C++ system did take a lot more resources (it was
>> done as a production system). The Lisp version was more
>> like a research project (let's see what we can do). As it
>> turned out the Lisp version did have more functionality
>> at comparable speed and was *much* cheaper to built.
> 
> This is total hearsay and of course is pointless as it says nothing
> about the the long term maintanance which usually consists of like 
> 80% of the project costs. If it was a research project, then it was
> highly likely that it was a poorly designed piece of crap.  Most
> researchers just don't have the discipline to be good software
> engineers.

[ More insults deleted ]

Before saying that this was all a fantasy concocted by crackpots
and liars, you might want to consider that Ericsson (very much
a competitor of AT&T) is starting to ship systems programmed in
Erlang, another functional language that, like Lisp, has little 
to do with either C or C++. Of course they must be utter crap...

      http://www.ericsson.se:800/erlang/sure/core/

Regards,

Olivier Lefevre
New York, NY

(not speaking for UBS; AFAIK we don't use Erlang)
From: Sean Matthews
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5me1ro$qej$1@pf1.phil.uni-sb.de>
In article <··········@uni.library.ucla.edu>, ·······@cs.ucla.edu (Jay Martin) writes:
> ······@lavielle.com (Rainer Joswig) writes:
> 
> >Well, AT&T was doing a switching system in Lisp and another one
> >in C++. The C++ system did take a lot more resources (it was
> >done as a production system). The Lisp version was more
> >like a research project (let's see what we can do). As it
> >turned out the Lisp version did have more functionality
> >at comparable speed and was *much* cheaper to built.
> 
> This is total heresay and of course is pointless as it says nothing
> about the the long term maintanance which usually consists of like 80%
> of the project costs.  If it was a research project, then it was
> highly likely that it was a poorly designed piece of crap.  Most
> researchers just don't have the discipline to be good software
> engineers.

Funny. You know, contrary to the apparent beliefs of some people
in this thread, there are imaginative programmers in other parts
of the world than the USA, and even companies other than Lucent in
the telcom switch business.

Eriksson has started programming their exchanges in Erlang,
a dynamically typed functional programming language (i.e., like scheme)
with facilities for parallelism. They do everything except hard
realtime stuff in it.

The reason is that after long study, they found that correct code
written in a functional style was easier to write, and easier to
maintain.

In fact I have a paper currently sitting on my desk `The concurrent
programming language Erlang - An overview',
from http://www.ericsson.se/cslab/~dan/

Opening paragraph:

   Erlang is the result of a consistent search for a better programming
   tool for telecom applications. At the beginning of the 1980's a large
   number of programming languages was tested for controlling a small
   telephone exchange. From the experiments, it became quite clear
   the symbolic programming lanuages, such as Lisp nad Prolog produced
   the shortest code'

That `quite clear' is very emphatic.

I think this, and the other Erlang papers might make educational
reading for some people in this thread.

Perhaps, if you'll forgive the speculation aloud, Eriksson, which
is not *quite* as big, rich and dominant as Lucent, thinks it needs
a competitive edge, and can't affort to indulge the conservativeness
of some of its programmers to the same extent.

Of course the only way to decide these things really is in practice,
so...

Seconds out?

Sean


-- 
Sean Matthews <····@mpi-sb.mpg.de>   http://www.mpi-sb.mpg.de/~sean/
Max-Planck-Institut fuer Informatik,         phone: +49 681 9325 217
Im Stadtwald, 66123 Saarbruecken, Germany      fax: +49 681 9325 299
From: Matthias Blume
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <izyb91av0c.fsf@mocha.CS.Princeton.EDU>
In article <············@pf1.phil.uni-sb.de> ····@mpi-sb.mpg.de (Sean Matthews) writes:


   In article <··········@uni.library.ucla.edu>, ·······@cs.ucla.edu (Jay Martin) writes:
   > This is total heresay and of course is pointless as it says nothing
   > about the the long term maintanance which usually consists of like 80%
   > of the project costs.  If it was a research project, then it was
   > highly likely that it was a poorly designed piece of crap.  Most
   > researchers just don't have the discipline to be good software
   > engineers.

   Funny. You know, contrary to the apparent beliefs of some people
   in this thread, there are imaginative programmers in other parts
   of the world than the USA, and even companies other than Lucent in
   the telcom switch business.

I think you are beating the wrong horse here.  First of all, many of
the hardcore C++ guys, Bjarne Stroustrup in particular, are NOT at
Lucent.  And then, there are things like SML/NJ, for example, which
started at AT&T Bell Labs and are now continued at Lucent Bell Labs.

Regards,
-- 
-Matthias
From: Jordan Henderson
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5mhk60$pik@Starbase.NeoSoft.COM>
In article <··············@mocha.CS.Princeton.EDU>,
Matthias Blume <·····@mocha.cs.princeton.edu> wrote:
>
>I think you are beating the wrong horse here.  First of all, many of
>the hardcore C++ guys, Bjarne Stroustrup in particular, are NOT at
>Lucent.  And then, there are things like SML/NJ, for example, which
>started at AT&T Bell Labs and are now continued at Lucent Bell Labs.
>

I've been dying to insert a comment into this discussion at some point,
and this is probably my last best chance to get it in.

The C++ advocates debating here (and elsewhere) often bring up the fact
that C++ has succeeded in the marketplace where alternatives, such as 
Lisp, have failed.  When it is pointed out to them that market acceptance
is not proof of worth, they agree and fall back on some other finer
point that can be gathered from the fact of market acceptance (like proof
that real software can be written in C++ and knocking down other similar
strawmen).  

The advantage to the C++ advocates in bringing up the relative success of
C++ vs. alternatives is to EMBARRASS the advocates of alternatives.  These
discussions generally go something like:

	C++ advocate: C++ is obviously a good thing, look at it's
		      market acceptance.

	Others: Yes, but Lisp is not accepted due to, uhhhh, 
                sloppy thinking, uhhhh, cabal of software "experts" and
                their trade press lackeys, uhhhh, Microsoft politics,
                uhhh....

The problem is that Lisp is not accepted better and nobody really knows 
why.  Those who attempt to explain it directly sound like paranoid 
conspiracy theorists, or they have some unfounded argument about Lisp
syntax or GC or some other technical detail.  I'm sure it's entertaining
to the C++ advocates to watch all the weak-sounding defenses of Lisp
(and alternatives) whenever they bring up the issue of market acceptance.

There has recently been a great deal of discussion about some studies that
some claim were done in their organization at some time in the past that
shows that C++ is, to some appreciable degree, better in most respects to
C.  The subjects of the studies were disciplined, expert C programmers.

In the spirit of asking embarrassing questions, why is it that the MOST
expert C programmers, those fine folks at lucent.com chose C as the 
implementation language for both of their most recent visible projects,
Plan 9 and Inferno?  These people have had access to the best C++
technology and expertise in the recent past AND they have not, in the
past, shown a reluctance to use other programming languages such as Pascal.  

No, I don't think that I've added anything to the ongoing discussions.  I
just couldn't help myself.

>Regards,
>-- 
>-Matthias

-Jordan Henderson
······@neosoft.com
From: Sean Matthews
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5mhjb0$3ia$1@pf1.phil.uni-sb.de>
In article <··············@mocha.CS.Princeton.EDU>, ·····@mocha.cs.princeton.edu (Matthias Blume) writes:
> In article <············@pf1.phil.uni-sb.de> ····@mpi-sb.mpg.de (Sean Matthews) writes:
> 
>    Funny. You know, contrary to the apparent beliefs of some people
>    in this thread, there are imaginative programmers in other parts
>    of the world than the USA, and even companies other than Lucent in
>    the telcom switch business.
> 
> I think you are beating the wrong horse here.  First of all, many of
> the hardcore C++ guys, Bjarne Stroustrup in particular, are NOT at
> Lucent.  And then, there are things like SML/NJ, for example, which
> started at AT&T Bell Labs and are now continued at Lucent Bell Labs.
> 
> Regards,
> -- 
> -Matthias

I think you misunderstand me. This remark wasn't aimed at people
at Lucent/ATT/Bell labs (I lose track of exactly which bit is
which these days).  I was referring, maybe too obliquely, to some
rather silly remarks made by other people which could generously
be described as parochial.


Sean

-- 
Sean Matthews <····@mpi-sb.mpg.de>   http://www.mpi-sb.mpg.de/~sean/
Max-Planck-Institut fuer Informatik,         phone: +49 681 9325 217
Im Stadtwald, 66123 Saarbruecken, Germany      fax: +49 681 9325 299
From: Peter da Silva
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5mhqj2$o1v@web.nmti.com>
In article <··········@starbase.neosoft.com>,
Jordan Henderson <······@Starbase.NeoSoft.COM> wrote:
> 	C++ advocate: C++ is obviously a good thing, look at it's
> 		      market acceptance.

Response: Windows 95 is obviously a good thing. Look at its market acceptance.

Side issue: let's not lump everyone into Lisp Advocate Versus C++ Advocate.

Some of us are devout agnostics.

> The problem is that Lisp is not accepted better and nobody really knows 
> why.

Lisp looks weird. I like it, but I'm a weirdo.

Heck, I like Tcl. But then Tcl is a lisp variant.

> No, I don't think that I've added anything to the ongoing discussions.  I
> just couldn't help myself.

You naughty boy, Jordan.

PS: "HI!"
-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: Chris Bitmead uid(x22068)
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <s6yn2pfm6bp.fsf@aalh02.alcatel.com.au>
·····@nmti.com (Peter da Silva) writes:

> Lisp looks weird. I like it, but I'm a weirdo.
> 
> Heck, I like Tcl. But then Tcl is a lisp variant.

I can't think of a language more different to Lisp than Tcl, except
maybe COBOL.
From: Peter da Silva
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5mk059$g5j@web.nmti.com>
In article <···············@aalh02.alcatel.com.au>,
Chris Bitmead uid(x22068) <·············@alcatel.com.au> wrote:
> I can't think of a language more different to Lisp than Tcl, except
> maybe COBOL.

It satisfies Eric Naggum's definition of lisp, you know.
-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: Bill Gooch
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <338AEA7F.723D@flash.net>
Jay Martin wrote:
> 
> ······@lavielle.com (Rainer Joswig) writes:
> 
> >Well, AT&T was doing a switching system in Lisp and another one
> >in C++. The C++ system did take a lot more resources (it was
> >done as a production system). The Lisp version was more
> >like a research project (let's see what we can do). As it
> >turned out the Lisp version did have more functionality
> >at comparable speed and was *much* cheaper to built.
> 
> This is total heresay and of course is pointless ....

Did you mean to write "hearsay" or "heresy?"  I can't tell.

>   If it was a research project, then it was
> highly likely that it was a poorly designed piece of crap.  Most
> researchers just don't have the discipline to be good software
> engineers.

Some researchers at least have enough discipline to 
communicate in a civil manner, and some of them in my
experience write damn good software.  Better than many
commercial products in some cases, partly because the
researchers might not be faced with unrealistic deadlines, 
scope creep, and all the other extraneous issues that 
often (usually?) attend commercial development projects.

> >This was a large project (if I remember correct, up to 100 people were
> >working on the switch based on Lisp). It did touch areas like real-time GC,
> >OODBMs, fault tolerance, the system should be down in the
> >range of a minute per year, etc.
> 
> Well it actually "touched" them, wow!

Brilliant retort.  Do you have anything substantive to
offer?

> >The group has reported about that publicly and they seemed a bit
> >frustrated that despite the clear superiority of their switch,
> >the company still wanted to market the system based on C++.
> 
> Do to that software is a incredibly incompetent and religious field, we
> have to wonder wether the group was the usual bunch zealot crackpots.

Present company excluded, I'm sure.

-- 
Bill Gooch			······@flash.net
From: John Dunning
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <JRD.97May27101634@hotsprings>
   From: ·······@cs.ucla.edu (Jay Martin)
   Date: 25 May 1997 22:35:18 GMT

   ······@lavielle.com (Rainer Joswig) writes:

   >In article <······················@Alcatel.com.au>,
   >·············@Alcatel.com.au wrote:

[...]
   >Well, AT&T was doing a switching system in Lisp and another one
   >in C++. The C++ system did take a lot more resources (it was
   >done as a production system). The Lisp version was more
   >like a research project (let's see what we can do). As it
   >turned out the Lisp version did have more functionality
   >at comparable speed and was *much* cheaper to built.

   This is total heresay 

Negative.  It existed, and probably still does.  I worked for one of
the contractors involved at the time it was going on, and worked on
the OS portion.

			 and of course is pointless as it says nothing
   about the the long term maintanance which usually consists of like 80%
   of the project costs.  

Maintenance cost was one of the reasons they decided to try something
else (lisp!?!  why would you want to use that??) in the first place.
The existing C/C++ system was so difficult to maintain that it took a
team of over a thousand people doing ongoing maintenance to stay on
top of it.  And any complex change was so risky that it was ages
before it actually materialized in the released software.

			  If it was a research project, then it was
   highly likely that it was a poorly designed piece of crap.  Most
   researchers just don't have the discipline to be good software
   engineers.

It's certainly true that some of the folks we worked with were more
along the lines of researchers than engineers.  (That seemed to be
true of all their groups, for what it's worth)  A bunch of the
engineers were refugees from other switch groups.

   >This was a large project (if I remember correct, up to 100 people were
   >working on the switch based on Lisp). It did touch areas like real-time GC,
   >OODBMs, fault tolerance, the system should be down in the
   >range of a minute per year, etc.

   Well it actually "touched" them, wow!

Enough to make it work as a real-time system.

Sarcasm, while, amusing, doesn't do much to advance the debate, or get
to the truth.  Perhaps those aren't among your goals?

   >The group has reported about that publicly and they seemed a bit
   >frustrated that despite the clear superiority of their switch,
   >the company still wanted to market the system based on C++.

   Do to that software is a incredibly incompetent and religious field, we 
   have to wonder wether the group was the usual bunch zealot crackpots.

They were serious, and they had technology that worked, for far less
effort than the alternative.

My understanding was that upper management was basically completely
unwilling to deploy anything not written in C (remember, big company,
big company politics), so no matter what results were acheived, there
was no chance that the stuff would be used for real.  The fact is that
it's a huge corporation, and it costs them essentially nothing to have
lots of technology groups kicking around, whether they plan to use the
results or not.
From: Andrew Koenig
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <EAw6t5.5ns@research.att.com>
In article <·················@hotsprings> ···@hotsprings (John Dunning) writes:

> Maintenance cost was one of the reasons they decided to try something
> else (lisp!?!  why would you want to use that??) in the first place.
> The existing C/C++ system was so difficult to maintain that it took a
> team of over a thousand people doing ongoing maintenance to stay on
> top of it.  And any complex change was so risky that it was ages
> before it actually materialized in the released software.

If this is the project I'm thinking of, it predates the existence of C++
by several years.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Thomas Lindgren
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3m9112id2j.fsf@groucho.csd.uu.se>
······@lavielle.com (Rainer Joswig) writes:

> Well, AT&T was doing a switching system in Lisp and another one
> in C++. The C++ system did take a lot more resources (it was
> done as a production system). The Lisp version was more
> like a research project (let's see what we can do). As it
> turned out the Lisp version did have more functionality
> at comparable speed and was *much* cheaper to built.
> 
> This was a large project (if I remember correct, up to 100 people were
> working on the switch based on Lisp). It did touch areas like real-time GC,
> OODBMs, fault tolerance, the system should be down in the
> range of a minute per year, etc.
> 
> The group has reported about that publicly and they seemed a bit
> frustrated that despite the clear superiority of their switch,
> the company still wanted to market the system based on C++.

Interestingly, Ericsson has started to move from C++ to Erlang, a
functional language, in developing telephony code (see for instance
their Mobility Server). Perhaps telephony is a niche that fits functional
languages well?

More on Erlang:

	http://www.ericsson.se/erlang/

			Thomas

-- 
Thomas Lindgren, Uppsala University		The unexamined death is
e-mail: thomasl csd uu se, lindgren sics se	not worth dying.
http://www.csd.uu.se/~thomasl/
From: Matt Kennel (Remove 'nospam' to reply)
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <slrn5oum91.o9b.kennel@lyapunov.ucsd.edu>
On 26 May 1997 15:21:24 +0200, Thomas Lindgren <·······@groucho.csd.uu.se> wrote:
:
:Interestingly, Ericsson has started to move from C++ to Erlang, a
:functional language, in developing telephony code (see for instance
:their Mobility Server). Perhaps telephony is a niche that fits functional
:languages well?

Doubtful.  More likely that the tradition of communication
engineering is not quite as anti-intellectual, stifling and faddish than
much of the remainder of the commercial software industry.

Von Neumann's early death set back the world 20 years. 

Another example is military and large scale government work: often the
software technology and disciplined process is reasonably advanced 
vs. typical commercial enterprises (Lisp, Ada, etc.) and yet the ill-considered
libertarian prejudices of the 'digerati' sometimes assume that simply
*because* it's governmental (or often, even anything from "socialistic"
Europe) that such technology must be inherently suspect. 

-- 
Matthew B. Kennel/Institute for Nonlinear Science, UCSD/
Don't blame me, I voted for Emperor Mollari. 
From: Thant Tessman
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3395D042.41C6@nospam.acm.org>
Thomas Lindgren wrote:

> [Ericsson uses Erlang]  Perhaps telephony is a niche that 
> fits functional languages well?

Matt Kennel wrote:

> Doubtful.  More likely that the tradition of communication
> engineering is not quite as anti-intellectual, stifling and 
> faddish than much of the remainder of the commercial 
> software industry.  [...]
>
> Another example is military and large scale government work: 
> often the software technology and disciplined process is 
> reasonably advanced vs. typical commercial enterprises (Lisp, 
> Ada, etc.) and yet the ill-considered libertarian prejudices 
> of the 'digerati' sometimes assume that simply *because* it's 
> governmental (or often, even anything from "socialistic"
> Europe) that such technology must be inherently suspect.

I think you're overjudging the degree to which business has
a libertarian agenda.  Businesses are usually just as eager 
to take advantage of Uncle Sugar as the average university 
is to spend a research grant.  If that research grant 
produces something a business can use, they'll use it.  All 
the better if Joe Taxpayer funded it.  

Given that C++ clearly sucks, one must look elsewhere for 
the explanation behind C++'s success against more "academic" 
languages.

-thant (Scheme programmer and libertarian)
From: William Paul Vrotney
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <vrotneyEB9w7q.5HL@netcom.com>
I promised myself that I would not get sucked into this thread but sometimes
the temptation to get sucked is just too great.

In article <·············@nospam.acm.org> Thant Tessman
<·····@nospam.acm.org> writes:

>   Matt Kennel wrote:
>
>   > Doubtful.  More likely that the tradition of communication
>   > engineering is not quite as anti-intellectual, stifling and 
>   > faddish than much of the remainder of the commercial 
>   > software industry.  [...]
>   >
>   > Another example is military and large scale government work: 
>   > often the software technology and disciplined process is 
>   > reasonably advanced vs. typical commercial enterprises (Lisp, 
>   > Ada, etc.) and yet the ill-considered libertarian prejudices 
>   > of the 'digerati' sometimes assume that simply *because* it's 
>   > governmental (or often, even anything from "socialistic"
>   > Europe) that such technology must be inherently suspect.
>
>   I think you're overjudging the degree to which business has
>   a libertarian agenda.  Businesses are usually just as eager 
>   to take advantage of Uncle Sugar as the average university 
>   is to spend a research grant.  If that research grant 
>   produces something a business can use, they'll use it.  All 
>   the better if Joe Taxpayer funded it.  
>

True.

>   Given that C++ clearly sucks, one must look elsewhere for 
>   the explanation behind C++'s success against more "academic" 
>   languages.

In my humble view the explanation is clear.  We humans are still quite naive
in the sense that we will allow religion to prevail over science.  Religion
seems to prevail over reason.  Hype seems to prevail over worth.  See Carl
Sagan's "The Demon Haunted World".

Science is not the business of appeasing people in general.  I hope computer
scientists will continue to improve Lisp and ignore hyped language threats.
I pray this thread ends soon.  I guess I'm naive.


-- 

William P. Vrotney - ·······@netcom.com
From: Jon S Anthony
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <JSA.97Jun5155506@alexandria.organon.com>
In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

> Given that C++ clearly sucks, one must look elsewhere for 
> the explanation behind C++'s success against more "academic" 
> languages.
> 
> -thant (Scheme programmer and libertarian)

Simple stupidity?  Why make the explanation more involved or
mysterious?

For example, one of the most odd (and very prevalent in my experience)
reasons given for using C++ against other viable alternatives -
alternatives which are even acknowledged by the parties involved as
being _clearly_ better - is some variant of the old "but everyone else
is using it".  Now, other than in the land of software, where else
would anyone actually suggest using an _inferior_ tool (or process or
whatever) to make your product _because_ your _competitor_ is using
that inferior tool?  Go figure.

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
···@organon.com
From: Peter da Silva
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5n7dli$4pu@web.nmti.com>
In article <················@alexandria.organon.com>,
Jon S Anthony <···@alexandria.organon.com> wrote:
> Now, other than in the land of software, where else
> would anyone actually suggest using an _inferior_ tool (or process or
> whatever) to make your product _because_ your _competitor_ is using
> that inferior tool?  Go figure.

Telecommunications.

Television.

The Automobile Industry.

(HDTV, ISDN, Alternative Fuels, anyone?)

(Well, ISDN is STARTING to live up to its promise, in SOME areas...)

(yes, I'm feeling grumpy)
-- 
This is The Reverend Peter da Silva's Boring Sig File - there are no references
to Wolves, Kibo, Discordianism, or The Church of the Subgenius in this document
From: Jon S Anthony
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <JSA.97Jun6185029@alexandria.organon.com>
In article <··········@web.nmti.com> ·····@nmti.com (Peter da Silva) writes:

> Telecommunications.

Really?  The hardware part?  What's your evidence?

> Television.

So, you claim that Sony (or some such) actually decides to use
inferior production to make its electronics (TVs in particular)?
Where's the evidence?


> The Automobile Industry.

This I know from experience is incorrect.


> (HDTV, ISDN, Alternative Fuels, anyone?)

So, you claim these people actually _knowingly choose_ inferior
tools,techniques, whatever to make the hardware for this?  Really?
Where's your evidence?

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
···@organon.com
From: Darin Johnson
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <slrn5pelq4.6a3.darin@connectnet1.connectnet.com>
>> Now, other than in the land of software, where else
>> would anyone actually suggest using an _inferior_ tool (or process or
>> whatever) to make your product _because_ your _competitor_ is using
>> that inferior tool?  Go figure.

"Competitor" is also a relative term.  My company's competitors are
not necessarily *my* competitors.  Company loyalty is near zero now
days (mostly because the reverse loyalty is also near zero).  As far
as inferior tools go, if I know the tools my company's competitors
use, then I'm in a position to work for that competitor (if I get laid
off say, or defect, etc).

Thus, just because of the sheer number of places that use C++, it's
worth knowing (you can't get by with the "I know 97 languages and have
programmed professionally for 18 years, so I can pick up C++ quickly
if you hire me" line, they'll rank you lower then the entry level guy
that's lying and says he's used it).

Also, employees rarely get a chance to choose tools, they're dictated
from above.  You personally may prefer Smalltalk or Eiffel, but most
management will tell you to use C or C++ (especially when they see the
prices of the alternate systems).  Chances are, you'll also be told
exactly which version of C++ to use as well, etc.  A newcomer to the
organization isn't going to be able to say "I don't like IDE's, I want
to use a Makefile instead" or "I've converted this module from C to C++".

-- 
Darin Johnson
·····@usa.net.delete_me
From: Jon S Anthony
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <JSA.97Jun6185343@alexandria.organon.com>
In article <····················@connectnet1.connectnet.com> ·····@usa.net.delete_me (Darin Johnson) writes:

> "Competitor" is also a relative term.  My company's competitors are
> not necessarily *my* competitors.  Company loyalty is near zero now

Yes, but that doesn't speak to why the people with the power to choose
knowingly make inferior choices.


> Thus, just because of the sheer number of places that use C++, it's

> Also, employees rarely get a chance to choose tools, they're dictated
> from above.  You personally may prefer Smalltalk or Eiffel, but most
> management will tell you to use C or C++ (especially when they see the

Exactly.  That's the point.  These are the people that _knowingly_
make these inferior choices.  Simply crazy.

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
···@organon.com
From: Gareth McCaughan
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <86lo4n9ovt.fsf@g.pet.cam.ac.uk>
Jon Anthony has been claiming that the software industry is unique
in having people knowingly use inferior products (meaning: C and
C++).


Firstly, that's not true. All over the place, for instance,
you'll find people using outmoded computer hardware because
it's easier to do that than it is to rewrite all their
programs and retrain all their staff. Newer hardware would
be better, but it would have a large initial cost.

It's not a coincidence that this example involves computers;
computing changes rapidly, and this inertia effect relies on
things becoming outmoded before they become entirely unusable,
and on there not being time to learn to use newer stuff
before the old stuff is obsolete.


Secondly, it's not clear to me that C and C++ are inferior
in the relevant sense. Certainly, they're rather nasty
*languages*. But when you choose a language, you're also
choosing a development environment, a set of libraries,
a particular implementation of the language, and so on.
Now, observe the following:

1. C and C++ systems have had a lot of work put into them
   by the likes of Borland and Microslop, with the result
   that they have powerful IDEs, good integration with the
   underlying "operating system" and many bells and whistles,
   whereas this isn't true of many languages that are
   inherently much nicer

   (thus C and C++ may not in fact be inferior in practice
   for the people using them)

2. The companies selling C and C++ systems have done very
   well for themselves by doing so (partly, I suppose,
   because it's rather easy to produce a *passable* compiler
   for C -- see Gabriel's famous "Good News, Bad News" paper
   for further comments on this)

   (thus the compilor vendors' choice of C and C++ hasn't
   proved irrational).

So, we could have had better languages, but producing good
environments for programming in those better languages wasn't
so lucrative for the compiler vendors, with the result that
those better languages aren't, for some purposes, better
after all.


So, it seems to me that (1) C and C++ aren't necessarily
inferior in the relevant sense, and (2) even if they are
the software industry is not unique in being saddled with
inferior products because changing is too inconvenient.


-- 
Gareth McCaughan       Dept. of Pure Mathematics & Mathematical Statistics,
·····@dpmms.cam.ac.uk  Cambridge University, England.
From: Darin Johnson
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <slrn5phged.1sn.darin@connectnet1.connectnet.com>
In article <················@alexandria.organon.com>, Jon S Anthony wrote:
>Yes, but that doesn't speak to why the people with the power to choose
>knowingly make inferior choices.

The people with the power to choose generally know the least about
what they're choosing.

-- 
Darin Johnson
·····@usa.net.delete_me
From: Ulf Wiger
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <339AC534.52A1@etxb.ericsson.se>
Jon S Anthony wrote:
> 
> In article <····················@connectnet1.connectnet.com> ·····@usa.net.delete_me (Darin Johnson) writes:
> 
> > "Competitor" is also a relative term.  My company's competitors are
> > not necessarily *my* competitors.  Company loyalty is near zero now
> 
> Yes, but that doesn't speak to why the people with the power to choose
> knowingly make inferior choices.


A friend of mine brought his BMW with him when he moved
back to the States from Germany. He *loved* that car,
but finally traded it for an American car. Why?
Spare parts were outrageously expensive for a BMW, and
he couldn't get good service at a reasonable price.
If it broke down, it could take months to get it fixed.
(This was a few decades ago.)

Technically, the Cadillac he bought instead was inferior,
but any auto shop in the U.S. can service it and you can
find parts in any old junkyard.

Which product is the best buy is not always easy to
determine.

-- 
Ulf Wiger, Chief Designer ETX/DN/XBS    <·······@etxb.ericsson.se>
Ericsson Telecom AB                          tfn: +46  8 719 81 95
Varuv�gen 9, �lvsj�                          mob: +46 70 519 81 95
S-126 25 Stockholm, Sweden                   fax: +46  8 719 43 44
From: Jon S Anthony
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <JSA.97Jun10132757@alexandria.organon.com>
In article <·············@etxb.ericsson.se> Ulf Wiger <·······@etxb.ericsson.se> writes:

> A friend of mine brought his BMW with him when he moved
> back to the States from Germany. He *loved* that car,
> but finally traded it for an American car. Why?
> Spare parts were outrageously expensive for a BMW, and
> he couldn't get good service at a reasonable price.
> If it broke down, it could take months to get it fixed.
> (This was a few decades ago.)
> 
> Technically, the Cadillac he bought instead was inferior,
> but any auto shop in the U.S. can service it and you can
> find parts in any old junkyard.

This is a category error, just like the Betamax example.

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
···@organon.com
From: Nick Leaton
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3397D2E7.168B@calfp.co.uk>
Darin Johnson wrote:

> Also, employees rarely get a chance to choose tools, they're dictated
> from above.  You personally may prefer Smalltalk or Eiffel, but most
> management will tell you to use C or C++ (especially when they see the
> prices of the alternate systems).  Chances are, you'll also be told
> exactly which version of C++ to use as well, etc.  A newcomer to the
> organization isn't going to be able to say "I don't like IDE's, I want
> to use a Makefile instead" or "I've converted this module from C to C++".

Just a little bit on cost. Eiffel development systems are not expensive.
The are also a lot cheaper because you don't need a make system, - the
compiler does that for you. You don't need Purify, Sentinel etc (at
least two of these are needed in my opinion). You don't need class
browsers. You don't need documentation tools. The compilers/IDEs do this
for you.

ISE http://www.eiffel.com/ are selling Personal Eiffel at $69.95
-- 

Nick
From: Darin Johnson
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <slrn5pelvs.6a3.darin@connectnet1.connectnet.com>
In article <··········@web.nmti.com>, Peter da Silva wrote:
>(Well, ISDN is STARTING to live up to its promise, in SOME areas...)

I just talked to a Lucent guy last week (phone fixer, not phone
builder) who was strongly of the opinion that there are lots of better
and cheaper alternatives than ISDN, and that most corporations that
use ISDN do so in order to ensure caller-id can't be blocked
(surprise, surprise).  I think it's useful for home office use (one
phone, fax, and modem), but his experience was more with corporations
I think.

-- 
Darin Johnson
·····@usa.net.delete_me
From: James Logajan
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <jameslEBBpuM.In0@netcom.com>
Jon S Anthony (···@alexandria.organon.com) wrote:
[on the issue of why anyone would use C++...]
: Simple stupidity?  Why make the explanation more involved or
: mysterious?

Because that explanation is wrong. And reasons aren't mysterious, as I'll
try to explain below.

: For example, one of the most odd (and very prevalent in my experience)
: reasons given for using C++ against other viable alternatives -
: alternatives which are even acknowledged by the parties involved as
: being _clearly_ better - is some variant of the old "but everyone else
: is using it".  Now, other than in the land of software, where else
: would anyone actually suggest using an _inferior_ tool (or process or
: whatever) to make your product _because_ your _competitor_ is using
: that inferior tool?  Go figure.

o Betamax was considered technologically better than VHS (so I'm told); but
  VHS won the market.

o PAL is considered better than NTSC, but nobody in the U.S. would
  consider switching TV standards, for reasons that aren't technical.

Having just been through the process of selecting programming language(s)
and environments, I can assure you that there are a couple good reasons to
consider the popularity of a language:

1) It takes time to learn a computer language and become proficient in it.
   If a language isn't popular, you will have a very difficult time finding
   programmers. That will cause schedules to slip and/or budgets to increase
   and allow competitors to get the jump on you. Training existing
   programmers (assuming you have some way to get them trained) in a
   language that is new to them will cost time AND money.

2) A popular language is likely to be available on a lot of platforms;
   this increases the size of the potential market.

These points must be weighed against their negatives:

A) Popular or unpopular, a programming language should encourage rapid
   development and maintainability. So while it might cost time to learn
   a language, it might be made up for in development and maintenance using
   a less popular but "better" language.

B) Just because a language is available on a lot of platforms doesn't mean
   that applications can be simply or easily ported to those platforms.

Of course there is a lot more to consider in a language, such as the
performance of the final applications, the maturity of the compilers or
interpreters, whether the language has an accepted standard, etc. Note that
NONE of these considerations deals with the language per se. But they are
important; probably just as important as language definition itself! (Except
insofar as the language definition enhances the language relative to those
considerations).
From: Erik Naggum
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3074540028207502@naggum.no>
* James Logajan
| o Betamax was considered technologically better than VHS (so I'm told);
|   but VHS won the market.

the professional video market is still using Betamax.  VHS is as unsuited
to television production as the audio cassette is for mastering records.

FWIW.

#\Erik
-- 
The juvenile sea squirt wanders through the sea searching for a suitable rock
or hunk of coral to cling to and make its home for life.  For this task, it has
a rudimentary nervous system.  When it finds its spot and takes root, it does
not need its brain anymore so it eats it!  It is rather like getting tenure.
From: Rolf Marvin B|e Lindgren
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <lbz67vsdqwv.fsf@tag.uio.no>
[Erik Naggum]

| the professional video market is still using Betamax.  VHS is as unsuited
| to television production as the audio cassette is for mastering records.

I think you'll find that small, independent, US television stations
actually use VHS for some of their productions.

_Beta_ (not Betamax) and VIDEO 2000 were both rival to and  better
systems than VHS.  VHS, however, had the largest installed base from
start, was probably better markedet.

-- 

       Rolf Lindgren           |       "The opinions expressed above are
       Sofienberggt. 13b       |        not necessarily those of anyone"
       N-0551 OSLO             |               ·····@ask.uio.no 
From: John Savard
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <339858cd.6208062@nntp.netcruiser>
Rolf Marvin B|e Lindgren <·····@tag.uio.no> wrote:

>| the professional video market is still using Betamax.  VHS is as unsuited
>| to television production as the audio cassette is for mastering records.

>I think you'll find that small, independent, US television stations
>actually use VHS for some of their productions.

>_Beta_ (not Betamax) and VIDEO 2000 were both rival to and  better
>systems than VHS.  VHS, however, had the largest installed base from
>start, was probably better markedet.

The term Betamax was used in connection with some consumer Beta-format
equipment, although it is used today to refer to a system using Beta cassettes
to record in an incompatible high-bandwidth method suitable for broadcast. The
standard Beta format, even Beta I, is not broadcast-quality.

A format similar to Betamax, but using VHS cassettes, was developed by RCA at
one time.

VHS, even in the short-play Standard Play mode, allows 2 hours of recording on a
standard T-120 tape. The standard Beta tapes, L-500 and L-750, allowed one hour
and one and a half hours, respectively, in their equivalent Beta I mode.

Therefore, only VHS let you watch - or record - a whole movie on one tape right
from the start. Beta pre-recorded tapes were usually in Beta II, equivalent to
LP in VHS, which meant that the loss of quality by going down a mode outweighed
the advantage Beta has over VHS in picture quality for equivalent modes.

VHS, therefore, offered something the consumer valued that Beta did not - lots
of recording time on a tape. Media cost and convenience, _not_ marketing hype,
drove the victory of VHS over Beta, even if a snowball effect took place once
the ball got rolling.

Ever tried upgrading a Macintosh by swapping the motherboard? (See #85 in a
recent WIRED article...)

John Savard
From: Thant Tessman
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <33985778.41C6@nospam.acm.org>
James Logajan wrote:

> o PAL is considered better than NTSC, but nobody in the U.S. would
>   consider switching TV standards, for reasons that aren't technical.

NTSC is an example of government-enforced privlege, not market
stupidity.  
It is illegal to broadcast any other format.  It's hard to untangle at 
least some of this kind of influence in every industry including
software.

(Besides, how is PAL better than NTSC?  Isn't it just a higher
resolution 
in exchange for a (noticeably) lower frame rate?)

-thant
From: Tony Finch
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5n9nnf$mdm@lyra.csx.cam.ac.uk>
Thant Tessman <·····@nospam.acm.org> wrote:
>
>NTSC is an example of government-enforced privlege, not market
>stupidity. It is illegal to broadcast any other format. It's hard to
>untangle at least some of this kind of influence in every industry
>including software.
>
>(Besides, how is PAL better than NTSC? Isn't it just a higher
>resolution in exchange for a (noticeably) lower frame rate?)

The colour encoding in PAL is considerably better.

Tony.
-- 
   o
 o o o
o o o o
From: Erik Naggum
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3074617969267367@naggum.no>
* Thant Tessman
| (Besides, how is PAL better than NTSC?  Isn't it just a higher resolution
| in exchange for a (noticeably) lower frame rate?)

* Tony Finch
| The colour encoding in PAL is considerably better.

Never Twice the Same Color.

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: Jon S Anthony
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <JSA.97Jun6185731@alexandria.organon.com>
In article <················@netcom.com> ······@netcom.com (James Logajan) writes:

> Because that explanation is wrong. And reasons aren't mysterious, as I'll
> try to explain below.

Your evidence below is off target.

> o Betamax was considered technologically better than VHS (so I'm told); but
>   VHS won the market.
> 
> o PAL is considered better than NTSC, but nobody in the U.S. would
>   consider switching TV standards, for reasons that aren't technical.

Irrelevant.  These are _end user_ commodities.  We are talking about
the sort of stuff used to _make_ these sorts of things.

> 1) It takes time to learn a computer language and become proficient in it.
>    If a language isn't popular, you will have a very difficult time finding

This is circular.  The point is about _why_ certain languages are
popular _even though_ those making the choice _know_ the choice is
_inferior_.


> 2) A popular language is likely to be available on a lot of platforms;
>    this increases the size of the potential market.

Irrelevant.  As a producer you only care about the market size of what
you are producing - not what you are producing with.

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
···@organon.com
From: James Logajan
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <jameslEBE2Kv.Kqo@netcom.com>
Jon S Anthony (···@alexandria.organon.com) wrote:
: The point is about _why_ certain languages are popular _even though_ those
: making the choice _know_ the choice is _inferior_.

If language X is inferior in all respects to language Y, then anyone
who chooses X would have to be considered "stupid." The problem with
your thesis is that there are damn few languages which are superior in
_all_ respects to all _other_ languages. C++ is clearly superior in _some_
respects to many other languages, including Scheme and ANSI C. Where those
aspects are heavily weighted in the decision process, C++ is not a stupid
choice, but an intelligent choice.

Or are you claiming that there exists some language 'X' (not C++) that
is superior in some "absolute" sense (perhaps all respects) to all other
languages? Pray tell, what is this language? Are you confortable enough
to defend your choice when presented with a variety of real and contrived
development environments and conditions?

: [I wrote;]
: > 2) A popular language is likely to be available on a lot of platforms;
: >    this increases the size of the potential market.

: Irrelevant.  As a producer you only care about the market size of what
: you are producing - not what you are producing with.

It is a nice simple universe where the _only_ consideration a producer
need worry about is the market size. Alas, the universe I inhabit is
not always so simple. I had not realized there are internet routers
to alternate universes. Those routers must have been made in that
alternate universe; I know the universe I inhabit has router manufacturers
who have to consider violations of causality and various physical laws.
The manufacturers of routers in that alternate universe must _only_ need
to care about market size, not what they have to manufacture _with_ (e.g.
physical reality).
From: Jon S Anthony
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <JSA.97Jun10132521@alexandria.organon.com>
In article <················@netcom.com> ······@netcom.com (James Logajan) writes:

> Jon S Anthony (···@alexandria.organon.com) wrote:
> : The point is about _why_ certain languages are popular _even though_ those
> : making the choice _know_ the choice is _inferior_.
> 
> If language X is inferior in all respects to language Y, then anyone
> who chooses X would have to be considered "stupid." The problem with
> your thesis is that there are damn few languages which are superior in

No, that is not a problem with my "thesis".  The point is, the people
involved determined that "yes, overall we know X is better than Y, but
we are still going to use Y".

> Or are you claiming that there exists some language 'X' (not C++) that

I'm not claiming anything.  I'm merely reporting what I've seen happen
time and time again.

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
···@organon.com
From: Chris Bitmead uid(x22068)
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <s6yyb8jkzyu.fsf@aalh02.alcatel.com.au>
···@alexandria.organon.com (Jon S Anthony) writes:

> > o Betamax was considered technologically better than VHS (so I'm told); but
> >   VHS won the market.
> > 
> > o PAL is considered better than NTSC, but nobody in the U.S. would
> >   consider switching TV standards, for reasons that aren't technical.
> 
> Irrelevant.  These are _end user_ commodities.  We are talking about
> the sort of stuff used to _make_ these sorts of things.

Unfortunately the level of investigation done my many companies into
what programming language to use is often much less than a well
informed consumer does in selecting a TV set.
From: Thant Tessman
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <33974FEA.41C6@nospam.acm.org>
Jon S Anthony wrote:

>  [...]  Now, other than in the land of software, where else
> would anyone actually suggest using an _inferior_ tool (or process 
> or whatever) to make your product _because_ your _competitor_ is 
> using that inferior tool?  Go figure.

Somehow I suspect the business of software isn't unique.  It just
happens to be what we're familiar with.  In business you don't 
have to be the best to survive, you only have to be good enough.
There is plenty of room in the market for solutions that are merely
good enough.  And since information is never complete, it often
makes sense to choose a tool merely because others use it--that is, 
because it is probably good enough.

(I'm currently forced to use C++ because it's what SGI supports 
and it's what my colleagues know best.  Both points aren't 
insurmountable, but it does take effort.)

Like I've said before, the fact that mediocre solutions exist
is not what puzzles me.  What puzzles me are the people who 
should know better, but still deliberately choose to use or
develop mediocre solutions (i.e. C++).

-thant
From: Jon S Anthony
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <JSA.97Jun6190611@alexandria.organon.com>
In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:

> Somehow I suspect the business of software isn't unique.  It just

I _strongly_ suspect it is in this respect.


> happens to be what we're familiar with.  In business you don't 
> have to be the best to survive, you only have to be good enough.
> There is plenty of room in the market for solutions that are merely
> good enough.

You are not speaking to the appropriate level.  I'm not talking about
what may or may not be "good enough" to sell to the end user.  I'm
talking about what is _known_ to be _better_ way of producing the end
result and knowingly not choosing it because your competitor uses the
inferior production technique.  This is simply irrational.  The better
process/tool/whatever will even likely be _cheaper_ in the production
process.  So, choosing the inferior capability means you are
_knowingly_ choosing something which will not only not work as well,
but cost you more.


> What puzzles me are the people who should know better, but still
> deliberately choose to use or develop mediocre solutions (i.e. C++).

Well, my point is - they not only _should_ know better they _do_ often
know better and yet still choose the inferior capability.  That's
simply nuts.

/Jon

-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
···@organon.com
From: David Chase
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <33980AB6.251F@world.std.com>
Thant Tessman wrote:

> Like I've said before, the fact that mediocre solutions exist
> is not what puzzles me.  What puzzles me are the people who
> should know better, but still deliberately choose to use or
> develop mediocre solutions (i.e. C++).

Sometimes, the problem is quite literally management.

At a former job, as part of the build step for a product (not
as part of the released product itself, mind you, just part of
the build) I wrote a big mess of Scheme, to generate code from
specifications.  Scheme seemed like the perfect tool, because
it was very flexible, and supported consistently everywhere,
and it had a standard.  This apparently was considered controversial
by one person higher up in the company, never mind that of the
alternates available, only Ansi C (not tcl, perl, ksh, or,
especially, C++) was similarly standardized and well-supported.

-- 
David Chase, ·····@world.std.com
Note: Mail filters automatically and silently discard mail from
······@bigfoot.com, ······@hotmail.com, ······@olg.com.
From: John Savard
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <339855a9.5404070@nntp.netcruiser>
Thant Tessman <·····@nospam.acm.org> wrote:

>Given that C++ clearly sucks, one must look elsewhere for 
>the explanation behind C++'s success against more "academic" 
>languages.

Why is C++ popular, and what is wrong with C++?

For one thing, it's really C that is popular. C++ is upwards-compatible with C,
and thus C++ compilers are all over the place, but they're usually used to write
C programs, with the odd extension from C++ perhaps used.

That's not entirely accurate - object libraries are used in the writing of
programs for

Microsoft Windows

and the

Macintosh.

And, of course, the popularity of C, and therefore the inertia behind it, owes a
great deal to a very popular operating system - Unix.

Fortran is a good language for writing very efficient numerical analysis
programs.

And C is also good for writing operating systems and the like, to run almost as
efficiently as if they were coded in machine language.

Newer, more innovative, methods of programming are often interpreted when first
implemented - Lisp and its dialect Scheme are examples, although Lisp can now be
compiled. And neither the lambda-calculus paradigm, nor the
functional-programming paradigm, is close to the existing mental habits of
programmers - or even their existing mental habits before they ever laid eyes on
a computer.

Sure, one can say that there are 'better' procedural languages - Pascal,
Modula-2, or whatever. But before a language will get even a chance to start
becoming popular, tools for that language are needed that allow programmers to
get their work done - 100% of it, not the first 90% - and that means that the
compilers with the biggest libraries win.

John Savard
From: Jay Krell
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <01bc7650$235a6840$a5d323c7@drugs>
[This is way too long, but basically agrees with John, adding that the OS
is a library.]

I think language choice is largely tool and library choice.

The "native" facilities of Unix, Windows, and the Mac have always been
first and most completely exposed in C or Pascal, so those languages were
the most natural languages to use for apps. To a large extent, the
operating systems were written in C (and Pascal I think, on the Mac) and
some assembly, so C was the most natural language to expose the operating
system in. Operating systems are just libraries, and cross language
developlement has never been a joy, even between equally low level and
imperative, non garbage collected langauges like C, C++, Pascal, and
Fortran, let alone something with a runtime or vm. Today, it is nearly
impossible to meet the binary compatibility (strict link) needs of an
operating system while using C++, due to a variety of well known issues
(object layout, inlining, name mangling), so C interfaces (possibly
implemented in C++) persist where link compatibility is paramount and C++
libraries include source (MacApp, MFC, I know there are significant
exceptions, forgive my generalizing from a small sample). If you strip C++
down to just use all virtual functions and no inlining and access data via
functions, you get something very close to COM. You could also take the SOM
approach, which has to do so much to support more of C++, that is
apparently unbearable without compiler support, whereas COM is bearable
imho.

C is low level enough that there are very few "ABI" (application binary
interface) decisions to make, so they are easier to make and stick with
(though this was screwed up on the 68k Mac and Microsoft still has __cdecl
and __stdcall).

Now, of course, OS writers are maybe the most concerned with runtime
efficiency, not their own productivity, so the C tradeoff isn't as bad. The
OS as library starts the ball rolling.

If you want to use java.awt (anybody?), you're best off using Java, even
though other languages compiler to jvm (Scheme, Ada, Pizza (Java with
something like C++ templates)).

Personally, I hate C and like C++ and I don't think I'm unique. There are
so many things cannot be done efficiently, easily, and type safely in C but
that be done so in C++. Simple link compatibility with existing C code (and
OS's) does help C++ a lot.

John Savard <······@netcom.ca> wrote in article
<················@nntp.netcruiser>...
> Thant Tessman <·····@nospam.acm.org> wrote:
> 
> >Given that C++ clearly sucks, one must look elsewhere for 
> >the explanation behind C++'s success against more "academic" 
> >languages.
> 
> Why is C++ popular, and what is wrong with C++?
> 
> For one thing, it's really C that is popular. C++ is upwards-compatible
with C,
> and thus C++ compilers are all over the place, but they're usually used
to write
> C programs, with the odd extension from C++ perhaps used.
> 
> That's not entirely accurate - object libraries are used in the writing
of
> programs for
> 
> Microsoft Windows
> 
> and the
> 
> Macintosh.
> 
> And, of course, the popularity of C, and therefore the inertia behind it,
owes a
> great deal to a very popular operating system - Unix.
> 
> Fortran is a good language for writing very efficient numerical analysis
> programs.
> 
> And C is also good for writing operating systems and the like, to run
almost as
> efficiently as if they were coded in machine language.
> 
> Newer, more innovative, methods of programming are often interpreted when
first
> implemented - Lisp and its dialect Scheme are examples, although Lisp can
now be
> compiled. And neither the lambda-calculus paradigm, nor the
> functional-programming paradigm, is close to the existing mental habits
of
> programmers - or even their existing mental habits before they ever laid
eyes on
> a computer.
> 
> Sure, one can say that there are 'better' procedural languages - Pascal,
> Modula-2, or whatever. But before a language will get even a chance to
start
> becoming popular, tools for that language are needed that allow
programmers to
> get their work done - 100% of it, not the first 90% - and that means that
the
> compilers with the biggest libraries win.
> 
> John Savard
> 
From: Dave Mason
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <m1enaoryol.fsf@jupiter.scs.Ryerson.CA>
Thomas Lindgren <·······@groucho.csd.uu.se> writes:

> Interestingly, Ericsson has started to move from C++ to Erlang, a
> functional language, in developing telephony code (see for instance
> their Mobility Server). Perhaps telephony is a niche that fits functional
> languages well?

I think it's more that telephony is a business where reliability is
important enough that doing things right can be fairly easily
justified economically.

Other areas such as the military, space, and nuclear power plants are
also willing to pay the money to do things right.  (Which is not to
say that they are always successful!)

../Dave
-- 
"Feminism:
   The belief (considered radical by some) that women are people, too."
From: David Hanley
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3389BC72.2E7D@nospan.netright.com>
Rainer Joswig wrote:

> Well, AT&T was doing a switching system in Lisp and another one
> in C++. The C++ system did take a lot more resources (it was
> done as a production system). The Lisp version was more
> like a research project (let's see what we can do). As it
> turned out the Lisp version did have more functionality
> at comparable speed and was *much* cheaper to built.
> 
> This was a large project (if I remember correct, up to 100 people were
> working on the switch based on Lisp). It did touch areas like real-time GC,
> OODBMs, fault tolerance, the system should be down in the
> range of a minute per year, etc.
> 
> The group has reported about that publicly and they seemed a bit
> frustrated that despite the clear superiority of their switch,
> the company still wanted to market the system based on C++.
> 

	This is *very* interesting.  Do you know where I can find
more detailed information about this?

dave
From: Erik Naggum
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3073076743643317@naggum.no>
* David Hanley
| ... Mr Strosup ...

his name is actually Bjarne Stroustrup.  (all good text editors can help
you write names correctly.  Fort� Agent probably doesn't have a good text
editor the way it breaks your lines, but it's worth investigating, anyway.)

| How does this apply to functional languages?  Well, for whatever reason
| functional languages are not the 'norm' in the software community.
| Sorry, that's the fact.  If I were to start a project and decide 'let's
| do it in LISP' i'd have a pretty hard time finding enough qualified lisp
| programmers, and a hard time convincing management it was a good idea to
| use lisp.

this is not my experience.  rational management is interested in solutions
to their problems, and will listen to their programmers.  irrational
management is interested in reducing their investments, at all costs.
there is probably a difference between hired personnell and consultants,
however.  on the other hand, I once worked with a programmer who bought a
Smalltalk system with his own money, delivered very useful software in time
and only a long time thereafter was he reimbursed for it.  we didn't have a
particularly bright manager, however.

| If C++ can get us increased productivity in the next quarter, great.
| Let's use it.  It would probably take more time than that to teach the
| whole staff passable LISP.

I realize that it has become the norm to guise wild guesses in the cloth of
respectable fact, but where do you find the foundation for your "probably"?

| We might surmise that a small software company could use LISP and be
| sucessful because of higher productivity.  Unfortunately, this evidence
| is mysteriously lacking.

sigh.  do you think the same can be said for any other languages or tools?
do you think it might be possible to say this for _all_ inventions at one
time or another?

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: David Hanley
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <3381C749.687E@nospan.netright.com>
Erik Naggum wrote:

> | How does this apply to functional languages?  Well, for whatever reason
> | functional languages are not the 'norm' in the software community.
> | Sorry, that's the fact.  If I were to start a project and decide 'let's
> | do it in LISP' i'd have a pretty hard time finding enough qualified lisp
> | programmers, and a hard time convincing management it was a good idea to
> | use lisp.
> 
> this is not my experience.  rational management is interested in solutions
> to their problems, and will listen to their programmers.

	Sure.  How many run-of-the-mill programmers advocate LISP for
large projects?  None of my co-workers understands functional languages,
so it would be very diffucult for me to start a new project in it, for
obvious reasons.

> | If C++ can get us increased productivity in the next quarter, great.
> | Let's use it.  It would probably take more time than that to teach the
> | whole staff passable LISP.
> 
> I realize that it has become the norm to guise wild guesses in the cloth of
> respectable fact, but where do you find the foundation for your "probably"?

	Quite a bit of personal experience.  Many functional programming 
advocates have stated, in this thread, that moving to functional
programming
takes quite a bit of time.  When I took SE in collecge, the prof tried
to 
teach lisp for 1/2 the semester.  No one cared about lisp--they wanted
to learn C++.
I've tried to show friends struggling with a C++ program how easy it
would be
in SML.  People don't care, and it seems foreign.  

> 
> | We might surmise that a small software company could use LISP and be
> | sucessful because of higher productivity.  Unfortunately, this evidence
> | is mysteriously lacking.
> 
> sigh.  do you think the same can be said for any other languages or tools?
> do you think it might be possible to say this for _all_ inventions at one
> time or another?

	True.  OTOH, LISP is much older than C++, or C for that matter.  So
it's
surprising that it hasn't caught on in all this time.  

	I still have a postive attitude about the whole language situation,
however.
I think as machines get faster, programmers will have less of an excuse
to keep
programming low-level code to save 10% of run-time.  It's not even a
valid excuse 
now, IMO, but people still use it.

	dave
From: Paul Campbell
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <33832035.3F54BC7E@lucent.com>
David Hanley wrote:

> I think as machines get faster, programmers will have less of an excuse
> to keep
> programming low-level code to save 10% of run-time.  It's not even a
> valid excuse
> now, IMO, but people still use it.
> 
>         dave

Exactly what people were saying 10 years ago :).

Paul C
UK.
From: Buddha M.D. Buck
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <87bu5wb1u4.fsf@not-a-real-site.acsu.buffalo.edu>
David Hanley <·····@nospan.netright.com> writes:

> Erik Naggum wrote:
> 
> > | If C++ can get us increased productivity in the next quarter, great.
> > | Let's use it.  It would probably take more time than that to teach the
> > | whole staff passable LISP.
> > 
> > I realize that it has become the norm to guise wild guesses in the cloth of
> > respectable fact, but where do you find the foundation for your "probably"?
> 
> 	Quite a bit of personal experience.  Many functional programming 
> advocates have stated, in this thread, that moving to functional
> programming
> takes quite a bit of time.  When I took SE in collecge, the prof tried
> to 
> teach lisp for 1/2 the semester.  No one cared about lisp--they wanted
> to learn C++.
> I've tried to show friends struggling with a C++ program how easy it
> would be
> in SML.  People don't care, and it seems foreign.  

To back this up, at my school C++ is taught to first-year computer
science students, because the students want to learn C++ -- it's a
marketable skill.  Personally, I think that it is a bad choice, due to
the complexity of the language.  Students who don't even know how to
think about programming a linear search over an array shouldn't have
to worry about writing code to do the search over any structure that
implements a forward iterator (but that's what they are doing).  Other
language choices (like C, Modula-2, or Scheme) were rejected because
C++ is the language of choice right now (and I have heard talk of
switching to Java)

> 	dave
Buddha
From: Fergus Henderson
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5lr5th$cq@mulga.cs.mu.OZ.AU>
David Hanley <·····@nospan.netright.com> writes:

> What if had a 'lispy C'--A C compiler with a few lisp features thrown
> in.  It would be easier to pitch to maangement (it's c with more
> features!) and I could find C programmers by shaking a stick in the
> dark.  Then, I could take this group of C programmers, spend a little
> time instructing then to use, say, garbage collection, and let them
> go.  I bet productivity would increase.  Periodically, 'lispy C' could
> add another lisp feature (Continuations? Higher order functions?) and
> this could be introduced to the programmers.  More productivity
> increases (as compared to C, mind you).

See Java (a somewhat lispy C) and Pizza (a somewhat Haskellish Java).

>Would such an approach be sucessful?

Time will tell ;-)

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Patrick Logan
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5ls5sq$6u3$2@nadine.teleport.com>
In comp.lang.functional David Hanley <·····@nospan.netright.com> wrote:

: 	Despite the fact that I don't like C++ too much as a language, I can
: somewhat buy the fact that Mr Strosups studies may be valid when taken
: in the proper context

I think what Henry Baker is driven at is that a more formal definition of
that context and the results of the study are required to elevate the
claims above useless anecdotal evidence.

-- 
Patrick Logan ·············@teleport.com
From: Peter da Silva
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5m46dm$2kb@web.nmti.com>
In article <······················@alcatel.com.au>,
Chris Bitmead uid(x22068) <·············@Alcatel.com.au> wrote:
> >	We might surmise that a small software company could use LISP 
> >and be sucessful because of higher productivity.  Unfortunately, this 
> >evidence is mysteriously lacking.  

> Well, the research papers give the evidence. What more do you want?

How about a few small companies actually doing it?
-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: Craig Brozefsky
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <m2sozei2ur.fsf@subject.cynico.com>
·····@nmti.com (Peter da Silva) writes:

> In article <······················@alcatel.com.au>,
> Chris Bitmead uid(x22068) <·············@Alcatel.com.au> wrote:
> > >	We might surmise that a small software company could use LISP 
> > >and be sucessful because of higher productivity.  Unfortunately, this 
> > >evidence is mysteriously lacking.  
> 
> > Well, the research papers give the evidence. What more do you want?
> 
> How about a few small companies actually doing it?

We are using the Allegro Common Lisp system to prototype and then
possibly develop a on-line trading client-server application with
encrypted socket connection to the server over the Internet.

We are amazed with the speed and efficiency of the development cycle
in such a package, no code-compile-debug routine.  Just code, run,
code, run, code, run, code run...  The REPL is great for fast
prototyping of a GUI, and the layout of Allegro's libraries is very
usable.  The editor and debugger are nice, and the whole package is a
very well integrated IDE with excellent control over layout and
properties of widgets that I have not seen in other IDEs for any other
languages so far.

Of course, our developers are in love with it, but we're catching some
managerial slack because 'maintenance' is supposed to be a headache.
This is most liekly because they plan on having dumbkopf's maintain it
who use macro packages in C to make it look like BASIC.

Our plan was to prototype it so fast, and exceed their expectations by
so much that they would crumble under our will.  It's happening so
far.  Our initial presentation of the prototype was about 2 stages
beyond what they had expected to see.


-- 
Craig Brozefsky              ·····@onshore.com
onShore Inc.                 http://www.onshore.com/~craig
Development Team             p_priority=PFUN+(p_work/4)+(2*p_cash)
From: Peter da Silva
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5m71dc$245@web.nmti.com>
In article <··············@subject.cynico.com>,
Craig Brozefsky  <·····@onshore.com> wrote:
> ·····@nmti.com (Peter da Silva) writes:
> > In article <······················@alcatel.com.au>,
> > Chris Bitmead uid(x22068) <·············@Alcatel.com.au> wrote:
> > > >	We might surmise that a small software company could use LISP 
> > > >and be sucessful because of higher productivity.  Unfortunately, this 
> > > >evidence is mysteriously lacking.  

> > > Well, the research papers give the evidence. What more do you want?

> > How about a few small companies actually doing it?

> We are using the Allegro Common Lisp system [...]

(also responding to the other message in this thread)

It would be valuable to collect these sorts of anecdotes into a single
web page that skeptics can be pointed at.

(Me, I'm a devout agnostic on the subject of language choices)
-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: Dave Mason
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <m1g1v4rzff.fsf@jupiter.scs.Ryerson.CA>
·····@nmti.com (Peter da Silva) writes:

> It would be valuable to collect these sorts of anecdotes into a single
> web page that skeptics can be pointed at.

I'm doing that.  See URL
	http://www.scs.ryerson.ca/dmason/common/functional.html

../Dave
From: Peter da Silva
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5mp8g5$gpq@web.nmti.com>
In article <··············@jupiter.scs.ryerson.ca>,
Dave Mason  <······@jupiter.scs.Ryerson.CA> wrote:
> I'm doing that.  See URL
> 	http://www.scs.ryerson.ca/dmason/common/functional.html

Cool. I'm temporarily browserless, but I've bookmarked it.
-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: mark carroll
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5m48jr$ek6$1@news.cis.ohio-state.edu>
In article <··········@web.nmti.com>, Peter da Silva <·····@nmti.com> wrote:
>In article <······················@alcatel.com.au>,
>Chris Bitmead uid(x22068) <·············@Alcatel.com.au> wrote:
>> >	We might surmise that a small software company could use LISP 
>> >and be sucessful because of higher productivity.  Unfortunately, this 
>> >evidence is mysteriously lacking.  
>
>> Well, the research papers give the evidence. What more do you want?
>
>How about a few small companies actually doing it?

A few do. The problem's the same as, say, with Modula-3 and Beta,
though.  Decent development environments exist, and they're very good
languages for writing general-purpose stuff in. But, everyone turns to
Java or something instead, not because it's superior, but because
there's big money behind it so you get the hype and the advertising
and, as with MS Windows, everyone uses it not realising what they're
missing. When you actually find a company using, say, Modula-3,
they're extremely happy and wouldn't change back for the world when
they realise what a decent language is like. The difference is
that things like Java gets more exposure because big business has
a vested interest in them.

You wouldn't believe, for instance, how many people don't think you
can do nice pretty multimedia stuff in Linux.

-- Mark (followups stripped down)
From: David Hanley
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <33871328.76D6@nospan.netright.com>
mark carroll wrote:
> 
> In article <··········@web.nmti.com>, Peter da Silva <·····@nmti.com> wrote:
> >In article <······················@alcatel.com.au>,
> >Chris Bitmead uid(x22068) <·············@Alcatel.com.au> wrote:
> >> >    We might surmise that a small software company could use LISP
> >> >and be sucessful because of higher productivity.  Unfortunately, this
> >> >evidence is mysteriously lacking.
> >
> >> Well, the research papers give the evidence. What more do you want?
> >
> >How about a few small companies actually doing it?
> 
> A few do. The problem's the same as, say, with Modula-3 and Beta,
> though.  Decent development environments exist, and they're very good
> languages for writing general-purpose stuff in. But, everyone turns to
> Java or something instead, not because it's superior, but because
> there's big money behind it so you get the hype and the advertising
> and, as with MS Windows, everyone uses it not realising what they're
> missing. When you actually find a company using, say, Modula-3,
> they're extremely happy and wouldn't change back for the world when
> they realise what a decent language is like. The difference is
> that things like Java gets more exposure because big business has
> a vested interest in them.

	Sorry, that's 110% irrelevant.  If a company can be say, 2-5x
more productive in a functional language, and they use it, they
out to be extremely profitable, and would eventually become a 
big, powerful company.  Companies that use 'inferior' languages 
would go out of business.

	Now, I do beleive that you could be a lot more productive in a
functional language, assuming equal development enviornments. The
question to ask the in why this has not happened. 

	I recently tried lookin for good lisp development enviornments for
windows.  Allegro CL is $3000 for a version that makes execuatables. 
Also appears to produce only 16-bit code as well.  

	oh,well...

	dave

dave
From: mark carroll
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <5m86cn$21l$1@news.cis.ohio-state.edu>
In article <·············@nospan.netright.com>,
David Hanley  <·····@nospam.netright.com> wrote:
>mark carroll wrote:
>> In article <··········@web.nmti.com>, Peter da Silva <·····@nmti.com> wrote:
(snip)
>> >How about a few small companies actually doing it?
>> 
>> A few do. The problem's the same as, say, with Modula-3 and Beta,
>> though.  Decent development environments exist, and they're very good
>> languages for writing general-purpose stuff in. But, everyone turns to
>> Java or something instead, not because it's superior, but because
>> there's big money behind it so you get the hype and the advertising
>> and, as with MS Windows, everyone uses it not realising what they're
>> missing. When you actually find a company using, say, Modula-3,
>> they're extremely happy and wouldn't change back for the world when
>> they realise what a decent language is like. The difference is
>> that things like Java gets more exposure because big business has
>> a vested interest in them.
>
>	Sorry, that's 110% irrelevant.  If a company can be say, 2-5x
>more productive in a functional language, and they use it, they
>out to be extremely profitable, and would eventually become a 
>big, powerful company.  Companies that use 'inferior' languages 
>would go out of business.

I suspect that there are a lot more factors that significantly affect
the success of a company than the productivity of the programming
language they use. Companies like Harlequin are using functional
languages a lot and doing very well. The reason why companies that
produce quality software don't do wonderfully well is that crap
software sells pretty well too, and IME time gained in productivity
using functional languages is usually spent in making sure it's not so
buggy. But, the companies don't do as well as they should because it's
the marketing that counts, not the quality of the product: buyers are
often too ignorant to realise that they shouldn't be so tolerant of
all these buggy C++ MS Windows applications[1] that are prone to
crashing.

>	Now, I do beleive that you could be a lot more productive in a
>functional language, assuming equal development enviornments. The
>question to ask the in why this has not happened. 

I think I've gone some way to answering this above.

>	I recently tried lookin for good lisp development enviornments for
>windows.  Allegro CL is $3000 for a version that makes execuatables. 
>Also appears to produce only 16-bit code as well.  

I'm afraid I don't know much about good lisp IDEs.

-- Mark

[1] Of course, you _can_ write wonderful things using C++. Unfortunately,
    it's all too easy not to.
From: Cyber Surfer
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <MPG.df4a8d3f5a0db839897da@news.demon.co.uk>
With a mighty <·············@nospan.netright.com>,
·····@nospan.netright.com uttered these wise words...

> 	I recently tried lookin for good lisp development enviornments for
> windows.  Allegro CL is $3000 for a version that makes execuatables. 
> Also appears to produce only 16-bit code as well.  

The code is 32bit. It can run under Win32s, which is a part of Windows 
that allows some (but not all) Win32 apps to run under Win16.

MS no longer distribute Win32s, BTW. No doubt they're trying to kill 
off Win16. Meanwhile, some people are still writing & selling software 
for it. Franz, for example.

Your mistake is an easy one to make. Perhaps when Win16 has finally 
died, this kind of confusion will end. For now, MS well 4 different 
varieties of Windows, depending on how you distinguish between them.
NTW and NTS are subtly distinct from each other, while Win95 is much 
more different, and Win16 is...16bit.

Please note that I'm only providing a little info about Windows and 
ACP/PC. I'm _not_ making any claims for Windows, nor am I defending 
it, promoting it, criticising it, or anything else. However, I may 
be suggesting that this may be in some small way relevant to ACL/PC 
and the way in which Franz market and sell it.
-- 
<URL:http://www.wildcard.demon.co.uk/> You can never browse enough
  Martin Rodgers | Programmer and Information Broker | London, UK
            Please note: my email address is gubbish.
From: David Hanley
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <338C6740.545D@nospan.netright.com>
Cyber Surfer wrote:
> 
> With a mighty <·············@nospan.netright.com>,
> ·····@nospan.netright.com uttered these wise words...
> 
> >       I recently tried lookin for good lisp development enviornments for
> > windows.  Allegro CL is $3000 for a version that makes execuatables.
> > Also appears to produce only 16-bit code as well.
> 
> The code is 32bit. It can run under Win32s, which is a part of Windows
> that allows some (but not all) Win32 apps to run under Win16.
> 
> MS no longer distribute Win32s, BTW. No doubt they're trying to kill
> off Win16. Meanwhile, some people are still writing & selling software
> for it. Franz, for example.
> 
> Your mistake is an easy one to make. Perhaps when Win16 has finally
> died, this kind of confusion will end.

	The reason I got the impression is because fixnums only extend
to +32767.  This gives the impression that the code is 16-bit.  Plus,
my e-mails to them on the subject have been ignored, while earlier
ones were answered.  And it was hard to determine the facts, because
of no power to create executables and no dissassembler in the test
version.

> However, I may
> be suggesting that this may be in some small way relevant to ACL/PC
> and the way in which Franz market and sell it.

	It's not a bad choice for them to still suppoer win 3.1.  A lot
of businesses still run it.  But they ought to make it clear the code
is, in fact, 32-bit.  

	dave
From: Markku Laukkanen
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <338D0808.3A62@research.nokia.com>
David Hanley wrote:
> 
> Cyber Surfer wrote:
> >
> > With a mighty <·············@nospan.netright.com>,
> > ·····@nospan.netright.com uttered these wise words...
> >
> > >       I recently tried lookin for good lisp development enviornments for
> > > windows.  Allegro CL is $3000 for a version that makes execuatables.
> > > Also appears to produce only 16-bit code as well.
> >
> > The code is 32bit. It can run under Win32s, which is a part of Windows
> > that allows some (but not all) Win32 apps to run under Win16.
> >
> > MS no longer distribute Win32s, BTW. No doubt they're trying to kill
> > off Win16. Meanwhile, some people are still writing & selling software
> > for it. Franz, for example.
> >
> > Your mistake is an easy one to make. Perhaps when Win16 has finally
> > died, this kind of confusion will end.
> 
>         The reason I got the impression is because fixnums only extend
> to +32767.  This gives the impression that the code is 16-bit.  Plus,
> my e-mails to them on the subject have been ignored, while earlier
> ones were answered.  And it was hard to determine the facts, because
> of no power to create executables and no dissassembler in the test
> version.
> 

They have a very weird datamodel for their LISP implementation, The size
of the fixnum (16 bits) indicaded, that the rest of the 32 bit word is
used for tagging information for various LISP datatypes.

	PKY
From: Jim Veitch
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <338E1561.24B0@franz.com>
Markku Laukkanen wrote:

> 
> They have a very weird datamodel for their LISP implementation, The size
> of the fixnum (16 bits) indicaded, that the rest of the 32 bit word is
> used for tagging information for various LISP datatypes.
> 
>         PKY

Please note that the 16 bit fixnum model is related to the old Windows
3.1 where 16 bit fixnums allowed for highly optimized arithmetic,
passing values in and out of parts of the Windows subsystem, and also
where the compiler could be clever about using the old 16 bit
operations.

In other words it was an optimization hack.

In general, most data objects are allocated in the heap and contain
their type information there.  Pointers and code are both full 32 bit. 
You can grow big heaps (multis of megabytes).

At the moment we are completely redoing the internals of the Lisp to
(among other things) support 30 bit fixnums and immediate data types.

Jim Veitch
Franz Inc.
From: Markku Laukkanen
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <338EB4B4.2E9C@research.nokia.com>
Jim Veitch wrote:
> 
> Markku Laukkanen wrote:
> 
> >
> > They have a very weird datamodel for their LISP implementation, The size
> > of the fixnum (16 bits) indicaded, that the rest of the 32 bit word is
> > used for tagging information for various LISP datatypes.
> >
> >         PKY
> 
> Please note that the 16 bit fixnum model is related to the old Windows
> 3.1 where 16 bit fixnums allowed for highly optimized arithmetic,
> passing values in and out of parts of the Windows subsystem, and also
> where the compiler could be clever about using the old 16 bit
> operations.
> 
> In other words it was an optimization hack.
> 
> In general, most data objects are allocated in the heap and contain
> their type information there.  Pointers and code are both full 32 bit.
> You can grow big heaps (multis of megabytes).
> 
> At the moment we are completely redoing the internals of the Lisp to
> (among other things) support 30 bit fixnums and immediate data types.
> 
> Jim Veitch
> Franz Inc.



Heh heh, Want to buy a really good compiler type interference system ?

	PKY
From: Marco Antoniotti
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <scfoh9tt1rm.fsf@infiniti.PATH.Berkeley.EDU>
In article <·············@franz.com> Jim Veitch <···@franz.com> writes:

   From: Jim Veitch <···@franz.com>
   Newsgroups: comp.lang.misc,comp.lang.lisp
   Date: Thu, 29 May 1997 16:46:41 -0700
   Organization: Franz Inc.
   Reply-To: ···@franz.com
   Lines: 26
   Mime-Version: 1.0
   Content-Type: text/plain; charset=us-ascii
   Content-Transfer-Encoding: 7bit
   X-Mailer: Mozilla 3.01 (Win95; I)
   Xref: agate comp.lang.misc:29917 comp.lang.lisp:28505

   Markku Laukkanen wrote:

   > 
   > They have a very weird datamodel for their LISP implementation, The size
   > of the fixnum (16 bits) indicaded, that the rest of the 32 bit word is
   > used for tagging information for various LISP datatypes.
   > 
   >         PKY

   Please note that the 16 bit fixnum model is related to the old Windows
   3.1 where 16 bit fixnums allowed for highly optimized arithmetic,
   passing values in and out of parts of the Windows subsystem, and also
   where the compiler could be clever about using the old 16 bit
   operations.

   In other words it was an optimization hack.

   In general, most data objects are allocated in the heap and contain
   their type information there.  Pointers and code are both full 32 bit. 
   You can grow big heaps (multis of megabytes).

   At the moment we are completely redoing the internals of the Lisp to
   (among other things) support 30 bit fixnums and immediate data types.

   Jim Veitch
   Franz Inc.

Assuming my identity of "agent provocateur" :) here is a question to
Franz:  how much CMUCL are you reworking in your product? :)

Cheers
-- 
Marco Antoniotti
==============================================================================
California Path Program - UCB
Richmond Field Station
tel. +1 - 510 - 231 9472
From: Jim Veitch
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <338F6784.5AF0@franz.com>
Marco Antoniotti wrote:

> Assuming my identity of "agent provocateur" :) here is a question to
> Franz:  how much CMUCL are you reworking in your product? :)

We are actually in the process of unifying our UNIX and PC products. 
The UNIX kernel has been ported to Windows and we are unifying the User
Interfaces, mostly based on the PC development environment and PC based
window system, Common Graphics.  The UNIX kernel is well developed,
stable and robust, with all sorts of optimizations, including 30 bit
fixnums, which it has had long before CMUCL.

At the moment we haven't actually used any CMUCL ideas, but they did a
good job on type inferencing which I'd like us to pick up on sometime in
the future.

Regards,

Jim Veitch
Franz Inc.
From: Marco Antoniotti
Subject: Re: Learning from C++'s success ( was C++ briar patch )
Date: 
Message-ID: <scf7mgfr22y.fsf@infiniti.PATH.Berkeley.EDU>
Thanks to Jim Veitch.  A honest response is always welcome.
-- 
Marco Antoniotti
==============================================================================
California Path Program - UCB
Richmond Field Station
tel. +1 - 510 - 231 9472
From: ···@teco.net
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <BITMEADC.97May20103402@Alcatel.com.au>
In article <·······················@10.0.2.1> ······@netcom.com (Henry Baker) writes:

>I'll calm down when I see the details of bs's study.  I'd like to know the
>actual calendar dates of this training, the number of people involved, the
>educational backgrounds of the people involved, the work experience (including
>computer languages used) of the people involved, the type of software involved,
>the nature of the productivity measurements, the number of people measuring,
>the controls utilized during this measurement, etc.  Without these and other
>details of this experiment, the results are worthless, and shouldn't be
>quoted in support of any productivity 'gains'.
>
>This isn't Tijuana Medical Clinic, this is Bell Labs.  We deserve better.

When I looked at C++ I thought that it *had* come out of Tijuana
Medical Clinic. Possibly having escaped off of one of the pietre
dishes.
From: James Logajan
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <jameslEA6M5H.C0H@netcom.com>
Bjarne Stroustrup (··@research.att.com) wrote:
: In some other thread, ······@netcom.com (Henry Baker) writes

:  > As to the assumption that one can turn a C programmer into a C++ programmer --
:  > good luck!  I doubt that 6 months will suffice, and in the mean-time, you'd
:  > better just kiss off the programmer (and all of his code that he writes
:  > during that period).

: This conjecture doesn't square with our experience at Bell Labs. In the early
: years, we carefully monitored and measured several projects converting from C
: to C++.

(This isn't clear to me: do you mean the code was converted from C to C++, the
programmers converted from C to C++, or a combination of the two?)

: The least improvement we found over the first half year (measured from
: the start of C++ training) was 15%. Most projects and individuals did much
: better according to most measures. We considered productivity according to
: several measures and tracked the projects later to consider maintenance costs
: and defect reports (on average the costs were halved).

You mean someone actually attempted programmer productivity measurements
of C to C++? Is that allowed? :-)

How formal was this measurement? Was it or could it be published? Would
you say that the individuals at Bell Labs that were measured constituted
a statistically valid cross-section of all C programmers? That is, did
their experience range from neophyte programmer to advanced?

Also, you said "most" projects/individuals did better by "most" measures.
What kind of projects, individuals, and measures did not improve? Was there
any common factor?

Sorry for all the questions; real metrics are hard to come by on Usenet;
anecdotal "proofs" seem to be the rule.
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-1405971806040001@10.0.2.1>
In article <··········@research.att.com>, ··@research.att.com (Bjarne
Stroustrup) wrote:

> In some other thread, ······@netcom.com (Henry Baker) writes
>  > As to the assumption that one can turn a C programmer into a C++
programmer --
>  > good luck!  I doubt that 6 months will suffice, and in the mean-time, you'd
>  > better just kiss off the programmer (and all of his code that he writes
>  > during that period).
> 
> This conjecture doesn't square with our experience at Bell Labs. In the early
> years, we carefully monitored and measured several projects converting from C
         ^^
> to C++. The least improvement we found over the first half year (measured from
> the start of C++ training) was 15%.

Bjarne:

I presume that you knew about the classic effect of organizational
psychology that was discovered in the 1920's.  GE wanted to sell more
electric lights to factories, but their potential customers kept saying
'show me the productivity'.  So GE set about to document productivity
gains from better lighting.  They outfitted a factory with lights capable
of a wide range of brightness.  Then they started increasing the light in
small increments and measured factory output.  As expected, the output
increased with the increase in brightness.

But these were real scientists, so they then started _reducing_ the light
output.  _Productivity increased_!  They kept on reducing the light and
productivity kept increasing, until the factory was so dark that they started
bumping into one another!  It turns out that productivity was far more dependent
upon management's attitude towards the workers than on any amount of light.  The
mere fact that management cared enough about what they were doing to pay
attention to them, made them work harder!

(Oh by the way, 6-12 months after the tests were done and the scientists
went away, productivity went back to essentially what it was before, regardless
of whether the new lights were left there or not.)

So unless you had some real professionals performing these tests, they
probably aren't worth the bits they are stored on.  (It is entirely possible
that C++ had reduced these people to wandering aimlessly around 'in the dark'.)

I hope that you also accounted for the increase in understanding of the
_previous_ language that they were working in.  Sometimes, merely being
exposed to a new language makes you think about the _old_ one in a new
light, and your productivity in the _old_ language may improve by as much,
or more, than your productivity in the _new_ language.  So you have to remeasure
their productivity again in the old language.

Finally, I would really like to know what fraction of the new language they
were using.  If they were taught a few minor things in C++, I could imagine
their productivity going up, because C++ finally fixed some real irritants
that C never got around to fixing.  But if they were programming in the
true 'OO' style, then I can predict a loss of between 6-9 months of work, while
they contemplated templates, objectified objects, and iterated loops.  (Hey,
we now know a _methodology_, man!)

There is this persistent myth in Computer Science that adding or subtracting
things from a language 'doesn't change it very much'.  But of course, CS
people haven't studied any linguistics, so they enter this battle of wits
completely unarmed.  Adding or subtracting relatively 'minor' features from
a language can _completely change the optimum programming style_ in a very
discontinuous way.  So there are at least 2 phases in learning a new language--
learning the bits and bytes, which normally doesn't take very long, and then
comes a much, much longer period, wherein a _style_ of programming is
developed that takes advantage of the changed situation and any new features,
and allows the programmer to finally achieve the best that the language has to
offer.

Those of us in the Lisp community are well aware of this.  New Lisp programmers
who came immigrated from other languages usually attempt to carry their
programming style with them -- at least at first.  Thus, we see Fortran-like
and C-like code that is amusing, but has to be junked.  Only after some
degree of maturity with the language is the style suited for the new language,
and the code ready to actually be used.
From: Darin Johnson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5npu66.ft5.darin@connectnet1.connectnet.com>
In article <·······················@10.0.2.1>, Henry Baker wrote:
>Those of us in the Lisp community are well aware of this.  New Lisp programmers
>who came immigrated from other languages usually attempt to carry their
>programming style with them -- at least at first.  Thus, we see Fortran-like
>and C-like code that is amusing, but has to be junked.  Only after some
>degree of maturity with the language is the style suited for the new language,
>and the code ready to actually be used.

I first learned Lisp in a comparative-languages course.  We slowly
learned it by adding more and more features, and were given
assignments that naturally built on top of functions we had already
written.  The professor did not let use use prog or variants (ie, no
sequential code).  About a year later, I took an AI class that used
Lisp, and after about 3 assignments, the professor spoke to me and
said "it's ok to use progn, and it will make your code easier for me
to read".  I was sort of stunned, as it hadn't dawned on me I was
still forcing myself to use a pure functional approach, even in
situations where it wasn't necessarily appropriate.


-- 
Darin Johnson
·····@usa.net.delete_me
From: Erik Naggum
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3072702392790368@naggum.no>
* Bjarne Stroustrup
| In the early years, we carefully monitored and measured several projects
| converting from C to C++.  The least improvement we found over the first
| half year (measured from the start of C++ training) was 15%.

since this took place in the early years, I surmise that very little of the
rotting driftwood had drifted into C++, and that it was relatively easy to
use the language.  those of us who have read your "early years" material
also know that you worked very hard to ascertain actual improvements and
fed data from such projects directly into the language design.  now, not
only considering the effect that is referred to as the Hawthorne effect, I
can certainly understand that lasting improvement would be found from
giving people the power to influence their programming language, especially
when the starting point is so limiting as C.

I have a few question.  (1) which features and/or changes caused the 15%
"carefully monitored and measured" improvement?  (2) is today's C++ able to
cause the same improvement?  (3) are the features that caused improvement
features that you would claim are _significant_ features of C++, or just
those "a better C" features?

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: Bjarne Stroustrup
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EAC7GJ.30r@research.att.com>
Erik Naggum <····@naggum.no> writes:

 > * Bjarne Stroustrup
 > | In the early years, we carefully monitored and measured several projects
 > | converting from C to C++.  The least improvement we found over the first
 > | half year (measured from the start of C++ training) was 15%.
 > 
 > since this took place in the early years, I surmise that very little of the
 > rotting driftwood had drifted into C++,

Very little of what have been added to C++ over the years deserve to be
called "rotting driftwood."

 > and that it was relatively easy to
 > use the language.  those of us who have read your "early years" material
 > also know that you worked very hard to ascertain actual improvements and
 > fed data from such projects directly into the language design.  now, not
 > only considering the effect that is referred to as the Hawthorne effect, I
 > can certainly understand that lasting improvement would be found from
 > giving people the power to influence their programming language, especially
 > when the starting point is so limiting as C.

Yes, and I consider most of what I have done to C++ over the last decade to
be direct responses to experience with real-world projects.


 > I have a few question.  (1) which features and/or changes caused the 15%
 > "carefully monitored and measured" improvement?

First for the benefit of people who have not followed this thread and don't
know where this figure comes from:

	The 15% improvement was the least improvement we ever measured for
	the first half year. The average was 45%. The measurements were of
	groups of experienced C programmers working of real-world projects
	considered critical for various parts of AT&T. The measurements
	were done by people responsible for product quality rather than
	language enthusiasts. The improvements were sustained and increased		over time.

The key features used in the initial half year were typically:

	Stronger type checking (compared to C).
	Better encapsulation (classes encapsulating things such as
		database access, device use, and IPC).
	A few simple library classes (such as string, list, map, ...)

After the initial half year programmers and designers because more adventurous.
For example, we saw more use of class hierarchies.

A consistent problem at this later stage was that people built single-rooted
hierarchies without maintaining proper firewalls. In many cases, the solution
was to introduce more abstract classes. It is a credit to the early code that
often abstract classes could be retrofitted into the systems to overcome
problems caused by overenthusiasm for class hierarchies. That is the design
had maintained proper abstraction and encapsulation that could be exploited
to reduce excess coupling caused by naive hierarchies.


 > (2) is today's C++ able to cause the same improvement?

Yes, when used cautiously relative to your experience as I consistently
advocate, it can cause greater improvements. There are also more libraries
available these days.


 > (3) are the features that caused improvement
 > features that you would claim are _significant_ features of C++, or just
 > those "a better C" features?

I would consider any feature that help cause a halving of defects and a
more than a halving of maintenance costs significant :-)

Seriously, stronger type checking is essential. Classes/encapsulation is
key and beyond the "better C" subset of C++. With it goes a greater
awareness of design issues and a greater emphasis on conceptual design.
Abstract classes (and the polymorphic code they bring into play) become
critical a bit later. With abstract class used extensively, class hierarchies
become manageable.

Some lessons I learned from (or had re-emphasized by) the early projects
are reflected in C++ as currently defined: 

	It is essensial to extend the strongly-typed view to containers
	and code manipulating them. This implies templates or something
	roughtly equivalent. 

	Especially when using separately-developed code with polymorphic
	interfaces, strong (static) type checking is not sufficient.
	In a few cases, determining the type of an object at run time
	is essential. This implies something like the C++ dynamic_cast.

	Name clashes is a steadily increasing problem as the size of
	programs and projects increase. Namespaces addresses that problem.

These are conclusions in the context of C++ and of a particular set of
demanding applications. For other languages and other application domains
other conclusions might apply.

	- Bjarne

Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html
From: Thant Tessman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <337E0B6E.41C6@nospam.acm.org>
Bjarne Stroustrup wrote:

[...C++ makes programmers more productive than C...]


Car salesman have a trick.  If a customer is hesitating on a certain car,
the saleman will ask the customer what color they would prefer the car in, 
thereby tricking the customer into subconsciously assuming that they've 
already decided to buy, but without denying them the sensation that they
have made a choice.

-thant

[...followups trimmed...]
From: Erik Naggum
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3072946195166010@naggum.no>
* Bjarne Stroustrup
| The key features used in the initial half year were typically:
| 
| 	Stronger type checking (compared to C).
| 	Better encapsulation (classes encapsulating things such as
| 		database access, device use, and IPC).
| 	A few simple library classes (such as string, list, map, ...)
| 
| After the initial half year programmers and designers because more
| adventurous.  For example, we saw more use of class hierarchies.

perhaps I should rephrase the question, since it took me some time to
realize that you're talking about the original K&R C and compilers like
"pcc", not ANSI C and gcc 2.7.  however, before ANSI C, I was an avid
`lint' user, and I don't understand how a user of C would be able to work
efficiently without using `lint'.

I remember when I discovered `lint'.  I had spent days on a bug that I just
could not track down.  everything looked correct, yet it dumped core on me.
I forget who told me to use `lint', but it discovered an inconsistency in
the number of arguments to a function called from two different files.
that was it.  this property of `lint' is available with function prototypes
exported to header files these days, but all of `lint' is not in ANSI C.

did the C programmers you tested this on use `lint'?  if not, I can easily
buy a 45% increase in productivity with a compiler that did most of what
`lint' did.  if they did use `lint' religously, I think you would need to
remove "stronger type checking" from your list to be fair.

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: Bjarne Stroustrup
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EAEA7E.GCI@research.att.com>
Erik Naggum <····@naggum.no> writes:

 > * Bjarne Stroustrup
 > | The key features used in the initial half year were typically:
 > | 
 > | 	Stronger type checking (compared to C).
 > | 	Better encapsulation (classes encapsulating things such as
 > | 		database access, device use, and IPC).
 > | 	A few simple library classes (such as string, list, map, ...)
 > | 
 > | After the initial half year programmers and designers because more
 > | adventurous.  For example, we saw more use of class hierarchies.
 > 
 > perhaps I should rephrase the question, since it took me some time to
 > realize that you're talking about the original K&R C and compilers like
 > "pcc", not ANSI C and gcc 2.7.  however, before ANSI C, I was an avid
 > `lint' user, and I don't understand how a user of C would be able to work
 > efficiently without using `lint'.

I agree (i.e. "neither do I"). 


 > did the C programmers you tested this on use `lint'?  if not, I can easily
 > buy a 45% increase in productivity with a compiler that did most of what
 > `lint' did.  if they did use `lint' religously, I think you would need to
 > remove "stronger type checking" from your list to be fair.

They did use `lint' religously. However, they also used casts a lot
and malloc. There is a distinct difference between code that has been
modified to shut up lint and code designed to be type safe. I suspect it
comes from writing code to pass a C++ compiler vs passing code produced
during the day through lint in the evening and then fixing it. My impression
is that few C programmers run lint before every debug run.

Also ANSI C's rules for function argument checking arenot a tight as C++'s.

I think "stronger type checking" belongs on the list. However, as mentioned,
I have no way of distinguishing what use of what features contributed to the
observed improvements or in what ways.

	- Bjarne

Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html
From: Richard A. O'Keefe
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5ls680$p1e$1@goanna.cs.rmit.edu.au>
··@research.att.com (Bjarne Stroustrup) writes:

>My impression
>is that few C programmers run lint before every debug run.

Few C programmers are _good_ C programmers.
My practice of using lint religiously has paid off handsomely this year:
Sun's lint can now catch a lot of errors that neither of the C++
compilers available to me can catch!
(lclint can do an even better job, but it isn't quite as robust.)

One major limitation of the C++ type system is that for a language where
state is pervasive and obtrusive, the type system doesn't help you with
state.  It ought, for example, to be a *static* check that tells you
you can't modify a container when you're iterating over it.  Such an
irony that the two languages available to me _whose type systems _do_
help with state (Mercury and Clean) are respectively a pure logic
programming language and a pure functional language.

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-1705971756470001@10.0.2.1>
In article <··········@research.att.com>, ··@research.att.com (Bjarne
Stroustrup) wrote:

>         The 15% improvement was the least improvement we ever measured for
>         the first half year. The average was 45%. The measurements were of
>         groups of experienced C programmers working of real-world projects
>         considered critical for various parts of AT&T. The measurements
>         were done by people responsible for product quality rather than
>         language enthusiasts. The improvements were sustained and
increased             over time.

Once again, Bjarne, 'show me the code'.  Let's see exactly what sort of code
these people were writing after a 1 week exposure to C++.  Since we're all
professional programmers here, we don't need anyone else to 'interpret'
the results for us.  We're perfectly capable of making this assessment
ourselves.

You're the one making the outrageous claims, so it is up to you to back them
up with facts that we can all understand.  We can all handwave 
unsubstantiated 'productivity' numbers.  Code is something that can't be
handwaved.

Show me the code!
From: ozan s. yigit
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <x6iv0euu47.fsf@ds9.rnd.border.com>
······@netcom.com (Henry Baker) writes:

> Show me the code!

henry, you *know* better!

what do you suppose that would prove? in the real world, programming
skills, ability to learn abstract concepts vary by a considerable margin.
if he showed you superlative code, you would claim there was an exceptional
programmer, surely not the "average" guy. if he showed you average code, you
would claim "see, there it is. they are all like that. not good at all" and
if he showed you really poor code, you would be happy, presuming your point
[for what its worth] is proven?

this would make for good netnews drama, but of negligible value in
reality. can you think of something else that would give you a more
reasonable evaluation of whatever it is you are after?

oz
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-2005971551510001@10.0.2.1>
In article <··············@ds9.rnd.border.com>, ··@ds9.rnd.border.com
(ozan s. yigit) wrote:
> ······@netcom.com (Henry Baker) writes:
> > Show me the code!
> 
> what do you suppose that would prove? in the real world, programming
> skills, ability to learn abstract concepts vary by a considerable margin.
> if he showed you superlative code, you would claim there was an exceptional
> programmer, surely not the "average" guy. if he showed you average code, you
> would claim "see, there it is. they are all like that. not good at all" and
> if he showed you really poor code, you would be happy, presuming your point
> [for what its worth] is proven?

You may have missed one of my posts, but I said that most of us reading
this thread are professional programmers (and therefore that we are quite
used to reading code).  We are therefore an unusual audience in not having to
have someone else 'interpret' the results of this test -- we can see for
ourselves.

I don't understand your question.  Are you saying that _no_ possible test
would prove anything?  Are you saying that someone else 'interpreting' the
code would make you feel better about the results of the test?  Are you
saying that a proper 'blind' test would somehow measure the results without
any knowledge of the language?  ('bs' also indicated that the code was
more reliable and maintainable, which is difficult to measure without
actually looking at it.)

Given that 'bs' said that these were professional C programmers of high
caliber, I would imagine that they already produced pretty high quality
C code.  So it is even more interesting to find out how converting to
C++ was able to make them substantially more productive.
From: ozan s. yigit
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <x64tbxgzbl.fsf@ds9.rnd.border.com>
······@netcom.com (Henry Baker) writes:

······@netcom.com (Henry Baker) writes [in part]:

> I don't understand your question.  Are you saying that _no_ possible test
> would prove anything?  Are you saying that someone else 'interpreting' the
> code would make you feel better about the results of the test? Are you
> saying that a proper 'blind' test would somehow measure the results without
> any knowledge of the language?  ('bs' also indicated that the code was
> more reliable and maintainable, which is difficult to measure without
> actually looking at it.)

no no, you are reading too much into what i said. i simply point out that
asking Stroustrup to post code will not resolve this. do you really expect
to hear a united sigh in these groups, and see everyone post "yes, you were
right" to stroustrup? that study will not get an objective review in this
forum, no matter what he posts.

perhaps the answer is to conduct an independent study. i would love to
see the same type of study for other important languages such as
scheme and java.

oz
---
if you torture the data long enough, it will confess. - anon
From: Bjarne Stroustrup
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EAM4Ep.LIw@research.att.com>
In a variety of articles ······@netcom.com (Henry Baker) exclaimed:

 > Once again, Bjarne, 'show me the code'.  Let's see exactly what sort of code
 > these people were writing after a 1 week exposure to C++.  Since we're all
 > professional programmers here, we don't need anyone else to 'interpret'
 > the results for us.  We're perfectly capable of making this assessment
 > ourselves.
 > 
 > You're the one making the outrageous claims, so it is up to you to back them
 > up with facts that we can all understand.  We can all handwave 
 > unsubstantiated 'productivity' numbers.  Code is something that can't be
 > handwaved.
 > 
 > Show me the code!
 > 
 > Show us the C++ code that they produced after a week in class.
 > 
 > Why should we believe you?  Show us 10 examples of where these people used
 > C++ constructs after 1 week in class.
 > 
 > But these people still had to learn a whole new language.
 > Show us the code.
 > 
 > Show us some examples of this.  Show us a piece of code that they produced
 > after your 1-week training course.  We will judge for ourselves whether this
 > is 'more maintainable' code.
 > 
 > OK, show us code that was produced 1 week, 1 month, 6 months, 1 year, and
 > 2 years after this 1-week course (no further 'training' allowed).
 > 
 > OK, show us some of this code, both before and after, so we can see how it
 > is 'better and more maintainable' than it was before.  Unless you also
 > post the timecards, I guess it would be difficult to tell whether this
 > code was 'produced faster', so we'll focus primarily on 'better and more
 > maintainable' for the moment.
 > 
 > What you have is a large-scale experiment that would be laughed out of any
 > peer-reviewed journal in a real _science_ like medicine.  Where is your
 > control?  Where is your blind?  Did you then put these people back onto a
 > C program to compare their productivity in C afterwards?
 > 
 > I don't care who you are talking about.  Show me the code.
 >
 > Me thinks you doth claim too much.  Show me the code.
 > 
 > 'bs' claimed that a one-week training course in C++ would convert a C
 > programmer having no previous training in OO languages and make that person
 > into a _more_ productive C++ programmer.  I don't believe him, and I'm calling
 > his bluff.
 > 
 > He claims to have done a study to prove this, so all I'm asking is for
 > 'bs' to post some of this wonderful code that was produced after this
 > 1-week C++ blitz course, so we can all decide for ourselves if this 1-week
 > course has produced anything useful in this previously C-only programmer.
 > 
 > Show me some code produced by a
 > C-only programmer after a 1-week course in C++ that improved the programmer's
 > productivity.  I want to see some of these templates and classes that this
 > person has produced.
 > 
 > I find outrageous the assertion that
 > 'bs' has taught C-only programmers to be productive in _C++_ after only a
 > one week course.  I'm interested in exactly what facilities of C++ that
 > aren't found in C are being used by these mythical programmers.)
 >
 > I'd like to know the
 > actual calendar dates of this training, the number of people involved, the
 > educational backgrounds of the people involved, the work experience (including
 > computer languages used) of the people involved, the type of software involved,
 > the nature of the productivity measurements, the number of people measuring,
 > the controls utilized during this measurement, etc.  Without these and other
 > details of this experiment, the results are worthless, and shouldn't be
 > quoted in support of any productivity 'gains'.
 > 
 > This isn't Tijuana Medical Clinic, this is Bell Labs.  We deserve better.

Curiously enough I have addressed the points Hery Baker emphasize in postings
preceeding Henry Baker's postings in this thread.

(1) Show me the code:

I wrote:

	I described the experience with several groups of programmers building
	industrial applications over years. The smallest of these groups had seven
	people. We are talking of several hundred thousand lines of code built and
	maintained over years. That is not the type of code one posts on the net
	- even if the systems hadn't been the basis of multi-billion-dollars-a-year
	businesses. 

	The programmers weren't "neophytes." They were experienced C programmers and
	most were experts in the domain they were programming in. Even the most
	brilliant programmer with the world's best tools would have been at a
	complete loss without that domain expertice.

Several people posted it this thread showing that they considered my point
reasonably clear:

  (1) The code is proprietary and not mine to show.

  (2) This kind of code is not particularly readable by non-domain experts.
      (without knowing the constraints on a problem you will have a hard time
      evaluating a solution).

In my opinion very few pieces of large-scale software are suitable for examination
of non-experts even it is was in the public domain.



(2) What kind of code?:

I wrote:

	The key features used in the initial half year were typically:

		Stronger type checking (compared to C).
		Better encapsulation (classes encapsulating things such as
			database access, device use, and IPC).
		A few simple library classes (such as string, list, map, ...)

	After the initial half year programmers and designers because more adventurous.
	For example, we saw more use of class hierarchies.

	A consistent problem at this later stage was that people built single-rooted
	hierarchies without maintaining proper firewalls. In many cases, the solution
	was to introduce more abstract classes. It is a credit to the early code that
	often abstract classes could be retrofitted into the systems to overcome
	problems caused by overenthusiasm for class hierarchies. That is the design
	had maintained proper abstraction and encapsulation that could be exploited
	to reduce excess coupling caused by naive hierarchies.

In other postings, I pointed out that the C code we compared with was primarily
K&R C with heavy use of lint. To repeat: during the initial half year the gains
were primarily due to better type checking and encapsulation, as more advanced
OO techniques using class hierarchies were introduced some problems emerged and
were addressed (with abstract classes being a major tool).



(3) Controlled experiments: 

I wrote:

	Genuine scientific multiway comparative studies are hard and expensive.
	We (meaning a group in AT&T Bell Labs not including me) compared groups
	of people (the smallest group I know of had seven people) that used to
	write in C, before, during, and after conversion to using C++. This was
	done for several groups.

	My main interest was to improve the quality of the systems produced based
	on the assumption that this could be done using a better language (C++)
	without undesirable sideefects on productivity or the quality of life
	for the individuals involved. The organizations letting groups convert
	and monitoring the conversions were - I think - more interested to see
	whether productivity could be improvements without lowering quality.

	There were, over the years, other groups that tried converting to other
	languages - modula-2, CHILL, and Lisp - springs to mind, but I have less
	knowledge of those, I have not seen data from those that could be used
	for comparison. My impression is that these experiements were abandoned
	because of unsatisfatory results rather than politics. However, I'm sure
	other people will have different opinions. But, no, I don't have solid
	comparative data. One data point is that several C++ projects succeeded
	in an environment that was hostile to all new languages (including C++)
	where projects that chose other languages failed (for a variety of reasons).

	Remember, the purpose of these measurements were simply to determine
	cost effective tools and techniques in a particular industrial setting.
	The purpose was not to isolate exactly what in the development process
	yielded the observed results.

and:

	Wouldn't it be nice if I could actually prove this? I can't. There are
	some numbers published by Denis Mancl, more numbers that are not released
	(corporations do not like to give hard numbers on their development
	projects), and some studies by James Coplien (in the "Pattern Languages
	of Programming" book), but they don't add up to scientific proof.

	On the other hand, I don't think there is scientific proof that workstations
	give better results than timesharing yet. People tend to vote with their
	feet (and money) before hard evidence can be gathered - and they won't
	go back to become a control group either.

Here are references for the Mancl articles that documents some of the experiences:

  Dennis Mancl and William Havanas, "A Study of the Impact
  of C++ on Software Maintenance," Proceedings of the IEEE
  Conference on Software Maintenance 1990, pp. 63-69.

  Dennis Mancl, "Experiences Using C++ to do Object-Oriented
  Programming," Proceedings of C++ World 1992, pp. 65-69.

Dennis also presented tutorials at C++ World in 1994, 1995, and 1996,
People who went to those tutorials may have more information.

One of Jim Copliens studies - which yielded quality and productivity improvements
far in excess of what have been mentioned in this thread - is:

  J.O.Coplien: "Borland Software craftmanship: A new look at process, quality,
  and productivity" Proc. 5th Annual Borland International Conference. Orlando, FL.
  June 1994.

I consider the AT&T results presented by Mancl fairly typical or even modest.
The Borland results documented by Coplien are extraordinary.



Let me repeat the key points I have been making here:

	(1) It is possible to teach a fairly typical a group C developers
	    to use C++ so that their productivity goes up - even during
	    the initial half year that includes the training time.

	(2) That the improvements are sustained over a period of years.

	(3) That the code produced is significantly more maintainable and
	    has few defects (by about a half) than comparable C code.

	(4) That this can be achieved with an initial training period of
	    a week followed by a gradual application of C++ features and
	    abstraction techniques into production code.

	(5) That the teaching/training needn't involve exceptional teachers.

	(6) All of the major features of C++ can be taught in a week to people
	    who are already programmers but do not know OO techniques, ``but not
	    to the point where people would be effective using it.

	    Trying to teach all of any unfamiliar language in a week and then
	    trying to apply it in a major project immediatly would be an almost
	    certain disaster. In fact, there has been noticeable disasters where
	    people - using a variety of languages - has gone overboard with OO
	    and language features that were new to them.

	    The key is a gradual approach to learning and using what you have
	    learned.

            I estimate that it on average takes between one and two years to
	    become fully comfortable with C++ and the main techiques it supports
	    (assuming you don't start with C++ already comfortable with abstraction
	    techniques). I consider it very important that a programmer can remain
	    productive during this period, and even increase his or her productivity
	    and the quality of the work produced in that period.''

	    (the quoted section is quotes from my previous postings in this thread).

	(7) Modern C++ and modern C++ libraries offer more than what was available
	    a few years ago and directly address problems observed with earlier use.




I don't consider these points in the least extraordinary or hard to believe.
I consider them far more modest than most of the hype on the net and elsewhere.

Point 6 is based on personal experience, rather than measurements on AT&T projects.
Point 7 is part opinion, part personal observation.

I cannot offer scientific proof, but then it is a very long time since I have
seen a scientific proof of anything involving large-scale software construction.
It would be nice if our industry was mature enough for major producers and
consumers of programming tools and techniques to finance proper trials as a
matter of ordinary operations. However, this is not so. 

	- Bjarne

Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-2305971250120001@10.0.2.1>
In article <··········@research.att.com>, ··@research.att.com (Bjarne
Stroustrup) wrote:
>   (1) The code is proprietary and not mine to show.

I said fine, show us exactly what features of C++ are used in the code.
Surely, this couldn't possibly be proprietary information.

>   (2) This kind of code is not particularly readable by non-domain experts.
>       (without knowing the constraints on a problem you will have a hard time
>       evaluating a solution).
> In my opinion very few pieces of large-scale software are suitable for
examination
> of non-experts even it is was in the public domain.

We're looking for evidence of C++-ness in the code.  Surely one doesn't have
to be a 'domain expert' to tell this?

>         The key features used in the initial half year were typically:
>                 Stronger type checking (compared to C).

Better than ANSI C?

>                 Better encapsulation (classes encapsulating things such as
>                         database access, device use, and IPC).
>                 A few simple library classes (such as string, list, map, ...)

Are these 1-week people _using_ these classes, or _writing_ them ?

>         After the initial half year programmers and designers because
more adventurous.
>         For example, we saw more use of class hierarchies.
                                   ^^^

Do you mean 'use' or 'write' here?

> In other postings, I pointed out that the C code we compared with was
primarily
> K&R C with heavy use of lint.

These other postings were not in response to me.

So after about a week and 100 messages, we have learned one very small bit of
additional information: we are talking about K&R C rather than ANSI C.

Whew!  Why was that so hard?

> To repeat: during the initial half year the gains
> were primarily due to better type checking and encapsulation, as more advanced
> OO techniques using class hierarchies were introduced some problems
emerged and
                ^^^^^
> were addressed (with abstract classes being a major tool).

'Using' or 'writing' ??

> Here are references for the Mancl articles that documents some of the
experiences:
>   Dennis Mancl and William Havanas, "A Study of the Impact
>   of C++ on Software Maintenance," Proceedings of the IEEE
>   Conference on Software Maintenance 1990, pp. 63-69.
> 
>   Dennis Mancl, "Experiences Using C++ to do Object-Oriented
>   Programming," Proceedings of C++ World 1992, pp. 65-69.
> 
>   J.O.Coplien: "Borland Software craftmanship: A new look at process, quality,
>   and productivity" Proc. 5th Annual Borland International Conference.
Orlando, FL.
>   June 1994.

> I consider the AT&T results presented by Mancl fairly typical or even modest.
> The Borland results documented by Coplien are extraordinary.

I don't have ready access to these august conference proceedings: 'C++ World'
and '5th Annual Borland Int'l Conf'.  Are these on the web somewhere?

> Let me repeat the key points I have been making here:
>         (1) It is possible to teach a fairly typical a group C developers
>             to use C++ so that their productivity goes up - even during
>             the initial half year that includes the training time.

Once again, is this K&R C or ANSI C?  What have you done to compensate for
the Hawthorne Effect?  Since you haven't given us any details about exactly
what was taught, and what was learned (as evidenced by what different
behavior was exhibited in the code), how can you conclude that teaching C++
had anything to do with productivity?  It could have been the coffee at
the training session, a better understanding of some algorithm that happened
to be used as one of the C++ examples, better morale, etc.

>         (2) That the improvements are sustained over a period of years.

What measurements are being 'improved'?  Lines of code, numbers of bug reports,
number of compiles, number of printouts, number of sick days, or what ??

>         (3) That the code produced is significantly more maintainable and
>             has few defects (by about a half) than comparable C code.

How is 'maintainable' and 'defect' defined?  Exactly what measurements did
you perform in order to conclude 'by about a half' ??

>         (4) That this can be achieved with an initial training period of
>             a week followed by a gradual application of C++ features and
>             abstraction techniques into production code.

Aha!  So the _initial_ training period was one week, and there were additional
ongoing refresher training periods?

>         (5) That the teaching/training needn't involve exceptional teachers.

Just exceptional students ;-)

>             I estimate that it on average takes between one and two years to
>             become fully comfortable with C++ and the main techiques it
supports
>             (assuming you don't start with C++ already comfortable with
abstraction
>             techniques). I consider it very important that a programmer
can remain
>             productive during this period, and even increase his or her
productivity
>             and the quality of the work produced in that period.''

Once again, I'll ask: How much of the code that this not-so-comfortable
programmer
do you have to (or want to) throw away before he/she becomes comfortable?

> I cannot offer scientific proof,

OK.  So your anecdotal evidence is no better than our anecdotal evidence.

> but then it is a very long time since I have
> seen a scientific proof of anything involving large-scale software
construction.
> It would be nice if our industry was mature enough for major producers and
> consumers of programming tools and techniques to finance proper trials as a
> matter of ordinary operations. However, this is not so. 
>         - Bjarne

So much for Computer 'Science'.  And Congress worries about medical
quackery with
unproven mirale drugs, when the real money seems to be in software quackery...

Tijuana Medical Clinic, eat your heart out!
From: Darin Johnson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5oc538.r7s.darin@connectnet1.connectnet.com>
In article <·······················@10.0.2.1>, Henry Baker wrote:
>>         The key features used in the initial half year were typically:
>>                 Stronger type checking (compared to C).
>
>Better than ANSI C?

This experiment could have been done before ANSI C.  Although a good
lint should pick up most things anyway.  ANSI C is even newer than C++,
and if these were early studies, then they're likely before ANSI C
(remember, ANSI C borrowed from C++).

>>                 Better encapsulation (classes encapsulating things such as
>>                         database access, device use, and IPC).
>>                 A few simple library classes (such as string, list, map, ...)
>
>Are these 1-week people _using_ these classes, or _writing_ them ?

Writing I would hope.  A string, list, or map class is not that hard to
write.  Writing a good one suitable for subtyping and maintenance would
be harder though, but just writing one that's usable is easy.  *And*
that's without prior OO experience (those aren't necessarily OO, they're
just ADT's).

In a 1 quarter (10 week) class I TA'd, which was the first time I or
the professor had seen C++ (1985), and none of the students had seen
it, and had only the first edition C++ book to go on; the students
were quite capable of creating ADT's for lists, hash tables, trees,
and so forth.  The list ADT was done within a couple of weeks from the
start of class.

Expert AT&T programmers undoubtedly could do better.  After all, they're
in a much better position to understand the benefits of abstraction than
novice programmers, and may have probably implemented their own ADT's
with K&R C previously (in a non-type safe and somewhat clumsy manner).

>>         (2) That the improvements are sustained over a period of years.
>
>What measurements are being 'improved'?  Lines of code, numbers of bug reports,
>number of compiles, number of printouts, number of sick days, or what ??

Why are you being so annoying about this?  It's not an unreasonable claim
that one shouldn't have to spend months or years before they can take
advantage of C++; to have expert programmers pick up and start making
effective use of *some* of C++ is to be expected.  What is it about
this that bugs you, do you sell training seminars or something?

C++ tries hard to be compatible with C.  Thus, any ANSI C program is
also a C++ program.  Anyone who can program effectively in ANSI C can
program effectively in C++.  So then, for the rest of C++, these are
incremental additions onto C.  How much time for each incremental
addition is a programmer allowed before you'll accept that he can use
it acceptably?

Yes, the modern fashion for C++ uses a completely different
programming paradigm, but Bjarne never stated that that the
programmers were using new paradigms right off the bat.
There's a book I can't recall the name of (C++ style guide?
by Saks and somebody), that lists three stages of C++ usage;
(roughly) the better-C-than-C stage, the C with ADT's stage,
and the full use of C++ with class hierarchies/templates stage.
Professional programmers can get into the first two stages very quickly.

-- 
Darin Johnson
·····@usa.net.delete_me
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-2305971609170001@10.0.2.1>
In article <····················@connectnet1.connectnet.com>,
·····@usa.net.delete_me (Darin Johnson) wrote:

> In article <·······················@10.0.2.1>, Henry Baker wrote:
> >>         The key features used in the initial half year were typically:
> >>                 Stronger type checking (compared to C).
> >
> >Better than ANSI C?
> 
> This experiment could have been done before ANSI C.  Although a good
> lint should pick up most things anyway.  ANSI C is even newer than C++,
> and if these were early studies, then they're likely before ANSI C
> (remember, ANSI C borrowed from C++).

Why do we have to speculate?  Why doesn't 'bs' simply tell us??

> >>                 Better encapsulation (classes encapsulating things such as
> >>                         database access, device use, and IPC).
> >>                 A few simple library classes (such as string, list,
map, ...)
> >
> >Are these 1-week people _using_ these classes, or _writing_ them ?
> 
> Writing I would hope....

Why do we have to speculate?  This was supposedly a real test, so let's hear
the real answer.

> >>         (2) That the improvements are sustained over a period of years.
> >
> >What measurements are being 'improved'?  Lines of code, numbers of bug
reports,
> >number of compiles, number of printouts, number of sick days, or what ??
> 
> Why are you being so annoying about this?  It's not an unreasonable claim
> that one shouldn't have to spend months or years before they can take
> advantage of C++; to have expert programmers pick up and start making
> effective use of *some* of C++ is to be expected.  What is it about
> this that bugs you, do you sell training seminars or something?

The thing that bugs me is that everyone is handwaving and speculating.  If
someone has real data, then let's hear it.  Exactly what features does a
C programmer feel comfortable enough about after a 1 week C++ course to
not only use, but use _productively_, and not have to later throw away ??

If someone quotes to you numbers like '15%' or '45%' productivity improvement,
or '50%' reduction in bugs, and this in a moderately formal study that had
independent people scoring, wouldn't you want to know exactly what was
measured and what was being claimed ??  If the data is that worthless that
there is no backup material, then that someone should stop being pedantic, and
simply say 'moderate _perceived_ improvement', or some such.  By quoting the
percentage numbers, this person is implying something far more precise and
scientific than is actually the case, since the higher precision has no
basis in fact.

The problem is that the trade press picks up these statements as the gospel
truth, and they get copied over and over again.  You can put in as many
caveats as you please, and the editor will simply delete them.  Pretty soon,
everyone in the industry is quoting each other's press releases, and no one has
any facts at all.  In my book, this is the definition of 'hype', whether it was
intended that way or not.
From: Benjamin Franksen
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <338D5693.593B@bii.bessy.de>
Bjarne Stroustrup wrote:
> The key features used in the initial half year were typically:
> 
>         Stronger type checking (compared to C).
>         Better encapsulation (classes encapsulating things such as
>                 database access, device use, and IPC).
>         A few simple library classes (such as string, list, map, ...)
....
> Seriously, stronger type checking is essential. Classes/encapsulation is
> key and beyond the "better C" subset of C++. With it goes a greater
> awareness of design issues and a greater emphasis on conceptual design.

I am not very astonished. These features have nothing to do with OO, in
Modula2 you can do the same with ADTs instead of classes. Data
encapsulation is even better: in C++ you are forced to reveal all
private data members to the rest of the world, whereas in a good
modularised procedural language you can keep them totally secret. What
about changing the implementation and leaving the interface intact??

Of course it enhances productivity to incorporate such (trivial)
features into a language which hasn't even a concept of _interface_
(header files are a poor substitute).

I think the greatest problem with C++ is that it tries to bridge a gap
of 10 years development in procedural languages. IMO, to go directly
from 'high assembler' C to OO seems a bit like trying to teach a baby
mathematics.

> ... For other languages and other application domains
> other conclusions might apply.

I'm quite sure.

	Ben
-- 
// snail: BESSY II, Rudower Chaussee 5, D-12489 Berlin, Germany
// email: ········@bii.bessy.de
// phone: +49 (30) 6392-4865
// fax:   +49 (30) 6392-4859
From: ········@wat.hookup.net
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5mkemr$g10$2@nic.wat.hookup.net>
In <·············@bii.bessy.de>, Benjamin Franksen <········@bii.bessy.de> writes:
> ...
>I am not very astonished. These features have nothing to do with OO, in
>Modula2 you can do the same with ADTs instead of classes. Data
>encapsulation is even better: in C++ you are forced to reveal all
>private data members to the rest of the world, whereas in a good
>modularised procedural language you can keep them totally secret. What

You would neet a very secure file system to keep the private parts really
secret.  And why is it such a big deal?  As long as the language enforces
sticking to the published interface it can't really hurt to make the other
details open to inspection.  For various optimizattions and inlining the
compiler has to know a few things.

> ...

Hartmann Schaffer
From: Bill House
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <01bc6c79$18042a20$03d3c9d0@wjh_dell_133.dazsi.com>
········@wat.hookup.net wrote in article <············@nic.wat.hookup.net>...
> 
> You would neet a very secure file system to keep the private parts really
> secret.  And why is it such a big deal?  As long as the language enforces
> sticking to the published interface it can't really hurt to make the other
> details open to inspection.  For various optimizattions and inlining the
> compiler has to know a few things.
> 
And thus the Fragile Base Class is born.
-- 
http://www.dazsi.com
Note: my e-mail address has been altered to
confuse the enemy. The views I express are
mine alone (unless you agree with me).
From: Fergus Henderson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5mm1da$9sl@mulga.cs.mu.OZ.AU>
········@wat.hookup.net writes:

>Franksen <········@bii.bessy.de> writes:
>> ...
>>I am not very astonished. These features have nothing to do with OO, in
>>Modula2 you can do the same with ADTs instead of classes. Data
>>encapsulation is even better: in C++ you are forced to reveal all
>>private data members to the rest of the world, whereas in a good
>>modularised procedural language you can keep them totally secret. What
>
>You would neet a very secure file system to keep the private parts really
>secret.  And why is it such a big deal? As long as the language enforces
>sticking to the published interface it can't really hurt to make the other
>details open to inspection.

Agreed, keeping the implementation details secret is not such a big deal.

However, keeping the implementation details _seperate_ is a big deal.
C++ doesn't do a very good job of that: header files are a mixture
of interface and implementation details, and the implementation details
for a module are split between the header file and the source file
for that module.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: John DiCamillo
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <milodEB09BC.J1I@netcom.com>
···@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
>········@wat.hookup.net writes:
>>Franksen <········@bii.bessy.de> writes:

>>>I am not very astonished. These features have nothing to do with OO, in
>>>Modula2 you can do the same with ADTs instead of classes. Data
>>>encapsulation is even better: in C++ you are forced to reveal all
>>>private data members to the rest of the world, whereas in a good

No, you are not.

>>>modularised procedural language you can keep them totally secret. What

>>You would neet a very secure file system to keep the private parts really
>>secret.  And why is it such a big deal? As long as the language enforces
>>sticking to the published interface it can't really hurt to make the other
>>details open to inspection.

>Agreed, keeping the implementation details secret is not such a big deal.

>However, keeping the implementation details _seperate_ is a big deal.
>C++ doesn't do a very good job of that: header files are a mixture
>of interface and implementation details, and the implementation details
>for a module are split between the header file and the source file
>for that module.

Only if the programmer wants to include private details in the header.
There are two common solutions to this "problem":  use an abstract
base class that has no private members;  or place the private members
in an incomplete structure and declare a private reference to them.

  class  Gen;
  struct Genitalia;

  class Gen {
  public:
     // the public interface

  private:
     Genitalia& dont_touch_me_here;
  };

-- 
    ciao,
    milo
================================================================
    John DiCamillo                         Fiery the Angels Fell 
    ·····@netcom.com       Deep thunder rode around their shores
From: Stefan Monnier
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5lraeni363.fsf@tequila.systemsz.cs.yale.edu>
·····@netcom.com (John DiCamillo) writes:
> Only if the programmer wants to include private details in the header.
> There are two common solutions to this "problem":  use an abstract
> base class that has no private members;  or place the private members
> in an incomplete structure and declare a private reference to them.

The first alternative forces the use of inheritance which might force
(depending on how much global analysis is done by your compiler) the use of
virtual method calls.

The second alternative might (very likely) force the compiler to introduce
an indirection.

So much for C++ being efficient !


        Stefan
From: Fergus Henderson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5mr5a0$pek@mulga.cs.mu.OZ.AU>
·····@netcom.com (John DiCamillo) writes:

>···@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
>>... keeping the implementation details _seperate_ is a big deal.
>>C++ doesn't do a very good job of that: header files are a mixture
>>of interface and implementation details, and the implementation details
>>for a module are split between the header file and the source file
>>for that module.
>
>Only if the programmer wants to include private details in the header.
>There are two common solutions to this "problem":  use an abstract
>base class that has no private members;  or place the private members
>in an incomplete structure and declare a private reference to them.

Yes, but both of these solutions have big efficiency costs,
because they require dynamic allocation and prevent inlining.
Most C++ implementations are currently not capable of optimizing any
of these costs away, and are not likely to become so anytime in the
near future.

Also the dynamic allocation complicates things.  With your first solution,
the burden of memory management is placed on the user.  With your second
solution, the memory management can be encapsulated in the class, but
it is still a little bit cumbersome.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Benjamin Franksen
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <338F20FC.3490@bii.bessy.de>
········@wat.hookup.net wrote:
> 
> Benjamin Franksen <········@bii.bessy.de> writes:
> > ...
> >I am not very astonished. These features have nothing to do with OO, in
> >Modula2 you can do the same with ADTs instead of classes. Data
> >encapsulation is even better: in C++ you are forced to reveal all
> >private data members to the rest of the world, whereas in a good
> >modularised procedural language you can keep them totally secret. What
> 
> You would neet a very secure file system to keep the private parts really
> secret.  And why is it such a big deal?  As long as the language enforces
> sticking to the published interface it can't really hurt to make the other
> details open to inspection.  For various optimizattions and inlining the
> compiler has to know a few things.

I think you didn't get my point. I thought it was common knowledge that
information hiding in the context of programming languages has nothing
to do with secret service activities whatsoever. ;)

The point is that revealing parts of the class implementation in the
interface definition (as happens naturally in C++) has some
disadvatages, mainly:

1) As i pointed out, it is no longer possible to replace the
implementation without (at least) recompiling every module that depends
on our class. That is: separate compilation is no longer possible.

2) It tends to make the user think about wrong things: if your class is
really intended to be (maybe among other things) an abstract data type,
then parts of the implementation that the user can see are just a
diversion.

But i agree with Fergus Henderson, that at least _separation_ of
interface and implementation would be a great step forward (for C++,
understood).

Anyway: this discussion has really _nothing_ to do with
comp.lang.scheme, comp.lang.lisp and comp.lang.functional. Therefore i
am going to post this answer only to comp.lang.misc and comp.lang.c++.
(What about another thread?)

	Ben
-- 
The Notorious Neb Nesknarf
// snail: BESSY II, Rudower Chaussee 5, D-12489 Berlin, Germany
// email: ········@bii.bessy.de
// phone/fax: +49(30)6392-4865 / 6392-4859
From: Benjamin Franksen
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <338F3D88.103A@bii.bessy.de>
> Anyway: this discussion has really _nothing_ to do with
> comp.lang.scheme, comp.lang.lisp and comp.lang.functional. Therefore i
> am going to post this answer only to comp.lang.misc and comp.lang.c++.

Well, actually i forgot to _do_ it...

	Ben
-- 
The Notorious Neb Nesknarf
// snail: BESSY II, Rudower Chaussee 5, D-12489 Berlin, Germany
// email: ········@bii.bessy.de
// phone/fax: +49(30)6392-4865 / 6392-4859
From: Silvio Bierman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <01bc6e09$b747ac60$e557b2c2@silvio>
Benjamin Franksen <········@bii.bessy.de> wrote in article
<·············@bii.bessy.de>...
> ········@wat.hookup.net wrote:
> > 
> > Benjamin Franksen <········@bii.bessy.de> writes:
> > > ...
> > >I am not very astonished. These features have nothing to do with OO,
in
> > >Modula2 you can do the same with ADTs instead of classes. Data
> > >encapsulation is even better: in C++ you are forced to reveal all
> > >private data members to the rest of the world, whereas in a good
> > >modularised procedural language you can keep them totally secret. What
> > 
> > You would neet a very secure file system to keep the private parts
really
> > secret.  And why is it such a big deal?  As long as the language
enforces
> > sticking to the published interface it can't really hurt to make the
other
> > details open to inspection.  For various optimizattions and inlining
the
> > compiler has to know a few things.
> 
> I think you didn't get my point. I thought it was common knowledge that
> information hiding in the context of programming languages has nothing
> to do with secret service activities whatsoever. ;)
> 
> The point is that revealing parts of the class implementation in the
> interface definition (as happens naturally in C++) has some
> disadvatages, mainly:
> 
> 1) As i pointed out, it is no longer possible to replace the
> implementation without (at least) recompiling every module that depends
> on our class. That is: separate compilation is no longer possible.
> 
> 2) It tends to make the user think about wrong things: if your class is
> really intended to be (maybe among other things) an abstract data type,
> then parts of the implementation that the user can see are just a
> diversion.
> 
> But i agree with Fergus Henderson, that at least _separation_ of
> interface and implementation would be a great step forward (for C++,
> understood).
> 
> Anyway: this discussion has really _nothing_ to do with
> comp.lang.scheme, comp.lang.lisp and comp.lang.functional. Therefore i
> am going to post this answer only to comp.lang.misc and comp.lang.c++.
> (What about another thread?)
> 
> 	Ben
> -- 
> The Notorious Neb Nesknarf
> // snail: BESSY II, Rudower Chaussee 5, D-12489 Berlin, Germany
> // email: ········@bii.bessy.de
> // phone/fax: +49(30)6392-4865 / 6392-4859
> 

C++ allows the private parts of a class to be in the declaration but if it
bothers you for some reason, you can easily hide it in the implementation
source at the cost of one extra allocation and deallocation for each
created object, and one extra indirection for every hidden member that is
accessed (which is always there in languages which chose to go the Modula3
way).

//X.H:

class X
{
class repr;
repr *rep;
public:
   int foo();
   float bar(int);
   //...
public:
   X();
   ~X();
};

//X.CPP

class X::repr
{
   int foo;
   float bar;
};

int X::foo() { return rep->m_foo; }

float X::bar(int n) { return n * rep->bar; }

X::X() : rep(new repr) { /*...*/ }

X::~X() { delete rep; }

//EOF.

The nested class mechanism enables picking a standard name for these
representation classes, so user can get customed to these kinds of header
files. The extra indirection (and allocation/deallocation) may hurt when
speed is essential, but this is the preferred way to keep build-times
limited on larger projects.

Silvio Bierman
From: Richard A. O'Keefe
Subject: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5lu7ar$2uf$1@goanna.cs.rmit.edu.au>
One of the things that was discussed in the "C++ briar patch" thread
was that Stepanov wanted to provide an *efficient* library, and that
C++ turned out to be the most practical choice for the job.  I'm NOT
disputing that point here.  For the purposes of _this_ thread, let's
stipulate that C++ is an excellent choice for the STL, and that once
you've chosen C++, the current STL is an excellent way to write code
that is acceptably efficient.

Just how efficient _is_ that?  That's my question.  It would take so
much work to do a really thorough comparison that I hope Stroustrup,
Stepanov, and all the good people who have worked on C++, G++, STL &
so on are not offended by my having spent a day's effort on just one
benchmark.

The benchmark is a mildly interesting one:
    given two text files A and B,
    list the words that occur at least once in A but not at all in B.
This is, of course, the guts of a very crude spelling checker.

Here's the algorithm:
    read all the words from file A into a list La.
    read all the words from file B into a list Lb.
    sort La eliminating duplicates.
    sort Lb eliminating duplicates.
    find the set difference of La and Lb.
    write that difference one word per line.

Of course this is not the most efficient way to do it, but it does
exercise sequences, sorting, duplicate elimination, set difference,
and strings.  It isn't as thorough as one would really like, but it
isn't _wholly_ unrealistic.

I timed four versions of the code:
  - A Scheme version using an existing generic set library
  - A Scheme version using a specialised copy of the set library functions
  - A straightforward C version using a singly linked list (but I hacked
    in an extra-fast allocator)
  - A C++ version using the STL files shipped with gcc 2.7.2.2.

The tests were done on an UltraSPARC running Solaris 2.4.  fpversion says
 CPU's clock rate appears to be approximately 158.0 MHz.
 Kernel says CPU's clock rate is 167.0 MHz.
 Kernel says main memory's clock rate is 83.0 MHz.
 FPU's frequency appears to be approximately 164.2 MHz.

The test files were made by catting great globs of info:

    cat /opt/gnu/info/emacs* > /tmp/EM
        1_201_163 bytes, 185_809 words, 27_844 lines.

    cat /opt/gnu/info/gcc* > /tmp/GC
        1_210_988 bytes, 176_125 words, 27_413 lines.

How the tests were done:

    Scheme version (Stalin 0.7)
        stalin-sun4m-SunOS-5.4 -cc gcc -copt -O6 -Ob -On word-test
        word-test /tmp/{EM,GC} | tail
    C version (gcc 2.7.2.2)
        gcc -O6 wds.c
        a.out /tmp/{EM,GC} | tail
    C++ version (g++ 2.7.2.2)
        g++ -O6 wds.cpp
        a.out /tmp/{EM,GC} | tail

The numbers (times in seconds as reported by clock()):

    Results             Scheme1         Scheme2         C               C++
    reading             1.68            1.70            0.56            2.15
    sorting             2.99            2.75            0.77  5.64+1.52=7.16
    matching            0.03            0.03            0.01            0.03
    writing             0.00            0.00            0.00            0.24
    total               4.70            4.48            1.34            9.58

    Lines               57              124             233             92

Scheme1: uses generic set library (comparison function is an argument).
Scheme2: uses a specialised version (comparison function is always string<?)
         plus it was hacked a bit to try to make it faster.  Note that
         run-time type checking was *NOT* disabled.

C:       straightforward singly linked list code, plus a specially hacked
	 fast allocator.  That only affects the reading time.  The sorting
	 and matching code uses strcmp(), whereas the Scheme code has to
	 use string<? and the C++ has to use string::operator<, which could
	 be up to a factor of 2 advantage for C.

C++:	 uses <string>, <list>, <iterator>, and <algorithm>
	 I must say I prefer
	    (ord-difference! L1 L2)
	 to
	    set_difference(W1.begin(), W1.end(), W2.begin(), W2.end(),
			   back_inserter(DF));
	 The Scheme and C versions use a sorting algorithm that discards
	 duplicates as it goes; there being no such algorithm in <list>
	 or <algorithm>, I had to use a .sort() (5.64 sec) followed by
	 .unique() (1.52 sec).

Note that the *same* compiler back end was used for all the programs:
Stalin compiles Scheme to C, which was then compiled by gcc.  Roughly
speaking,
	C : Scheme : C++
    ::  1 :   3.4  : 7.1			(total)
        1 :   3.6  : 9.2			(sorting+matching only)

The second line here avoids input/output issues.

This does not look like an advertisement for C++ ``efficiency'' to me.
I am sure the C++ code can be improved.  Point is, it is a simple and
straightforward use of the library facilities.

If anyone really wants to see the code, I can make it available, but
I am reluctant to do so until I have found out why the Scheme code
did so much worse than I expected.

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Ben Hanson
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <3382F359.4D0A@cristie.co.uk>
Richard A. O'Keefe wrote:
<snip>
> This does not look like an advertisement for C++ ``efficiency'' to me.
> I am sure the C++ code can be improved.  Point is, it is a simple and
> straightforward use of the library facilities.
> 
> If anyone really wants to see the code, I can make it available, but
> I am reluctant to do so until I have found out why the Scheme code
> did so much worse than I expected.

Very interesting.  How about a test that uses the MFC containers?! ;-\

Regards,

Ben
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5m0naa$2uq$1@goanna.cs.rmit.edu.au>
Ben Hanson <····@cristie.co.uk> writes:

>Richard A. O'Keefe wrote:
><snip>
>Very interesting.  How about a test that uses the MFC containers?! ;-\

Are they available for SPARC/Solaris?

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Boris Fomitchev
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <yfhg1vh7z8z.fsf@spirit.mcst.ru>
In article <············@goanna.cs.rmit.edu.au> 
··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

>How the tests were done:
>
>    Scheme version (Stalin 0.7)
>        stalin-sun4m-SunOS-5.4 -cc gcc -copt -O6 -Ob -On word-test
>        word-test /tmp/{EM,GC} | tail
>    C version (gcc 2.7.2.2)
>        gcc -O6 wds.c
>        a.out /tmp/{EM,GC} | tail
>    C++ version (g++ 2.7.2.2)
>        g++ -O6 wds.cpp
>        a.out /tmp/{EM,GC} | tail
...
>Note that the *same* compiler back end was used for all the programs:
>Stalin compiles Scheme to C, which was then compiled by gcc.  Roughly
>speaking,
>	C : Scheme : C++
>    ::  1 :   3.4  : 7.1			(total)
>        1 :   3.6  : 9.2			(sorting+matching only)
>
>The second line here avoids input/output issues.

The same backend is not sufficient : gcc-2.7.2 is known to be _very_
bad on inlining templates ( the feature on which STL efficiency
relies). It is not capable to inline even iterator_category()
functions. If you recompile the code with, say, SunPro CC 4.2, you'll
probably get an order of magnitude improvement. 

>
>This does not look like an advertisement for C++ ``efficiency'' to me.
>I am sure the C++ code can be improved.  Point is, it is a simple and
>straightforward use of the library facilities.
Yes, after you choose appropriate compiler, you may try the same with
vector ( IMHO even more straightforward solution ). 

>
>If anyone really wants to see the code, I can make it available, but
>I am reluctant to do so until I have found out why the Scheme code
>did so much worse than I expected.

Yes, please post C++ code. I'll run it on Ultra with SunPro.

Best regards,
-- 
-Boris	*  [···@mcst.ru] * Opinions expressed here are mine alone.
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5m0mvu$2go$1@goanna.cs.rmit.edu.au>
···@spirit.mcst.ru (Boris Fomitchev) writes:
>The same backend is not sufficient : gcc-2.7.2 is known to be _very_
>bad on inlining templates ( the feature on which STL efficiency
>relies). It is not capable to inline even iterator_category()
>functions. If you recompile the code with, say, SunPro CC 4.2, you'll
>probably get an order of magnitude improvement. 

There are a number of things to say about that.
I think the most important is that it is a completely fair test
of what is available to *me* today.
Any advocate of any language can play "oh, you should use a better
compiler, there'll be one along in a few years" games.
A fair test is one that uses compilers available NOW.

If I had not wanted to be fair, I would have used SunPro C 4.2 as
the compiler for the C version of the test.

Another one is that I *DID* try recompiling the code with SunPro CC 4.2.
Here's what it said:
"wds.cpp", line 3: Error: Could not open include file <string>.
"wds.cpp", line 4: Error: Could not open include file <cstdlib>.
"wds.cpp", line 6: Error: Could not open include file <list>.
"wds.cpp", line 8: Error: Could not open include file <iterator>.
"wds.cpp", line 9: Error: Could not open include file <algorithm>.

Stepanov kindly told me where I could find a version of the STL that
has been hacked to support a number of compilers (isn't that rather
back to front?) and I _have_ downloaded it, and _do_ mean to try it
out, but I haven't had the time to unpack and install it yet.

>Yes, please post C++ code. I'll run it on Ultra with SunPro.

Ok, here's the C++.  There are a number of things I want to try with
the Scheme code.  (Telling the compiler not to emit type checking code
made so little difference that it was lost in the noise.  The main thing
to try is a different string comparison function.)  From my use of stdio
instead of iostreams, you may be able to estimate how long I've been
using C++.

cat >wds.cpp <<'------ EOF ------'
#include <iostream.h>
#include <stdio.h>
#include <string>
#include <cstdlib>
#include <ctype.h>
#include <list>
#include <time.h>
#include <iterator>
#include <algorithm>

typedef list<string> word_list;

void read_words(char const *File, word_list &result) {
    register FILE *f;
    register int c;
    register char *p;
    char buff[81];

    f = fopen(File, "r");
    if (f == 0) {
	fprintf(stderr, "Cannot open %s\n", File);
	exit(EXIT_FAILURE);
    }
    for (;;) {
	do c = getc(f); while (c != EOF && !isalpha(c));
	if (c == EOF) break;
	p = buff;
	do *p++ = c, c = getc(f); while (c != EOF && isalpha(c));
	*p = '\0';
	result.push_front(string(buff));
    }
    fclose(f);
}


double time_in_seconds(void) {
    return clock()/(double)(CLOCKS_PER_SEC);
}

int main(int argc, char **argv) {
    double T0 = time_in_seconds();

    word_list W1;
    read_words(argv[1], W1);
    word_list W2;
    read_words(argv[2], W2);
    printf("W1 has %ld words\n", (long)W1.size());
    printf("W2 has %ld words\n", (long)W2.size());

    double T1 = time_in_seconds();

    /*  This was *supposed* to be a test of the sort() algorithm in
	<algorithm>, but that demands RandomAccessIterators, heaven
	only knows why.  It therefore provded necessary to use the
	list::sort method instead.
    */
    W1.sort();
    W2.sort();
    /*  However, we _can_ use the unique() algorithm, which only
	requires ForwardIterators.  Or at least we _ought_ to be
	able to, but g++_ reports that operator!= is ambiguous,
	and I haven't a clue what to do about it.
    */
    W1.unique();
    W2.unique();
//  printf("W1 has %ld words\n", (long)W1.size());
//  printf("W2 has %ld words\n", (long)W2.size());

    double T2 = time_in_seconds();

    word_list DF;
    /*  set_difference(..., DF.begin()) was the obvious thing to try,
        but it *quietly* produced an empty set.
    */
    (void) set_difference(W1.begin(), W1.end(),
			  W2.begin(), W2.end(), back_inserter(DF));
    printf("DF has %ld words\n", (long)DF.size());

    double T3 = time_in_seconds();

//  word_list::iterator W;
//  for (W = DF.begin(); W != DF.end(); W++) cout << *W << endl;

    double T4 = time_in_seconds();

    printf("reading     %8.3f\n", T1-T0);
    printf("sorting     %8.3f\n", T2-T1);
    printf("matching    %8.3f\n", T3-T2);
    printf("writing     %8.3f\n", T4-T3);
    printf("TOTAL      %9.3f\n",  T4-T0);
    return 0;
}
------ EOF ------
-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Darin Johnson
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <slrn5obnpd.slo.darin@connectnet1.connectnet.com>
In article <············@goanna.cs.rmit.edu.au>, Richard A. O'Keefe wrote:
>Any advocate of any language can play "oh, you should use a better
>compiler, there'll be one along in a few years" games.
>A fair test is one that uses compilers available NOW.

Hey, now you're not playing fair!  Surely you know that every single
criticism of STL (and other advanced features) can be deflected via
"get a better compiler"?

-- 
Darin Johnson
·····@usa.net.delete_me
From: Matt Kennel (Remove 'nospam' to reply)
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <slrn5oumbn.o9b.kennel@lyapunov.ucsd.edu>
On 23 May 1997 18:15:53 GMT, Darin Johnson <·····@usa.net.delete_me> wrote:
:In article <············@goanna.cs.rmit.edu.au>, Richard A. O'Keefe wrote:
:>Any advocate of any language can play "oh, you should use a better
:>compiler, there'll be one along in a few years" games.
:>A fair test is one that uses compilers available NOW.
:
:Hey, now you're not playing fair!  Surely you know that every single
:criticism of STL (and other advanced features) can be deflected via
:"get a better compiler"?

It's astonishing that it's the apologists of the 
"mainstream commercial language" is the one that must make this cry.  

Shouldn't it be the other way around? 

-- 
Matthew B. Kennel/Institute for Nonlinear Science, UCSD/
Don't blame me, I voted for Emperor Mollari. 
From: Bill House
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <01bc65f2$fade60a0$03d3c9d0@wjh_dell_133.dazsi.com>
Why not try the Scheme test with a Scheme that compiles directly to native?

Bill House
-- 
http://www.dazsi.com
Note: my e-mail address has been altered to
confuse the enemy. The views I express are
mine alone (unless you agree with me).
From: Fergus Henderson
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5m0m9t$t0f@mulga.cs.mu.OZ.AU>
"Bill House" <······@dazsi.nospam.com> writes:

>Why not try the Scheme test with a Scheme that compiles directly to native?

From what I have heard, the Scheme compiler that Richard O'Keefe used,
namely Stalin, generates very good code; it probably beats other Scheme
compilers even though they might compile directly to native code.

Compiling via C isn't necessarily less efficient than compiling
directly to native code.  Although it does have some small overheads,
the developer(s) may be able to use the time saved from not writing
lots of different architecture-specific backends to implement additional
front-end optimizations with bigger payoffs.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Bill House
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <01bc6718$996c0300$03d3c9d0@wjh_dell_133.dazsi.com>
Fergus Henderson <···@mundook.cs.mu.OZ.AU> wrote in article
<··········@mulga.cs.mu.OZ.AU>...
> 
> From what I have heard, the Scheme compiler that Richard O'Keefe used,
> namely Stalin, generates very good code; it probably beats other Scheme
> compilers even though they might compile directly to native code.
> 
Demonstrating that point is also a very good reason to include a native Scheme
compiler in the test. ;-)

Bill House
-- 
http://www.dazsi.com
Note: my e-mail address has been altered to
confuse the enemy. The views I express are
mine alone (unless you agree with me).


Fergus Henderson <···@mundook.cs.mu.OZ.AU> wrote in article
<··········@mulga.cs.mu.OZ.AU>...
> "Bill House" <······@dazsi.nospam.com> writes:
> 
> >Why not try the Scheme test with a Scheme that compiles directly to native?
> 
> From what I have heard, the Scheme compiler that Richard O'Keefe used,
> namely Stalin, generates very good code; it probably beats other Scheme
> compilers even though they might compile directly to native code.
> 
> Compiling via C isn't necessarily less efficient than compiling
> directly to native code.  Although it does have some small overheads,
> the developer(s) may be able to use the time saved from not writing
> lots of different architecture-specific backends to implement additional
> front-end optimizations with bigger payoffs.
> 
> --
> Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
> WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
> PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
> 
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5m3dis$3k7$1@goanna.cs.rmit.edu.au>
"Bill House" <······@dazsi.nospam.com> writes:

>Why not try the Scheme test with a Scheme that compiles directly to native?

Because the only such Scheme I currently have installed is MacGambit,
and I haven't got a C++ compiler for either Macintosh.  The point was
to see what Scheme, C, or C++ would buy _me_ TODAY.

By the way, the Scheme results have since been improved.

The interesting thing is that I originally set out to demonstrate the
impact of a design decision in the STL which I regard as dubious, and
that decision is also present in Scheme.  The design decision is make
all comparison-based algorithms use exclusively a BOOLEAN-valued test.
This roughly DOUBLES the cost of any merging-based algorithm, because
it takes 2(M+N)+O(1) comparisons instead of M+N+O(1).  In all honesty,
what I *really truly genuinely expected* from the plain C -vs- C++STL
comparison was that the matching part would be roughly twice as slow
in C++STL as in C.  I also expected that the sorting and matching
phases in Scheme would be about twice as slow as the C versions, for
the same reason.  Scheme has
	(string<? x y)
	(string<=? x y)
	(string>? x y)
	(string>=? x y)
	(string=? x y)
but no analogue of strcmp().  Well, Jeff Siskind pointed out to me
that string<? is not really built into Stalin; Stalin actually handles
it by compiling user-level Scheme code.  He pointed out that this meant
I could write a (string-compare x y) in Scheme, and offered model code.
This actually reduced the sort + match time from
	2.78 seconds
to	1.60 seconds
Now, replacing code like
	(if (string<? x y) L
	    (if (string<? y x) G
		E))
by	(let ((c (string-compare x y)))
	    (cond ((< c 0) L)
		  ((> c 0) G)
		  (else    E)))
means replacing an average of 1.5 calls to string<? with 1 call to
string-compare.  Actually, it's better than that, because the test
data have lots of equality cases, so it's closer to replacing two
calls with one.  So, roughly speaking, that the time
	0.4 seconds list processing and other book-keeping
	1.2 seconds string comparison (new version)
	2.4 seconds string comparison (old version)
and since the C strcmp() function _is_ specially coded library stuff
which, if I am reading the disassembled code correctly, ought to be
able to gulp down 4 bytes at a time instead of the 1 at a time that
the Scheme code does, I'd expect that to be about 4 times as fast as
string-compare.  If that _were_ the case, the C string comparison time
would be about 0.4 seconds, making the C time estimate 0.8 seconds,
close enough to the actual measurement.

So for the sorting and matching part, comparing Scheme -vs- C, we find

 - factor of two for using (string<? x y) twice instead of
   (string-compare x y) once.  THIS ALSO APPLIES TO THE DESIGN OF THE
   INTERFACES IN THE C++ STL.

 - factor of up to four for using one-byte-per loop (string-compare x y)
   instead of C library strcmp().

There are two conclusions there for Scheme:

A) If there is a T<? function, there ought to be a T-compare function.

B) String comparisons really want to be implemented as top notch library
   code.

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Matt Austern
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <fxtyb8ztvp4.fsf@isolde.mti.sgi.com>
··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

> The interesting thing is that I originally set out to demonstrate the
> impact of a design decision in the STL which I regard as dubious, and
> that decision is also present in Scheme.  The design decision is make
> all comparison-based algorithms use exclusively a BOOLEAN-valued test.

Yes, that was a dubious design decision.  In fact, I'd go so far as to
simply say "wrong".  Three-way comparisons are sometimes much
better than two-way.

(The original version of the STL, before it was incorporated into the
C++ standard, did have algorithms with both two-way and three-way
comparisons.  When it was made part of the standard, though, features
were removed.  This wasn't the only useful feature tobe taken out.)

It's easy to construct test cases that show three-way comparisons to
be much better than two-way.  It's also easy, of course, to construct
test cases that show exactly the opposite.  A good library ought to
provide both.
From: Hans-Juergen Boehm
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <33833DD7.41C6@mti.sgi.com>
Richard A. O'Keefe wrote:

> Note that the *same* compiler back end was used for all the programs:
> Stalin compiles Scheme to C, which was then compiled by gcc.  Roughly
> speaking,
>         C : Scheme : C++
>     ::  1 :   3.4  : 7.1                        (total)
>         1 :   3.6  : 9.2                        (sorting+matching only)

It would help if you posted output from an execution profiler as well. 
It would also be nice to make the source available, so that it could be
compared to results with different C++ compilers.

There are many things that could have gone wrong in the C++ case, some
of which have been pointed out:

1) String swapping could be expensive.  (If the standard library shipped
with g++ was used, this is unlikely, I think.  This is not one of its
problems.)

2) My understanding is that g++ 2.7.X can just barely compile a
simplified version of the STL.  It takes some performance hits in the
process (e.g. allocation is slower).  G++ 2.8 is likely to do
significantly better.

3) Many C++ string classes are generic in the character type.  This
shouldn't slow things down with a good C++ implementation.  But
currently it often does.  In particular, string comparison tends to
suffer. 

4) Many current implementations of C++ I/O have significant performance
problems.

If the point was that current C++ implementations don't necessarily give
you reasonable performance with STL, I agree completely.  (I'll
personally also agree with many other criticisms of C++ and especially
existing implementations.)

But I still believe that STL-like libraries have a great deal of
potential.  The C++ instantiation has a number of problems, including
the fact it is essentially impossible to diagnose errors in invoking STL
templates without referring to STL internals, and performance problems
with existing compilers.
 
-- 
This is my personal opinion ...
Hans-Juergen Boehm
·····@mti.sgi.com
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5m3ged$7ll$1@goanna.cs.rmit.edu.au>
Hans-Juergen Boehm <·····@mti.sgi.com> writes:

>Richard A. O'Keefe wrote:

>> Note that the *same* compiler back end was used for all the programs:
>> Stalin compiles Scheme to C, which was then compiled by gcc.  Roughly
>> speaking,
>>         C : Scheme : C++
>>     ::  1 :   3.4  : 7.1                        (total)
>>         1 :   3.6  : 9.2                        (sorting+matching only)

>It would help if you posted output from an execution profiler as well. 

So it would.  Unfortunately,
 - I have spent hours trying to get the code to compile with Sun's C++
   compiler and failed,
 - there seems to be some sort of local installation/configuration
   problem with gcc and g++ which means that g++ -p fails.  (This tends
   to happen every time we install a new release.)
 - the execution profiler for Scheme would be "cc -p", but the function
   names in the generated code bear no discernable relation to the names
   in the source (or, for that matter, to the _existence_ of functions
   in the source; the Scheme compiler likes to take things apart and
   put them together in surprising ways).

>It would also be nice to make the source available, so that it could be
>compared to results with different C++ compilers.

I have posted the C++ code.  I was hoping to get it going with Sun's
compiler, using the Sun port of the STL that Stepanov kindly told me
the location of, but failed.

>There are many things that could have gone wrong in the C++ case, some
>of which have been pointed out:

All of which are none of my business.
MY question was "does the STL buy me efficiency today",
and the answer is "no it doesn't."
*WHY* it didn't is someone else's problem.

>1) String swapping could be expensive.  (If the standard library shipped
>with g++ was used, this is unlikely, I think.  This is not one of its
>problems.)

It _was_ library shipped with g++, it _doesn't_ have that problem, and
the sorting algorithm was list::sort(), which as far as I can see doesn't
do any swapping anyway.

>2) My understanding is that g++ 2.7.X can just barely compile a
>simplified version of the STL.  It takes some performance hits in the
>process (e.g. allocation is slower).  G++ 2.8 is likely to do
>significantly better.

Gee, I dunno about you, but I for one am heartily sick of
"jam tomorrow".  When is it going to be "jam TODAY?"
Whatever it's faults, g++ does at least COMPILE the bloody thing SOMEHOW.
Sun's compiler can't even manage that.  (More jam tomorrow.  Supposedly
a good compiler, SOME day it will be within hailing distance of the
draft standard, but RIGHT NOW IT ISN'T.)

>3) Many C++ string classes are generic in the character type.

And the one in libg++ is, just like the draft standard says.
I have really been pleasantly surprised by g++.

>In particular, string comparison tends to suffer. 

So?  What can _I_ do about that?

>4) Many current implementations of C++ I/O have significant performance
>problems.

Yeah.  Well, I'm not actually all that clued up about C++ IO, frankly.
When I timed the writing phase, I used cout, but the reading phase was
the *SAME* C <stdio.h> code that I used in the C version.  The cost
difference there _has_ to be some sort of fairly major overheads in
strings.

>If the point was that current C++ implementations don't necessarily give
>you reasonable performance with STL, I agree completely.

And THAT is all I claim.
There is no jam TODAY.

>But I still believe that STL-like libraries have a great deal of
>potential.

Why, so do I!

But when will there be jam TODAY?
-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Hans-Juergen Boehm
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <33861832.41C6@mti.sgi.com>
Richard A. O'Keefe wrote:
> 
> Hans-Juergen Boehm <·····@mti.sgi.com> writes:
> 
> >Richard A. O'Keefe wrote:
> 
> >> Note that the *same* compiler back end was used for all the programs:
> >> Stalin compiles Scheme to C, which was then compiled by gcc.  Roughly
> >> speaking,
> >>         C : Scheme : C++
> >>     ::  1 :   3.4  : 7.1                        (total)
> >>         1 :   3.6  : 9.2                        (sorting+matching only)
> 

> MY question was "does the STL buy me efficiency today",
> and the answer is "no it doesn't."
> *WHY* it didn't is someone else's problem.
> 
I think the answer is "it depends".  See below.

Perhaps we can agree on some things:

1) As I've stated before, the current state of the C++ language
definition and of implementations is not satisfactory.  This is
particularly true for the features needed to support STL, which are
young by Scheme standards.  It's less true of the older features
(members, destructors, inheritance etc.), which I haven't found terribly
useful.  (It's probably also an issue with newer features like RTTI,
which I also haven't found useful.  I haven't tried.)

2) C++ code that uses the features of C++ I find interesting is not
normally portable at this point.  Making it portable is hard.  For code
that has to run quickly on every conceivable platform, I would currently
use C, not C++.

3) This benchmark excercises several areas that are particularly weak:

a) The "standard" C++ string class has many problems, which have been
discussed before.  The implementations vary from problematic (g++) to
nonexistent (ours).  (Well none that we recommend you use, anyway.)

b) It uses doubly linked lists as the container type in C++.  That's not
a great data structure choice for the problem anyway.  Vectors would
work better.  It's also not what's used in C and Scheme, I suspect.

c) There is no particular reason to use C++ strings anyway.  STL
containers should work fine with C strings.  Unfortunately,  sorting
lists of C strings is often painful today because of compiler
restrictions on template members.  

I quickly rewrote the benchmark using C strings, vectors, and my (SGI
Indy, SGI C++ 7.1) environment.  I get about a factor of 4 speedup for
the sorting phase.  (The input phase is pretty sloppy.  It should just
read the whole file into a buffer, and insert NULs instead of
reallocating piecemeal.)

Here's the new version.  (No guarantees about correctness.  I do
guarantee it's not portable.)

#include <iostream.h>
#include <stdio.h>
#include <rope.h>
#include <stdlib.h>
#include <ctype.h>
#include <vector.h>
#include <time.h>
#include <iterator.h>
#include <algo.h>

typedef char *string;

typedef vector<string> word_list;



void read_words(char const *File, word_list &result) {
    register FILE *f;
    register int c;
    register char *p;
    char buff[81];

    f = fopen(File, "r");
    if (f == 0) {
        fprintf(stderr, "Cannot open %s\n", File);
        exit(EXIT_FAILURE);
    }
    for (;;) {
        do c = getc(f); while (c != EOF && !isalpha(c));
        if (c == EOF) break;
        p = buff;
        do *p++ = c, c = getc(f); while (c != EOF && isalpha(c));
        *p = '\0';
        result.push_back(strdup(buff));
    }
    fclose(f);
}


double time_in_seconds(void) {
    return clock()/(double)(CLOCKS_PER_SEC);
}

struct sl : binary_function<char *, char *, bool> {
    bool operator()(char *x, char *y) { return strcmp(x,y) < 0; }
} string_less;

struct se : binary_function<char *, char *, bool> {
    bool operator()(char *x, char *y) { return strcmp(x,y) == 0; }
} string_equal;

int main(int argc, char **argv) {
    double T0 = time_in_seconds();

    word_list W1;
    read_words(argv[1], W1);
    word_list W2;
    read_words(argv[2], W2);
    printf("W1 has %ld words\n", (long)W1.size());
    printf("W2 has %ld words\n", (long)W2.size());

    double T1 = time_in_seconds();

    /*  This was *supposed* to be a test of the sort() algorithm in
        <algorithm>, but that demands RandomAccessIterators, heaven
        only knows why.  It therefore provded necessary to use the
        list::sort method instead.
    */
    sort(W1.begin(), W1.end(), string_less);
    sort(W2.begin(), W2.end(), string_less);
    /*  However, we _can_ use the unique() algorithm, which only
        requires ForwardIterators.  Or at least we _ought_ to be
        able to, but g++_ reports that operator!= is ambiguous,
        and I haven't a clue what to do about it.
    */
    word_list::iterator W1last = unique(W1.begin(), W1.end(),
string_equal);
    word_list::iterator W2last = unique(W2.begin(), W2.end(),
string_equal);

//  printf("W1 has %ld words\n", (long)W1.size());
//  printf("W2 has %ld words\n", (long)W2.size());

    double T2 = time_in_seconds();

    word_list DF;
    /*  set_difference(..., DF.begin()) was the obvious thing to try,
        but it *quietly* produced an empty set.
    */
    (void) set_difference(W1.begin(), W1last,
                          W2.begin(), W2last, back_inserter(DF),
string_less);
    printf("DF has %ld words\n", (long)DF.size());

    double T3 = time_in_seconds();

//  word_list::iterator W;
//  for (W = DF.begin(); W != DF.end(); W++) cout << *W << endl;

    double T4 = time_in_seconds();

    printf("reading     %8.3f\n", T1-T0);
    printf("sorting     %8.3f\n", T2-T1);
    printf("matching    %8.3f\n", T3-T2);
    printf("writing     %8.3f\n", T4-T3);
    printf("TOTAL      %9.3f\n",  T4-T0);
    return 0;
}


-- 
Hans-Juergen Boehm
·····@mti.sgi.com
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mbjp9$2r4$1@goanna.cs.rmit.edu.au>
Hans-Juergen Boehm <·····@mti.sgi.com> writes:
>Perhaps we can agree on some things:

>1) As I've stated before, the current state of the C++ language
>definition and of implementations is not satisfactory.

This says it all.

Jam tomorrow.

>2) C++ code that uses the features of C++ I find interesting is not
>normally portable at this point.

Yeah, ditto.  I've been in touch with a couple of serious software
projects using C++.  None of the compilers available (and the two
projects together looked at about eight) came close to matching the
95 draft, and no two accepted the same language.  Porting between
compilers was a _major_ problem, and they had to solve the problem
by never using templates at all.

>3) This benchmark excercises several areas that are particularly weak:

So?  Jam tomorrow.

>a) The "standard" C++ string class has many problems, which have been
>discussed before.  The implementations vary from problematic (g++) to
>nonexistent (ours).  (Well none that we recommend you use, anyway.)

>b) It uses doubly linked lists as the container type in C++.  That's not
>a great data structure choice for the problem anyway.  Vectors would
>work better.  It's also not what's used in C and Scheme, I suspect.

I see absolutely no reason to expect vectors to work better.
Vectors are _worse_ for sorting in C++, because you have to invoke
copy constructors, swap() methods, and the like.  And recall that I
am not trying to evaluate C++ as such, but the STL.  The C and Scheme
code used singly linked lists.  If the standardised data structure has
higher overheads, that's a _relevant_ fact about the standard and using
it in a benchmark is fair.

>c) There is no particular reason to use C++ strings anyway.
[Claim 1]

Why not?  I used Scheme strings in Scheme.

And there most certainly *is* a reason to use C++ strings!
The whole thing hangs on string::operator <.  If I used C strings,
the less than operator would be doing entirely the wrong thing.
I was deliberately trying _not_ to bias things by forcing the
code to go through an extra comparison function!

>Unfortunately,  sorting
>lists of C strings is often painful today because of compiler
>restrictions on template members.  
[Claim 2]

It seems to me that Claim 2 contradicts Claim 1.


>I quickly rewrote the benchmark using C strings, vectors, and my (SGI
>Indy, SGI C++ 7.1) environment.  I get about a factor of 4 speedup for
>the sorting phase.

A factor of 4 speedup leaves us with the C++ code running 2 1/4 times
slower than the C code.  (This is also a different compiler.  It would
be interesting to see the numbers for the original code.  That might be
better too:  it might just be a better compiler.  Maybe SGI offer jam
today; it wouldn't be the first time.)

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Andrew Koenig
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <EAJGtK.Iu@research.att.com>
In article <············@goanna.cs.rmit.edu.au> ··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

> One of the things that was discussed in the "C++ briar patch" thread
> was that Stepanov wanted to provide an *efficient* library, and that
> C++ turned out to be the most practical choice for the job.  I'm NOT
> disputing that point here.  For the purposes of _this_ thread, let's
> stipulate that C++ is an excellent choice for the STL, and that once
> you've chosen C++, the current STL is an excellent way to write code
> that is acceptably efficient.

> Just how efficient _is_ that?  That's my question.  It would take so
> much work to do a really thorough comparison that I hope Stroustrup,
> Stepanov, and all the good people who have worked on C++, G++, STL &
> so on are not offended by my having spent a day's effort on just one
> benchmark.

Not at all.  But I wonder if you could check out one thing for me?

One of the hard things about benchmarking is being sure that what you're
measuring is actually what you thing you're measuring.

In this particular example, for instance, you measure how long it takes
to sort arrays of strings.  But is that really measuring how fast the
language is, or is it measuring how fast the particular sort implementation
or the particular string implementation is.

Knowing that strings are not part of STL, and knowing that Alex put quite
a bit of effort into making sort efficient, I would be inclined to suspect
that

	you are using a string library in which swapping two strings
	involves copying all the characters of both strings, and
	perhaps allocating additional memory as well, and

	the time spent doing so dominates the execution time of your
	benchmark

Now, the proposed standard string class offers a fast way of swapping
strings: if s1 and s2 are strings, then executing s1.swap(s2) interchanges
the contents of s1 and s2 and a good implementation will not do any memory
allocation to do so.

Moreover, STL is supposed to take advantage of such a swap by having the
library include a specialization:

	void swap(string& s, string& t)
	{
		s.swap(t);
	}

So my question is whether the string class being used in your benchmarks
has these useful implementation properties.

If it does not, I expect that you will find that replacing the string class
by one that implements swapping appropriately will make a dramatic difference
in the execution time of your benchmark.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Stephen Norman
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5lvdv3$n24@ds2.acs.ucalgary.ca>
In article <·········@research.att.com>,
Andrew Koenig <···@research.att.com> wrote:

[Commenting on data presented by Richard O'Keefe ... ]

>Not at all.  But I wonder if you could check out one thing for me?
>
>One of the hard things about benchmarking is being sure that what you're
>measuring is actually what you thing you're measuring.
>
>In this particular example, for instance, you measure how long it takes
>to sort arrays of strings.  But is that really measuring how fast the
>language is, or is it measuring how fast the particular sort implementation
>or the particular string implementation is.
>
>Knowing that strings are not part of STL, and knowing that Alex put quite
>a bit of effort into making sort efficient, I would be inclined to suspect
>that
>
>	you are using a string library in which swapping two strings
>	involves copying all the characters of both strings, and
>	perhaps allocating additional memory as well, and
>
>	the time spent doing so dominates the execution time of your
>	benchmark

I don't know if the experiment was conducted with the most recent version
of GNU libstdc++, which has an efficient reference-counting implementation
to the standard string class.  (An approximate implementation, I imagine,
given the state of the standardization process and the state of g++.)

I suspect that apparent poor performance comes from the inability of
the g++ 2.7.2 compiler to inline code generated from templates.
I suspect that if Mr. O'Keefe examined the code generated for his
C++ program, he would find it littered with call instructions that
a better compiler would have replaced with inline code.

--Steve Norman
  U of Calgary Dept of Electrical & Computer Engineering
  ······@enel.ucalgary.ca
From: Erik Naggum
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <3073246705972749@naggum.no>
* Stephen Norman
| I suspect that apparent poor performance comes from the inability of the
| g++ 2.7.2 compiler to inline code generated from templates.  I suspect
| that if Mr. O'Keefe examined the code generated for his C++ program, he
| would find it littered with call instructions that a better compiler
| would have replaced with inline code.

how is this argument any different from the argument that Lisp can be made
extremely efficient by a "sufficiently smart compiler"?  why are you C++
guys buying this argument when applied to C++ and vehemently object to it
when applied to Lisp?  "of course, C++ has to be fast, because it's heresy
in my religion to say that it isn't!"

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: Stephen Norman
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5m0i3r$nc2@ds2.acs.ucalgary.ca>
In article <················@naggum.no>, Erik Naggum  <····@naggum.no> wrote:
>* Stephen Norman
>| I suspect that apparent poor performance comes from the inability of the
>| g++ 2.7.2 compiler to inline code generated from templates.  I suspect
>| that if Mr. O'Keefe examined the code generated for his C++ program, he
>| would find it littered with call instructions that a better compiler
>| would have replaced with inline code.
>
>how is this argument any different from the argument that Lisp can be made
>extremely efficient by a "sufficiently smart compiler"?  why are you C++
>guys buying this argument when applied to C++ and vehemently object to it
>when applied to Lisp?  "of course, C++ has to be fast, because it's heresy
>in my religion to say that it isn't!"

I object to having the label "C++ guy" applied to me.  I was not
trying to make any point whatsover about Lisp, nor was I trying to say
anything about C++ and C++ implementations in general.

I was simply making an educated guess at why some STL code appeared to
be much slower than equivalent hand-coded C when compiled with *one
particular C++ compiler*, which is known to do a poor job at
generating efficient machine code from templates.

--Steve Norman
  U of Calgary Dept of Electrical & Computer Engineering
  ······@enel.ucalgary.ca
From: Erik Naggum
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <3073296251831122@naggum.no>
* Stephen Norman
| I was simply making an educated guess at why some STL code appeared to be
| much slower than equivalent hand-coded C when compiled with *one
| particular C++ compiler*, which is known to do a poor job at generating
| efficient machine code from templates.

and I was just noting that such explanations and rationalizations are
perfectly OK in the C++ world, where people will instantly look for a
better compiler or rationalize away the whole problem by "waiting for the
next version of compiler" or somesuch.  however, when an optimizable
construct is not optimized to its fullest, the common sentiment is not that
the Lisp compiler a bad choice, it's that _Lisp_ is slow.  I was commenting
on the asymmetrical attitude problem with respect to prejudice against slow
compilers and languages, that's all.

thanks for demonstrating that it's perfectly OK to blame the compiler in
the C++ world.  (if other compilers are so much better, just perform your
own comparison and post the results.  how hard can it be?)

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: Henry Baker
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <hbaker-2105971741190001@10.0.2.1>
In article <··········@ds2.acs.ucalgary.ca>, ······@enel.ucalgary.ca
(Stephen Norman) wrote:
> I don't know if the experiment was conducted with the most recent version
> of GNU libstdc++, which has an efficient reference-counting implementation
> to the standard string class.  (An approximate implementation, I imagine,
> given the state of the standardization process and the state of g++.)
> 
> I suspect that apparent poor performance comes from the inability of
> the g++ 2.7.2 compiler to inline code generated from templates.
> I suspect that if Mr. O'Keefe examined the code generated for his
> C++ program, he would find it littered with call instructions that
> a better compiler would have replaced with inline code.

The last time I tried gcc, it _was_ able to inline reference counting
increments and decrements.  gcc does inlining pretty late in the day, after
the code has already been converted into some sort of RTL.  This part of
the compiler is pretty slow, but because it is pretty much of a sledge-hammer,
it works most of the time.  So I would be very surprised if inlining had any
idea where the code came from -- templates or no.
From: Stephen Norman
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5m0ill$bbs@ds2.acs.ucalgary.ca>
In article <·······················@10.0.2.1>,
Henry Baker <······@netcom.com> wrote:
>In article <··········@ds2.acs.ucalgary.ca>, ······@enel.ucalgary.ca
>(Stephen Norman) wrote:
>> I suspect that apparent poor performance comes from the inability of
>> the g++ 2.7.2 compiler to inline code generated from templates.
>> I suspect that if Mr. O'Keefe examined the code generated for his
>> C++ program, he would find it littered with call instructions that
>> a better compiler would have replaced with inline code.
>
>The last time I tried gcc, it _was_ able to inline reference counting
>increments and decrements.  gcc does inlining pretty late in the day, after
>the code has already been converted into some sort of RTL.  This part of
>the compiler is pretty slow, but because it is pretty much of a sledge-hammer,
>it works most of the time.  So I would be very surprised if inlining had any
>idea where the code came from -- templates or no.

I don't know anything about gcc internals, but I did try an experiment.
I compiled the following file with g++ -O3 -S (max optimization, 
generate assembler as output):

  #include <list> // Use STL supplied with g++ 2.7.2

  void double_the_items(list<int>& the_list)
  {
    for (list<int>::iterator it = the_list.begin();
	 it != the_list.end(); 
	 ++it)
      *it *= 2;
  }

I observed four non-inlined function calls in the loop.  There are
only four function calls made in the loop, and all have very simple
definitions.  Inlining is not happening with this compiler and this
code.

--Steve Norman
  U of Calgary Dept of Electrical & Computer Engineering
  ······@enel.ucalgary.ca
From: Mike Haertel
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <slrn5oe23s.8hr.mike@ducky.net>
In article <·······················@10.0.2.1>, Henry Baker wrote:
>The last time I tried gcc, it _was_ able to inline reference counting
>increments and decrements.  gcc does inlining pretty late in the day, after
>the code has already been converted into some sort of RTL.  This part of
>the compiler is pretty slow, but because it is pretty much of a sledge-hammer,
>it works most of the time.  So I would be very surprised if inlining had any
>idea where the code came from -- templates or no.

I did some experiments with templates under GCC awhile back.  I recall
being disappointed with the code generated (some things I expected to
be inline were not), so I played around a bit.  What I found is that GCC
seems to have difficulty simultaneously instantiating and inlining
a template.  When I forced the templates to be instantiated before
they were used, GCC inlined things with no trouble.
From: David Hanley
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <3388A9DC.7100@nospan.netright.com>
Mike Haertel wrote:
> 
> I did some experiments with templates under GCC awhile back.  I recall
> being disappointed with the code generated (some things I expected to
> be inline were not), so I played around a bit.  What I found is that GCC
> seems to have difficulty simultaneously instantiating and inlining
> a template.  When I forced the templates to be instantiated before
> they were used, GCC inlined things with no trouble.

	I talked to one of the GCC programmers about this, when I was
writing a big C++ program that used templates.  He suggested
this:

inline int dummy()
{
    Stack<int> dummyIntStack;
}

int traverse( .. )
{ 
    Stack<int> intStackINeedToHaveInlined;
}

	Since the dummy function is inline and not called, 
it generates not code aside from it's template instantiation.
I did it.  It helped my code's speed *a lot*.  Especially 
since I was using numerical template specilization.

	The code-generate is not reentrant, basically.


	dave
From: Dave Mason
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <m1n2pjgyum.fsf@jupiter.scs.Ryerson.CA>
······@enel.ucalgary.ca (Stephen Norman) writes:

> I don't know if the experiment was conducted with the most recent version
> of GNU libstdc++, which has an efficient reference-counting implementation
> to the standard string class.  (An approximate implementation, I imagine,
> given the state of the standardization process and the state of g++.)
> 
> I suspect that apparent poor performance comes from the inability of
> the g++ 2.7.2 compiler to inline code generated from templates.
> I suspect that if Mr. O'Keefe examined the code generated for his
> C++ program, he would find it littered with call instructions that
> a better compiler would have replaced with inline code.

I find this truly amusing (and amazing!).

If a functional language person had said something about the slow
performance of a Scheme (say) program being because the particular
implementation didn't perform an obvious optimization that some other
compilers do, they would be laughed at as being poor losers!

In fairness to our slow cousin C++, the Scheme compiler used was one
of the best (though Richard *was* wondering why it produced such a
slow program), and it would be nice to see what the best C++ compiler
can do with the program.

../Dave
-- 
"Feminism:
   The belief (considered radical by some) that women are people, too."
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5m3f7f$5io$1@goanna.cs.rmit.edu.au>
···@research.att.com (Andrew Koenig) writes:

>Not at all.  But I wonder if you could check out one thing for me?

>One of the hard things about benchmarking is being sure that what you're
>measuring is actually what you thing you're measuring.

>In this particular example, for instance, you measure how long it takes
>to sort arrays of strings.

Ah, no.  I did say _lists_ of strings.

>But is that really measuring how fast the
>language is, or is it measuring how fast the particular sort implementation
>or the particular string implementation is.

I don't _care_.  The original thread from which my little test started
was the "I *had* to choose C++ as the implementation language for the
STL in order to get an _efficient_ library."  The obvious question is,
ok, so that rather inflammatory claim (it is inflammatory even if, or
indeed, especially if, it is true) was posted in comp.lang.scheme, so
*DOES* using the C++STL buy me efficiency NOW, TODAY, WITH THE SYSTEMS
AVAILABLE TO ME RIGHT NOW, compared with Scheme (same conditions), or
does it not.

The answer was "no it doesn't."

In fact, it's worse than that.  I promised to try it again with the
SunPro 4.2 C++ compiler.   Well, I did.  I downloaded the 1997-04-23
version of the STL from the web site that Stepanov kindly pointed me
to, unpacked it, ran configure, telling it to use Sun's CC (there are
about 13 language features from the standard that configure says 'no'
to when checking CC; I may be out by one or two, but it was a lot).
Then I tried to compile my test program.

Well, I couldn't.  SunPro C++ 4.2 does not come with a <string> header.
I tried using the one from g++, but that was a fairly massive failure.
We have the Rogue Wage library, version 7, which I haven't actually
used before.  So I plugged in an ifdef and a couple of macros to try
to use RWCString, and eventually got down to just these messages from
the compiler:

y% !C
CC -I/public/224/STL -I/opt/SUNWspro/SC4.2/include/CC/rw7/rw -DRW wds.cpp
"/public/224/STL/alloc.h", line 672: Warning (Anachronism):
__default_alloc_template::obj is not accessible from file level.
"/public/224/STL/alloc.h", line 672: Note: Type "CC -migration" for more
on anachronisms.

"/public/224/STL/algobase.h", line 188: Error: Too many arguments in call to
operator new(unsigned).
"wds.cpp",     Where: While instantiating "__list<RWCString,
__default_alloc_template<0, 0>>::make_node(const RWCString&)".
"wds.cpp",     Where: Instantiated from non-template code.
1 Error(s) and 1 Warning(s) detected.

With respect to the first message:
 - this version of the STL is *supposed* to have been ported to SunPro C++
   4.2, and the accompanying documentation claims that it just works.
With respect to the second message:
 - ditto!  This is unmodified STL code.  I have no idea what's going on
   or what I can do about this error message in what is *supposed* to be
   code that works with this compiler.

The code was written with some care to conform to the April 1995 draft
standard.  It was checked with similar care against the December 1996
draft standard which I recently picked up.  (I've forgotten who told me
where to find it.  Whoever you were, thank you very much.)

Now, when you put it all together, it took me longer to try to port this
C++ code from one compiler to another on the same system than it took me
to write the C or the Scheme code in the first place.  I say "try".  The
code doesn't work with Sun's compiler and I don't know why.  It is clear
that the easiest way to get it working would be to write my own string
class that implements just the operations I need.  Well, foo on that!

>Knowing that strings are not part of STL,

but they _are_ a part of the draft C++ standard,
even if the SunPro C++ compiler doesn't know that.

>and knowing that Alex put quite
>a bit of effort into making sort efficient,

I'm sure he did, BUT 

 - the vector sorting routine in the g++ version of the STL is a fairly
   naive quicksort, and

 - the vector sorting routine in the April 97 version that I was trying
   to use with SunPro C++ 4.2 is a slightly different version of quick-
   sort that
	- doesn't take care to stack the smaller subfile, so the call
	  stack can get cN deep.
	- doesn't seem to have taken on board any of the lessons from
	  the SP&E "Engineering a Sort" paper (e.g. it does a final
	  insertion sort pass, which is _not_ a good idea unless you
	  know you are sorting numbers, in which case there are better
	  things than quicksort, and it only uses median-of-three).
   Using simple clean code is THE RIGHT ENGINEERING DECISION, even if
   it means the efficiency isn't in the first rank.

 - the list sorting method in the April 97 version is a clean bottom-
   up merge that works on single-element chunks; it's clean, but you
   really don't have to try very hard to make it more efficient.  
   Given the fairly major implementation costs of trying to get any
   non-trivial C++ library code working under more than one compiler,
   providing simple clean code is THE RIGHT ENGINEERING DECISION at
   least until more compilers actually support the full language.  And
   when I say "more efficient", I'm talking about the 10--20% level,
   not order-of-magnitude or even large constant improvements.


>I would be inclined to suspect that

>	you are using a string library in which swapping two strings
>	involves copying all the characters of both strings, and
>	perhaps allocating additional memory as well, and

A) I said which C++ I was using: g++ 2.7.2.2.
B) Here's string::swap (actually basic_string::swap):

   void swap (basic_string &s) { charT *d = dat; dat = s.dat; s.dat = d; }

   charT here turns out to be plain char, so this does NOT involve
   copying all the characters OR allocating any memory

>	the time spent doing so dominates the execution time of your
>	benchmark

C) and in any case, I would expect a _list_ sort not to do any swapping
   anyway.

>So my question is whether the string class being used in your benchmarks
>has these useful implementation properties.

To the best of my understanding, it does.

>If it does not, I expect that you will find that replacing the string class
>by one that implements swapping appropriately will make a dramatic difference
>in the execution time of your benchmark.

Yeah, but <string> is part of the draft standard, and has been for over two
years.  A language where I have to rewrite basic parts of the libary in
order to get good performance is not a language that lends itself to the
development of efficient software.  (I am _not_ happy about the absence
of ternary comparison functions from Scheme either.  The tradition of
writing strcmp()-like functions, strongly encouraged by the qsort() and
bsearch() interfaces, is one of the things I like about C.)

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Andrew Koenig
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <EAMz60.2y1@research.att.com>
In article <············@goanna.cs.rmit.edu.au> ··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

> I don't _care_.  The original thread from which my little test started
> was the "I *had* to choose C++ as the implementation language for the
> STL in order to get an _efficient_ library."  The obvious question is,
> ok, so that rather inflammatory claim (it is inflammatory even if, or
> indeed, especially if, it is true) was posted in comp.lang.scheme, so
> *DOES* using the C++STL buy me efficiency NOW, TODAY, WITH THE SYSTEMS
> AVAILABLE TO ME RIGHT NOW, compared with Scheme (same conditions), or
> does it not.

> The answer was "no it doesn't."

First, let me note that I did not make the original claim -- Alex Stepanov
did.  And Alex wrote a generic algorithm library in Scheme long before
he even learned C++.

Second, although you may be reading this message in comp.lang.scheme,
I am posting it in comp.lang.c++, which is where I saw it.

Third, I should point out that although I don't use Scheme, and don't
know it particularly well, I like and respect what I do know of it.

OK ... now what about that benchmark?  Well, by itself it doesn't show
much of anything one way or the other.  Among the reasons:

1. What is the benchmark actually measuring?  That is, where are the two
programs spending their time?  In an earlier message, I suggested that
if there was a particular, simple, optimization missing from the C++
library you used, it might make a dramatic difference in execution
time.  Another possibility might be that the memory allocator on
your machine was horrendously slow -- many systems provide a really
slow allocator by default and allow the option of substituting a faster
one.  The reason the fast one isn't the default is that some C programs
assume that freeing memory doesn't change its contents (yecch!) and
they want to be compatible with that.  Or there might be some other
reason.  Any persuasive power that benchmark numbers have will come
from understanding what they really measure.

2. Are the programs comparable?  Lists in Scheme and C++ are substantially
different data structures -- for one thing, C++ lists allow traversal
forwards and backwards.  This suggests that some Scheme list operations
will be faster than the corresponding C++ list operations and others
will be slower.

3. Are the programs representative?  That is, are they typical of what
useful programs actually do?  By definition, a program that does only
one sharply defined task is probably not representative, which is one
of the things that makes useful benchmarks so difficult.  Another such
thing is that short-running programs in garbage-collected languages
have an apparent advantage that disappears as the programs run for
longer times, and that is that if the program never uses enough memory
to trigger the garbage collector, its execution time doesn't contribute
to the benchmark.

4. Is the benchmark fair?  This is closely related to (1), in the sense
that sometimes, when you discover what the benchmark actually measures,
you also discover that a tiny change to the program produces a dramatic
change in the execution time.

So, while I encourage benchmarking in general, I want to point out that
constructing benchmarks that provide genuinely useful data is hard.

Finally, I should say what I think Alex means by `an efficient library,'
because what I think he means is something that cannot be determined by
comparing the speed of Scheme programs with the speed of C++ programs.
I know this statement sounds surprising, but please bear with me.

The C library comes with a sort function that takes four arguments:

	the address of the initial element of an array to sort
	the number of elements
	the size of an element of the array, in bytes
	the address of a function that can compare elements

Inside that sort function, there are two sources of overhead:

(a) because the function doesn't know the size of an element until
you call it, the code that moves elements around has to be written
in terms of an execution-time loop.  If the sizes were known during
compilation, the compiler would be able to generate specialized code.

(b) each call to the comparison function is a call through a pointer
rather than a direct call that the compiler might be able to expand
inline.

As a result, if you use the C library sort function, it will probably
be substantially slower than if you were to copy the relevant code
yourself, substituting the relevant types as appropriate.

The C++ template mechanism does exactly this substitution, which
means that the C++ library sort template will be dramatically faster
than the C library sort function in most contexts.

And that is what I believe Alex is actually after: Is it possible to
write a generic algorithm library whose algorithms will run as fast
as the corresponding hand-coded algorithms in the same language?

So if you want to gainsay Alex's claims, the question you should be
asking is not whether you can sort lists of strings as fast in Scheme
as you can in C++.  Rather, the question to ask is whether you can
write a sort that doesn't know what it's sorting but runs as fast
as one that does.

And, as it happens, sorting is not even a particularly good test,
because the fastest way to sort is quite sensitive to the particular
data structure for purely algorithmic, language-independent reasons.
In particular, some data structures can be rearranged in place by
moving pointers around, and others require that elements be copied.
So that means that writing a fully generic sort is much harder than,
say, writing a fully generic linear search.

So perhaps one question worth asking, which I think is at the heart of
what Alex is getting at, is whether it is possible to write a fully
generic linear search algorithm that runs as fast as does one that
knows what data structure it is searching or what the types of the
elements are.  In C++ the answer to that question is yes.  Is it
in Scheme?  Here is where my knowledge runs out.

But I do think it would be interesting if someone who knows Scheme much
better than I do would try to construct a generic library along lines
similar (or analogous) to STL and find out whether modern Scheme
implementations allow such a library to be more efficient than
it was when Alex was working on it.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Chris Bitmead uid(x22068)
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <BITMEADC.97May26125740@Alcatel.com.au>
In article <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

>OK ... now what about that benchmark?  Well, by itself it doesn't show
>much of anything one way or the other.  Among the reasons:

<snip>

I think what the benchmark was designed to show, and what it had some
degree of success showing, was that many of the people who choose C++
because they think that they need it for efficiency, are at best not
getting their priorities right, and at worst are just wrong.
From: Andrew Koenig
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <EAuq23.3BA@research.att.com>
In article <······················@Alcatel.com.au> ·············@Alcatel.com.au writes:

> I think what the benchmark was designed to show, and what it had some
> degree of success showing, was that many of the people who choose C++
> because they think that they need it for efficiency, are at best not
> getting their priorities right, and at worst are just wrong.

But it doesn't show that.  No single benchmark could.

Nor does it do what I thought it was intended to do,
which was to refute the claim that C++ allows generic
programs to run as fast as their hand-coded counterparts.

What it does do is compare programs written in Scheme and C++
that solve one specific problem.  It is not clear that either of
those programs is the most efficient that could be written in
their respective languages, nor is it clear whether or not either of
the compilers used have performance bugs.

I've seen examples of similar comparisons before.  Typically,
small tweaks in the programs in question can make large differences
in the execution time, both in C++ and in other languages.
So genuinely useful comparisons are hard to come by.

Moreover, truly fair benchmarks have to be run by someone
who does not have a vested interest in any particular result.
That is one reason I do not post benchmarks.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Hans-Juergen Boehm
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <338B3C7D.2781@mti.sgi.com>
Andrew Koenig wrote:
> 
> In article <······················@Alcatel.com.au> ·············@Alcatel.com.au writes:
> 
> > I think what the benchmark was designed to show, and what it had some
> > degree of success showing, was that many of the people who choose C++
> > because they think that they need it for efficiency, are at best not
> > getting their priorities right, and at worst are just wrong.
> 
> What it does do is compare programs written in Scheme and C++
> that solve one specific problem.  It is not clear that either of
> those programs is the most efficient that could be written in
> their respective languages, nor is it clear whether or not either of
> the compilers used have performance bugs.
> 
I think it has been established that the C++ program is NOT the most
efficient way to solve the problem in C++.  Two of us have posted much
faster C++ solutions to the same problem, using either sets or vectors
instead of lists.  It also presumably does not use the same data
structure as the Scheme program (the C++ code uses doubly linked lists,
I would be amazed if the Scheme program did), nor does it use the same
algorithm (duplicates eliminated early vs. late).

Thus it seems to me the Scheme to C++ comparisons using this benchmark
don't show much, as it stands.  You either need to compare the fastest
possible programs to solve a given problem, or solutions based on
exactly the same algorithms and data structures.  (The latter is still
tricky because Scheme implementations emphasize list handling, where C++
usually does better with arrays.) The current benchmark does neither,
though it was an honest attempt to do the latter.  Benchmarking is hard.

I haven't seen the C version, so I can't judge whether that's comparable
to the others.

Hans

-- 
Hans-Juergen Boehm
·····@mti.sgi.com
From: Erik Naggum
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <3073758616856349@naggum.no>
* Hans-Juergen Boehm
| Thus it seems to me the Scheme to C++ comparisons using this benchmark
| don't show much, as it stands.  You either need to compare the fastest
| possible programs to solve a given problem, or solutions based on exactly
| the same algorithms and data structures.

other axes of comparison are certainly possible.  for instance, you can
give the same problem to top-notch (or even "average") programmers in each
language and compare their results when they are "satisfied" with a
solution, or give top-notch (or "average") programmers a specific time to
solve the problem, and compare their results according to completeness,
correctness, and execution speed.

choosing exactly the same algorithm and implementing it in different
languages (ignoring the cost of implementing it) would obviously ignore
_algorithmic_ advantages in one language over the other, or remove the
meaning from the benchmark altogether.

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mh3tn$4h3$1@goanna.cs.rmit.edu.au>
Hans-Juergen Boehm <·····@mti.sgi.com> writes:
>I think it has been established that the C++ program is NOT the most
>efficient way to solve the problem in C++.

Of course not!  The most efficient way to solve the problem in C++
is to compile the C version with a C++ compiler!

>Two of us have posted much
>faster C++ solutions to the same problem, using either sets or vectors
>instead of lists.

I cannot get over this!  I write a program precisely to test out one
particular data structure, and people dismiss it because _another_
data structure isn't as bad!

I have also posted numbers for a more efficient solution to the problem,
and while the C++ code using <set> AND <list> was less inefficient than
the C++ code using <list> alone, it was STILL no less than FOUR TIMES
SLOWER than the corresponding C code.

>It also presumably does not use the same data
>structure as the Scheme program (the C++ code uses doubly linked lists,

Again, *THAT IS THE BLOODY POINT*!

Now, I *do* accept as a valid criticism that there *is* an STL-
compatible <slist>, and I know where to find it.  A pity it isn't
in the standard.  Perhaps it will be.

>I would be amazed if the Scheme program did), nor does it use the same
>algorithm (duplicates eliminated early vs. late).

Again, THAT IS THE BLOODY POINT!  The fact that the efficient algorithm
was *missing* is an important and relevant fact!

>Thus it seems to me the Scheme to C++ comparisons using this benchmark
>don't show much, as it stands.  You either need to compare the fastest
>possible programs to solve a given problem, or solutions based on
>exactly the same algorithms and data structures.

Come *on*!  Anyone who tries to understand this as a Scheme -vs- C++
contest has missed everything that matters about it.  It isn't even
a *C* -vs- C++ contest, although that would be more accurate.  My
interest was in the STL!  The point at issue is whether using the
STL does or does not make it easy to do efficient sort/sort/merge operations.
The entire absence of batch operations from <set> made it pointless
to use that data structure at all.  

I consider it beyond any possible dispute that >>> C++ <<< can solve this
problem (or indeed most others) as efficiently as C.

The question is whether *using the STL* helps.  The aim was to build the
simplest clearest solution using the STL in a fair way, and to compare
that with reusing existing Scheme and C library code.

>(The latter is still
>tricky because Scheme implementations emphasize list handling, where C++
>usually does better with arrays.)

>The current benchmark does neither,
>though it was an honest attempt to do the latter.  Benchmarking is hard.

For what it's worth, the STL version using <set> is STILL FOUR TIMES SLOWER
than using C code that maintains a set.  At least half of this must be due
to using <string> instead of char*.  But there again, if I've got to avoid
<string> in order to get good performance, what's the point of having it?

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Matt Austern
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <fxtsoz6t09i.fsf@isolde.mti.sgi.com>
··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

> >Two of us have posted much
> >faster C++ solutions to the same problem, using either sets or vectors
> >instead of lists.
> 
> I cannot get over this!  I write a program precisely to test out one
> particular data structure, and people dismiss it because _another_
> data structure isn't as bad!

The problem is that you aren't testing the data structure that you
think you are.  The data structure you're testing is basic_string<>,
which is not part of the STL.
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mh219$167$1@goanna.cs.rmit.edu.au>
···@research.att.com (Andrew Koenig) writes:

>Nor does it do what I thought it was intended to do,
>which was to refute the claim that C++ allows generic
>programs to run as fast as their hand-coded counterparts.

How does it fail to do so?
Is there any conceivable test that would do so?

[I am interpreting 'allows' to me 'allows RIGHT NOW with EXISTING
 compilers'.  I am only too willing to concede that the language
 design may in some distant future permit this.]

>What it does do is compare programs written in Scheme and C++
>that solve one specific problem.

How could it be otherwise?

>It is not clear that either of
>those programs is the most efficient that could be written in
>their respective languages,

Come now:  it is dishonest to insist on such a condition.
To do so would be to ban all benchmarking for all time.

For what it's worth, I have benchmarked the particular sorting
method used in the C and Scheme versions against the methods offered by
vendors for C, Prolog, and Lisp, and it _always_ does very well.
And surely we have agreed that Stepanov is a highly competent C++
programmer, library designer, and algorithm selector?

>nor is it clear whether or not either of
>the compilers used have performance bugs.

But that's *relevant*.  Be honest man:  I can only do tests with
the compilers I *have*, not with hypothetical non-buggy compilers
that probably don't even exist.

>I've seen examples of similar comparisons before.  Typically,
>small tweaks in the programs in question can make large differences
>in the execution time, both in C++ and in other languages.

Ok, I posted the C++ code.  What small tweak to it would *YOU*
make, that still leaves it using only the <list> types, to make
a large difference in the execution time?  I assure you, I have
tried *numerous* changes to the Scheme version, and the only change
that made any difference at all was replacing string comparison calls
with calls to the C library strcmp() function.  (This Scheme puts a
\0 at the end of each string, and the data couldn't include any \0
bytes, so it was certain to be safe.)  I haven't reported that time,
because that was using a highly non-standard feature of that compiler.

>So genuinely useful comparisons are hard to come by.

>Moreover, truly fair benchmarks have to be run by someone
>who does not have a vested interest in any particular result.

That _almost_ sounds libellous.
For the record:
 - I do not work for a C compiler vendor, nor have I ever done so.
 - I do not work for a Scheme compiler vendor, nor have I ever done so.
 - I do not work for a C++ compiler vendor, nor have I ever done so.
 - I *have* worked for a Prolog compiler vendor, but did not include
   Prolog in this test.
 - I have no vested interest of any form in any of the languages used
   in the test.

* To paraphrase a Listerine ad, "I _hate_ C.  Twice a day."

* I love Scheme, but regard the standard language as too `small'.
  (Too much of the standard is optional, which is surprising in
  a 50-page standard.  There is no standard define-structure; all
  the Schemes I use have one, but they are all different.  There
  is no POSIX binding.  There is no exception handling.)

* I actually *recommended* C++ to someone today, so I'm not prejudiced
  against it either.

>That is one reason I do not post benchmarks.

But your vested interest does not prevent you using arguments against
someone else that would muzzle *everyone* who did test, if those
arguments were valid?

Andrew Koenig, you used to be one of my heroes.
-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Chris Bitmead uid(x22068)
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <BITMEADC.97May28124547@Alcatel.com.au>
In article <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

>In article <······················@Alcatel.com.au> ·············@Alcatel.com.au writes:
>
>> I think what the benchmark was designed to show, and what it had some
>> degree of success showing, was that many of the people who choose C++
>> because they think that they need it for efficiency, are at best not
>> getting their priorities right, and at worst are just wrong.
>
>But it doesn't show that.  No single benchmark could.
>
>Nor does it do what I thought it was intended to do,
>which was to refute the claim that C++ allows generic
>programs to run as fast as their hand-coded counterparts.

It wasn't meant to refute anything. The author was expecting to prove
the opposite.

Forget the C++ results for a moment. Let's assume they are flawed for
whatever reason.

The closeness of the C and Scheme results seems to justify my original
statement: That being that it "had some degree of success showing, was
that many of the people who choose C++ because they think that they
need it for efficiency, are at best not getting their priorities
right, and at worst are just wrong."

"Some degree" doesn't mean that it is proof, but that it is one piece
of evidence that could form the start of something meaningful.

The point is, most people who think they need C++ for "hand-coded
performance" are probably wrong.
From: Andrew Koenig
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <EAwH7F.H8J@research.att.com>
In article <······················@Alcatel.com.au> ·············@Alcatel.com.au writes:

> The closeness of the C and Scheme results seems to justify my original
> statement: That being that it "had some degree of success showing, was
> that many of the people who choose C++ because they think that they
> need it for efficiency, are at best not getting their priorities
> right, and at worst are just wrong."

But it doesn't show that.  No one benchmark could.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: David Hanley
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <338F30A1.6BC7@nospan.netright.com>
Andrew Koenig wrote:
> 
> In article <······················@Alcatel.com.au> ·············@Alcatel.com.au writes:
> 
> > The closeness of the C and Scheme results seems to justify my original
> > statement: That being that it "had some degree of success showing, was
> > that many of the people who choose C++ because they think that they
> > need it for efficiency, are at best not getting their priorities
> > right, and at worst are just wrong."
> 
> But it doesn't show that.  No one benchmark could.

	Absolutely.  But it seems that it could show one thing:

	That people who choose one language over another for speed,
without careful consideration to the target domain, may be making
a mistake.  

	I can envision application domains in which I would use either LISP or
C++, depending on what I needed to do.  However, many people
pick C++ for tasks automatically, because of some preconcieved notion
that it will make their code run vey quickly as opposed to other
languages.  

	A simple benchmark can show that this notion is incorrect or incorrect,
depending on the target domain, by providing, or failing
to provide, a relevant counterexample.

	dave



> --
>                                 --Andrew Koenig
>                                   ···@research.att.com
>                                   http://www.research.att.com/info/ark
From: Bijan Parsia
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <bparsia-ya02408000R2905971835180001@News.oit.unc.edu>
In article <··········@research.att.com>, ···@research.att.com (Andrew
Koenig) wrote:

[lots cut]
>
>Moreover, truly fair benchmarks have to be run by someone
>who does not have a vested interest in any particular result.
>That is one reason I do not post benchmarks.

First, there's a bit of innuendo here--that O'Keefe (the one, I believe,
who wrote and ran the benchmark) has a vested interest in a particular
result. Not only is it reasonable to think that this is not true, it's even
reasonable to think that he didn't *expect* of the actual result (a much
more dangerous bias in general scientific work).

Second, surely the fairness of a benchmark is independent of who *runs* it,
and even of who *writes* it.  It's also true that, especially recently,
there has been a lot of noise about venders tuning their product to do well
on this or that benchmark, at the price of "interesting" performance. Thus,
*perceived* fairness is not going to be accorded to benchmarks produced by
those with a vested interest in any particular result (except, perhaps, in
the case where the writers have a vested interest in producing the
particular result of "objective and fair comparison").

Furthermore, I'm not sure exactly how "fairness" is supposed to apply to
benchmarks--a lot depends on what one is trying to benchmark. This
particular attempt was, I believe, trying to measure performance gained
from available tools given a straightforward programming effort by a single
programmer competent (though not necessarily expert) in the test language
of a common programming task.

Given these criteria, these criticisms of the benchmark are off target:
 
  1. The results are tainted by the poorness of the compiler or library
implementation. ("... nor is it clear whether or not either of
the compilers used have performance bugs.")

      This is irrelevant given the "available tool" criterion. "Jam today,"
is, I believe, the battle cry.
      This might be relevant if it were a *fluke* that the problem selected
*happened* to hit an *obscure*, *idiosyncratic* bug or weakness. However,
just about everyone admits that C++ implementations are in very bad shape.
It's more reasonable, given the state of the art, to be suspicious of
unanticipated *good* results as representative of the norm--after all, in
that case, it could be that the problem happened to hit something that this
compiler vender happened to get right, and to have optimized highly for
idiosyncratic reasons. This *should* change as the state of art advances,
but then, that's a "jam tomorrow" claim, which does *not* challenge the
validity of the benchmark.

   2. The programs aren't sufficiently optimized in one or the other
examples. ("..It is not clear that either of those programs is the most
efficient that could be written in their respective languages,")

   Optimality of the programs is, in itself, irrelevant, given that the
test is what happens when a competent, not necessarily expert in the
language, programmer tries to solve a straightforward problem in a
straightforward manner. Here, straightforwardness matters most. Even if
there is an "equally" straightforward and even idiomatic way of solving the
problem that is much faster, this doesn't necessarily invalidate the
benchmark, though it certainly alters its significance, and indicates the
need for some broader, supplementary benchmarks.

   Note: The "smallest" of a radically performance enhancing tweak is less
important than the "obviousness" (straightforwardness) of the tweak.

As usual, the hard part about benchmarks is interpreting them.

Cheers,
Bijan Parsia
·······@email.unc.edu
From: Mukesh Prasad
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <338EC8FE.24F2@polaroid.com>
Bijan Parsia wrote:
[snip]
> First, there's a bit of innuendo here--that O'Keefe (the one, I believe,
> who wrote and ran the benchmark) has a vested interest in a particular
> result. Not only is it reasonable to think that this is not true, it's even
> reasonable to think that he didn't *expect* of the actual result (a much
> more dangerous bias in general scientific work).

I would have to disagree.  O'Keefe, as I recall, obtained
results which showed ratios of 1:3:9 (or something in that
progression) for C:Scheme:C++ w/STL.

While O'Keefe demanded fast performance from C++ w/STL,
as implemented, RIGHT NOW, he did spend time on making the
Scheme version faster instead of taking the RIGHT NOW verdict
and dumping Scheme immediately in favor of C.  This
would show a bias in favor of Scheme.

I did not observe any bias in reporting the results
as obtained, or in the test methodology.  But there
would appear a bias in the interpretation of results
and followup modifications to the test suite.  If help from
Suskind was accepted in improving the Scheme test suite,
help from C++/STL experts should have also been accepted
in improving the C++/STL test suite.

Otherwise, we are left with the result that without
understanding reasonably well what you are doing, you cannot
use C++/STL to obtain decent performance.  This result
applies to C equally well.  Anybody who has seen
freshman C programs can testify that C can be
used to write very inefficient programs.
A level of proficiency and in-depth understanding
is required to obtained good performance.

One result which does seem clear and undisputable,
however, is that C++ currently is not implemented
very portably across the compilers, when it comes
to something like the STL.
From: Bijan Parsia
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <bparsia-ya02408000R3005971808510001@News.oit.unc.edu>
[As I think I saw the author sign off the thread, I took the liberty of
mailing a copy.]

In article <·············@polaroid.com>, ·······@polaroid.com wrote:

>Bijan Parsia wrote:
>[snip]
>> First, there's a bit of innuendo here--that O'Keefe (the one, I believe,
>> who wrote and ran the benchmark) has a vested interest in a particular
>> result. Not only is it reasonable to think that this is not true, it's even
>> reasonable to think that he didn't *expect* of the actual result (a much
>> more dangerous bias in general scientific work).
>
>I would have to disagree.  O'Keefe, as I recall, obtained
>results which showed ratios of 1:3:9 (or something in that
>progression) for C:Scheme:C++ w/STL.
>
>While O'Keefe demanded fast performance from C++ w/STL,
>as implemented, RIGHT NOW, he did spend time on making the
>Scheme version faster instead of taking the RIGHT NOW verdict
>and dumping Scheme immediately in favor of C.  This
>would show a bias in favor of Scheme.

I think you are confusing the *benchmark* (and its interpretation) with the
investigation of *why* the results were the way they were. Note that
O'Keefe *didn't* alter the reported benchmark results to reflect the
improved Scheme code.

In essence, there were two "surprise" results (for O'Keefe): the Scheme
code was slower than expected, and the C++ code was *way* slower than
expected. Neither fact invalidates the original benchmark, and that O'Keefe
is (now) interested in investigating the deviation of expectation in the
case of the Scheme code also does not prove (or exhibit) that he had a
vested interest in a certain result of the benchmark.

You may be reacting to his rather vehement (though, I hope to show)
justified reaction to all the "That C++ code is not optimal. You should
have used x, instead of y. *Everyone* knows that C++'s x is dog slow. Geez,
what a biased benchmark." posts. Since, as I pointed out in my prior post,
the benchmark was to be a test of a *straightforward*  solution to a common
programming task implemented by a
not-necessarily-an-expert-in-C++-or-the-particular-compiler-
but-otherwise-quite-competent programmer, *neither* the optimized Scheme
program, *nor* the optimized C++ program would be in the spirit of the
benchmark. Thus, O'Keefe's rejection of the various criticisms of his C++
code *as a criticism* of his benchmarks and its results is on target. (Note
that he did not replace the original Scheme result with the optimized one.)

>I did not observe any bias in reporting the results
>as obtained, or in the test methodology.  But there
>would appear a bias in the interpretation of results
>and followup modifications to the test suite.  If help from
>Suskind was accepted in improving the Scheme test suite,
>help from C++/STL experts should have also been accepted
>in improving the C++/STL test suite.

As I said above, it wasn't an improvement in the test suite, it was a
report on how one can, in fact, optimize the code. If the C++ examples were
presented that way, then I don't think O'Keefe would complain (at least, I
don't think he'd be entitled to). It's the presentation of the optimized
C++ results as a *criticism* of the original benchmark that's an error
(and, indeed, evidence of the critic's C++ bias--though not necessarily
*conclusive* evidence).

>Otherwise, we are left with the result that without
>understanding reasonably well what you are doing, you cannot
>use C++/STL to obtain decent performance.  This result
>applies to C equally well.  Anybody who has seen
>freshman C programs can testify that C can be
>used to write very inefficient programs.
>A level of proficiency and in-depth understanding
>is required to obtained good performance.

Well, the issue is *what* level of proficiency and in-depth understanding
is needed. The benchmark was testing a *certain* level. Notice that he
didn't do anything particular speed clever or minded in *any* of the code
samples. He aimed for the straightforward. If the level of in-depth
understanding needed for *decent* performance requires *counterintuitive*,
or *wildly* implementation dependant, choices, then I don't see that C++ is
going to do well on a benchmark of *straightforward* code. This is one
thing the actual results indicate (though, of course, they do not *prove*
it). That *is* a significant result, and worth further investigation and
(dis)confirmation. But again, it's not evidence of interpretive bias.

>One result which does seem clear and undisputable,
>however, is that C++ currently is not implemented
>very portably across the compilers, when it comes
>to something like the STL.

I agree--though I don't think anyone needed this benchmark to know that.

Cheers,
Bijan Parsia
·······@email.unc.edu
From: Sean Matthews
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mmmel$7bg$1@pf1.phil.uni-sb.de>
In article <·············@polaroid.com>, Mukesh Prasad <·······@polaroid.com> writes:
> Bijan Parsia wrote:
> [snip]
> > First, there's a bit of innuendo here--that O'Keefe (the one, I believe,
> > who wrote and ran the benchmark) has a vested interest in a particular
> > result. Not only is it reasonable to think that this is not true, it's even
> > reasonable to think that he didn't *expect* of the actual result (a much
> > more dangerous bias in general scientific work).
> 
> I would have to disagree.  O'Keefe, as I recall, obtained
> results which showed ratios of 1:3:9 (or something in that
> progression) for C:Scheme:C++ w/STL.
> 
> While O'Keefe demanded fast performance from C++ w/STL,
> as implemented, RIGHT NOW, he did spend time on making the
> Scheme version faster instead of taking the RIGHT NOW verdict
> and dumping Scheme immediately in favor of C.  This
> would show a bias in favor of Scheme.
> 
> I did not observe any bias in reporting the results
> as obtained, or in the test methodology.  But there
> would appear a bias in the interpretation of results
> and followup modifications to the test suite.  If help from
> Suskind was accepted in improving the Scheme test suite,
> help from C++/STL experts should have also been accepted
> in improving the C++/STL test suite.

It's hard to kick against the pricks.

I find this thread fascinating, for sociological reasons.
I think any computer science relevance is disappearing
rapidly, but the whiff of testosterone is strengthening.

You are completely misrepresenting Richard, either because
like many people here, you haven't bothered to read what
he is saying, or because you don't want to.
Richard made a careful distinction between the modified
version of the Scheme program and the standard version,
his benchmarks are for the standard version.

When posting the standard figures he observe that the Scheme
version was disappointingly slower than he expected, and after
some hints with Jeff Suskind, he produced a hacked version of
the Scheme program that made use of Stalin specific hacks, and
ran significantly faster. It was not the program he was comparing,
any more than the versions of the C++ program that had been patched
in various ways were.

Of all the people I have ever read about programming R O'K is, I
think, just about the least likely to retreat to implementation
specific hacks when making a comparision. Part of the basic Richard
O'Keefe gospel is that you should program primarily from the language
specification, not from an implemenation manual.

If you are not willing to understand this (at least to me utterly
self-evident point) then you don't understand part of his position.

Sean

-- 
Sean Matthews <····@mpi-sb.mpg.de>   http://www.mpi-sb.mpg.de/~sean/
Max-Planck-Institut fuer Informatik,         phone: +49 681 9325 217
Im Stadtwald, 66123 Saarbruecken, Germany      fax: +49 681 9325 299
From: Mukesh Prasad
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <338F02D8.59AB@polaroid.com>
Sean Matthews wrote:
[snip]
> It's hard to kick against the pricks.

Ah, we seem to have reached the typical contemporary
linguistic and logical levels of modern day Lisp/Scheme
fanatics.  That's about enough of this
thread for me, bye now...
From: Chris Bitmead uid(x22068)
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <BITMEADC.97Jun3114204@Alcatel.com.au>
In article <·············@polaroid.com> Mukesh Prasad <·······@polaroid.com> writes:

>Sean Matthews wrote:
>[snip]
>> It's hard to kick against the pricks.
>
>Ah, we seem to have reached the typical contemporary

Hardly contemporary, since it's a biblical quote.

>linguistic 

If the "Lisp fanatic"'s linguistic levels are up to biblical
standards, I think I would take that as a complement.

>and logical levels of modern day Lisp/Scheme
>fanatics.  That's about enough of this
>thread for me, bye now...
From: Chris Bitmead uid(x22068)
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <BITMEADC.97Jun3114044@Alcatel.com.au>
In article <·············@polaroid.com> Mukesh Prasad <·······@polaroid.com> writes:

>Sean Matthews wrote:
>[snip]
>> It's hard to kick against the pricks.
>
>Ah, we seem to have reached the typical contemporary

Hardly contemporary, since it's a biblical quote.

>linguistic 

If the "Lisp fanatic"'s linguistic levels are up to biblical
standards, I think I would take that as a complement.

>and logical levels of modern day Lisp/Scheme
>fanatics.  That's about enough of this
>thread for me, bye now...
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5n7v8f$3ei$1@goanna.cs.rmit.edu.au>
Mukesh Prasad <·······@polaroid.com> writes:

>Bijan Parsia wrote:
>[snip]
>> First, there's a bit of innuendo here--that O'Keefe (the one, I believe,
>> who wrote and ran the benchmark) has a vested interest in a particular
>> result. Not only is it reasonable to think that this is not true, it's even
>> reasonable to think that he didn't *expect* of the actual result (a much
>> more dangerous bias in general scientific work).

>I would have to disagree.  O'Keefe, as I recall, obtained
>results which showed ratios of 1:3:9 (or something in that
>progression) for C:Scheme:C++ w/STL.

>While O'Keefe demanded fast performance from C++ w/STL,
>as implemented, RIGHT NOW, he did spend time on making the
>Scheme version faster instead of taking the RIGHT NOW verdict
>and dumping Scheme immediately in favor of C.  This
>would show a bias in favor of Scheme.

This is a total distortion of what I wrote.
I did spend time on the Scheme code to see why it was slower than
I expected.  BUT I REPORTED THE ORIGINAL UNOPTIMISED TIME.

On the basis of the numbers I reported, if sorting strings was an
important part of an application, I would certainly code it in C.


>I did not observe any bias in reporting the results
>as obtained, or in the test methodology.  But there
>would appear a bias in the interpretation of results
>and followup modifications to the test suite.  If help from
>Suskind was accepted in improving the Scheme test suite,

That's Siskind.  And I REPORTED THE ORIGINAL UNOPTIMISED TIME.

>help from C++/STL experts should have also been accepted
>in improving the C++/STL test suite.

IT BLOODY WELL *WAS*!  I have reported some such results!

>Otherwise, we are left with the result that without
>understanding reasonably well what you are doing, you cannot
>use C++/STL to obtain decent performance.  This result
>applies to C equally well.  Anybody who has seen
>freshman C programs can testify that C can be
>used to write very inefficient programs.
>A level of proficiency and in-depth understanding
>is required to obtained good performance.

Which is why the efficiency of a library is so important.

>One result which does seem clear and undisputable,
>however, is that C++ currently is not implemented
>very portably across the compilers, when it comes
>to something like the STL.

You seriously understate the case.
C++ code that steps outside "C with classes" is not yet portable.
Period.
Basic facilities like <string> that have been in the draft standard
for over two years are not yet usable in portable code.

(Once again, let me say it:  there are many important facilities that
are not standardly available in Scheme.  defstruct is perhaps the most
obvious, although I personally would like a standard way to handle
failed attempts to open files.)
-- 
Four policemen playing jazz on an up escalator in the railway station.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mbhae$um$1@goanna.cs.rmit.edu.au>
···@research.att.com (Andrew Koenig) writes:

>First, let me note that I did not make the original claim -- Alex Stepanov
>did.  And Alex wrote a generic algorithm library in Scheme long before
>he even learned C++.

I didn't say that you did make the claim.
And I don't see what Stepanov's having written a generic library in
Scheme has to do with the case.  (Has he made it available anywhere?
It would surely have been a useful addition to slib.)

>OK ... now what about that benchmark?  Well, by itself it doesn't show
>much of anything one way or the other.

Wrong.  If someone says that swans are white, all I have to do is
produce one naturally black swan to explode the claim.  (Australian
swans _are_ black, by the way.)  If someone tells me that the STL is
efficient because of C++, all I have to do is produce one simple and
natural use of the STL that is not efficient to explode that claim.
Well, I _have_ produced just such a simple and natural use of the STL.

>1. What is the benchmark actually measuring?  That is, where are the two
>programs spending their time?

I told you:  in the sorting phase.

>In an earlier message, I suggested that
>if there was a particular, simple, optimization missing from the C++
>library you used, it might make a dramatic difference in execution
>time.

And I told you that the optimisation in question (a) is actually
irrelevant and (b) ISN'T missing.

>Another possibility might be that the memory allocator on
>your machine was horrendously slow -- many systems provide a really
>slow allocator by default and allow the option of substituting a faster
>one.

And I also pointed out that the phase where almost all the time goes
ISN'T ALLOCATING ANYTHING.  Not in C, not in Scheme, and not in C++.
The time is going in list<string>::sort(), which doesn't swap or copy
any strings, and which recycles the existing list cells.

>Any persuasive power that benchmark numbers have will come
>from understanding what they really measure.

No.  If someone is dead, a postmortem may tell you _why_ they died,
but it won't make them live again.  No amount of just so stories
about what _might_ have been going on (but in fact wasn't) will change
the fact that a simple, really really straightforward use of the STL,
that was in fact constructed to test a completely different issue
entirely,

 - couldn't be compiled *AT ALL* by the compiler from one major vendor

 - was 9 times slower than plain C using g++


>2. Are the programs comparable?  Lists in Scheme and C++ are substantially
>different data structures -- for one thing, C++ lists allow traversal
>forwards and backwards.  This suggests that some Scheme list operations
>will be faster than the corresponding C++ list operations and others
>will be slower.

Naughty naughty!  There are STL lists, but there is nothing in C++ that
*forces* you to use them.  It is, for example, possible to compile the
C version of my test with a C++ compiler (you only have to change about
5% of the code to make it C++-compatible).  If you do that, the version
that took 1.34 seconds using g++ takes 1.47 seconds using SunPro CC 4.2.
I'll buy that as being "the same" within benchmarking accuracy.

And if you will only try to keep in mind what I have to keep reminding
you about, which is that this is a test of the STL, not a test of C,
the fact that STL <list>-type lists have extra overheads is PRECISELY
(part of) the point.

Let me say this one more time, in the hope that the point will be
understood.

	I AM NOT MAKING ANY GENERAL CLAIMS ABOUT C++ EFFICIENCY.

	I AM *SOLELY* CONCERNED WITH THE QUESTION "DOES USING THE
	STL AS AVAILABLE TO ME *NOW* WITH THE COMPILERS AVAILABLE
	TO ME *NOW* GIVE ME OVERALL EFFICIENCY *NOW*."
	
Indeed, the fact that CC -xO5 and gcc -O6 give comparable performance
for (essentially) the same source code is important to my evaluation
of the use of the STL.

>3. Are the programs representative?

Representative of _what_, pray?  The test is, after all, one of the
historic UNIX utilities (the 'poor man's spelling checker').  Sorting
sequences, followed by merging them, is "representative" (whatever that
means) of a huge volume of traditional EDP code.  That's why COBOL has
the SORT and MERGE verbs, after all.  And sequence processing is what
the <algorithm> header is all about, is it not?

>That is, are they typical of what
>useful programs actually do?

If they _aren't_ then Stepanov has wasted a great deal of his life
trying to make it easy for people to write them.

>By definition, a program that does only
>one sharply defined task is probably not representative, which is one
>of the things that makes useful benchmarks so difficult.  Another such
>thing is that short-running programs in garbage-collected languages

Again, this is pontificating in a vacuum.  One of the things that the
Stalin compiler optimises is garbage collection!  It puts a lot of work
into trying to stack-allocate things.

And surely you are not trying to argue that C is a garbage collected
language?  (Remember 9:1 speed advatnage for C in this test.)

>4. Is the benchmark fair?  This is closely related to (1), in the sense
>that sometimes, when you discover what the benchmark actually measures,
>you also discover that a tiny change to the program produces a dramatic
>change in the execution time.

Yeah, well, all I can say is that the test was actually written in the
expectation that it would show something very different.  I found the
results *shockingly* different from what I had expected.  It certainly
wasn't written with the intention of stressing whatever it is that it
does stress.

>So, while I encourage benchmarking in general, I want to point out that
>constructing benchmarks that provide genuinely useful data is hard.

Well, it all depends on what you mean "genuinely useful", doesn't it?
Let me tell you once again what this test has *definitely* demonstrated
desapite any special pleading from the other side:

 - an experienced programmer wrote a program in three languages.
 - the program is small, but follows an historically extremely important
   outline: sort two sequences and merge them.
 - the programmer is experienced in C and Scheme.
 - the programmer is not experienced in C++, so had to keep the code
   simple and clear.
 - the programmer's documentation at the time was the April 1995 C++
   draft, which turned out to describe g++ 2.7.2.2's library reasonably
   well.
 - the test was _expected_ to show roughly the same performance in each
   of the three languages, except that the C++ and Scheme versions would
   do roughly twice as many string comparisons, and the Scheme version
   would do worse at string comparisons
 - the results were shockingly different: 1:3:9 C:Scheme:C++ times.

 - it was found that the choice of algorithms in the C++ selection from
   the STL forced a less efficient use of sorting
 - it was found that while the STL in general goes to some trouble to make
   all kinds of sequences look the same, this does NOT carry over to
   sorting, so that lists cannot be sorted like vectors, and vectors cannot
   be sorted like lists.  (You have to use list<T>::sort(), not the generic
   sort, and there is no vector<T>::sort() so you have to use the generic one.)
 - this also applies to unique().
 - for whatever reason, the result was spectacularly slow.

There is no reason to believe that other experienced (but not in C++)
programmers trying to use the STL in C++ will obtain any different
results.

>Finally, I should say what I think Alex means by `an efficient library,'
>because what I think he means is something that cannot be determined by
>comparing the speed of Scheme programs with the speed of C++ programs.

Yeah, but c'mon, Humpty-Dumptyism gets us nowhere.  That's what everyone
_else_ understood him to mean.  That's why people perceived his posting as
an attack on their favourite languages.  And that's the _kind_ of efficiency
other people _want_ from a generic library.  What good is an 'efficient'
library whose operations take a lot of time?

>I know this statement sounds surprising, but please bear with me.

>The C library comes with a sort function that takes four arguments:

>	the address of the initial element of an array to sort
>	the number of elements
>	the size of an element of the array, in bytes
>	the address of a function that can compare elements

So what?  That function was not used in any of the tests.

>Inside that sort function, there are two sources of overhead:

>(a) because the function doesn't know the size of an element until
>you call it, the code that moves elements around has to be written
>in terms of an execution-time loop.  If the sizes were known during
>compilation, the compiler would be able to generate specialized code.

>(b) each call to the comparison function is a call through a pointer
>rather than a direct call that the compiler might be able to expand
>inline.

>As a result, if you use the C library sort function, it will probably
>be substantially slower than if you were to copy the relevant code
>yourself, substituting the relevant types as appropriate.

This applies to C.  It does *not* apply to Scheme.  The Scheme compiler
is perfectly capable of splitting off a clone of a sorting function and
open-coding calls to the comparison function.

>The C++ template mechanism does exactly this substitution, which
>means that the C++ library sort template will be dramatically faster
>than the C library sort function in most contexts.

BUT IT ISN'T!

To start with, I have been experimenting with sorting routines in
various languages for *years*.  I don't use qsort() in C code that
must be fast, I either use a list merge or I use a version of the
Bentley & McIlroy "Engineered" quick-sort, which actually has two
copies of the code:  one where the element size is the same size as
a pointer, and a generic version.  So the `don't know the size' overhead
in practice does not exist.  (Qsort() _could_ be implemented this way,
and I've seen one that was.)  As for the 'call through a pointer' cost,
this overhead is tiny compared with the cost of a non-trivial comparison.
(If you know that you are sorting numbers, you should not be using qsort()
or any generic sort.  You should be using a linear-expected-time method
like bucket sort or radix sort.)

>And that is what I believe Alex is actually after: Is it possible to
>write a generic algorithm library whose algorithms will run as fast
>as the corresponding hand-coded algorithms in the same language?

>So if you want to gainsay Alex's claims, the question you should be
>asking is not whether you can sort lists of strings as fast in Scheme
>as you can in C++.  Rather, the question to ask is whether you can
>write a sort that doesn't know what it's sorting but runs as fast
>as one that does.

BUT I *DID* THAT.  Here's the call to the sorting function:

Here's the top level of the Scheme program:

(let* ((F1 (vector-ref ARGV 1))
       (F2 (vector-ref ARGV 2))
       (T0 (time-in-seconds))
       (W1 (words F1))
       (W2 (words F2))
       (T1 (time-in-seconds))
       (L1 (list->ordset! W1 string<?))		;<--
       (L2 (list->ordset! W2 string<?))		;<--
       (T2 (time-in-seconds))
       (DF (ord-difference! L1 L2 string<?))	;<--
       (T3 (time-in-seconds)))
  (do ((W DF (cdr W)))
       ((null? W))
    (display W)
    (newline))
  (let ((T4 (time-in-seconds)))
    (display "reading   ") (write (- T1 T0)) (newline)
    (display "sorting   ") (write (- T2 T1)) (newline)
    (display "matching  ") (write (- T3 T2)) (newline)
    (display "writing   ") (write (- T4 T3)) (newline)
    (display "TOTAL     ") (write (- T4 T0)) (newline))

Look at the flagged (;<--) lines.  They call a generic list to set
(sort and eliminate duplicates) function, PASSING THE COMPARISON FUNCTION
AS AN ARGUMENT, and a generic difference-of-sets-as-ordered-lists
function, PASSING THE COMPARISON FUNCTION AS AN ARGUMENT.

The answer is, yes, it _does_ run as fast as one that does know what
it's sorting.

>And, as it happens, sorting is not even a particularly good test,
>because the fastest way to sort is quite sensitive to the particular
>data structure for purely algorithmic, language-independent reasons.
>In particular, some data structures can be rearranged in place by
>moving pointers around, and others require that elements be copied.
>So that means that writing a fully generic sort is much harder than,
>say, writing a fully generic linear search.

Yeah, but this is quite irrelevant to the STL, because the generic
sort in the STL *CANNOT SORT LISTS*.  It requires random access
iterators, and you don't get those from lists.  As the code I posted
showed quite plainly, the sorting method used in the C++ version of
the program called the list<string>::sort() method, which is NOT
generic in that sense and DOES know that it is sorting lists and
DOES use an algorithm that rearranges the olist by moving pointers.

You are quite right that writing a __fully__ generic sort is hard,
and that's why the STL simply hasn't got one.  The STL has a sort
that can be used with vector-like data structures (that is, with
things that provide random access iterators), and it cannot be used
with list.  It also has a list-specific sorting method.

>So perhaps one question worth asking, which I think is at the heart of
>what Alex is getting at, is whether it is possible to write a fully
>generic linear search algorithm that runs as fast as does one that
>knows what data structure it is searching or what the types of the
>elements are.  In C++ the answer to that question is yes.

But WHERE IS YOUR EVIDENCE for that proposition?
I've tried the experiment.
The specific code took 1.47 seconds.
The generic code took 9.58 seconds.

Given this evidence, the statement that "In C++ the answer to that
question is yes" is a triumph of faith over reason.  I *tried* it.
It just plain DID NOT HAPPEN THAT WAY.  C++ generic/C++ specific = 6/1.

>Is it in Scheme?  Here is where my knowledge runs out.

In this case, it genuinely was.
The specific code took 4.48 seconds.
The generic code took 4.70 seconds.
That's close enough for me.

Of course, that was sorting and set difference, not linear search.

>But I do think it would be interesting if someone who knows Scheme much
>better than I do would try to construct a generic library along lines
>similar (or analogous) to STL and find out whether modern Scheme
>implementations allow such a library to be more efficient than
>it was when Alex was working on it.

I don't think so.
If an admittedly brilliant software designer, thinking about the
problem for a _long_ time, and trying out his approach in several
languages, ends up with something that _doesn't_ for example provide
a generic sort and _doesn't_ provide efficiency for generic code
comparable to that for specific code (and I am only too happy to agree
that this is because of limitations in current C++ compilers), then
perhaps we should be looking along very different lines if we want an
efficient (in the non-Humpty-Dumptyish sense) generic library.

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: ozan s. yigit
Subject: stepanov? [Re: STL efficiency...]
Date: 
Message-ID: <x6d8qee4ii.fsf_-_@ds9.rnd.border.com>
it seems to me that Richard's comparisons are quite valid so far as it
goes in dealing with stepanov's assertions about C++ and other languages;
i for one really appreciated the effort and resulting discussion. since
stepanov has given up posting to the net thanks to all the rotten vegetables,
could someone act as an intermediary and get a detailed response from him?
even those of us who would much prefer other languages to C++ would be
interested in what he has to say. [who knows, maybe we can convert
him to scheme :)]

oz	[oz at tor dot securecomputing dot com]
---
Civilization is expensive.     --John Kenneth Galbraith
From: Andrew Koenig
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <EAur0q.5p1@research.att.com>
In article <···········@goanna.cs.rmit.edu.au> ··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

[a 346-line message, to which I do not have time to respond in detail,
 but of which I believe the main point is]

> Yeah, well, all I can say is that the test was actually written in the
> expectation that it would show something very different.  I found the
> results *shockingly* different from what I had expected.  It certainly
> wasn't written with the intention of stressing whatever it is that it
> does stress.

 ...

>  - an experienced programmer wrote a program in three languages.
>  - the program is small, but follows an historically extremely important
>    outline: sort two sequences and merge them.

 ...

>  - the results were shockingly different: 1:3:9 C:Scheme:C++ times.

 ...

> question is yes" is a triumph of faith over reason.  I *tried* it.
> It just plain DID NOT HAPPEN THAT WAY.  C++ generic/C++ specific = 6/1.

If this is true -- that is, if what you think you are measuring is what
you are actually measuring, then there is surely a performance bug somewhere.

It might be in the compiler, or in the particular implementation of STL,
or elsewhere in the library, but something is definitely not working
as it should.

If you had said `I don't want to use C++ because the compiler available
to me has a serious performance bug,' I would have nothing to say.
If you had proof that what looks like a bug is actually an
intrinsic flaw in the language, then I would also have nothing to say.

But to dismiss the entire language because one implementation appears
to have a performance bug that shows up in one test case is just silly.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Reginald Perry
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <sxlwwok2keh.fsf@yakko.zso.dec.com>
···@research.att.com (Andrew Koenig) writes:

> If you had said `I don't want to use C++ because the compiler available
> to me has a serious performance bug,' I would have nothing to say.
> If you had proof that what looks like a bug is actually an
> intrinsic flaw in the language, then I would also have nothing to say.
> 
> But to dismiss the entire language because one implementation appears
> to have a performance bug that shows up in one test case is just silly.
> -- 

I don't think that Richard is dismissing the C++ language. This whole
measurement thing has been blown up to silly proportions. This looks
to me like a very simple empirical study (emphasis on _very
simple_). People (not you of course) waltz over to
comp.lang.lisp/scheme and make stupid/absurd claims about how much
better C++ is than lisp/scheme from the one-dimensional point of view
of efficiency. This is very silly in my opinion since we all know that
for a large percentage of the complex applications out there, out of
all possible paths through the code, only through profiling can you
determine where to concentrate your efforts and that effort is usually
concentrated in a small percentage of the code.

Anyway these people (I am trying to be polite) waltz in here and
crosspost to most of the known universe that C++ is superior along the
efficiency dimension. In addition Mr. Stepanov says that C++ is the
only language in which he could effectively implement his ideas. So
Mr. O'Keefe said to himself "OK self. Since all of these people make
this claim about C++, I should be able to write a simple generic
program in C++, scheme and maybe a couple of other languages and the
C++ version should be clearly faster". He says this because people
keep making this "Lisp is sooooo slow" claim and it doesn't matter
that we point them to several Lisp and scheme implementations that are
obviously _not_ slow. No matter that we point to this feature or that
feature. It doesn't matter what we say, we are dammed if we do and
dammed if we don't. So if C++ is that straightforward, one should be
able to find a compiler that implements the language efficiently. In
fact I ran his first example in DEC C++ v5.6 deleting one #include
line. Seemed pretty quick. I know that it inlines pretty well. If you
don't believe me, give me a snippet of code and Ill send you back the
assembly file.

What he finds instead is that his program is slower in C++ with the
compilers he has available and that one won't compile it at all! Now
this is no less than what these whiners in the C++ camp do. Now of
course this does not include you or Mr. Boehm, or Mr. Stepanov or
Austen. What you guys would like to see is a complete study done. But
that is not the point. With the sort of money that has been put into
C++, I argue that if it was straightforward to compile generic C++
into very efficient code, it would be in every compiler, free, pay,
whatever. What we see instead is that the language is tough to compile
cleanly. Thats OK, lots of power, lots of trouble. But there is this
perception that I can walk up to some drunk on the street and he will
hand me a bottle and a blazingly fast C++ compiler. Whereas
Mr. Siskind, not even working in his specialty, with no direct funding
for this work, was able to write a Scheme compiler that competes with
C on some programs and beat the pants off of the given C++
program. And that the language was so straightforward, that there was
a little extra functionality in the Scheme code and it was still faster.

Mr. Stepanov claimed that C++ was the most effective language for
writing his generic algorithm package. At first glance I dismissed
that statement, but then I thought about it a bit. The conclusion that
I have come to is that that may be true in a very restricted
sense. Lisp+CLOS could do the exact same thing. The difference lies in
the history of the languages. Since Mr. Stroustrup did not package a
library with his implementation of C++, the field was wide open.
Because you had nothing, one could do anything. With Lisp, CLOS did
not get accepted until quite a few vendors, some of them pretty major
like DEC for example had DEC Lisp for VAX/VMS, already had
implementations out based on CLTL1. If the Lisp standards committee
could have somehow forced all of the vendors to redo those
implementations with CLOS throughout, it would have been pretty
straightforward to add in generic functions to do what he wanted. If
he felt that it was to slow, he could have used the MOP to make the
metaclass more efficient. Instead Lisp has some 20 years of baggage
that it still carries around (how many old-timers still use car/cdr
instead of first/rest).

So All Mr. O'Keefe did was write some simple generic functions and
compared. This is what thousands of small and big time C++ programmers
do when they are telling their boss which C++ implementation is the
best to buy. They don't have time to do extensive studies, they just
believe the hype machines of the rags that run these stupid benchmarks
which probably run nothing like the program they are designing, or run
micro-benchmarks which either tell you everything or nothing at all,
and then recomend which implementation to spend the next $30,000 on. He
just extended the test to other languages. C++ happened to lose. Now
the experts show up, with the whiners in the background yelling
sic'em, and you would like a formal study done.

Ill tell you what, lets all take a year or so out of our product
delivery schedules and design a fair test to compare the quality of
languages across the board. OO, functional, both, neither, logical,
all three, and assembly language too. Oops, my boss won't let me do
that, he just wants me to pick out the best C++ implementation so that
we can try to get this product out of the door. "Those other languages
are too darn slow Reggie. Get your butt back to your desk and find me
the best buzzword compliant, popular language implementation"(this is
sarcasm ladies and gents). Back to small-time hacks and
semi-meaningless micro-benchmarks. Let me know what the results
are. Remember, it has to be a significant problem.

Turnabout _is_ fair play in this case. Jam Now _not_ Jam Later

P.S. This is not directed at you personally. I have lots of respect
for you and the work you and BS and AS have done. It was because of
you and C++ that I got a promotion! So I can't be that upset with what
brung me to the dance. :-)

-------------------
Reginald S. Perry                      e-mail: ·····@zso.dec.com   
Digital Equipment Corporation
Performance Manager Group	               
http://www.UNIX.digital.com/unix/sysman/perf_mgr/

The train to Success makes many stops in the state of Failure.
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5n7tti$165$1@goanna.cs.rmit.edu.au>
Reginald Perry <·····@yakko.zso.dec.com> writes:
>I don't think that Richard is dismissing the C++ language.

Right.  Read the topic line:  "Re: STL efficiency".

>Mr. Stepanov claimed that C++ was the most effective language for
>writing his generic algorithm package.

Now let's see an example suggested by Stepanov.
Remember, my question is not whether C++ is better than Scheme,
but whether the STL is efficient.
If the STL is _not_ efficient, then language aspects that got in its
way cease to be evidence for the deficiency of other languages.

Stepanov challenged me to look at sorting 200 000 integers, instead of
however many strings it was I sorted.  I wasn't keen about that, because
I regard such a test as designedly biased towards quicksort.  Quicksort
is efficient _only_ when comparisons are unusually cheap.  Stepanov
pointed out that for large quantities of data, caching effects are
important, and said that quicksort was better than merge sort.  (As it
happens, if you are sorting strings implemented as header + separate
body, as libg++ does for <string>, it's actually fairly easy to see that
quicksort is much *worse* for caches than array merge.  That's another
story, though.)

Eventually, I decided to take the challenge, but
 - I have left Scheme out (this is not a Scheme-vs-C++ war)
 - I have done an array merge (quicksort takes 1N words, array merge
   takes 1.5Nspace, list merge takes 2N space when pointers and
   integers are both "words").
 - The main array is permanently allocated, while the cost of allocating
   and freeing 0.5N words of workspace _is_ included in the measured cost
   of the array merge.

The version of array merge used
 - ping-pongs instead of copying
 - has in-line optimal code for N=0..4
 - sorts the upper subfile before the lower one (this helps the cache)
 - has a merge loop that does one load per iteration, instead of the
   three you get from naive code (I have figured out how to unroll this
   loop and push the 'inner loop' cost of merging down even lower, but
   haven't tested that yet)
None of this is rocket science.  The improved merge loop and sorting
the upper subfile first are new; the other ideas were in existing code.

I measured three algorithms;

    - amgr
      the array merge outlined above (no, the code is _not_ available
      except to other RMIT staff members; it is so much better than the
      alternatives that I want to publish)

    - bsqd
      the 4.4BSD implementation of qsort(), revised to know what the
      element type is and to call LEQ() directly instead of a compare()
      parameter.  All the 'generic' overheads are thus removed.

    - sort
      the `sort' algorithm from <algorithm>, g++ version of the STL.

There are more measurements I would like to do, including
 - list merge
 - unrolling the merge loop in the array merge
 - other compilerSTL combinations
but I'm going away for a few days and wanted to get this out now.

The measurements were done on goanna.cs.rmit.edu.au.
It's an UltraSPARC.  fpversion says
 CPU's clock rate appears to be approximately 158.0 MHz.
 Kernel says CPU's clock rate is 167.0 MHz.
 Kernel says main memory's clock rate is 83.0 MHz.
 Sun-4 floating-point controller version 0 found.
 An UltraSPARC chip is available.
 FPU's frequency appears to be approximately 152.9 MHz.
cc -fast -native -xO4 -# 
reports, amongst other things,
 -xcache=16/32/1:512/64/1
which I think means that the compiler believes there are
 32k of L1 cache
512k of L2 cache, and from other tools I know that there are
512M of physical memory.

The measurements are all in microseconds per element.
To get the time in seconds for sorting N elements, multiply the
reported figure by N/1000000.

Here are the results:

C version (int a[N], uses int*)
with LEQ and LSS as macros:


      N  amrg  bsdq
  10000  0.87  1.17
  20000  0.96  1.27
  50000  1.08  1.37
 100000  1.14  1.58
 200000  1.22  1.60
 500000  1.32  1.70


C version (int a[N], uses int*)
with LEQ and LSS as external functions:


      N  amrg  bsdq
  10000  2.01  2.33
  20000  2.11  2.55
  50000  2.32  2.87
 100000  2.46  3.05
 200000  2.65  3.20
 500000  2.85  3.42

C++STL version (vector<int> a(N), uses vector<int>::iterator)
with LEQ and LSS as macros:

      N  amrg  bsdq  sort
  10000  0.93  1.19  1.01
  20000  1.01  1.21  1.10
  50000  1.07  1.37  1.21
 100000  1.16  1.47  1.27
 200000  1.24  1.60  1.42
 500000  1.32  1.71  1.54

C++STL version (vector<int> a(N), uses vector<int>::iterator)
with LEQ and LSS as external functions:

      N  amrg  bsdq  sort
  10000  1.89  2.30  3.00
  20000  2.06  2.48  3.22
  50000  2.14  2.64  3.31
 100000  2.38  2.88  3.66
 200000  2.50  3.08  3.86
 500000  2.69  3.24  4.24

The differences between the C and C++ times for amrg and bsdq
when LSS and LEQ are macros are within measurement error.
The C++ times when LSS and LEQ are external functions are
_better_ than the C times, even though the C++ version is
using vector<int> (a template instance).  Clearly, there are
no grounds here for blaming the C++ compiler's handling of
templates.

Of the three algorithms, the array merge is _always_ the fastest.
The 4.4BSD version of qsort() beats sort() handily when comparisons
involve function calls.  There are some tuning parameters which
were originally tuned for a SuperSPARC; it is probable that a bit
of tuning could improve the bsdq times.  (But then, I also have
good reason to expect that I canimprove the amrg times; I.)

Just looking at the last two lines of each table, we find

 - when LSS and LEQ are macros,  sort/amrg = 1.15 
 - when LSS and LEQ are externs, sort/amrg = 1.55

32k of L1 cache corresponds to 
  N = 32k/(4*1.5) =  5461 for amrg
  N = 32k/(4*1.0) =  8192 for bsdq, sort

so if the array merge were bad for L1 cache, it really ought to have
shown up in these figures (that's why the lower cutoff for N was taken
as 10000).

512k of L2 cache corresponds to
   N = 512k/(4*1.5) =  83381 for amrg
   N = 512k/(4*1.0) = 131072 for bsqd, sort

so if the array merge were bad for L2 cache, it really ought to have
shown up in the last three lines of each table.

I don't call taking 1.55 times longer "efficient".

The bottom line here is,
 if you switch from good C library code (and the amrg code is quite
 reusable via the preprocessor) to the STL, does it
 - make your program faster?
 - leave it about where it was?
 - make your program slower?

If it makes your program slower, what does it mean to call it "efficient"?

Yes, this particular hole can be patched.
It would be perfectly possible to write the sort() function in
<algorithm> so that it used array merge if the space were available,
switching over to quicksort only if the space were not available.
However, there's a reason why you wouldn't want to do that.

What's the reason?

The reason is that with present compilers, the C++ compiler has to
*see* the template.  The standard requires that _all_ the algorithms
be in the one <algorithm> header, so if you wnat to use _any_
algorithm (say 'find') the compiler has to scan _all_ over them.
Increasing the size of complexity of the sort() implementation
pushes up the compile time costs EVEN FOR PEOPLE WHO AREN'T USING sort().

This is an efficiency problem that can be attributed to the design of
the STL.  Is there any reason why we couldn't have had
	#include <algorithm/find>
	#include <algorithm/sort>
and so on, so that the compiler wouldn't have to parse algorithms you
weren't actually using?

Yes, I am aware of the concept of 'precompiled headers'.  No, I do not
have access to a C++ compiler that uses them.  (For me, they count as
`jam tomorrow'.)  They may _reduce_ that cost, but do they actually
_eliminate_ it?  Given the absence of basic features of the draft
standard such as namespaces, should compiler writers devote more
resources to implementing namepsaces, or to precompiled headers?

(Just to repeat:  I _would_ like to give corresponding Scheme figures,
but I wanted to get my preliminary results out.  For what it's worth,
the array merge has been thoroughly tested.)

-- 
Four policemen playing jazz on an up escalator in the railway station.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Paul Campbell
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <33981B43.31DFF4F5@lucent.com>
Richard A. O'Keefe wrote:

> 
> I don't call taking 1.55 times longer "efficient".
>

I thing that is quite cheap for the extra power, flexibility and
programmer
productivity. If it was 5 or 10 times slower I would be more worried.

Paul C.
UK
From: Max Moroz
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <338B6D2F.9AD4BF12@ucla.edu>
Andrew Koenig wrote:
> 
> > question is yes" is a triumph of faith over reason.  I *tried* it.
> > It just plain DID NOT HAPPEN THAT WAY.  C++ generic/C++ specific = 6/1.
> 
> If this is true -- that is, if what you think you are measuring is what
> you are actually measuring, then there is surely a performance bug somewhere.
> 
> It might be in the compiler, or in the particular implementation of STL,
> or elsewhere in the library, but something is definitely not working
> as it should.

No, the "performance bug" is mostly in the source code. Several people
have pointed to very clear misuse of STL features in the original code.
Richard was objective and kind enough to partially correct C++ code as I
suggested, and rerun it on his machine. He posted the results with the
total time reduced 2.4 times. Obviously, improvements can also be made
to Scheme and C code. But just as obviously, the results measure
Richard's relative skills in the three languages much more than they
measure anything about the languages themselves.

Also, if Richard went one step further and rerun the C++ coded with all
obvious corrections I suggested, including the use of const char*
instead of String to read in the input data, he would have obtained
another improvement; my experience shows it to be about 1.4 times.
Richard for some reason believes he must use String to test C++, while
in this context the advantage of const char* is obvious, and nothing
prohibits a C++ programmer from using it.

And if he went one *more* step further, and posted the C code he used, I
am sure we would identify the source of the remaining performance
difference. My guess is that after C and C++ codes are reasonably
optimized, C++ code would be slower than C by a factor of not more than
2. More likely, C++ code would run *just as fast* as C.

	-- Max
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mh49f$51i$1@goanna.cs.rmit.edu.au>
Max Moroz <······@ucla.edu> writes:
>Also, if Richard went one step further and rerun the C++ coded with all
>obvious corrections I suggested, including the use of const char*
>instead of String to read in the input data, he would have obtained
>another improvement; my experience shows it to be about 1.4 times.

Yeah.  I accept that.  But oh my, it is a *DAMNING* indictment of C++
to say "so <string> is in the standard, never mind, don't use it, just
keep on writing C instead if you want performance".

>Richard for some reason believes he must use String to test C++, while
>in this context the advantage of const char* is obvious, and nothing
>prohibits a C++ programmer from using it.

I have said why.

1) <string> is every bit as much a standard part of C++ (according to
   the two drafts I have seen) as strings are of Scheme.  If it is fair
   to Scheme to use Scheme strings, it must be equally fair to C++ to
   use C++ strings.

2) Using char const * is obviously error prone:  it _will_ be accepted as
   an argument for <set> or <list>, but the *wrong* comparison operator
   will be used.

>And if he went one *more* step further, and posted the C code he used, I
>am sure we would identify the source of the remaining performance
>difference. My guess is that after C and C++ codes are reasonably
>optimized, C++ code would be slower than C by a factor of not more than
>2. More likely, C++ code would run *just as fast* as C.

Yes, but then the C++ could would *BE* the C code.

I AM NOT AND HAVE NEVER BEEN INTERESTED IN THE QUESTION OF WHETHER C++
CAN BE AS FAST AS C.

I take it as my *starting* point that if you write C in C++, you will
get C performance.

So the fact that C++ can do as well as C, *IF* you avoid the specific
features of C++ (like <string>) is both granted in advance and totally
uninteresting.

The question was and remains whether using the new features (things like
<string>, <list>, <algorithm>, and so on) does in fact help to write
efficient programs.  Surely it is obvious to anyone that in order to
answer _that_ question one must actually _use_ the features one is
asking about!?

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Matt Austern
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <fxtraeqszr1.fsf@isolde.mti.sgi.com>
··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

> The question was and remains whether using the new features (things like
> <string>, <list>, <algorithm>, and so on) does in fact help to write
> efficient programs.

Some of them do, and some of them don't.  None of them help to write
efficient programs (or any other kind of programs) if they're used
blindly.

One of the morals of this exercise is  that writing a benchmark across
two different languages  is  tricky---it's  impossible, unless  you're
equally skilled in both languages.

If I tried to do the same task in Scheme and in C++, I'm certain that
I would finish the C++ program more quickly than the Scheme program
and that it would be more efficient.  I use C++ every day, after all,
but I haven't used Scheme for a few years; I wouldn't make any of the
obvious performance blunders in the C++ version that we've seen on
this thread, but I probably would make equally obvious performance
blunders in the Scheme version.
From: Thant Tessman
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <338F3C28.41C6@nospam.acm.org>
Matt Austern wrote:


> [...]  One of the morals of this exercise is that writing a benchmark 
> across two different languages is tricky [...]

Especially if you don't like the result.

-thant
From: Max Moroz
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <338E5AF1.FDD82B2D@ucla.edu>
> 
> >Richard for some reason believes he must use String to test C++, while
> >in this context the advantage of const char* is obvious, and nothing
> >prohibits a C++ programmer from using it.
> 
> I have said why.
> 
> 1) <string> is every bit as much a standard part of C++ (according to
>    the two drafts I have seen) as strings are of Scheme.  If it is fair
>    to Scheme to use Scheme strings, it must be equally fair to C++ to
>    use C++ strings.

Frankly, I don't know where <string> class is useful. After I
participated in this testing, I would think five times before I ever
again write #include <string>. But it has nothing to do with generic
programming, which I think was what you wanted to test. Generic
programming and STL actually *did* help by allowing me in a few minutes
and less than 10 lines of code to switch from sorted sets to hash sets
with large improvement in efficiency.

> 
> 2) Using char const * is obviously error prone:  it _will_ be accepted as
>    an argument for <set> or <list>, but the *wrong* comparison operator
>    will be used.

Yes. But it's very easy to avoid. After all const char* has lots of
other dangerous features, and still C/C++ people have been and are using
it A LOT. It's just a kind of idiom, which must be handled carefully.

> 
> >And if he went one *more* step further, and posted the C code he used, I
> >am sure we would identify the source of the remaining performance
> >difference. My guess is that after C and C++ codes are reasonably
> >optimized, C++ code would be slower than C by a factor of not more than
> >2. More likely, C++ code would run *just as fast* as C.
> 
> Yes, but then the C++ could would *BE* the C code.

Maybe. But maybe it's just a question of memory allocator, file I/O,
etc., which CAN be incorporated into C++ without making it C code. I
don't know at this moment.

Anyway, this has been a very interesting test for my understanding of
C++ and STL efficiency. As far as I am concerned, it lead me to trust
STL efficiency much more than I did before (if only because I wrote an
extra function, which STL did not provide; and it turned out STL's
approach was more efficient).

But it also eliminated my blind trust in the efficiency of *all* C++
features (particularly, in efficiency of <string> and endl; both being
at least twice less efficient than const char* and '\n').

	-- Max
From: Matt Austern
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <fxtlo4wua2h.fsf@isolde.mti.sgi.com>
Max Moroz <······@ucla.edu> writes:

> Anyway, this has been a very interesting test for my understanding of
> C++ and STL efficiency. As far as I am concerned, it lead me to trust
> STL efficiency much more than I did before (if only because I wrote an
> extra function, which STL did not provide; and it turned out STL's
> approach was more efficient).
> 
> But it also eliminated my blind trust in the efficiency of *all* C++
> features (particularly, in efficiency of <string> and endl; both being
> at least twice less efficient than const char* and '\n').

Blind trust tends to be a bad thing in general!  

I certainly encourage people to do more performance measurements.
Performance characteristics vary widely between different parts of the
C++ library, and between different implementations.  If one component
of the library is slow, you should complain to your vendor.  (In order
to make a sensible complaint, of course, you have to know exactly
which component you're measuring.)

Most STL implementations are at least tolerable, since everyone had
the example of the Stepanov-Lee implementation to study.  That's not
always true of strings, iostreams, valarrays, and other standard
library components, though: there was no freely distributable
demonstration implementation.  I have found that some string
implementation are more than an order of magnitude faster than others.
From: ······@SpryNET.com
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <33907431.64447590@news.interserv.com>
On Thu, 29 May 1997 21:43:29 -0700, Max Moroz <······@ucla.edu> wrote:

[snip]

>features (particularly, in efficiency of <string> and endl; both being
>at least twice less efficient than const char* and '\n').
>
>	-- Max

endl forces a buffer flush.

Charlie V.

email -> ······@SpryNET.com

- Found this in a post; hope it catches on ...

- Hey everybody - whenever you get email spam - put the address of the
  perpetrators in your .sig, and the email greppers will start spamming
  themselves: ··········@savetrees.com, ··········@agis.net
From: Joe Keane
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mregl$noo@shellx.best.com>
In article <·················@ucla.edu>
Max Moroz <······@ucla.edu> writes:
>Generic programming and STL actually *did* help by allowing me in a few
>minutes and less than 10 lines of code to switch from sorted sets to
>hash sets with large improvement in efficiency.

STL has no hash anything.  Dumb as all hell, but there it is.

--
Joe Keane, amateur mathematician
From: Pete Becker
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <33918E51.7A86@acm.org>
Joe Keane wrote:
> 
> In article <·················@ucla.edu>
> Max Moroz <······@ucla.edu> writes:
> >Generic programming and STL actually *did* help by allowing me in a few
> >minutes and less than 10 lines of code to switch from sorted sets to
> >hash sets with large improvement in efficiency.
> 
> STL has no hash anything.  Dumb as all hell, but there it is.

Not dumb at all, but a legitimate trade-off between useful features and
time to completion. This is the sort of decision we are all faced with
every day of our working lives, and I would expect that professional
programmers would understand it well enough to avoid a simiplistic
characterization like "dumb". Perhaps I am expecting too much.
	-- Pete
From: Joe Keane
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5n98aq$qdt@shellx.best.com>
In article <·············@acm.org>
Pete Becker <··········@acm.org> writes:
>Not dumb at all, but a legitimate trade-off between useful features and
>time to completion. This is the sort of decision we are all faced with
>every day of our working lives, and I would expect that professional
>programmers would understand it well enough to avoid a simiplistic
>characterization like "dumb". Perhaps I am expecting too much.

I understand well enough to know that pushing something out the door,
when it's missing important things, is not doing a favor to anyone.

Simple people may think it's `done', but we know that it will take five
or ten years to get something that's really usable, and trying to rush
things only moves that further away and causes problems for more people.
You can't change this, but people ignore it just the same.

For example, Pascal didn't have strings.  Of course people didn't stop
using strings, they implemented strings themselves, but not very well,
and vendors made non-standard extensions with lots of incompatibilities.
No one was helped by this, not vendors, not programmers, and not users.

Hash tables are so basic, i really just can't understand the reasoning.
Lisp has them.  Smalltalk has them.  Most C or C++ class libraries that
i've seen have them.  These things have nothing with the power of STL,
but STL has no hash anything.  That is just so weird.

Meanwhile the STL has comparison-based sets and mappings.  Sure they are
interesting theoretically, but i almost never find a place to use them.
Don't take this wrong, but i wonder if these people do lots of low-level
programming.  I'm all for having more choices, but it's also important
to have a good default, and that is not the right default.

We had a good chance to set a *standard* for how hash-based data
structures should work: what is the protocol; what are the requirements
on both sides; and what are the expected performance characteristics.

--
Joe Keane, amateur mathematician
From: Hans-Juergen Boehm
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <33983F94.41C6@mti.sgi.com>
Joe Keane wrote:
> 
> Hash tables are so basic, i really just can't understand the reasoning.
> Lisp has them.  Smalltalk has them.  Most C or C++ class libraries that
> i've seen have them.  These things have nothing with the power of STL,
> but STL has no hash anything.  That is just so weird.
> 
Welcome to the world of standards committee politics.

SGIs STL does have hash tables.  See http://www.sgi.com/Technology/STL.

-- 
Hans-Juergen Boehm
·····@mti.sgi.com
From: Pete Becker
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <339957A1.7B57@acm.org>
Hans-Juergen Boehm wrote:
> 
> Joe Keane wrote:
> >
> > Hash tables are so basic, i really just can't understand the reasoning.
> > Lisp has them.  Smalltalk has them.  Most C or C++ class libraries that
> > i've seen have them.  These things have nothing with the power of STL,
> > but STL has no hash anything.  That is just so weird.
> >
> Welcome to the world of standards committee politics.

That's a bit misleading. There was wholesale agreement that the proposal
for hash tables made good sense, but that there simply wasn't enough
time to integrate it carefully into the standard. That's not politics,
but sound engineering.

> 
> SGIs STL does have hash tables.  See http://www.sgi.com/Technology/STL.
>
From: Pete Becker
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <33982E33.7DD5@acm.org>
Joe Keane wrote:
> 
> In article <·············@acm.org>
> Pete Becker <··········@acm.org> writes:
> >Not dumb at all, but a legitimate trade-off between useful features and
> >time to completion. This is the sort of decision we are all faced with
> >every day of our working lives, and I would expect that professional
> >programmers would understand it well enough to avoid a simiplistic
> >characterization like "dumb". Perhaps I am expecting too much.
> 
> I understand well enough to know that pushing something out the door,
> when it's missing important things, is not doing a favor to anyone.

Nobody's "pushing something out the door". STL as it is currently
specified provides solid usable technology. The fact that there are
other things that people would like it to do does not change this. There
are always things that can be added. If you insist on adding them you
will never finish, and there will never be a C++ standard.

> 
> Simple people may think it's `done', but we know that it will take five
> or ten years to get something that's really usable, and trying to rush
> things only moves that further away and causes problems for more people.
> You can't change this, but people ignore it just the same.

Are you suggesting that we should wait five or ten years to standardize
C++?

> 
> For example, Pascal didn't have strings.  Of course people didn't stop
> using strings, they implemented strings themselves, but not very well,
> and vendors made non-standard extensions with lots of incompatibilities.
> No one was helped by this, not vendors, not programmers, and not users.
> 
> Hash tables are so basic, i really just can't understand the reasoning.

The reasoning is simple: adding hash tables to STL is not trivial.
Understanding the implications of that change would delay the standard
for at least a year. That is not an acceptable cost at this point.

> Lisp has them.  Smalltalk has them.  Most C or C++ class libraries that
> i've seen have them.  These things have nothing with the power of STL,
> but STL has no hash anything.  That is just so weird.
> 
> Meanwhile the STL has comparison-based sets and mappings.  Sure they are
> interesting theoretically, but i almost never find a place to use them.

I find maps extremely useful. Haven't done much with sets yet, but from
the number of questions I see about how they work, there seem to be
quite a few people using them.

> Don't take this wrong, but i wonder if these people do lots of low-level
> programming.  

During my time at Borland I ported the 32 bit linker from OS/2 to
Windows NT, wrote all of implib and impdef, did maintenance work on
tlib, did some of the implementation of the runtime library, designed
the message dispatching mechanism for OWL, and designed and implemented
OWL's initial support for multi-threaded applications. Many of the
members of the ANSI/ISO committee have similar qualifications. Yes,
"these people" do lots of low-level programming.

>I'm all for having more choices, but it's also important
> to have a good default, and that is not the right default.
> 
> We had a good chance to set a *standard* for how hash-based data
> structures should work: what is the protocol; what are the requirements
> on both sides; and what are the expected performance characteristics.

If we had done it we would have delayed all of the rest of the C++
Standard. That was not acceptable. If STL had been proposed a year or
two earlier we probably would have hash tables. That didn't happen, so
we have what we have. There are three options here:

1. Standardize C++ without STL, and get a standard sometime in 1998
2. Standardize C++ with STL but no hash tables, and get a standard
sometime in 1998
3. Standardize C++ with STL and hash tables, and get a standard in 1999
or 2000.

The absence of hash tables is not a serious enough problem to justify 1,
nor is it serious enough to justify 3.
	-- Pete
From: Max Moroz
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <3392103C.97660921@ucla.edu>
Joe Keane wrote:
> 
> In article <·················@ucla.edu>
> Max Moroz <······@ucla.edu> writes:
> >Generic programming and STL actually *did* help by allowing me in a few
> >minutes and less than 10 lines of code to switch from sorted sets to
> >hash sets with large improvement in efficiency.
> 
> STL has no hash anything.  Dumb as all hell, but there it is.

If you mean by STL the library defined by DWP, it has no hash
containers.

If you mean by STL the actual libraries (normally called STL) that are
available to C++ programmer today, they do have hash containers. E.g.
SGI STL does.


	-- Max
> 
> --
> Joe Keane, amateur mathematician
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5n7usk$2u4$1@goanna.cs.rmit.edu.au>
Max Moroz <······@ucla.edu> writes:
>Frankly, I don't know where <string> class is useful.

Then why is it in the standard?
There are <string> classes all over the place.
Programmers want to use them.
The <string> class in the C++ draft has obviously had a *ton* of design
work go into it.

>After I
>participated in this testing, I would think five times before I ever
>again write #include <string>. But it has nothing to do with generic
>programming, which I think was what you wanted to test.

Can it possibly be that an advocate of C++ doesn't know that
'string' _is_ an instance of a template?
The generic version is basic_string<charT, charTraits>.
A test using <string> *is* a test of generics!

>Generic
>programming and STL actually *did* help by allowing me in a few minutes
>and less than 10 lines of code to switch from sorted sets to hash sets
>with large improvement in efficiency.

Be careful what you say.
What you _said_ was a large improvement in efficiency.
What you _meant_ was a large decrease in inefficiency.
They are not the same thing.

I've had a Pascal library for the last six years that lets me switch
from sorted sets to hash sets with just two lines of change:

	instance(StringSet, `/public/241/sets/unordclset.imp',
	    EltType,  mystring,
	    EltEqual, mystringeql);

changes to

!	instance(StringSet, `/public/241/sets/hashset.imp',
	    EltType,  mystring,
+	    EltHash,  mystringhash,
	    EltEqual, mystringeql);

It really really really is not hard to set this kind of thing up.
All it takes is naming discipline.  (And of course, M4.  Sigh.)


>> 2) Using char const * is obviously error prone:  it _will_ be accepted as
>>    an argument for <set> or <list>, but the *wrong* comparison operator
>>    will be used.

>Yes. But it's very easy to avoid.

Sorry, this simply isn't true.
For example, when I was working on the integer sorting benchmarks
I posted earlier today, I was very puzzled when the STL sort() time
didn't change when I replaced a macro LSS by a function LSS.  It
turned out that it was picking up the default <.
It is *VERY EASY* to end up using the wrong comparison function in
the current STL interface.

>After all const char* has lots of
>other dangerous features, and still C/C++ people have been and are using
>it A LOT. It's just a kind of idiom, which must be handled carefully.

It's not const char* that's the problem,
it is a combination of the fact that
 - the STL interface uses built-in operators by default
 - the default < for const char * is wrong.
As I just said, I had precisely the same problem where the
default < for integers was the wrong comparison operator to use.

>Maybe. But maybe it's just a question of memory allocator, file I/O,
>etc., which CAN be incorporated into C++ without making it C code. I
>don't know at this moment.

It wasn't any of those things.  I have said over and over that the
code where the time was spent DIDN'T ALLOCATE ANY MEMORY OR DO ANY I/O.

>Anyway, this has been a very interesting test for my understanding of
>C++ and STL efficiency. As far as I am concerned, it lead me to trust
>STL efficiency much more than I did before (if only because I wrote an
>extra function, which STL did not provide; and it turned out STL's
>approach was more efficient).

Why did STL code running unexpectedly slow _increase_ your trust in
the STL?  I don't understand this.
-- 
Four policemen playing jazz on an up escalator in the railway station.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Hans-Juergen Boehm
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <3398491C.167E@mti.sgi.com>
Richard A. O'Keefe wrote:
> 
> Max Moroz <······@ucla.edu> writes:
> >Frankly, I don't know where <string> class is useful.
I don't either.
> 
> Then why is it in the standard?
Historical explanations are easy to come by, but probably not what you
were looking for.

> There are <string> classes all over the place.
> Programmers want to use them.
> The <string> class in the C++ draft has obviously had a *ton* of design
> work go into it.
It may have had a ton of design work go into it.  But if so, that
has largely been lost to history: 

1) The interface is completely irregular (e.g. I can insert a const
basic_string& into a string, but only if I specify its position with a
size_t instead of an iterator, there seems to be no uniform convention
about argument order, ...)  I'm told that this is unlikely to be fixed.

2) The current rules about reference lifetimes prohibit

string s;
...
if (s[0] == s[1]) ...
...

This has to be fixed.  But it's not easy to fix.  (Existing
implementations actually handle the above correctly, but fail on more
obscure sequential examples, and fail, though very rarely and
irreproducibly, on natural multi-threaded examples.  They basically
require locking between READ accesses from separate threads.)

Basic_string in the draft standard is, in my opinion, BROKEN.
Independent of performance, in my opinion, it should not be used as is.

> 
> Can it possibly be that an advocate of C++ doesn't know that
> 'string' _is_ an instance of a template?
> The generic version is basic_string<charT, charTraits>.
> A test using <string> *is* a test of generics!
> 

Generics are only part of the problem.  It has to do in large part with
big string headers and reference counting, which are unrelated to
generics.  (It does also have something to do with the fact that
comparison and swap are poorly or not specialized for
basic_string<char>, which you can blame on some current template and
library implementations.  The SGI one does specialize vector<char>
comparisons to an invocation of memcmp.  It doesn't do basic_string.)

-- 
Standard disclaimer ...
Hans-Juergen Boehm
·····@mti.sgi.com
From: Matt Austern
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <fxtraef4cfd.fsf@isolde.mti.sgi.com>
··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

> Can it possibly be that an advocate of C++ doesn't know that
> 'string' _is_ an instance of a template?
> The generic version is basic_string<charT, charTraits>.
> A test using <string> *is* a test of generics!

It is not, however, a test of generic programming or the STL.  The
class basic_string is not part of the STL; it has an entirely
different history and it had entirely different design goals.
Basic_string was not written with generic programming in mind.

Performance tests are interesting, and it's interesting to know that
there is at least one bad basic_string implementation out there.
(I've done performance tests myself, and I know of at least one
basic_string implementation that's even worse.)  It's important,
however, to know exactly what you're measuring.  I hope that none of
us would make the logical fallacy of thinking we're learned something
about a library by testing a component that isn't even part of that
library.
From: Michael Greenwald
Subject: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <michaelg.864866904@Xenon.Stanford.EDU>
I think there's value in understanding why Stepanov thought there was
some fundamental reason that he couldn't implement STL *efficiently*
in Scheme/Lisp.  I'm not sure I understood his comments.  Since he's
no longer reading this thread, could someone confirm my guess as to
his meaning?

It *seemed* like he was arguing as follows.  For efficiency, he needed
a (constant-time) random access data structure, like an array.
However, we need to be able to pass intermediate state to callers.
Lisp provides us no way to pass a pointer to the middle of an array
(locf isn't portable, of course, and neither is depending on CDR-coded
lists --- in any case we can't guarantee that the entire list
*remains* cdr-coded, so we can't just use the offset for access).  We
can use a list (then each cell is "named"), but then we lose random
access.  We can cons up a pointer to (array . offset), but then we
have to cons since we can't store this in an immediate reference, and
therefore must pay the cost of GC.  This doesn't use the arithmetic
properties of pointers, but it isn't supported in Lisp.  C++ *does*
support this.

I don't think I agree with Stepanov about how important this is, nor
how expensive, but it is a valid difference between Scheme/Lisp and
C++.  Is this what he meant?

On the other hand, (and assuming my understanding is correct) why
can't he pass back a *mutable* opaque object to the client of STL that
they then pass back in, where the index is (conventionally) only
modified by the data-structure-specific iteration code inside the STL?

Consing once per client call (to, say, sort) doesn't seem an onerous
burden.

Thanks for any clarification.
From: Chris Bitmead uid(x22068)
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <BITMEADC.97Jun3115524@Alcatel.com.au>
In article <··················@Xenon.Stanford.EDU> ········@Xenon.Stanford.EDU (Michael Greenwald) writes:

>It *seemed* like he was arguing as follows.  For efficiency, he needed
>a (constant-time) random access data structure, like an array.
>However, we need to be able to pass intermediate state to callers.
>Lisp provides us no way to pass a pointer to the middle of an array

You seem to be saying that Steponov wanted a vector of pointers with
the ability to take the address of one of those pointers and modify it
in place without knowing that the pointer was contained in an array.

I can't think of any reason at all for needing to do this, but give us
a specific example of where this is used. Otherwise, I think we will
argue over nothing.
From: Michael Greenwald
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <michaelg.865365547@Xenon.Stanford.EDU>
·············@Alcatel.com.au (Chris Bitmead uid(x22068)) writes:

>In article <··················@Xenon.Stanford.EDU> ········@Xenon.Stanford.EDU (Michael Greenwald) writes:

>>It *seemed* like he was arguing as follows.  For efficiency, he needed
>>a (constant-time) random access data structure, like an array.
>>However, we need to be able to pass intermediate state to callers.
>>Lisp provides us no way to pass a pointer to the middle of an array

>You seem to be saying that Steponov wanted a vector of pointers with
>the ability to take the address of one of those pointers and modify it
>in place without knowing that the pointer was contained in an array.

No, I "seemed to be saying" that I didn't understand exactly what
Stepanov was saying.  So I have no idea exactly what he wanted.  I
ventured a guess and was specifically asking for confirmation or
contradiction of my reading.  By proposing a concrete interpretation
of his more general remarks I thought I might be able to understand
his argument better.  That's all.

>I can't think of any reason at all for needing to do this, but give us
>a specific example of where this is used. Otherwise, I think we will
>argue over nothing.

Who is arguing?  I'm *asking* someone (anyone) to explain concretely
what Stepanov's general remarks meant.  In other words, a *specific*
example of something he needed to do to implement STL that could be
done in C++ but *not* in Lisp or Scheme.  No one came up with one, so
I proposed my own guess and am asking for confirmation or denial.

To be more clear: I'll grant you that he had no reason at all for
doing this, and that this is not what he needed, as long as you can
tell me what *he* did need that he couldn't get out of Lisp/Scheme.

(If your answer is "nothing", then you're in the wrong thread.  I've
accepted his argument that he understand Scheme well enough to not be
"just wrong" or "ignorant".  I would like to understand, concretely,
what *he* thought the drawback in Lisp/Scheme was.  I've read his
posts and do *not* understand them clearly.  Only when I _understand_
his point can I possibly hope to decide whether he's right or not.)
From: Anthony Shipman
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <5n0u2m$7vp@ephor.tusc.com.au>
In <··················@Xenon.Stanford.EDU> ········@Xenon.Stanford.EDU (Michael Greenwald) writes:

>I think there's value in understanding why Stepanov thought there was
>some fundamental reason that he couldn't implement STL *efficiently*
>in Scheme/Lisp.  I'm not sure I understood his comments.  Since he's
>no longer reading this thread, could someone confirm my guess as to
>his meaning?

>It *seemed* like he was arguing as follows.  For efficiency, he needed
>a (constant-time) random access data structure, like an array.
>However, we need to be able to pass intermediate state to callers.
>Lisp provides us no way to pass a pointer to the middle of an array
>(locf isn't portable, of course, and neither is depending on CDR-coded
>lists --- in any case we can't guarantee that the entire list
>*remains* cdr-coded, so we can't just use the offset for access).  We
>can use a list (then each cell is "named"), but then we lose random
>access.  We can cons up a pointer to (array . offset), but then we
>have to cons since we can't store this in an immediate reference, and
>therefore must pay the cost of GC.  This doesn't use the arithmetic
>properties of pointers, but it isn't supported in Lisp.  C++ *does*
>support this.

>I don't think I agree with Stepanov about how important this is, nor
>how expensive, but it is a valid difference between Scheme/Lisp and
>C++.  Is this what he meant?



My bit of the elephant, from his postings had to do with templates.  I'm
not familiar with the latest semantics in C++ but it appears from what
he was saying that he could use templates like generic functions with
multi-dispatch a la CLOS, dylan except that the dispatch is determined
entirely at compile-time.

This means he can have different algorithms selected for different types
of arguments and have no dynamic dispatch overhead.  This combined with
overloading and default arguments makes for neat end-user syntax
combined with efficiency (in theory).

-- 
Anthony Shipman                 "You've got to be taught before it's too late,
TUSC Computer Systems Pty Ltd    Before you are six or seven or eight,
                                 To hate all the people your relatives hate,
E-mail:  ···@tusc.com.au         You've got to be carefully taught."  R&H
From: Michael Greenwald
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <michaelg.865366122@Xenon.Stanford.EDU>
···@tusc.com.au (Anthony Shipman) writes:

>My bit of the elephant, from his postings had to do with templates.  I'm
>not familiar with the latest semantics in C++ but it appears from what
>he was saying that he could use templates like generic functions with
>multi-dispatch a la CLOS, dylan except that the dispatch is determined
>entirely at compile-time.

>This means he can have different algorithms selected for different types
>of arguments and have no dynamic dispatch overhead.  This combined with
>overloading and default arguments makes for neat end-user syntax
>combined with efficiency (in theory).

Point taken, but how does this square with his statement that his big
insight was (something like) "addresses are fundamental"?
From: Peter da Silva
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <5mk0jb$gi2@web.nmti.com>
In article <··················@xenon.stanford.edu>,
Michael Greenwald <········@Xenon.Stanford.EDU> wrote:
> We can cons up a pointer to (array . offset), but then we
> have to cons since we can't store this in an immediate reference, and
> therefore must pay the cost of GC.  This doesn't use the arithmetic
> properties of pointers, but it isn't supported in Lisp.  C++ *does*
> support this.

Actually, it does involve pointer arithmetic. The C language definition is
quite clear: the idiom "&A[i]" is exactly identical to "A + i". They are
different syntaxes, but the semantics are the same.

In fact if you allow that idiom to slip by as being "not pointer arithmetic"
then you can argue that C doesn't have pointer arithmetic at all, because
every example of "P + offset" can be transformed to the semanticly equivalent
form "&P[offset]".

Besides... is it even useful to talk about evading the cost of GC in a Lisp
program? You'd practically have to write "C in Lisp" to do it, with all
sorts of horrible machine and compiler specific knowledge. Ick.
-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: Michael Greenwald
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <michaelg.864915236@CS.Stanford.EDU>
·····@nmti.com (Peter da Silva) writes:

>In article <··················@xenon.stanford.edu>,
>Michael Greenwald <········@Xenon.Stanford.EDU> wrote:
>> We can cons up a pointer to (array . offset), but then we
>> have to cons since we can't store this in an immediate reference, and
>> therefore must pay the cost of GC.  This doesn't use the arithmetic
>> properties of pointers, but it isn't supported in Lisp.  C++ *does*
>> support this.

>Actually, it does involve pointer arithmetic. The C language definition is
>quite clear: the idiom "&A[i]" is exactly identical to "A + i". They are
>different syntaxes, but the semantics are the same.

We disagree, but I'll let it pass (until a separate message).  Just
change my example to &(a.foo) instead of &a[i], ok?  Or consider a
hypothetical variant of C++ that allows the & operator, but doesn't
allow + or - on pointers, and that performs bounds checking on array
indices.  It now has an operator that is not supported by Lisp (&),
but it doesn't do pointer arithmetic.

>In fact if you allow that idiom to slip by as being "not pointer arithmetic"
>then you can argue that C doesn't have pointer arithmetic at all, because
>every example of "P + offset" can be transformed to the semanticly equivalent
>form "&P[offset]".

I don't think that argument would hold.  What about 
 T *p1, *p2;
 ...
 frob(p1 - p2);

>Besides... is it even useful to talk about evading the cost of GC in a Lisp
>program? You'd practically have to write "C in Lisp" to do it, with all
>sorts of horrible machine and compiler specific knowledge. Ick.

Huh?  We *know* that (CONS A INDEX) conses.  It is *highly probable*
that (LOCF (STRUCT-FOO A)) doesn't cons to create the locative
(assuming a LOCF primitive existed).  (If you don't like to speculate
about non-portable and non-standard locf, it's still certainly valid
to compare the storage management cost of (CONS A INDEX) in Lisp to
&(a.foo) in C++).  But I'll argue with your general point: Of course
it makes sense to try to reduce storage management overhead in Lisp,
as long as you balance performance gains against decreased clarity and
maintainability).  What machine and compiler specific knowledge are
you talking about?  The size of fixnums?  That sort of knowledge is
known even in C++ programs -- you need to know when you're ints might
wrap around, the width of masks, etc.  Luckily, in both C++ and Lisp,
constants are defined to specify machine-specific limits,
e.g. most-positive-fixnum etc.

Or, are you talking about stack-allocation?  Limit yourself to
declarative statements of intent (e.g. (DECLARE (DYNAMIC-EXTENT FOO)))
and let the compiler do the rest.

Or what?
From: ········@wat.hookup.net
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <5mkdvb$g10$1@nic.wat.hookup.net>
In <··················@CS.Stanford.EDU>, ········@Radon.Stanford.EDU (Michael Greenwald) writes:
> ...
>>In fact if you allow that idiom to slip by as being "not pointer arithmetic"
>>then you can argue that C doesn't have pointer arithmetic at all, because
>>every example of "P + offset" can be transformed to the semanticly equivalent
>>form "&P[offset]".
>
>I don't think that argument would hold.  What about 
> T *p1, *p2;
> ...
> frob(p1 - p2);

Unless the ANSI standard has changed, this is an undefined operation.  You
can  do p1 - p2 only of both point to objects in the same array

>>Besides... is it even useful to talk about evading the cost of GC in a Lisp
>>program? You'd practically have to write "C in Lisp" to do it, with all
>>sorts of horrible machine and compiler specific knowledge. Ick.
>
> ...

Hartmann Schaffer
From: Michael Greenwald
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <michaelg.864932689@Xenon.Stanford.EDU>
········@wat.hookup.net writes:

>>I don't think that argument would hold.  What about 
>> T *p1, *p2;
>> ...
>> frob(p1 - p2);

>Unless the ANSI standard has changed, this is an undefined operation.  You
>can  do p1 - p2 only of both point to objects in the same array

I meant that to be implicit.  Sorry, I should have specified it more
clearly.  The counter-example still holds.
From: Peter da Silva
Subject: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <5mkc42$5no@web.nmti.com>
In article <··················@cs.stanford.edu>,
Michael Greenwald <········@Radon.Stanford.EDU> wrote:
> >Actually, it does involve pointer arithmetic. The C language definition is
> >quite clear: the idiom "&A[i]" is exactly identical to "A + i". They are
> >different syntaxes, but the semantics are the same.

> We disagree, but I'll let it pass (until a separate message).  Just
> change my example to &(a.foo) instead of &a[i], ok?

Would a locative that doesn't operate on arrays suffice for Stepanov's
purposes?

> Or consider a
> hypothetical variant of C++ that allows the & operator, but doesn't
> allow + or - on pointers, and that performs bounds checking on array
> indices.

The + and - operators on pointers are not necessary for pointer arithmetic,
and the C language doesn't define the results of exceeding the bounds of
an array... and there are at least two C compilers that do perform bounds
checking on array indexes.

Therefore anything you can do with pointer arithmetic in portable C you can
still do with this more restricted construct, therefore it is still pointer
arithmetic.

> I don't think that argument would hold.  What about 
>  T *p1, *p2;
>  ...
>  frob(p1 - p2);

This code fragment is meaningless unless I know where the contents of p1 and
p2 came from. It may not even be real "C"... you can't perform arithmetic
on pointers in the general case.

You're right, though. You can't derive the offset between two pointers into
the same array without using explicit "-" syntax. Is that operation required
by Stepanov?

> But I'll argue with your general point: Of course
> it makes sense to try to reduce storage management overhead in Lisp,
> as long as you balance performance gains against decreased clarity and
> maintainability).

Worrying about a CONS cell seems to me to be excessive micromanagement.

> What machine and compiler specific knowledge are
> you talking about?  The size of fixnums?  That sort of knowledge is
> known even in C++ programs -- you need to know when you're ints might
> wrap around, the width of masks, etc.

Yes, C++ is much lower level than Lisp. This is one of the problems with C++.

-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: Michael Greenwald
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <michaelg.864929473@Xenon.Stanford.EDU>
·····@nmti.com (Peter da Silva) writes:

>In article <··················@cs.stanford.edu>,
>Michael Greenwald <········@Radon.Stanford.EDU> wrote:
>> >Actually, it does involve pointer arithmetic. The C language definition is
>> >quite clear: the idiom "&A[i]" is exactly identical to "A + i". They are
>> >different syntaxes, but the semantics are the same.

>> 							Just
>> change my example to &(a.foo) instead of &a[i], ok?

>Would a locative that doesn't operate on arrays suffice for Stepanov's
>purposes?

Probably not, but it *is* sufficient to show that the semantics of "&"
are not _identical_ to pointer arithmetic on arrays.

>> Or consider a
>> hypothetical variant of C++ that allows the & operator, but doesn't
>> allow + or - on pointers, and that performs bounds checking on array
>> indices.

>The + and - operators on pointers are not necessary for pointer arithmetic,
>and the C language doesn't define the results of exceeding the bounds of
>an array... and there are at least two C compilers that do perform bounds
>checking on array indexes.

Fine, I was just trying to anticipate some possible objections.  It's
not fundamental to my point.

>Therefore anything you can do with pointer arithmetic in portable C you can
>still do with this more restricted construct, therefore it is still pointer
>arithmetic.

Explain to me again, how A[i] *is* pointer arithmetic but (aref a i)
is *not*.

>> I don't think that argument would hold.  What about 
>>  T *p1, *p2;
>>  ...
>>  frob(p1 - p2);

>This code fragment is meaningless unless I know where the contents of p1 and
>p2 came from. It may not even be real "C"... you can't perform arithmetic
>on pointers in the general case.

Actually, I was assuming they were pointing into the same array.

>You're right, though. You can't derive the offset between two pointers into
>the same array without using explicit "-" syntax. Is that operation required
>by Stepanov?

I don't know.

>> But I'll argue with your general point: Of course
>> it makes sense to try to reduce storage management overhead in Lisp,
>> as long as you balance performance gains against decreased clarity and
>> maintainability).

>Worrying about a CONS cell seems to me to be excessive micromanagement.

Worrying about millions of CONS cells might not; when using STL to
sort a data-set of thousands of elements could (in a bad
implementation) result in CONSing millions of cells of garbage.

As I said, I did *not* agree with Stepanov that efficiency *was* an
issue here; I was just guessing that he might have thought of that.

>> What machine and compiler specific knowledge are
>> you talking about?  The size of fixnums?  That sort of knowledge is
>> known even in C++ programs -- you need to know when you're ints might
>> wrap around, the width of masks, etc.

>Yes, C++ is much lower level than Lisp. This is one of the problems with C++.

All I meant (and thought I said) was that in optimizing *real*,
*large*, Lisp systems people *do* try to reduce storage management
overhead (when it is relevant), and don't always need to resort to
system and compiler-specific knowledge.
From: Peter da Silva
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <5mkslh$s5f@web.nmti.com>
In article <··················@xenon.stanford.edu>,
Michael Greenwald <········@Xenon.Stanford.EDU> wrote:
> ·····@nmti.com (Peter da Silva) writes:
> 
> >In article <··················@cs.stanford.edu>,
> >Michael Greenwald <········@Radon.Stanford.EDU> wrote:
> >> >Actually, it does involve pointer arithmetic. The C language definition is
> >> >quite clear: the idiom "&A[i]" is exactly identical to "A + i". They are
> >> >different syntaxes, but the semantics are the same.

> >> 							Just
> >> change my example to &(a.foo) instead of &a[i], ok?

> >Would a locative that doesn't operate on arrays suffice for Stepanov's
> >purposes?

> Probably not, but it *is* sufficient to show that the semantics of "&"
> are not _identical_ to pointer arithmetic on arrays.

Since I didn't claim that they were, but rather that a specific *usage* of
& was, I'm not enirely sure what your point is.

> >Therefore anything you can do with pointer arithmetic in portable C you can
> >still do with this more restricted construct, therefore it is still pointer
> >arithmetic.

> Explain to me again, how A[i] *is* pointer arithmetic but (aref a i)
> is *not*.

A[i] isn't pointer arithmetic.

&A[i] is.

I don't know enough about locatives to say whether (aref a i) is or not.

Can you take (aref a i) and generate from it the equivalent to (aref a j),
where j is derived from i by some integer operation?

(that is, the equivalent of "p = &A[i]" then "p[2]" being the same as
 "&A[i+2]".)

> >Worrying about a CONS cell seems to me to be excessive micromanagement.

> Worrying about millions of CONS cells might not; when using STL to
> sort a data-set of thousands of elements could (in a bad
> implementation) result in CONSing millions of cells of garbage.

Depending on how he's using it, he should be able to reuse the same CONS
cells with RPLACA and RPLACD, thus avoiding garbage collection until the
end of the operation.

-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: Michael Greenwald
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <michaelg.864944049@Xenon.Stanford.EDU>
·····@nmti.com (Peter da Silva) writes:

>In article <··················@xenon.stanford.edu>,
>Michael Greenwald <········@Xenon.Stanford.EDU> wrote:
>> ·····@nmti.com (Peter da Silva) writes:
>> 
>> >In article <··················@cs.stanford.edu>,
>> >Michael Greenwald <········@Radon.Stanford.EDU> wrote:
>> >> >Actually, it does involve pointer arithmetic. ... the idiom
>> >> >"&A[i]" is exactly identical to "A + i". ... the semantics are
>> >> >the same. 

>> >> Just change my example to &(a.foo) instead of &a[i], ok?

>> >Would a locative that doesn't operate on arrays suffice for Stepanov's
>> >purposes?

>> Probably not, but it *is* sufficient to show that the semantics of "&"
>> are not _identical_ to pointer arithmetic on arrays.

>Since I didn't claim that they were, but rather that a specific *usage* of
>& was, I'm not enirely sure what your point is.

Once again: my point is that there exists a property of C pointers
that (a) does not depend on pointer arithmetic and (b) scheme/lisp
does not possess.

>> >Therefore anything you can do with pointer arithmetic in portable C you can
>> >still do with this more restricted construct, therefore it is still pointer
>> >arithmetic.

How do you subtract two pointers in the restricted language?

>> Explain to me again, how A[i] *is* pointer arithmetic but (aref a i)
>> is *not*.

>A[i] isn't pointer arithmetic.

>&A[i] is.

>I don't know enough about locatives to say whether (aref a i) is or
>not.

I must have confused you.  (aref a i) doesn't use locatives.  It is
simply a reference to the i-th element of array a.

>Depending on how he's using it, he should be able to reuse the same CONS
>cells with RPLACA and RPLACD, thus avoiding garbage collection until the
>end of the operation.

Then, bingo, we agree.  I said (while trying to figure out what
Stepanov really meant, which *is* the subject of this thread) that
perhaps he didn't favor returning millions of copies of 
(array . index) because of the potential storage management overhead.  
You said it was pointless to try to avoid GC overhead in Lisp.
From: Peter da Silva
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <5ml6eb$stf@web.nmti.com>
In article <··················@xenon.stanford.edu>,
Michael Greenwald <········@Xenon.Stanford.EDU> wrote:
> Once again: my point is that there exists a property of C pointers
> that (a) does not depend on pointer arithmetic and (b) scheme/lisp
> does not possess.

It's a rather vague property, the ability to create a reference to an
object in an unordered collection. Since you can't do anything with it
that you couldn't do by referring to the object itself, what is the
point? It's sort of like transubstantiation, I guess.

> I must have confused you.  (aref a i) doesn't use locatives.  It is
> simply a reference to the i-th element of array a.

You must have.

Then (aref a 1) isn't pointer arithmetic any more than A[i] is.

> You said it was pointless to try to avoid GC overhead in Lisp.

Is that all you're worried about? I'll retract the statement. I still
think worrying about one CONS cell in a sea of allocations and deallocations
is silly, though.
-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: Markku Laukkanen
Subject: iterators (e.g.) in C++/STL versus Common Lisp versus programming versus universe
Date: 
Message-ID: <338E93DC.5309@research.nokia.com>
... Awaful much of messy comments by different persons SNIPPED

I suppose, that the original claim maid by Stephanov was, that the STL
iterators couldn't be implemented efficiently for e.g. Common Lisp. So
he chose the awful C++ syntax instead.

As a matter of fact, the STL is a very good tool for creating complex
algorithms in a single thread system.


BUT.....

Does anybody has a experience in so called thread safe implementations
of STL and their implementation of thread safe iterators ?

I would LOVE to hear, how e.g. RogueWave and ObjectSpace has implemented
the thread safe iterarors in a threaded programming model. And how fast
the implementations are compared to straigthforward brute & force
programming style without using the STL ?


	PKY
From: Wolfgang Grieskamp
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <1ohgfm9dkj.fsf@cs.tu-berlin.de>
Michael Greenwald <········@Xenon.Stanford.EDU> wrote:
> We can cons up a pointer to (array . offset), but then we
> have to cons since we can't store this in an immediate reference, and
> therefore must pay the cost of GC.  

A clever compiler for LISP or similar languages can relative easily
figure out, that (array . index) doesn't escapes its static scope in
the intended usage, and thus doesn't needs to be allocated on the
heap, but may reside in some other frame (eg the stack).

Conceptually no big problem -- as templates can be conceptually
specialised and optimised by c++ compilers ...

-- 
··@cs.tu-berlin.de  http://uebb.cs.tu-berlin.de/~wg/
From: Michael Greenwald
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <michaelg.864943277@Xenon.Stanford.EDU>
Wolfgang Grieskamp <··@cs.tu-berlin.de> writes:

>Michael Greenwald <········@Xenon.Stanford.EDU> wrote:
>> We can cons up a pointer to (array . offset), but then we
>> have to cons since we can't store this in an immediate reference, and
>> therefore must pay the cost of GC.  

>A clever compiler for LISP or similar languages can relative easily
>figure out, that (array . index) doesn't escapes its static scope in
>the intended usage, and thus doesn't needs to be allocated on the
>heap, but may reside in some other frame (eg the stack).

No, the whole point of the above was to pass (array . offset) out to
the caller (the client of STL), so it *does* escape its static scope.
From: Wolfgang Grieskamp
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <1oenapao2x.fsf@cs.tu-berlin.de>
········@Xenon.Stanford.EDU (Michael Greenwald) writes:

> Wolfgang Grieskamp <··@cs.tu-berlin.de> writes:
> 
> >A clever compiler for LISP or similar languages can relative easily
> >figure out, that (array . index) doesn't escapes its static scope in
> >the intended usage, and thus doesn't needs to be allocated on the
> >heap, but may reside in some other frame (eg the stack).
> 
> No, the whole point of the above was to pass (array . offset) out to
> the caller (the client of STL), so it *does* escape its static scope.

If (array . offset) is a kind of enumerator what I've supposed then
its constructor will naturally be inlined.  Once created, an
enumerator will usually not leave its scope.

Wolfgang

-- 
··@cs.tu-berlin.de  http://uebb.cs.tu-berlin.de/~wg/
From: Michael Greenwald
Subject: Re: What Stepanov *really* meant [Was: STL efficiency]
Date: 
Message-ID: <michaelg.864947246@Xenon.Stanford.EDU>
Wolfgang Grieskamp <··@cs.tu-berlin.de> writes:

>If (array . offset) is a kind of enumerator what I've supposed then
>its constructor will naturally be inlined.  Once created, an
>enumerator will usually not leave its scope.

Sorry for the confusion.  It is *not* an enumerator.  (array . index)
is dotted list notation for a tuple containing a pointer to an array
and an integer index.  It is like calling new to alloc a struct with
two slots, {T *array; int index; } and passing it to a caller instead
of returning &(array[index]).
From: David Hanley
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <338C6BCE.5731@nospan.netright.com>
Andrew Koenig wrote:
> 
> In article <···········@goanna.cs.rmit.edu.au> ··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:
> 
> [a 346-line message, to which I do not have time to respond in detail,
>  but of which I believe the main point is]
> 
> > Yeah, well, all I can say is that the test was actually written in the
> > expectation that it would show something very different.  I found the
> > results *shockingly* different from what I had expected.  It certainly
> > wasn't written with the intention of stressing whatever it is that it
> > does stress.
> 
>  ...
> 
> >  - an experienced programmer wrote a program in three languages.
> >  - the program is small, but follows an historically extremely important
> >    outline: sort two sequences and merge them.
> 
>  ...
> 
> >  - the results were shockingly different: 1:3:9 C:Scheme:C++ times.
> 
>  ...
> 
> > question is yes" is a triumph of faith over reason.  I *tried* it.
> > It just plain DID NOT HAPPEN THAT WAY.  C++ generic/C++ specific = 6/1.
> 
> If this is true -- that is, if what you think you are measuring is what
> you are actually measuring, then there is surely a performance bug somewhere.
> 
> It might be in the compiler, or in the particular implementation of STL,
> or elsewhere in the library, but something is definitely not working
> as it should.
> 
> If you had said `I don't want to use C++ because the compiler available
> to me has a serious performance bug,' I would have nothing to say.
> If you had proof that what looks like a bug is actually an
> intrinsic flaw in the language, then I would also have nothing to say.
> 
> But to dismiss the entire language because one implementation appears
> to have a performance bug that shows up in one test case is just silly.

	It does show one important thing: 

	This discussion came from the STL thread.  What eventually seemed to
come from
that thread was that C++ was used for STL was because it would be faster
than other
languages available.  At least, I never heard anyone claim that C++ was
used
for any other reason, and I asked many times.

	Mr okeffe's test shows that, a least for a naive program, such as
_many_ 
programmers might write, that STL in C++ will not necessarily be faster
than
the alternatives.

	Now, I don't care what Mr Stepanov wrote his STL in.  If he likes C++,
fine, wonderful.  I'd like to find out why he likes it, though I never
did figure
it out.  And now he's gone away.

	Incedentally, common lisp has hashtables, and I'd be interested to see
how common lisp code from a good compiler competes with the C++ STL
hashset version.
But I don't expect this would prove anything to anyone.  If the LISP
code were
slower, or the C++ code were slower, people would still remain in their
respective camps.  I personally think they'd be pretty close in speed if
both
were 'tweaked'.

	Interestingly, it seems that generics in SML ought to be as fast as the
'best possible' C++ generics, though ML compilers seem to have lagged. 
However, 
some LISP compilers seem to emit pretty good generic code!  

	dave
From: Matt Kennel (Remove 'nospam' to reply)
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <slrn5oumjd.o9b.kennel@lyapunov.ucsd.edu>
Would somebody point me to downloadable versions of these test programs
currently used?  I want to try my personal favorite langauge out, as I know
it has decent performance and genericity. 

-- 
Matthew B. Kennel/Institute for Nonlinear Science, UCSD/
Don't blame me, I voted for Emperor Mollari. 
From: Jeffrey Mark Siskind
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <xohiuzvfykg.fsf@qobi.nj.nec.com>
> Would somebody point me to downloadable versions of these test programs
> currently used?  I want to try my personal favorite langauge out, as I know
> it has decent performance and genericity. 

Here is some email that I sent to Richard O'Keefe. Among other things, it
contains C, C++, and several Scheme variants of the programs under question.

    Jeff (http://www.neci.nj.nec.com/homepages/qobi.html)
-------------------------------------------------------------------------------
Return-Path: <qobi>
Date: Tue, 3 Jun 1997 12:10:02 -0400
From: Jeffrey Mark Siskind <····@qobi.nj.nec.com>
To: ··@goanna.cs.rmit.edu.au
Subject: more on C++:Scheme:C
Reply-to: ····@research.nj.nec.com

Richard - I've done some more analysis on the code generated by Stalin for
your word-test example.

Let me first delineate the minor changes I made:

  1. I've made slight modifications to the C version to get it to compile
     under Linux.

	  ····@qobi>diff wds.c ../word-test-c.c
	  48,49d47
	  < #include "emalloc.h"
	  < #include "efopen.h"
	  64c62
	  <  return emalloc(n);
	  ---
	  >  return malloc(n);
	  67c65
	  <         block = emalloc(CHUNK);
	  ---
	  >     block = malloc(CHUNK);
	  83c81
	  <     register FILE *f = efopen_input(File);
	  ---
	  >     register FILE *f = fopen(File, "r");
	  102c100
	  <     efclose(f);
	  ---
	  >     fclose(f);

  2. I've changed the Scheme version to use 1.0e-2 instead of 1.0e-6 for
     TIME-IN-SECONDS because Linux has CLOCKS_PER_SEC=100.

  3. I wrapped the Scheme version in one large BEGIN. The reason for this is
     that, as will be described later, I'm going to redefine/shadow the
     definitions of the primitives CHAR-ALPHABETIC? and STRING<?. One could
     simply do either:

     (define (string<? s1 s2) ...)

     or:

     (set! string<? (lambda (s1 s2) ...))

     which would be completely equivalent to redefine a primitive. But with
     the flow analysis currently in Stalin, the variable STRING<? would then
     get a union type of the old and the new definition. 0CFA can't determine
     that the old version is never called so each call site will have a
     dispatch and the variable STRING<? will not be fictitious. By wrapping the
     whole program inside a BEGIN, a new binding context is created. Putting

     (define (string<? s1 s2) ...)

     in that context creates a different variable STRING<? that shadows the
     previous variable of the same name. That new variable will have only a
     single procedure assigned to it (by the definition) so it will be a
     monotype and will be fictitious. And the dispatch will be eliminated.

  4. You had specialized the code in your second Scheme version to remove the
     parameter LESS? and hardwire in STRING<?. This is unnecessary because
     Stalin does this for you. So I undid this specialization.

  5. I fixed a bug. The first Scheme version had (display W) while the
     second Scheme version had (display (car W)). The later is correct so I
     fixed the former.

  6. I removed the tabs in the string printouts so that it prints better.

Anyway, the first inefficiency I discovered is that Stalin has the following
definitions:

   (define (char-alphabetic? char)
    (or (and (char>=? char #\a) (char<=? char #\z))
        (and (char>=? char #\A) (char<=? char #\Z))))

   (define (char<=? char1 char2 . chars)
    (let loop ((char1 char1) (char2 char2) (chars chars))
     (and (<= (char->integer char1) (char->integer char2))
          (or (null? chars) (loop char2 (car chars) (cdr chars))))))

   (define (char>=? char1 char2 . chars)
    (let loop ((char1 char1) (char2 char2) (chars chars))
     (and (>= (char->integer char1) (char->integer char2))
          (or (null? chars) (loop char2 (car chars) (cdr chars))))))

Since CHAR<=? and CHAR>=? are each called twice they are not in-lined. And
thus the (OR (AND ...) (AND ...)) can't be compiled away as the branch tree
that would be part of the <= and and >= comparisons. And further, because
Stalin represents #T and #F differently than C TRUE and FALSE there is
translation involved. This translation is largely removed by Stalin when
comparisons like <= are in-lined in Boolean expressions which are in turn
in-lined in the antecedent of an IF. But that doesn't happen here. And since
CHAR-ALPHABETIC? happens in the inner loop of READ-WORD it slows it down
considerably. So one could rewrite the definition of CHAR-ALPHABETIC? to be:

   (define (char-alphabetic? char)
    (or (and (>= (char->integer char) (char->integer #\a))
	     (<= (char->integer char) (char->integer #\z)))
        (and (>= (char->integer char) (char->integer #\A))
	     (<= (char->integer char) (char->integer #\Z)))))

This still only gets part of the way because CHAR-ALPHABETIC? gets called
twice so it is not in-lined into the antecedent of an IF so there is still a
little residue of translation between #T/#F and TRUE/FALSE.

This would all be solved when I debug the polyvariance code in Stalin because
that will allow these things to be split and in-lined.

Anyway, it is interesting to note that even though CHAR<=? and CHAR>=? have
loops to handle varargs, these loops get compiled away because Stalin can
determine that the &rest arg is always (). Even the &rest arg gets compiled
away because it is fictitious. I was quite amazed by this myself that such
optimization follows from general principles.

The second inefficiency stems from the fact that Stalin uses C representations
for strings, i.e. null termination without an explicit length field. This
means that STRING-REF and STRING-SET! take O(n) because of the bounds check.
And all of the primitives which are built on top of STRING-REF and STRING-SET!,
like STRING<?, take O(n^2) instead of O(n). This is eliminated with -Ob. But
there are two related sources of inefficiency that are not eliminated with -Ob.
First, MAKE-STRING must initialize the new string with non-null characters,
even when not given the optional second argument because otherwise a mistaken
null will confuse the length. So MAKE-STRING takes O(n) instead of O(1). This
means that SUBSTRING has a higher constant factor:

   (define (substring string start end)
    (let ((r (make-string (- end start))))
     (let loop ((k start))
      (if (< k  end)
          (begin
	   (string-set! r (- k start) (string-ref string k))
	   (loop (+ k 1)))))
     r))

SUBSTRING makes two O(1) passes, one explicit by the loop and one implicit by
MAKE-STRING. I know of no way to avoid this short of making SUBSTRING a
primitive.

Second, STRING-LENGTH takes O(n) instead of O(1). This means that STRING<? has
a higher constant factor:

   (define (string<? string1 string2)
    (let ((n1 (string-length string1))
	  (n2 (string-length string2)))
     (let loop ((k 0))
      (if (= k n1)
	  (< k n2)
	  (and (< k n2)
	       (or (char<? (string-ref string1 k) (string-ref string2 k))
	           (and (char=? (string-ref string1 k) (string-ref string2 k))
			(loop (+ k 1)))))))))

I've manually folded out the varargs from the actual definition to yield the
above definition to emulate what Stalin would do. Still,  STRING<? makes three
O(1) passes, one explicit by the loop and two implicit by STRING-LENGTH. On
can avoid this by using the following definition:

   (define (string<? s1 s2)
    (let loop ((i 0))
     (if (zero? (char->integer (string-ref s1 i)))
         (not (zero? (char->integer (string-ref s2 i))))
         (and (not (zero? (char->integer (string-ref s2 i))))
	      (or (char<? (string-ref s1 i) (string-ref s2 i))
		  (and (char=? (string-ref s1 i) (string-ref s2 i))
		       (loop (+ i 1))))))))

This is not R4RS compliant and also only works with -Ob. But to avoid the
problems, I could make STRING<? a primitive and have that primitive do
essentially the above.

So I've made sixteen variants of the Scheme version of word-test. There are two
variants along each of four orthogonal axes.

The first axis is your word-test.sc vs. wtest2.sc (without the specialization
of LESS? in w-test2.) I call the former version <empty> and the later version
-short.

The second axis is replacing two LESS? tests with one COMPARE test that yields
'<, '=, or '>. The LESS? version is called <empty> and the COMPARE version is
called -compare.

The third axis is whether the builtin version of CHAR-ALPHABETIC? is used or
whether the modified version is used. The builtin version is called <empty>
and the modified version is called -alpha.

The fourth axis is whether the builting version of STRING<? is used or whether
the modified version is used. The builtin version is called <empty> and the
modified version is called -bound. For -compare versions (which don't use
STRING<?) this indicates whether the following R4RS-compliant version of
STRING-COMPARE is used:

   (define (string-compare s1 s2)
    (let ((l1 (string-length s1))
	  (l2 (string-length s2)))
     (let loop ((i 0))
      (cond ((= i l1) (if (= i l2) '= '<))
	    ((= i l2) '>)
	    ((char<? (string-ref s1 i) (string-ref s2 i)) '<)
	    ((char>? (string-ref s1 i) (string-ref s2 i)) '>)
	    (else (loop (+ i 1)))))))

or whether this following faster version is used:

   (define (string-compare s1 s2)
    (let loop ((i 0))
     (cond ((zero? (char->integer (string-ref s1 i)))
	    (if (zero? (char->integer (string-ref s2 i))) '= '<))
	   ((zero? (char->integer (string-ref s2 i))) '>)
	   ((char<? (string-ref s1 i) (string-ref s2 i)) '<)
	   ((char>? (string-ref s1 i) (string-ref s2 i)) '>)
	   (else (loop (+ i 1))))))

So the different versions are obtained by appending some subset of
{-short,-compare,-alpha,-bound} to the base name. There are no other
difference between the versions (as you can check with diff).

I've enclosed a shar file with all sixteen variants as well as the C and C++
variants and a shell script that compiles and runs them all three times. I've
also included the timing results.

Now for the results. The matching times and writing times were all so small as
to not be statiscally significant. Here are the best reading and sorting times:

       |  C | C++|Scheme|-alpha|-compare|-bound|-compare-bound|
---------------------------------------------------------------
reading|0.52|1.63|  1.68|  1.27|        |      |              |
sorting|1.18|8.17|  4.63|      |    3.47|  1.65|          1.56|

As expected, -alpha only affects reading time and -compare and -bound only
affect sorting time. -short doesn't affect anything significantly. -alpha
improves reading time by 22%. -compare improves sorting time by 25% -bound
improves sorting time by 64%. And -compare-bound improves sorting time by 66%.
Comparing the best reading and writing times yields a C++:Scheme:C ratio of
3.13:2.44:1 for reading times and 6.92:1.32:1 for sorting times. Comparing
TOTAL times yields:

     |  C | C++|Scheme|
-----------------------
TOTAL|1.71|9.85|  2.85|

or a C++:Scheme:C ratio of 5.76:1.66:1.

I believe that if CHAR-ALPHABETIC? is in-lined, the reading times will be on
parity and the TOTAL times will bring the Scheme:C ratio to about 30%. I'm
still disappointed because I don't know where the remaining 30% is coming
from. That will require further analysis.

    Jeff (http://www.neci.nj.nec.com/homepages/qobi.html)
-------------------------------------------------------------------------------
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1997-06-03 12:07 EDT by <····@qobi.nj.nec.com>.
# Source directory was `/home/qobi/stalin/tests/word-test'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#   2053 -rw-r--r-- results-best.text
#   5113 -rw-r--r-- results-clean.text
#   5647 -rw-r--r-- results.text
#   7167 -rw-r--r-- run.text
#   4268 -rwxr-xr-x word-test
#   5213 -rw-r--r-- word-test-c.c
#   2408 -rw-r--r-- word-test-cpp.cpp
#   3867 -rw-r--r-- word-test-scheme-alpha-bound.sc
#   3522 -rw-r--r-- word-test-scheme-alpha.sc
#   3615 -rw-r--r-- word-test-scheme-bound.sc
#   4011 -rw-r--r-- word-test-scheme-compare-alpha-bound.sc
#   3974 -rw-r--r-- word-test-scheme-compare-alpha.sc
#   3759 -rw-r--r-- word-test-scheme-compare-bound.sc
#   3722 -rw-r--r-- word-test-scheme-compare.sc
#   3334 -rw-r--r-- word-test-scheme-short-alpha-bound.sc
#   2989 -rw-r--r-- word-test-scheme-short-alpha.sc
#   3082 -rw-r--r-- word-test-scheme-short-bound.sc
#   3374 -rw-r--r-- word-test-scheme-short-compare-alpha-bound.sc
#   3337 -rw-r--r-- word-test-scheme-short-compare-alpha.sc
#   3122 -rw-r--r-- word-test-scheme-short-compare-bound.sc
#   3085 -rw-r--r-- word-test-scheme-short-compare.sc
#   2737 -rw-r--r-- word-test-scheme-short.sc
#   3270 -rw-r--r-- word-test-scheme.sc
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh10074; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= results-best.text ==============
if test -f 'results-best.text' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'results-best.text' '(file already exists)'
else
  $echo 'x -' extracting 'results-best.text' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'results-best.text' &&
word-test-c
reading     0.52
sorting     1.18
matching    0.01
writing     0.00
TOTAL       1.71
X
word-test-cpp
reading     1.63
sorting     8.19
matching    0.03
writing     0.00
TOTAL       9.85
X
word-test-scheme
reading     1.71
sorting     4.63
matching    0.03
writing     0.00
TOTAL       6.37
X
word-test-scheme-short
reading     1.71
sorting     4.64
matching    0.03
writing     0.00
TOTAL       6.38
X
word-test-scheme-compare
reading     1.69
sorting     3.47
matching    0.02
writing     0.01
TOTAL       5.19
X
word-test-scheme-short-compare
reading     1.68
sorting     3.47
matching    0.02
writing     0.01
TOTAL       5.18
X
word-test-scheme-alpha
reading     1.29
sorting     4.64
matching    0.02
writing     0.01
TOTAL       5.96
X
word-test-scheme-short-alpha
reading     1.34
sorting     4.65
matching    0.02
writing     0.01
TOTAL       6.02
X
word-test-scheme-compare-alpha
reading     1.30
sorting     3.48
matching    0.01
writing     0.01
TOTAL       4.80
X
word-test-scheme-short-compare-alpha
reading     1.30
sorting     3.48
matching    0.02
writing     0.00
TOTAL       4.80
X
word-test-scheme-bound
reading     1.71
sorting     1.66
matching    0.01
writing     0.01
TOTAL       3.39
X
word-test-scheme-short-bound
reading     1.72
sorting     1.66
matching    0.01
writing     0.01
TOTAL       3.40
X
word-test-scheme-compare-bound
reading     1.71
sorting     1.57
matching    0.01
writing     0.00
TOTAL       3.29
X
word-test-scheme-short-compare-bound
reading     1.70
sorting     1.57
matching    0.01
writing     0.00
TOTAL       3.28
X
word-test-scheme-alpha-bound
reading     1.27
sorting     1.66
matching    0.02
writing     0.00
TOTAL       2.95
X
word-test-scheme-short-alpha-bound
reading     1.30
sorting     1.67
matching    0.01
writing     0.00
TOTAL       2.98
X
word-test-scheme-compare-alpha-bound
reading     1.27
sorting     1.56
matching    0.01
writing     0.01
TOTAL       2.85
X
word-test-scheme-short-compare-alpha-bound
reading     1.28
sorting     1.59
matching    0.01
writing     0.00
TOTAL       2.88
SHAR_EOF
  $shar_touch -am 0529133997 'results-best.text' &&
  chmod 0644 'results-best.text' ||
  $echo 'restore of' 'results-best.text' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'results-best.text:' 'MD5 check failed'
d1d0e39fe0ebb4a4e193b419569c8766  results-best.text
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'results-best.text'`"
    test 2053 -eq "$shar_count" ||
    $echo 'results-best.text:' 'original size' '2053,' 'current size' "$shar_count!"
  fi
fi
# ============= results-clean.text ==============
if test -f 'results-clean.text' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'results-clean.text' '(file already exists)'
else
  $echo 'x -' extracting 'results-clean.text' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'results-clean.text' &&
word-test-c
reading     0.58
sorting     1.18
matching    0.01
writing     0.01
TOTAL       1.78
reading     0.52
sorting     1.18
matching    0.01
writing     0.00
TOTAL       1.71
reading     0.52
sorting     1.18
matching    0.02
writing     0.00
TOTAL       1.72
X
word-test-cpp
reading     1.67
sorting     8.17
matching    0.02
writing     0.00
TOTAL       9.86
reading     1.68
sorting     8.23
matching    0.02
writing     0.00
TOTAL       9.93
reading     1.63
sorting     8.19
matching    0.03
writing     0.00
TOTAL       9.85
X
word-test-scheme
reading     1.70
sorting     4.64
matching    0.03
writing     0.00
TOTAL       6.37
reading     1.71
sorting     4.65
matching    0.03
writing     0.00
TOTAL       6.39
reading     1.71
sorting     4.63
matching    0.03
writing     0.00
TOTAL       6.37
X
word-test-scheme-short
reading     1.71
sorting     4.64
matching    0.03
writing     0.00
TOTAL       6.38
reading     1.70
sorting     4.66
matching    0.03
writing     0.00
TOTAL       6.39
reading     1.74
sorting     4.66
matching    0.03
writing     0.00
TOTAL       6.43
X
word-test-scheme-compare
reading     1.69
sorting     3.47
matching    0.02
writing     0.01
TOTAL       5.19
reading     1.70
sorting     3.48
matching    0.02
writing     0.01
TOTAL       5.21
reading     1.72
sorting     3.47
matching    0.02
writing     0.00
TOTAL       5.21
X
word-test-scheme-short-compare
reading     1.68
sorting     3.47
matching    0.02
writing     0.01
TOTAL       5.18
reading     1.72
sorting     3.47
matching    0.02
writing     0.00
TOTAL       5.21
reading     1.70
sorting     3.48
matching    0.01
writing     0.01
TOTAL       5.20
X
word-test-scheme-alpha
reading     1.29
sorting     4.64
matching    0.02
writing     0.01
TOTAL       5.96
reading     1.34
sorting     4.64
matching    0.03
writing     0.01
TOTAL       6.02
reading     1.32
sorting     4.65
matching    0.03
writing     0.00
TOTAL       6.00
X
word-test-scheme-short-alpha
reading     1.37
sorting     4.67
matching    0.02
writing     0.01
TOTAL       6.07
reading     1.34
sorting     4.65
matching    0.02
writing     0.01
TOTAL       6.02
reading     1.37
sorting     4.68
matching    0.03
writing     0.01
TOTAL       6.09
X
word-test-scheme-compare-alpha
reading     1.30
sorting     3.48
matching    0.01
writing     0.01
TOTAL       4.80
reading     1.31
sorting     3.50
matching    0.02
writing     0.01
TOTAL       4.84
reading     1.39
sorting     3.47
matching    0.02
writing     0.01
TOTAL       4.89
X
word-test-scheme-short-compare-alpha
reading     1.33
sorting     3.47
matching    0.02
writing     0.01
TOTAL       4.83
reading     1.30
sorting     3.48
matching    0.02
writing     0.00
TOTAL       4.80
reading     1.30
sorting     3.51
matching    0.02
writing     0.00
TOTAL       4.83
X
word-test-scheme-bound
reading     1.71
sorting     1.66
matching    0.01
writing     0.01
TOTAL       3.39
reading     1.72
sorting     1.68
matching    0.02
writing     0.00
TOTAL       3.42
reading     1.78
sorting     1.67
matching    0.01
writing     0.01
TOTAL       3.47
X
word-test-scheme-short-bound
reading     1.75
sorting     1.66
matching    0.02
writing     0.00
TOTAL       3.43
reading     1.72
sorting     1.66
matching    0.01
writing     0.01
TOTAL       3.40
reading     1.78
sorting     1.65
matching    0.02
writing     0.00
TOTAL       3.45
X
word-test-scheme-compare-bound
reading     1.69
sorting     1.59
matching    0.01
writing     0.01
TOTAL       3.30
reading     1.71
sorting     1.57
matching    0.01
writing     0.00
TOTAL       3.29
reading     1.73
sorting     1.56
matching    0.01
writing     0.01
TOTAL       3.31
X
word-test-scheme-short-compare-bound
reading     1.70
sorting     1.57
matching    0.01
writing     0.00
TOTAL       3.28
reading     1.75
sorting     1.56
matching    0.01
writing     0.01
TOTAL       3.33
reading     1.72
sorting     1.57
matching    0.01
writing     0.00
TOTAL       3.30
X
word-test-scheme-alpha-bound
reading     1.27
sorting     1.66
matching    0.02
writing     0.00
TOTAL       2.95
reading     1.33
sorting     1.66
matching    0.01
writing     0.01
TOTAL       3.01
reading     1.30
sorting     1.66
matching    0.01
writing     0.01
TOTAL       2.98
X
word-test-scheme-short-alpha-bound
reading     1.30
sorting     1.67
matching    0.01
writing     0.00
TOTAL       2.98
reading     1.31
sorting     1.67
matching    0.01
writing     0.00
TOTAL       2.99
reading     1.34
sorting     1.67
matching    0.01
writing     0.01
TOTAL       3.03
X
word-test-scheme-compare-alpha-bound
reading     1.35
sorting     1.57
matching    0.00
writing     0.01
TOTAL       2.93
reading     1.30
sorting     1.57
matching    0.00
writing     0.01
TOTAL       2.88
reading     1.27
sorting     1.56
matching    0.01
writing     0.01
TOTAL       2.85
X
word-test-scheme-short-compare-alpha-bound
reading     1.27
sorting     1.59
matching    0.01
writing     0.01
TOTAL       2.88
reading     1.28
sorting     1.59
matching    0.01
writing     0.00
TOTAL       2.88
reading     1.30
sorting     1.59
matching    0.01
writing     0.00
TOTAL       2.90
SHAR_EOF
  $shar_touch -am 0529133297 'results-clean.text' &&
  chmod 0644 'results-clean.text' ||
  $echo 'restore of' 'results-clean.text' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'results-clean.text:' 'MD5 check failed'
96e90baa3518ca772423ad087c0ccff6  results-clean.text
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'results-clean.text'`"
    test 5113 -eq "$shar_count" ||
    $echo 'results-clean.text:' 'original size' '5113,' 'current size' "$shar_count!"
  fi
fi
# ============= results.text ==============
if test -f 'results.text' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'results.text' '(file already exists)'
else
  $echo 'x -' extracting 'results.text' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'results.text' &&
word-test-c
reading        0.580
sorting        1.180
matching       0.010
writing        0.010
TOTAL          1.780
reading        0.520
sorting        1.180
matching       0.010
writing        0.000
TOTAL          1.710
reading        0.520
sorting        1.180
matching       0.020
writing        0.000
TOTAL          1.720
X
word-test-cpp
reading        1.670
sorting        8.170
matching       0.020
writing        0.000
TOTAL          9.860
reading        1.680
sorting        8.230
matching       0.020
writing        0.000
TOTAL          9.930
reading        1.630
sorting        8.190
matching       0.030
writing        0.000
TOTAL          9.850
X
word-test-scheme
reading     1.7
sorting     4.64
matching    0.02999973
writing     0.0
TOTAL       6.369999
reading     1.71
sorting     4.65
matching    0.02999973
writing     0.0
TOTAL       6.389999
reading     1.71
sorting     4.63
matching    0.02999973
writing     0.0
TOTAL       6.369999
X
word-test-scheme-short
reading     1.71
sorting     4.64
matching    0.03000021
writing     0.0
TOTAL       6.38
reading     1.7
sorting     4.66
matching    0.02999973
writing     0.0
TOTAL       6.389999
reading     1.74
sorting     4.66
matching    0.02999973
writing     0.0
TOTAL       6.43
X
word-test-scheme-compare
reading     1.69
sorting     3.47
matching    0.01999998
writing     0.01000023
TOTAL       5.19
reading     1.7
sorting     3.48
matching    0.01999998
writing     0.01000023
TOTAL       5.21
reading     1.72
sorting     3.47
matching    0.01999998
writing     0.0
TOTAL       5.21
X
word-test-scheme-short-compare
reading     1.68
sorting     3.47
matching    0.01999998
writing     0.01000023
TOTAL       5.18
reading     1.72
sorting     3.47
matching    0.01999998
writing     0.0
TOTAL       5.21
reading     1.7
sorting     3.48
matching    0.01000023
writing     0.009999752
TOTAL       5.2
X
word-test-scheme-alpha
reading     1.29
sorting     4.64
matching    0.01999998
writing     0.01000023
TOTAL       5.96
reading     1.34
sorting     4.64
matching    0.03000021
writing     0.009999752
TOTAL       6.02
reading     1.32
sorting     4.65
matching    0.03000021
writing     0.0
TOTAL       6.0
X
word-test-scheme-short-alpha
reading     1.37
sorting     4.67
matching    0.01999998
writing     0.009999752
TOTAL       6.07
reading     1.34
sorting     4.65
matching    0.01999998
writing     0.009999752
TOTAL       6.02
reading     1.37
sorting     4.68
matching    0.02999973
writing     0.01000023
TOTAL       6.09
X
word-test-scheme-compare-alpha
reading     1.3
sorting     3.48
matching    0.009999752
writing     0.01000023
TOTAL       4.8
reading     1.31
sorting     3.5
matching    0.01999998
writing     0.009999752
TOTAL       4.84
reading     1.39
sorting     3.47
matching    0.02000046
writing     0.009999752
TOTAL       4.89
X
word-test-scheme-short-compare-alpha
reading     1.33
sorting     3.47
matching    0.01999998
writing     0.01000023
TOTAL       4.83
reading     1.3
sorting     3.48
matching    0.01999998
writing     0.0
TOTAL       4.8
reading     1.3
sorting     3.51
matching    0.01999998
writing     0.0
TOTAL       4.829999
X
word-test-scheme-bound
reading     1.71
sorting     1.66
matching    0.00999999
writing     0.00999999
TOTAL       3.39
reading     1.72
sorting     1.68
matching    0.01999998
writing     0.0
TOTAL       3.42
reading     1.78
sorting     1.67
matching    0.00999999
writing     0.00999999
TOTAL       3.47
X
word-test-scheme-short-bound
reading     1.75
sorting     1.66
matching    0.01999998
writing     0.0
TOTAL       3.43
reading     1.72
sorting     1.66
matching    0.00999999
writing     0.00999999
TOTAL       3.4
reading     1.78
sorting     1.65
matching    0.02000022
writing     0.0
TOTAL       3.45
X
word-test-scheme-compare-bound
reading     1.69
sorting     1.59
matching    0.00999999
writing     0.00999999
TOTAL       3.3
reading     1.71
sorting     1.57
matching    0.00999999
writing     0.0
TOTAL       3.29
reading     1.73
sorting     1.56
matching    0.00999999
writing     0.00999999
TOTAL       3.31
X
word-test-scheme-short-compare-bound
reading     1.7
sorting     1.57
matching    0.00999999
writing     0.0
TOTAL       3.28
reading     1.75
sorting     1.56
matching    0.00999999
writing     0.00999999
TOTAL       3.33
reading     1.72
sorting     1.57
matching    0.00999999
writing     0.0
TOTAL       3.3
X
word-test-scheme-alpha-bound
reading     1.27
sorting     1.66
matching    0.02000022
writing     0.0
TOTAL       2.95
reading     1.33
sorting     1.66
matching    0.00999999
writing     0.00999999
TOTAL       3.01
reading     1.3
sorting     1.66
matching    0.00999999
writing     0.00999999
TOTAL       2.98
X
word-test-scheme-short-alpha-bound
reading     1.3
sorting     1.67
matching    0.00999999
writing     0.0
TOTAL       2.98
reading     1.31
sorting     1.67
matching    0.00999999
writing     0.0
TOTAL       2.99
reading     1.34
sorting     1.67
matching    0.00999999
writing     0.00999999
TOTAL       3.03
X
word-test-scheme-compare-alpha-bound
reading     1.35
sorting     1.57
matching    0.0
writing     0.00999999
TOTAL       2.93
reading     1.3
sorting     1.57
matching    0.0
writing     0.00999999
TOTAL       2.88
reading     1.27
sorting     1.56
matching    0.00999999
writing     0.00999999
TOTAL       2.85
X
word-test-scheme-short-compare-alpha-bound
reading     1.27
sorting     1.59
matching    0.00999999
writing     0.00999999
TOTAL       2.88
reading     1.28
sorting     1.59
matching    0.00999999
writing     0.0
TOTAL       2.88
reading     1.3
sorting     1.59
matching    0.00999999
writing     0.0
TOTAL       2.9
SHAR_EOF
  $shar_touch -am 0529132697 'results.text' &&
  chmod 0644 'results.text' ||
  $echo 'restore of' 'results.text' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'results.text:' 'MD5 check failed'
b2a6fbccfc6c5caf25efe374ea975f3c  results.text
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'results.text'`"
    test 5647 -eq "$shar_count" ||
    $echo 'results.text:' 'original size' '5647,' 'current size' "$shar_count!"
  fi
fi
# ============= run.text ==============
if test -f 'run.text' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'run.text' '(file already exists)'
else
  $echo 'x -' extracting 'run.text' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'run.text' &&
····@qobi>./word-test
word-test-c
zA
zap
zombie
zone
zones
reading        0.580
sorting        1.180
matching       0.010
writing        0.010
TOTAL          1.780
zA
zap
zombie
zone
zones
reading        0.520
sorting        1.180
matching       0.010
writing        0.000
TOTAL          1.710
zA
zap
zombie
zone
zones
reading        0.520
sorting        1.180
matching       0.020
writing        0.000
TOTAL          1.720
word-test-cpp
W1 has 200170 words
W2 has 176278 words
DF has 3745 words
reading        1.670
sorting        8.170
matching       0.020
writing        0.000
TOTAL          9.860
W1 has 200170 words
W2 has 176278 words
DF has 3745 words
reading        1.680
sorting        8.230
matching       0.020
writing        0.000
TOTAL          9.930
W1 has 200170 words
W2 has 176278 words
DF has 3745 words
reading        1.630
sorting        8.190
matching       0.030
writing        0.000
TOTAL          9.850
word-test-scheme
zA
zap
zombie
zone
zones
reading     1.7
sorting     4.64
matching    0.02999973
writing     0.0
TOTAL       6.369999
zA
zap
zombie
zone
zones
reading     1.71
sorting     4.65
matching    0.02999973
writing     0.0
TOTAL       6.389999
zA
zap
zombie
zone
zones
reading     1.71
sorting     4.63
matching    0.02999973
writing     0.0
TOTAL       6.369999
word-test-scheme-short
zA
zap
zombie
zone
zones
reading     1.71
sorting     4.64
matching    0.03000021
writing     0.0
TOTAL       6.38
zA
zap
zombie
zone
zones
reading     1.7
sorting     4.66
matching    0.02999973
writing     0.0
TOTAL       6.389999
zA
zap
zombie
zone
zones
reading     1.74
sorting     4.66
matching    0.02999973
writing     0.0
TOTAL       6.43
word-test-scheme-compare
zA
zap
zombie
zone
zones
reading     1.69
sorting     3.47
matching    0.01999998
writing     0.01000023
TOTAL       5.19
zA
zap
zombie
zone
zones
reading     1.7
sorting     3.48
matching    0.01999998
writing     0.01000023
TOTAL       5.21
zA
zap
zombie
zone
zones
reading     1.72
sorting     3.47
matching    0.01999998
writing     0.0
TOTAL       5.21
word-test-scheme-short-compare
zA
zap
zombie
zone
zones
reading     1.68
sorting     3.47
matching    0.01999998
writing     0.01000023
TOTAL       5.18
zA
zap
zombie
zone
zones
reading     1.72
sorting     3.47
matching    0.01999998
writing     0.0
TOTAL       5.21
zA
zap
zombie
zone
zones
reading     1.7
sorting     3.48
matching    0.01000023
writing     0.009999752
TOTAL       5.2
word-test-scheme-alpha
zA
zap
zombie
zone
zones
reading     1.29
sorting     4.64
matching    0.01999998
writing     0.01000023
TOTAL       5.96
zA
zap
zombie
zone
zones
reading     1.34
sorting     4.64
matching    0.03000021
writing     0.009999752
TOTAL       6.02
zA
zap
zombie
zone
zones
reading     1.32
sorting     4.65
matching    0.03000021
writing     0.0
TOTAL       6.0
word-test-scheme-short-alpha
zA
zap
zombie
zone
zones
reading     1.37
sorting     4.67
matching    0.01999998
writing     0.009999752
TOTAL       6.07
zA
zap
zombie
zone
zones
reading     1.34
sorting     4.65
matching    0.01999998
writing     0.009999752
TOTAL       6.02
zA
zap
zombie
zone
zones
reading     1.37
sorting     4.68
matching    0.02999973
writing     0.01000023
TOTAL       6.09
word-test-scheme-compare-alpha
zA
zap
zombie
zone
zones
reading     1.3
sorting     3.48
matching    0.009999752
writing     0.01000023
TOTAL       4.8
zA
zap
zombie
zone
zones
reading     1.31
sorting     3.5
matching    0.01999998
writing     0.009999752
TOTAL       4.84
zA
zap
zombie
zone
zones
reading     1.39
sorting     3.47
matching    0.02000046
writing     0.009999752
TOTAL       4.89
word-test-scheme-short-compare-alpha
zA
zap
zombie
zone
zones
reading     1.33
sorting     3.47
matching    0.01999998
writing     0.01000023
TOTAL       4.83
zA
zap
zombie
zone
zones
reading     1.3
sorting     3.48
matching    0.01999998
writing     0.0
TOTAL       4.8
zA
zap
zombie
zone
zones
reading     1.3
sorting     3.51
matching    0.01999998
writing     0.0
TOTAL       4.829999
word-test-scheme-bound
zA
zap
zombie
zone
zones
reading     1.71
sorting     1.66
matching    0.00999999
writing     0.00999999
TOTAL       3.39
zA
zap
zombie
zone
zones
reading     1.72
sorting     1.68
matching    0.01999998
writing     0.0
TOTAL       3.42
zA
zap
zombie
zone
zones
reading     1.78
sorting     1.67
matching    0.00999999
writing     0.00999999
TOTAL       3.47
word-test-scheme-short-bound
zA
zap
zombie
zone
zones
reading     1.75
sorting     1.66
matching    0.01999998
writing     0.0
TOTAL       3.43
zA
zap
zombie
zone
zones
reading     1.72
sorting     1.66
matching    0.00999999
writing     0.00999999
TOTAL       3.4
zA
zap
zombie
zone
zones
reading     1.78
sorting     1.65
matching    0.02000022
writing     0.0
TOTAL       3.45
word-test-scheme-compare-bound
zA
zap
zombie
zone
zones
reading     1.69
sorting     1.59
matching    0.00999999
writing     0.00999999
TOTAL       3.3
zA
zap
zombie
zone
zones
reading     1.71
sorting     1.57
matching    0.00999999
writing     0.0
TOTAL       3.29
zA
zap
zombie
zone
zones
reading     1.73
sorting     1.56
matching    0.00999999
writing     0.00999999
TOTAL       3.31
word-test-scheme-short-compare-bound
zA
zap
zombie
zone
zones
reading     1.7
sorting     1.57
matching    0.00999999
writing     0.0
TOTAL       3.28
zA
zap
zombie
zone
zones
reading     1.75
sorting     1.56
matching    0.00999999
writing     0.00999999
TOTAL       3.33
zA
zap
zombie
zone
zones
reading     1.72
sorting     1.57
matching    0.00999999
writing     0.0
TOTAL       3.3
word-test-scheme-alpha-bound
zA
zap
zombie
zone
zones
reading     1.27
sorting     1.66
matching    0.02000022
writing     0.0
TOTAL       2.95
zA
zap
zombie
zone
zones
reading     1.33
sorting     1.66
matching    0.00999999
writing     0.00999999
TOTAL       3.01
zA
zap
zombie
zone
zones
reading     1.3
sorting     1.66
matching    0.00999999
writing     0.00999999
TOTAL       2.98
word-test-scheme-short-alpha-bound
zA
zap
zombie
zone
zones
reading     1.3
sorting     1.67
matching    0.00999999
writing     0.0
TOTAL       2.98
zA
zap
zombie
zone
zones
reading     1.31
sorting     1.67
matching    0.00999999
writing     0.0
TOTAL       2.99
zA
zap
zombie
zone
zones
reading     1.34
sorting     1.67
matching    0.00999999
writing     0.00999999
TOTAL       3.03
word-test-scheme-compare-alpha-bound
zA
zap
zombie
zone
zones
reading     1.35
sorting     1.57
matching    0.0
writing     0.00999999
TOTAL       2.93
zA
zap
zombie
zone
zones
reading     1.3
sorting     1.57
matching    0.0
writing     0.00999999
TOTAL       2.88
zA
zap
zombie
zone
zones
reading     1.27
sorting     1.56
matching    0.00999999
writing     0.00999999
TOTAL       2.85
word-test-scheme-short-compare-alpha-bound
zA
zap
zombie
zone
zones
reading     1.27
sorting     1.59
matching    0.00999999
writing     0.00999999
TOTAL       2.88
zA
zap
zombie
zone
zones
reading     1.28
sorting     1.59
matching    0.00999999
writing     0.0
TOTAL       2.88
zA
zap
zombie
zone
zones
reading     1.3
sorting     1.59
matching    0.00999999
writing     0.0
TOTAL       2.9
2907.450u 15.040s 52:51.27 92.1% 0+0k 0+0io 46596pf+0w
····@qobi>
SHAR_EOF
  $shar_touch -am 0529132097 'run.text' &&
  chmod 0644 'run.text' ||
  $echo 'restore of' 'run.text' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'run.text:' 'MD5 check failed'
15208c47d7af7dcd26859e17a0793298  run.text
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'run.text'`"
    test 7167 -eq "$shar_count" ||
    $echo 'run.text:' 'original size' '7167,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test ==============
if test -f 'word-test' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test' '(file already exists)'
else
  $echo 'x -' extracting 'word-test' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test' &&
#!/bin/csh -f
# needs work: should try without -Ot
# needs work: should try without -O6
# needs work: should try with -O2
set o = "-Ob -On -Ot -cc gcc -copt -O6"
gcc -O6 -o word-test-c word-test-c.c
g++ -O6 -o word-test-cpp word-test-cpp.cpp
stalin-0.7 $o word-test-scheme.sc
stalin-0.7 $o word-test-scheme-short.sc
stalin-0.7 $o word-test-scheme-compare.sc
stalin-0.7 $o word-test-scheme-short-compare.sc
stalin-0.7 $o word-test-scheme-alpha.sc
stalin-0.7 $o word-test-scheme-short-alpha.sc
stalin-0.7 $o word-test-scheme-compare-alpha.sc
stalin-0.7 $o word-test-scheme-short-compare-alpha.sc
stalin-0.7 $o word-test-scheme-bound.sc
stalin-0.7 $o word-test-scheme-short-bound.sc
stalin-0.7 $o word-test-scheme-compare-bound.sc
stalin-0.7 $o word-test-scheme-short-compare-bound.sc
stalin-0.7 $o word-test-scheme-alpha-bound.sc
stalin-0.7 $o word-test-scheme-short-alpha-bound.sc
stalin-0.7 $o word-test-scheme-compare-alpha-bound.sc
stalin-0.7 $o word-test-scheme-short-compare-alpha-bound.sc
rm -rf /tmp/{EM,GC}
zcat /usr/info/emacs* >/tmp/EM
zcat /usr/info/gcc* >/tmp/GC
echo word-test-c
X./word-test-c /tmp/{EM,GC}|tail
X./word-test-c /tmp/{EM,GC}|tail
X./word-test-c /tmp/{EM,GC}|tail
echo word-test-cpp
X./word-test-cpp /tmp/{EM,GC}|tail
X./word-test-cpp /tmp/{EM,GC}|tail
X./word-test-cpp /tmp/{EM,GC}|tail
echo word-test-scheme
X./word-test-scheme /tmp/{EM,GC}|tail
X./word-test-scheme /tmp/{EM,GC}|tail
X./word-test-scheme /tmp/{EM,GC}|tail
echo word-test-scheme-short
X./word-test-scheme-short /tmp/{EM,GC}|tail
X./word-test-scheme-short /tmp/{EM,GC}|tail
X./word-test-scheme-short /tmp/{EM,GC}|tail
echo word-test-scheme-compare
X./word-test-scheme-compare /tmp/{EM,GC}|tail
X./word-test-scheme-compare /tmp/{EM,GC}|tail
X./word-test-scheme-compare /tmp/{EM,GC}|tail
echo word-test-scheme-short-compare
X./word-test-scheme-short-compare /tmp/{EM,GC}|tail
X./word-test-scheme-short-compare /tmp/{EM,GC}|tail
X./word-test-scheme-short-compare /tmp/{EM,GC}|tail
echo word-test-scheme-alpha
X./word-test-scheme-alpha /tmp/{EM,GC}|tail
X./word-test-scheme-alpha /tmp/{EM,GC}|tail
X./word-test-scheme-alpha /tmp/{EM,GC}|tail
echo word-test-scheme-short-alpha
X./word-test-scheme-short-alpha /tmp/{EM,GC}|tail
X./word-test-scheme-short-alpha /tmp/{EM,GC}|tail
X./word-test-scheme-short-alpha /tmp/{EM,GC}|tail
echo word-test-scheme-compare-alpha
X./word-test-scheme-compare-alpha /tmp/{EM,GC}|tail
X./word-test-scheme-compare-alpha /tmp/{EM,GC}|tail
X./word-test-scheme-compare-alpha /tmp/{EM,GC}|tail
echo word-test-scheme-short-compare-alpha
X./word-test-scheme-short-compare-alpha /tmp/{EM,GC}|tail
X./word-test-scheme-short-compare-alpha /tmp/{EM,GC}|tail
X./word-test-scheme-short-compare-alpha /tmp/{EM,GC}|tail
echo word-test-scheme-bound
X./word-test-scheme-bound /tmp/{EM,GC}|tail
X./word-test-scheme-bound /tmp/{EM,GC}|tail
X./word-test-scheme-bound /tmp/{EM,GC}|tail
echo word-test-scheme-short-bound
X./word-test-scheme-short-bound /tmp/{EM,GC}|tail
X./word-test-scheme-short-bound /tmp/{EM,GC}|tail
X./word-test-scheme-short-bound /tmp/{EM,GC}|tail
echo word-test-scheme-compare-bound
X./word-test-scheme-compare-bound /tmp/{EM,GC}|tail
X./word-test-scheme-compare-bound /tmp/{EM,GC}|tail
X./word-test-scheme-compare-bound /tmp/{EM,GC}|tail
echo word-test-scheme-short-compare-bound
X./word-test-scheme-short-compare-bound /tmp/{EM,GC}|tail
X./word-test-scheme-short-compare-bound /tmp/{EM,GC}|tail
X./word-test-scheme-short-compare-bound /tmp/{EM,GC}|tail
echo word-test-scheme-alpha-bound
X./word-test-scheme-alpha-bound /tmp/{EM,GC}|tail
X./word-test-scheme-alpha-bound /tmp/{EM,GC}|tail
X./word-test-scheme-alpha-bound /tmp/{EM,GC}|tail
echo word-test-scheme-short-alpha-bound
X./word-test-scheme-short-alpha-bound /tmp/{EM,GC}|tail
X./word-test-scheme-short-alpha-bound /tmp/{EM,GC}|tail
X./word-test-scheme-short-alpha-bound /tmp/{EM,GC}|tail
echo word-test-scheme-compare-alpha-bound
X./word-test-scheme-compare-alpha-bound /tmp/{EM,GC}|tail
X./word-test-scheme-compare-alpha-bound /tmp/{EM,GC}|tail
X./word-test-scheme-compare-alpha-bound /tmp/{EM,GC}|tail
echo word-test-scheme-short-compare-alpha-bound
X./word-test-scheme-short-compare-alpha-bound /tmp/{EM,GC}|tail
X./word-test-scheme-short-compare-alpha-bound /tmp/{EM,GC}|tail
X./word-test-scheme-short-compare-alpha-bound /tmp/{EM,GC}|tail
SHAR_EOF
  $shar_touch -am 0528203597 'word-test' &&
  chmod 0755 'word-test' ||
  $echo 'restore of' 'word-test' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test:' 'MD5 check failed'
4b5f234f0147ea2dd277b67a279b05d6  word-test
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test'`"
    test 4268 -eq "$shar_count" ||
    $echo 'word-test:' 'original size' '4268,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-c.c ==============
if test -f 'word-test-c.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-c.c' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-c.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-c.c' &&
/*  Comparison.
X    cat /opt/gnu/info/emacs* > /tmp/EM
X	1_201_163 bytes, 185_809 words, 27_844 lines.
X
X    cat /opt/gnu/info/gcc* > /tmp/GC
X	1_210_988 bytes, 176_125 words, 27_413 lines.
X
X    Scheme version (Stalin 0.7)
X	stalin-sun4m-SunOS-5.4 -cc gcc -copt -O6 -Ob -On word-test
X	word-test /tmp/{EM,GC} | tail
X    C version (gcc 2.7.2.2)
X	gcc -O6 wds.c
X	a.out /tmp/{EM,GC} | tail
X    C++ version (g++ 2.7.2.2)
X	g++ -O6 wds.cpp
X	a.out /tmp/{EM,GC} | tail
X
X    Results		Scheme1		Scheme2		C		C++
X    reading		1.68		1.70		0.56		2.15
X    sorting		2.99		2.75		0.77  5.64+1.52=7.16
X    matching		0.03		0.03		0.01		0.03
X    writing		0.00		0.00		0.00		0.24
X    total		4.70		4.48		1.34		9.58
X
X    Lines		57		124		233		92
X
X    Scheme1 is my original generic version.  It uses a generic library for
X    set processing, which is not included in the line count (like C++).
X    Scheme2 is hacked to use string<? explicitly instead of less?
X    and also uses more compact source code for ord-union! and
X    ord-difference!  No change to reading or writing time was
X    expected, but it _does_ seem to have improved the sorting time.
X    Now, except for calling string<? twice instead of strcmp() once,				 
X    the sorting code is effectively identical to the C code.  If we
X    assume that the cost of strcmp() accounts for 0.77 seconds, then
X    maybe the Scheme sorting time would be 1.98 seconds instead of
X    2.75 seconds, which is still more than double the C time.  The
X    Stalin (0.7) compiler cannot eliminate all run-time tests; in the
X    case of Scheme2 this is because the sorting() routine protects
X    its cars and cdrs with an integer length (n >= 2 -> (pair? seq)
X    and (pair? (cdr seq))) but that's way beyond Stalin's abilities.    
X
X    The C++ version takes 5.64 seconds to sort followed by 1.52 seconds
X    to remove duplicates.  It takes twice as long to remove duplicates
X    as the C version takes to do the whole list->set conversion!
X    Trying to do this in C++ gave me some nasty surprises.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
X
#define CHUNK (1024*1021)
char *block;
size_t left;
X
void *alloc(size_t n) {
X    void *result;
X    n = (n+7)&~7;
X    if (n >= CHUNK) {
X	return malloc(n);
X    }
X    if (left < n) {
X	block = malloc(CHUNK);
X	left = CHUNK;
X    }
X    result = block;
X    block += n;
X    left -= n;
X    return result;
}
X
typedef struct Word *list;
struct Word {
X    list        next;
X    char const *word;
};
X
list words(char const *File) {
X    register FILE *f = fopen(File, "r");
X    list result;
X    list n;
X    register int c;
X    register char *p;
X    char buff[81];
X
X    result = 0;
X    for (;;) {
X	do c = getc(f); while (c != EOF && !isalpha(c));
X	if (c == EOF) break;
X	p = buff;
X	do *p++ = c, c = getc(f); while (c != EOF && isalpha(c));
X	*p = '\0';
X	n = alloc(sizeof *n);
X	n->next = result;
X	n->word = strcpy(alloc(1 + strlen(buff)), buff);
X	result = n;
X    }
X    fclose(f);
X    return result;
}
X
list ord_union(list a, list b) {
X    int c;
X    list r;
X    list *e;
X
X    e = &r;
X    for (;;) {
X	if (!a) { *e = b; return r; }
X	if (!b) { *e = a; return r; }
X	c = strcmp(a->word, b->word);
X	if (c < 0) {
X	    *e = a;
X	    e = &a->next;
X	    a = a->next;
X	} else
X	if (c > 0) {
X	    *e = b;
X	    e = &b->next;
X	    b = b->next;
X	} else {
X	    *e = a;
X	    e = &a->next;
X	    a = a->next;
X	    b = b->next;
X	}
X    }
}
X
X
list ord_difference(list a, list b) {
X    list r;
X    list *e;
X    int c;
X
X    e = &r;
X    for (;;) {
X	if (!a) { *e = 0; return r; }
X	if (!b) { *e = a; return r; }
X	c = strcmp(a->word, b->word);
X	if (c < 0) {
X	    *e = a;
X	    e = &a->next;
X	    a = a->next;
X	} else
X	if (c > 0) {
X	    b = b->next;
X	} else {
X	    a = a->next;
X	    b = b->next;
X	}
X    }
}
X
list xxx;
X
list lto_step(int n) {
X    if (n > 2) {
X	int j = n/2;
X	list a = lto_step(j);
X	list z = lto_step(n-j);
X	return ord_union(a, z);
X    } else
X    if (n == 2) {
X	list x = xxx;
X	list y = x->next;
X	int c = strcmp(x->word, y->word);
X	xxx = y->next;
X
X	if (c < 0) {
X	    y->next = 0;
X	    return x;
X	} else
X	if (c > 0) {
X	    y->next = x;
X	    x->next = 0;
X	    return y;
X	} else {
X	    x->next = 0;
X	    return x;
X	}
X    } else
X    if (n == 1) {
X	list x = xxx;
X	xxx = x->next;
X	x->next = 0;
X	return x;
X    } else {
X	return 0;
X    }
}
X
list list_to_ordset(list seq) {
X    int n;
X    list p;
X
X    n = 0;
X    for (p = seq; p; p = p->next)
X	n++;
X    xxx = seq;
X    p = lto_step(n);
X    return p;
}
X
double time_in_seconds(void) {
X    return clock()/(double)(CLOCKS_PER_SEC);
}
X
int main(int argc, char **argv) {
X    double T0 = time_in_seconds();
X    list W1 = words(argv[1]);
X    list W2 = words(argv[2]);
X    double T1 = time_in_seconds();
X    list L1 = list_to_ordset(W1);
X    list L2 = list_to_ordset(W2);
X    double T2 = time_in_seconds();
X    list DF = ord_difference(L1, L2);
X    double T3 = time_in_seconds();
X    double T4;
X    list W;
X
X    for (W = DF; W; W = W->next)
X	puts(W->word);
X    T4 = time_in_seconds();
X    printf("reading     %8.3f\n", T1-T0);
X    printf("sorting     %8.3f\n", T2-T1);
X    printf("matching    %8.3f\n", T3-T2);
X    printf("writing     %8.3f\n", T4-T3);
X    printf("TOTAL      %9.3f\n",  T4-T0);
X    return 0;
}
SHAR_EOF
  $shar_touch -am 0526000897 'word-test-c.c' &&
  chmod 0644 'word-test-c.c' ||
  $echo 'restore of' 'word-test-c.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-c.c:' 'MD5 check failed'
861110eab4cd91f4959c0b3b63e21195  word-test-c.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-c.c'`"
    test 5213 -eq "$shar_count" ||
    $echo 'word-test-c.c:' 'original size' '5213,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-cpp.cpp ==============
if test -f 'word-test-cpp.cpp' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-cpp.cpp' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-cpp.cpp' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-cpp.cpp' &&
#include <iostream.h>
#include <stdio.h>
#include <string>
#include <cstdlib>
#include <ctype.h>
#include <list>
#include <time.h>
#include <iterator>
#include <algorithm>
X
typedef list<string> word_list;
X
void read_words(char const *File, word_list &result) {
X    register FILE *f;
X    register int c;
X    register char *p;
X    char buff[81];
X
X    f = fopen(File, "r");
X    if (f == 0) {
X	fprintf(stderr, "Cannot open %s\n", File);
X	exit(EXIT_FAILURE);
X    }
X    for (;;) {
X	do c = getc(f); while (c != EOF && !isalpha(c));
X	if (c == EOF) break;
X	p = buff;
X	do *p++ = c, c = getc(f); while (c != EOF && isalpha(c));
X	*p = '\0';
X	result.push_front(string(buff));
X    }
X    fclose(f);
}
X
X
double time_in_seconds(void) {
X    return clock()/(double)(CLOCKS_PER_SEC);
}
X
int main(int argc, char **argv) {
X    double T0 = time_in_seconds();
X
X    word_list W1;
X    read_words(argv[1], W1);
X    word_list W2;
X    read_words(argv[2], W2);
X    printf("W1 has %ld words\n", (long)W1.size());
X    printf("W2 has %ld words\n", (long)W2.size());
X
X    double T1 = time_in_seconds();
X
X    /*  This was *supposed* to be a test of the sort() algorithm in
X	<algorithm>, but that demands RandomAccessIterators, heaven
X	only knows why.  It therefore provded necessary to use the
X	list::sort method instead.
X    */
X    W1.sort();
X    W2.sort();
X    /*  However, we _can_ use the unique() algorithm, which only
X	requires ForwardIterators.  Or at least we _ought_ to be
X	able to, but g++_ reports that operator!= is ambiguous,
X	and I haven't a clue what to do about it.
X    */
X    W1.unique();
X    W2.unique();
//  printf("W1 has %ld words\n", (long)W1.size());
//  printf("W2 has %ld words\n", (long)W2.size());
X
X    double T2 = time_in_seconds();
X
X    word_list DF;
X    /*  set_difference(..., DF.begin()) was the obvious thing to try,
X        but it *quietly* produced an empty set.
X    */
X    (void) set_difference(W1.begin(), W1.end(),
X			  W2.begin(), W2.end(), back_inserter(DF));
X    printf("DF has %ld words\n", (long)DF.size());
X
X    double T3 = time_in_seconds();
X
//  word_list::iterator W;
//  for (W = DF.begin(); W != DF.end(); W++) cout << *W << endl;
X
X    double T4 = time_in_seconds();
X
X    printf("reading     %8.3f\n", T1-T0);
X    printf("sorting     %8.3f\n", T2-T1);
X    printf("matching    %8.3f\n", T3-T2);
X    printf("writing     %8.3f\n", T4-T3);
X    printf("TOTAL      %9.3f\n",  T4-T0);
X    return 0;
}
SHAR_EOF
  $shar_touch -am 0525235297 'word-test-cpp.cpp' &&
  chmod 0644 'word-test-cpp.cpp' ||
  $echo 'restore of' 'word-test-cpp.cpp' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-cpp.cpp:' 'MD5 check failed'
15a5d2941fdb5488332ac9b87eafa44d  word-test-cpp.cpp
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-cpp.cpp'`"
    test 2408 -eq "$shar_count" ||
    $echo 'word-test-cpp.cpp:' 'original size' '2408,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-alpha-bound.sc ==============
if test -f 'word-test-scheme-alpha-bound.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-alpha-bound.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-alpha-bound.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-alpha-bound.sc' &&
(begin
X (define (char-alphabetic? char)
X  (or (and (>= (char->integer char) (char->integer #\a))
X	   (<= (char->integer char) (char->integer #\z)))
X      (and (>= (char->integer char) (char->integer #\A))
X	   (<= (char->integer char) (char->integer #\Z)))))
X
X (define (string<? s1 s2)
X  (let loop ((i 0))
X   (if (zero? (char->integer (string-ref s1 i)))
X       (not (zero? (char->integer (string-ref s2 i))))
X       (and (not (zero? (char->integer (string-ref s2 i))))
X	    (or (char<? (string-ref s1 i) (string-ref s2 i))
X		(and (char=? (string-ref s1 i) (string-ref s2 i))
X		     (loop (+ i 1))))))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define (ord-union! a b less?)
X  (define (loop r a b)
X   (cond ((less? (car a) (car b))
X	  (set-cdr! r a)
X	  (if (null? (cdr a)) (set-cdr! a b) (loop a (cdr a) b)))
X	 ((less? (car b) (car a))
X	  (set-cdr! r b)
X	  (if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b))))
X	 ((null? (cdr a))
X	  (set-cdr! r a)
X	  (set-cdr! a (cdr b)))
X	 ((null? (cdr b)) (set-cdr! r a))
X	 (else (set-cdr! r a)
X	       (loop a (cdr a) (cdr b)))))
X  (cond ((null? a) b)
X	((null? b) a)
X	((less? (car a) (car b))
X	 (if (null? (cdr a)) (set-cdr! a b) (loop a b (cdr a)))
X	 a)
X	((less? (car b) (car a))
X	 (if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b)))
X	 b)
X	((null? (cdr a))
X	 (set-cdr! a (cdr b))
X	 a)
X	((null? (cdr b))
X	 (set-cdr! b (cdr a))
X	 b)
X	(else (loop a (cdr b) (cdr a))
X	      a)))
X
X (define (list->ordset! seq less?)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b less?)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (cond ((less? x y) (set-cdr! (cdr p) '()))
X		 ((less? y x)
X		  (set-car! p y)
X		  (set-car! (cdr p) x)
X		  (set-cdr! (cdr p) '()))
X		 (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b less?)
X  (define (loop r a b)
X   (cond ((null? a) (set-cdr! r a))
X	 ((null? b) (set-cdr! r a))
X	 ((less? (car a) (car b))
X	  (set-cdr! r a)
X	  (loop a (cdr a) b))
X	 ((less? (car b) (car a)) (loop r a (cdr b)))
X	 (else (loop r (cdr a) (cdr b)))))
X  (cond ((null? a) a)
X	((null? b) a)
X	((less? (car a) (car b))
X	 (loop a (cdr a) b)
X	 a)
X	((less? (car b) (car a)) (ord-difference! a (cdr b) less?))
X	(else (ord-difference! (cdr a) (cdr b) less?))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string<?))
X	(L2 (list->ordset! W2 string<?))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string<?))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0526031797 'word-test-scheme-alpha-bound.sc' &&
  chmod 0644 'word-test-scheme-alpha-bound.sc' ||
  $echo 'restore of' 'word-test-scheme-alpha-bound.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-alpha-bound.sc:' 'MD5 check failed'
dd360bfbafe90b11115c8a44c83289d0  word-test-scheme-alpha-bound.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-alpha-bound.sc'`"
    test 3867 -eq "$shar_count" ||
    $echo 'word-test-scheme-alpha-bound.sc:' 'original size' '3867,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-alpha.sc ==============
if test -f 'word-test-scheme-alpha.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-alpha.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-alpha.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-alpha.sc' &&
(begin
X (define (char-alphabetic? char)
X  (or (and (>= (char->integer char) (char->integer #\a))
X	   (<= (char->integer char) (char->integer #\z)))
X      (and (>= (char->integer char) (char->integer #\A))
X	   (<= (char->integer char) (char->integer #\Z)))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define (ord-union! a b less?)
X  (define (loop r a b)
X   (cond ((less? (car a) (car b))
X	  (set-cdr! r a)
X	  (if (null? (cdr a)) (set-cdr! a b) (loop a (cdr a) b)))
X	 ((less? (car b) (car a))
X	  (set-cdr! r b)
X	  (if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b))))
X	 ((null? (cdr a))
X	  (set-cdr! r a)
X	  (set-cdr! a (cdr b)))
X	 ((null? (cdr b)) (set-cdr! r a))
X	 (else (set-cdr! r a)
X	       (loop a (cdr a) (cdr b)))))
X  (cond ((null? a) b)
X	((null? b) a)
X	((less? (car a) (car b))
X	 (if (null? (cdr a)) (set-cdr! a b) (loop a b (cdr a)))
X	 a)
X	((less? (car b) (car a))
X	 (if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b)))
X	 b)
X	((null? (cdr a))
X	 (set-cdr! a (cdr b))
X	 a)
X	((null? (cdr b))
X	 (set-cdr! b (cdr a))
X	 b)
X	(else (loop a (cdr b) (cdr a))
X	      a)))
X
X (define (list->ordset! seq less?)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b less?)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (cond ((less? x y) (set-cdr! (cdr p) '()))
X		 ((less? y x)
X		  (set-car! p y)
X		  (set-car! (cdr p) x)
X		  (set-cdr! (cdr p) '()))
X		 (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b less?)
X  (define (loop r a b)
X   (cond ((null? a) (set-cdr! r a))
X	 ((null? b) (set-cdr! r a))
X	 ((less? (car a) (car b))
X	  (set-cdr! r a)
X	  (loop a (cdr a) b))
X	 ((less? (car b) (car a)) (loop r a (cdr b)))
X	 (else (loop r (cdr a) (cdr b)))))
X  (cond ((null? a) a)
X	((null? b) a)
X	((less? (car a) (car b))
X	 (loop a (cdr a) b)
X	 a)
X	((less? (car b) (car a)) (ord-difference! a (cdr b) less?))
X	(else (ord-difference! (cdr a) (cdr b) less?))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string<?))
X	(L2 (list->ordset! W2 string<?))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string<?))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528193897 'word-test-scheme-alpha.sc' &&
  chmod 0644 'word-test-scheme-alpha.sc' ||
  $echo 'restore of' 'word-test-scheme-alpha.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-alpha.sc:' 'MD5 check failed'
3be881805093f4815dde62f2b85d7dd8  word-test-scheme-alpha.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-alpha.sc'`"
    test 3522 -eq "$shar_count" ||
    $echo 'word-test-scheme-alpha.sc:' 'original size' '3522,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-bound.sc ==============
if test -f 'word-test-scheme-bound.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-bound.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-bound.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-bound.sc' &&
(begin
X (define (string<? s1 s2)
X  (let loop ((i 0))
X   (if (zero? (char->integer (string-ref s1 i)))
X       (not (zero? (char->integer (string-ref s2 i))))
X       (and (not (zero? (char->integer (string-ref s2 i))))
X	    (or (char<? (string-ref s1 i) (string-ref s2 i))
X		(and (char=? (string-ref s1 i) (string-ref s2 i))
X		     (loop (+ i 1))))))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define (ord-union! a b less?)
X  (define (loop r a b)
X   (cond ((less? (car a) (car b))
X	  (set-cdr! r a)
X	  (if (null? (cdr a)) (set-cdr! a b) (loop a (cdr a) b)))
X	 ((less? (car b) (car a))
X	  (set-cdr! r b)
X	  (if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b))))
X	 ((null? (cdr a))
X	  (set-cdr! r a)
X	  (set-cdr! a (cdr b)))
X	 ((null? (cdr b)) (set-cdr! r a))
X	 (else (set-cdr! r a)
X	       (loop a (cdr a) (cdr b)))))
X  (cond ((null? a) b)
X	((null? b) a)
X	((less? (car a) (car b))
X	 (if (null? (cdr a)) (set-cdr! a b) (loop a b (cdr a)))
X	 a)
X	((less? (car b) (car a))
X	 (if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b)))
X	 b)
X	((null? (cdr a))
X	 (set-cdr! a (cdr b))
X	 a)
X	((null? (cdr b))
X	 (set-cdr! b (cdr a))
X	 b)
X	(else (loop a (cdr b) (cdr a))
X	      a)))
X
X (define (list->ordset! seq less?)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b less?)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (cond ((less? x y) (set-cdr! (cdr p) '()))
X		 ((less? y x)
X		  (set-car! p y)
X		  (set-car! (cdr p) x)
X		  (set-cdr! (cdr p) '()))
X		 (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b less?)
X  (define (loop r a b)
X   (cond ((null? a) (set-cdr! r a))
X	 ((null? b) (set-cdr! r a))
X	 ((less? (car a) (car b))
X	  (set-cdr! r a)
X	  (loop a (cdr a) b))
X	 ((less? (car b) (car a)) (loop r a (cdr b)))
X	 (else (loop r (cdr a) (cdr b)))))
X  (cond ((null? a) a)
X	((null? b) a)
X	((less? (car a) (car b))
X	 (loop a (cdr a) b)
X	 a)
X	((less? (car b) (car a)) (ord-difference! a (cdr b) less?))
X	(else (ord-difference! (cdr a) (cdr b) less?))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string<?))
X	(L2 (list->ordset! W2 string<?))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string<?))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528193997 'word-test-scheme-bound.sc' &&
  chmod 0644 'word-test-scheme-bound.sc' ||
  $echo 'restore of' 'word-test-scheme-bound.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-bound.sc:' 'MD5 check failed'
ef2e61a7557349391c1bf6ed4d8797ac  word-test-scheme-bound.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-bound.sc'`"
    test 3615 -eq "$shar_count" ||
    $echo 'word-test-scheme-bound.sc:' 'original size' '3615,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-compare-alpha-bound.sc ==============
if test -f 'word-test-scheme-compare-alpha-bound.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-compare-alpha-bound.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-compare-alpha-bound.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-compare-alpha-bound.sc' &&
(begin
X (define (char-alphabetic? char)
X  (or (and (>= (char->integer char) (char->integer #\a))
X	   (<= (char->integer char) (char->integer #\z)))
X      (and (>= (char->integer char) (char->integer #\A))
X	   (<= (char->integer char) (char->integer #\Z)))))
X
X (define (string-compare s1 s2)
X  (let loop ((i 0))
X   (cond ((zero? (char->integer (string-ref s1 i)))
X	  (if (zero? (char->integer (string-ref s2 i))) '= '<))
X	 ((zero? (char->integer (string-ref s2 i))) '>)
X	 ((char<? (string-ref s1 i) (string-ref s2 i)) '<)
X	 ((char>? (string-ref s1 i) (string-ref s2 i)) '>)
X	 (else (loop (+ i 1))))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define (ord-union! a b compare)
X  (define (loop r a b)
X   (case (compare (car a) (car b))
X    ((<)
X     (set-cdr! r a)
X     (if (null? (cdr a)) (set-cdr! a b) (loop a (cdr a) b)))
X    ((>)
X     (set-cdr! r b)
X     (if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b))))
X    (else (cond ((null? (cdr a))
X		 (set-cdr! r a)
X		 (set-cdr! a (cdr b)))
X		((null? (cdr b)) (set-cdr! r a))
X		(else (set-cdr! r a)
X		      (loop a (cdr a) (cdr b)))))))
X  (cond ((null? a) b)
X	((null? b) a)
X	(else (case (compare (car a) (car b))
X	       ((<)
X		(if (null? (cdr a)) (set-cdr! a b) (loop a b (cdr a)))
X		a)
X	       ((>)
X		(if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b)))
X		b)
X	       (else (cond ((null? (cdr a))
X			    (set-cdr! a (cdr b))
X			    a)
X			   ((null? (cdr b))
X			    (set-cdr! b (cdr a))
X			    b)
X			   (else (loop a (cdr b) (cdr a))
X				 a)))))))
X
X (define (list->ordset! seq compare)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b compare)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (case (compare x y)
X	    ((<) (set-cdr! (cdr p) '()))
X	    ((>)
X	     (set-car! p y)
X	     (set-car! (cdr p) x)
X	     (set-cdr! (cdr p) '()))
X	    (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b compare)
X  (define (loop r a b)
X   (cond ((null? a) (set-cdr! r a))
X	 ((null? b) (set-cdr! r a))
X	 (else (case (compare (car a) (car b))
X		((<)
X		 (set-cdr! r a)
X		 (loop a (cdr a) b))
X		((>) (loop r a (cdr b)))
X		(else (loop r (cdr a) (cdr b)))))))
X  (cond ((null? a) a)
X	((null? b) a)
X	(else (case (compare (car a) (car b))
X	       ((<)
X		(loop a (cdr a) b)
X		a)
X	       ((>) (ord-difference! a (cdr b) compare))
X	       (else (ord-difference! (cdr a) (cdr b) compare))))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string-compare))
X	(L2 (list->ordset! W2 string-compare))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string-compare))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0526033197 'word-test-scheme-compare-alpha-bound.sc' &&
  chmod 0644 'word-test-scheme-compare-alpha-bound.sc' ||
  $echo 'restore of' 'word-test-scheme-compare-alpha-bound.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-compare-alpha-bound.sc:' 'MD5 check failed'
9688c4f16ac2d731869b3c6a5c4b396d  word-test-scheme-compare-alpha-bound.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-compare-alpha-bound.sc'`"
    test 4011 -eq "$shar_count" ||
    $echo 'word-test-scheme-compare-alpha-bound.sc:' 'original size' '4011,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-compare-alpha.sc ==============
if test -f 'word-test-scheme-compare-alpha.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-compare-alpha.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-compare-alpha.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-compare-alpha.sc' &&
(begin
X (define (char-alphabetic? char)
X  (or (and (>= (char->integer char) (char->integer #\a))
X	   (<= (char->integer char) (char->integer #\z)))
X      (and (>= (char->integer char) (char->integer #\A))
X	   (<= (char->integer char) (char->integer #\Z)))))
X
X (define (string-compare s1 s2)
X  (let ((l1 (string-length s1))
X	(l2 (string-length s2)))
X   (let loop ((i 0))
X    (cond ((= i l1) (if (= i l2) '= '<))
X	  ((= i l2) '>)
X	  ((char<? (string-ref s1 i) (string-ref s2 i)) '<)
X	  ((char>? (string-ref s1 i) (string-ref s2 i)) '>)
X	  (else (loop (+ i 1)))))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define (ord-union! a b compare)
X  (define (loop r a b)
X   (case (compare (car a) (car b))
X    ((<)
X     (set-cdr! r a)
X     (if (null? (cdr a)) (set-cdr! a b) (loop a (cdr a) b)))
X    ((>)
X     (set-cdr! r b)
X     (if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b))))
X    (else (cond ((null? (cdr a))
X		 (set-cdr! r a)
X		 (set-cdr! a (cdr b)))
X		((null? (cdr b)) (set-cdr! r a))
X		(else (set-cdr! r a)
X		      (loop a (cdr a) (cdr b)))))))
X  (cond ((null? a) b)
X	((null? b) a)
X	(else (case (compare (car a) (car b))
X	       ((<)
X		(if (null? (cdr a)) (set-cdr! a b) (loop a b (cdr a)))
X		a)
X	       ((>)
X		(if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b)))
X		b)
X	       (else (cond ((null? (cdr a))
X			    (set-cdr! a (cdr b))
X			    a)
X			   ((null? (cdr b))
X			    (set-cdr! b (cdr a))
X			    b)
X			   (else (loop a (cdr b) (cdr a))
X				 a)))))))
X
X (define (list->ordset! seq compare)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b compare)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (case (compare x y)
X	    ((<) (set-cdr! (cdr p) '()))
X	    ((>)
X	     (set-car! p y)
X	     (set-car! (cdr p) x)
X	     (set-cdr! (cdr p) '()))
X	    (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b compare)
X  (define (loop r a b)
X   (cond ((null? a) (set-cdr! r a))
X	 ((null? b) (set-cdr! r a))
X	 (else (case (compare (car a) (car b))
X		((<)
X		 (set-cdr! r a)
X		 (loop a (cdr a) b))
X		((>) (loop r a (cdr b)))
X		(else (loop r (cdr a) (cdr b)))))))
X  (cond ((null? a) a)
X	((null? b) a)
X	(else (case (compare (car a) (car b))
X	       ((<)
X		(loop a (cdr a) b)
X		a)
X	       ((>) (ord-difference! a (cdr b) compare))
X	       (else (ord-difference! (cdr a) (cdr b) compare))))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string-compare))
X	(L2 (list->ordset! W2 string-compare))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string-compare))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528201097 'word-test-scheme-compare-alpha.sc' &&
  chmod 0644 'word-test-scheme-compare-alpha.sc' ||
  $echo 'restore of' 'word-test-scheme-compare-alpha.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-compare-alpha.sc:' 'MD5 check failed'
80abc6501f8c7030f3cf4170d0dcdadf  word-test-scheme-compare-alpha.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-compare-alpha.sc'`"
    test 3974 -eq "$shar_count" ||
    $echo 'word-test-scheme-compare-alpha.sc:' 'original size' '3974,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-compare-bound.sc ==============
if test -f 'word-test-scheme-compare-bound.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-compare-bound.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-compare-bound.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-compare-bound.sc' &&
(begin
X (define (string-compare s1 s2)
X  (let loop ((i 0))
X   (cond ((zero? (char->integer (string-ref s1 i)))
X	  (if (zero? (char->integer (string-ref s2 i))) '= '<))
X	 ((zero? (char->integer (string-ref s2 i))) '>)
X	 ((char<? (string-ref s1 i) (string-ref s2 i)) '<)
X	 ((char>? (string-ref s1 i) (string-ref s2 i)) '>)
X	 (else (loop (+ i 1))))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define (ord-union! a b compare)
X  (define (loop r a b)
X   (case (compare (car a) (car b))
X    ((<)
X     (set-cdr! r a)
X     (if (null? (cdr a)) (set-cdr! a b) (loop a (cdr a) b)))
X    ((>)
X     (set-cdr! r b)
X     (if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b))))
X    (else (cond ((null? (cdr a))
X		 (set-cdr! r a)
X		 (set-cdr! a (cdr b)))
X		((null? (cdr b)) (set-cdr! r a))
X		(else (set-cdr! r a)
X		      (loop a (cdr a) (cdr b)))))))
X  (cond ((null? a) b)
X	((null? b) a)
X	(else (case (compare (car a) (car b))
X	       ((<)
X		(if (null? (cdr a)) (set-cdr! a b) (loop a b (cdr a)))
X		a)
X	       ((>)
X		(if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b)))
X		b)
X	       (else (cond ((null? (cdr a))
X			    (set-cdr! a (cdr b))
X			    a)
X			   ((null? (cdr b))
X			    (set-cdr! b (cdr a))
X			    b)
X			   (else (loop a (cdr b) (cdr a))
X				 a)))))))
X
X (define (list->ordset! seq compare)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b compare)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (case (compare x y)
X	    ((<) (set-cdr! (cdr p) '()))
X	    ((>)
X	     (set-car! p y)
X	     (set-car! (cdr p) x)
X	     (set-cdr! (cdr p) '()))
X	    (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b compare)
X  (define (loop r a b)
X   (cond ((null? a) (set-cdr! r a))
X	 ((null? b) (set-cdr! r a))
X	 (else (case (compare (car a) (car b))
X		((<)
X		 (set-cdr! r a)
X		 (loop a (cdr a) b))
X		((>) (loop r a (cdr b)))
X		(else (loop r (cdr a) (cdr b)))))))
X  (cond ((null? a) a)
X	((null? b) a)
X	(else (case (compare (car a) (car b))
X	       ((<)
X		(loop a (cdr a) b)
X		a)
X	       ((>) (ord-difference! a (cdr b) compare))
X	       (else (ord-difference! (cdr a) (cdr b) compare))))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string-compare))
X	(L2 (list->ordset! W2 string-compare))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string-compare))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528195597 'word-test-scheme-compare-bound.sc' &&
  chmod 0644 'word-test-scheme-compare-bound.sc' ||
  $echo 'restore of' 'word-test-scheme-compare-bound.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-compare-bound.sc:' 'MD5 check failed'
40919962448fd4618dfb8696edf1d85c  word-test-scheme-compare-bound.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-compare-bound.sc'`"
    test 3759 -eq "$shar_count" ||
    $echo 'word-test-scheme-compare-bound.sc:' 'original size' '3759,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-compare.sc ==============
if test -f 'word-test-scheme-compare.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-compare.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-compare.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-compare.sc' &&
(begin
X (define (string-compare s1 s2)
X  (let ((l1 (string-length s1))
X	(l2 (string-length s2)))
X   (let loop ((i 0))
X    (cond ((= i l1) (if (= i l2) '= '<))
X	  ((= i l2) '>)
X	  ((char<? (string-ref s1 i) (string-ref s2 i)) '<)
X	  ((char>? (string-ref s1 i) (string-ref s2 i)) '>)
X	  (else (loop (+ i 1)))))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define (ord-union! a b compare)
X  (define (loop r a b)
X   (case (compare (car a) (car b))
X    ((<)
X     (set-cdr! r a)
X     (if (null? (cdr a)) (set-cdr! a b) (loop a (cdr a) b)))
X    ((>)
X     (set-cdr! r b)
X     (if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b))))
X    (else (cond ((null? (cdr a))
X		 (set-cdr! r a)
X		 (set-cdr! a (cdr b)))
X		((null? (cdr b)) (set-cdr! r a))
X		(else (set-cdr! r a)
X		      (loop a (cdr a) (cdr b)))))))
X  (cond ((null? a) b)
X	((null? b) a)
X	(else (case (compare (car a) (car b))
X	       ((<)
X		(if (null? (cdr a)) (set-cdr! a b) (loop a b (cdr a)))
X		a)
X	       ((>)
X		(if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b)))
X		b)
X	       (else (cond ((null? (cdr a))
X			    (set-cdr! a (cdr b))
X			    a)
X			   ((null? (cdr b))
X			    (set-cdr! b (cdr a))
X			    b)
X			   (else (loop a (cdr b) (cdr a))
X				 a)))))))
X
X (define (list->ordset! seq compare)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b compare)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (case (compare x y)
X	    ((<) (set-cdr! (cdr p) '()))
X	    ((>)
X	     (set-car! p y)
X	     (set-car! (cdr p) x)
X	     (set-cdr! (cdr p) '()))
X	    (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b compare)
X  (define (loop r a b)
X   (cond ((null? a) (set-cdr! r a))
X	 ((null? b) (set-cdr! r a))
X	 (else (case (compare (car a) (car b))
X		((<)
X		 (set-cdr! r a)
X		 (loop a (cdr a) b))
X		((>) (loop r a (cdr b)))
X		(else (loop r (cdr a) (cdr b)))))))
X  (cond ((null? a) a)
X	((null? b) a)
X	(else (case (compare (car a) (car b))
X	       ((<)
X		(loop a (cdr a) b)
X		a)
X	       ((>) (ord-difference! a (cdr b) compare))
X	       (else (ord-difference! (cdr a) (cdr b) compare))))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string-compare))
X	(L2 (list->ordset! W2 string-compare))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string-compare))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528201197 'word-test-scheme-compare.sc' &&
  chmod 0644 'word-test-scheme-compare.sc' ||
  $echo 'restore of' 'word-test-scheme-compare.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-compare.sc:' 'MD5 check failed'
ce3fd8a4351855d9eec105d64ae03c11  word-test-scheme-compare.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-compare.sc'`"
    test 3722 -eq "$shar_count" ||
    $echo 'word-test-scheme-compare.sc:' 'original size' '3722,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-short-alpha-bound.sc ==============
if test -f 'word-test-scheme-short-alpha-bound.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-short-alpha-bound.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-short-alpha-bound.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-short-alpha-bound.sc' &&
(begin
X (define (char-alphabetic? char)
X  (or (and (>= (char->integer char) (char->integer #\a))
X	   (<= (char->integer char) (char->integer #\z)))
X      (and (>= (char->integer char) (char->integer #\A))
X	   (<= (char->integer char) (char->integer #\Z)))))
X
X (define (string<? s1 s2)
X  (let loop ((i 0))
X   (if (zero? (char->integer (string-ref s1 i)))
X       (not (zero? (char->integer (string-ref s2 i))))
X       (and (not (zero? (char->integer (string-ref s2 i))))
X	    (or (char<? (string-ref s1 i) (string-ref s2 i))
X		(and (char=? (string-ref s1 i) (string-ref s2 i))
X		     (loop (+ i 1))))))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define dummy (list ""))
X
X (define (ord-union! a b less?)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e b)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((less? (car a) (car b))
X	  (set-cdr! e a)
X	  (loop a (cdr a) b))
X	 ((less? (car b) (car a))
X	  (set-cdr! e b)
X	  (loop b a (cdr b)))
X	 (else (set-cdr! e a)
X	       (loop a (cdr a) (cdr b))))))
X
X (define (list->ordset! seq less?)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b less?)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (cond ((less? x y) (set-cdr! (cdr p) '()))
X		 ((less? y x)
X		  (set-car! p y)
X		  (set-car! (cdr p) x)
X		  (set-cdr! (cdr p) '()))
X		 (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b less?)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((less? (car a) (car b))
X	  (set-cdr! e a)
X	  (loop a (cdr a) b))
X	 ((less? (car b) (car a)) (loop e a (cdr b)))
X	 (else (loop e (cdr a) (cdr b))))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string<?))
X	(L2 (list->ordset! W2 string<?))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string<?))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528194397 'word-test-scheme-short-alpha-bound.sc' &&
  chmod 0644 'word-test-scheme-short-alpha-bound.sc' ||
  $echo 'restore of' 'word-test-scheme-short-alpha-bound.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-short-alpha-bound.sc:' 'MD5 check failed'
975afcfd396cd1191b4bd2ffb4db8601  word-test-scheme-short-alpha-bound.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-short-alpha-bound.sc'`"
    test 3334 -eq "$shar_count" ||
    $echo 'word-test-scheme-short-alpha-bound.sc:' 'original size' '3334,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-short-alpha.sc ==============
if test -f 'word-test-scheme-short-alpha.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-short-alpha.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-short-alpha.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-short-alpha.sc' &&
(begin
X (define (char-alphabetic? char)
X  (or (and (>= (char->integer char) (char->integer #\a))
X	   (<= (char->integer char) (char->integer #\z)))
X      (and (>= (char->integer char) (char->integer #\A))
X	   (<= (char->integer char) (char->integer #\Z)))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define dummy (list ""))
X
X (define (ord-union! a b less?)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e b)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((less? (car a) (car b))
X	  (set-cdr! e a)
X	  (loop a (cdr a) b))
X	 ((less? (car b) (car a))
X	  (set-cdr! e b)
X	  (loop b a (cdr b)))
X	 (else (set-cdr! e a)
X	       (loop a (cdr a) (cdr b))))))
X
X (define (list->ordset! seq less?)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b less?)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (cond ((less? x y) (set-cdr! (cdr p) '()))
X		 ((less? y x)
X		  (set-car! p y)
X		  (set-car! (cdr p) x)
X		  (set-cdr! (cdr p) '()))
X		 (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b less?)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((less? (car a) (car b))
X	  (set-cdr! e a)
X	  (loop a (cdr a) b))
X	 ((less? (car b) (car a)) (loop e a (cdr b)))
X	 (else (loop e (cdr a) (cdr b))))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string<?))
X	(L2 (list->ordset! W2 string<?))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string<?))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528194397 'word-test-scheme-short-alpha.sc' &&
  chmod 0644 'word-test-scheme-short-alpha.sc' ||
  $echo 'restore of' 'word-test-scheme-short-alpha.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-short-alpha.sc:' 'MD5 check failed'
2ef299ce8600724c536914ea0a21dfa6  word-test-scheme-short-alpha.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-short-alpha.sc'`"
    test 2989 -eq "$shar_count" ||
    $echo 'word-test-scheme-short-alpha.sc:' 'original size' '2989,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-short-bound.sc ==============
if test -f 'word-test-scheme-short-bound.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-short-bound.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-short-bound.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-short-bound.sc' &&
(begin
X (define (string<? s1 s2)
X  (let loop ((i 0))
X   (if (zero? (char->integer (string-ref s1 i)))
X       (not (zero? (char->integer (string-ref s2 i))))
X       (and (not (zero? (char->integer (string-ref s2 i))))
X	    (or (char<? (string-ref s1 i) (string-ref s2 i))
X		(and (char=? (string-ref s1 i) (string-ref s2 i))
X		     (loop (+ i 1))))))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define dummy (list ""))
X
X (define (ord-union! a b less?)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e b)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((less? (car a) (car b))
X	  (set-cdr! e a)
X	  (loop a (cdr a) b))
X	 ((less? (car b) (car a))
X	  (set-cdr! e b)
X	  (loop b a (cdr b)))
X	 (else (set-cdr! e a)
X	       (loop a (cdr a) (cdr b))))))
X
X (define (list->ordset! seq less?)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b less?)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (cond ((less? x y) (set-cdr! (cdr p) '()))
X		 ((less? y x)
X		  (set-car! p y)
X		  (set-car! (cdr p) x)
X		  (set-cdr! (cdr p) '()))
X		 (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b less?)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((less? (car a) (car b))
X	  (set-cdr! e a)
X	  (loop a (cdr a) b))
X	 ((less? (car b) (car a)) (loop e a (cdr b)))
X	 (else (loop e (cdr a) (cdr b))))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string<?))
X	(L2 (list->ordset! W2 string<?))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string<?))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528194397 'word-test-scheme-short-bound.sc' &&
  chmod 0644 'word-test-scheme-short-bound.sc' ||
  $echo 'restore of' 'word-test-scheme-short-bound.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-short-bound.sc:' 'MD5 check failed'
a9d56d3d36a999e656fcda2019fc86fb  word-test-scheme-short-bound.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-short-bound.sc'`"
    test 3082 -eq "$shar_count" ||
    $echo 'word-test-scheme-short-bound.sc:' 'original size' '3082,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-short-compare-alpha-bound.sc ==============
if test -f 'word-test-scheme-short-compare-alpha-bound.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-short-compare-alpha-bound.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-short-compare-alpha-bound.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-short-compare-alpha-bound.sc' &&
(begin
X (define (char-alphabetic? char)
X  (or (and (>= (char->integer char) (char->integer #\a))
X	   (<= (char->integer char) (char->integer #\z)))
X      (and (>= (char->integer char) (char->integer #\A))
X	   (<= (char->integer char) (char->integer #\Z)))))
X
X (define (string-compare s1 s2)
X  (let loop ((i 0))
X   (cond ((zero? (char->integer (string-ref s1 i)))
X	  (if (zero? (char->integer (string-ref s2 i))) '= '<))
X	 ((zero? (char->integer (string-ref s2 i))) '>)
X	 ((char<? (string-ref s1 i) (string-ref s2 i)) '<)
X	 ((char>? (string-ref s1 i) (string-ref s2 i)) '>)
X	 (else (loop (+ i 1))))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define dummy (list ""))
X
X (define (ord-union! a b compare)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e b)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 (else (case (compare (car a) (car b))
X		((<)
X		 (set-cdr! e a)
X		 (loop a (cdr a) b))
X		((>)
X		 (set-cdr! e b)
X		 (loop b a (cdr b)))
X		(else (set-cdr! e a)
X		      (loop a (cdr a) (cdr b))))))))
X
X (define (list->ordset! seq compare)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b compare)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (case (compare x y)
X	    ((<) (set-cdr! (cdr p) '()))
X	    ((>)
X	     (set-car! p y)
X	     (set-car! (cdr p) x)
X	     (set-cdr! (cdr p) '()))
X	    (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b compare)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 (else (case (compare (car a) (car b))
X		((<)
X		 (set-cdr! e a)
X		 (loop a (cdr a) b))
X		((>) (loop e a (cdr b)))
X		(else (loop e (cdr a) (cdr b))))))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string-compare))
X	(L2 (list->ordset! W2 string-compare))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string-compare))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528195397 'word-test-scheme-short-compare-alpha-bound.sc' &&
  chmod 0644 'word-test-scheme-short-compare-alpha-bound.sc' ||
  $echo 'restore of' 'word-test-scheme-short-compare-alpha-bound.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-short-compare-alpha-bound.sc:' 'MD5 check failed'
76a78590bd0a5228130755d65a652e9f  word-test-scheme-short-compare-alpha-bound.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-short-compare-alpha-bound.sc'`"
    test 3374 -eq "$shar_count" ||
    $echo 'word-test-scheme-short-compare-alpha-bound.sc:' 'original size' '3374,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-short-compare-alpha.sc ==============
if test -f 'word-test-scheme-short-compare-alpha.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-short-compare-alpha.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-short-compare-alpha.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-short-compare-alpha.sc' &&
(begin
X (define (char-alphabetic? char)
X  (or (and (>= (char->integer char) (char->integer #\a))
X	   (<= (char->integer char) (char->integer #\z)))
X      (and (>= (char->integer char) (char->integer #\A))
X	   (<= (char->integer char) (char->integer #\Z)))))
X
X (define (string-compare s1 s2)
X  (let ((l1 (string-length s1))
X	(l2 (string-length s2)))
X   (let loop ((i 0))
X    (cond ((= i l1) (if (= i l2) '= '<))
X	  ((= i l2) '>)
X	  ((char<? (string-ref s1 i) (string-ref s2 i)) '<)
X	  ((char>? (string-ref s1 i) (string-ref s2 i)) '>)
X	  (else (loop (+ i 1)))))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define dummy (list ""))
X
X (define (ord-union! a b compare)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e b)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 (else (case (compare (car a) (car b))
X		((<)
X		 (set-cdr! e a)
X		 (loop a (cdr a) b))
X		((>)
X		 (set-cdr! e b)
X		 (loop b a (cdr b)))
X		(else (set-cdr! e a)
X		      (loop a (cdr a) (cdr b))))))))
X
X (define (list->ordset! seq compare)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b compare)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (case (compare x y)
X	    ((<) (set-cdr! (cdr p) '()))
X	    ((>)
X	     (set-car! p y)
X	     (set-car! (cdr p) x)
X	     (set-cdr! (cdr p) '()))
X	    (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b compare)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 (else (case (compare (car a) (car b))
X		((<)
X		 (set-cdr! e a)
X		 (loop a (cdr a) b))
X		((>) (loop e a (cdr b)))
X		(else (loop e (cdr a) (cdr b))))))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string-compare))
X	(L2 (list->ordset! W2 string-compare))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string-compare))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528201197 'word-test-scheme-short-compare-alpha.sc' &&
  chmod 0644 'word-test-scheme-short-compare-alpha.sc' ||
  $echo 'restore of' 'word-test-scheme-short-compare-alpha.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-short-compare-alpha.sc:' 'MD5 check failed'
f4c31926b47a3d25b6a726455eb628ec  word-test-scheme-short-compare-alpha.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-short-compare-alpha.sc'`"
    test 3337 -eq "$shar_count" ||
    $echo 'word-test-scheme-short-compare-alpha.sc:' 'original size' '3337,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-short-compare-bound.sc ==============
if test -f 'word-test-scheme-short-compare-bound.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-short-compare-bound.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-short-compare-bound.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-short-compare-bound.sc' &&
(begin
X (define (string-compare s1 s2)
X  (let loop ((i 0))
X   (cond ((zero? (char->integer (string-ref s1 i)))
X	  (if (zero? (char->integer (string-ref s2 i))) '= '<))
X	 ((zero? (char->integer (string-ref s2 i))) '>)
X	 ((char<? (string-ref s1 i) (string-ref s2 i)) '<)
X	 ((char>? (string-ref s1 i) (string-ref s2 i)) '>)
X	 (else (loop (+ i 1))))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define dummy (list ""))
X
X (define (ord-union! a b compare)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e b)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 (else (case (compare (car a) (car b))
X		((<)
X		 (set-cdr! e a)
X		 (loop a (cdr a) b))
X		((>)
X		 (set-cdr! e b)
X		 (loop b a (cdr b)))
X		(else (set-cdr! e a)
X		      (loop a (cdr a) (cdr b))))))))
X
X (define (list->ordset! seq compare)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b compare)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (case (compare x y)
X	    ((<) (set-cdr! (cdr p) '()))
X	    ((>)
X	     (set-car! p y)
X	     (set-car! (cdr p) x)
X	     (set-cdr! (cdr p) '()))
X	    (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b compare)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 (else (case (compare (car a) (car b))
X		((<)
X		 (set-cdr! e a)
X		 (loop a (cdr a) b))
X		((>) (loop e a (cdr b)))
X		(else (loop e (cdr a) (cdr b))))))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string-compare))
X	(L2 (list->ordset! W2 string-compare))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string-compare))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528195697 'word-test-scheme-short-compare-bound.sc' &&
  chmod 0644 'word-test-scheme-short-compare-bound.sc' ||
  $echo 'restore of' 'word-test-scheme-short-compare-bound.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-short-compare-bound.sc:' 'MD5 check failed'
8d6c13730e91e4e6185fbd3d0dfa7445  word-test-scheme-short-compare-bound.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-short-compare-bound.sc'`"
    test 3122 -eq "$shar_count" ||
    $echo 'word-test-scheme-short-compare-bound.sc:' 'original size' '3122,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-short-compare.sc ==============
if test -f 'word-test-scheme-short-compare.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-short-compare.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-short-compare.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-short-compare.sc' &&
(begin
X (define (string-compare s1 s2)
X  (let ((l1 (string-length s1))
X	(l2 (string-length s2)))
X   (let loop ((i 0))
X    (cond ((= i l1) (if (= i l2) '= '<))
X	  ((= i l2) '>)
X	  ((char<? (string-ref s1 i) (string-ref s2 i)) '<)
X	  ((char>? (string-ref s1 i) (string-ref s2 i)) '>)
X	  (else (loop (+ i 1)))))))
X
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define dummy (list ""))
X
X (define (ord-union! a b compare)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e b)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 (else (case (compare (car a) (car b))
X		((<)
X		 (set-cdr! e a)
X		 (loop a (cdr a) b))
X		((>)
X		 (set-cdr! e b)
X		 (loop b a (cdr b)))
X		(else (set-cdr! e a)
X		      (loop a (cdr a) (cdr b))))))))
X
X (define (list->ordset! seq compare)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b compare)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (case (compare x y)
X	    ((<) (set-cdr! (cdr p) '()))
X	    ((>)
X	     (set-car! p y)
X	     (set-car! (cdr p) x)
X	     (set-cdr! (cdr p) '()))
X	    (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b compare)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 (else (case (compare (car a) (car b))
X		((<)
X		 (set-cdr! e a)
X		 (loop a (cdr a) b))
X		((>) (loop e a (cdr b)))
X		(else (loop e (cdr a) (cdr b))))))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string-compare))
X	(L2 (list->ordset! W2 string-compare))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string-compare))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528201297 'word-test-scheme-short-compare.sc' &&
  chmod 0644 'word-test-scheme-short-compare.sc' ||
  $echo 'restore of' 'word-test-scheme-short-compare.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-short-compare.sc:' 'MD5 check failed'
bf16f5fd09076495523658ebc6d50d22  word-test-scheme-short-compare.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-short-compare.sc'`"
    test 3085 -eq "$shar_count" ||
    $echo 'word-test-scheme-short-compare.sc:' 'original size' '3085,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme-short.sc ==============
if test -f 'word-test-scheme-short.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme-short.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme-short.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme-short.sc' &&
(begin
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define dummy (list ""))
X
X (define (ord-union! a b less?)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e b)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((less? (car a) (car b))
X	  (set-cdr! e a)
X	  (loop a (cdr a) b))
X	 ((less? (car b) (car a))
X	  (set-cdr! e b)
X	  (loop b a (cdr b)))
X	 (else (set-cdr! e a)
X	       (loop a (cdr a) (cdr b))))))
X
X (define (list->ordset! seq less?)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b less?)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (cond ((less? x y) (set-cdr! (cdr p) '()))
X		 ((less? y x)
X		  (set-car! p y)
X		  (set-car! (cdr p) x)
X		  (set-cdr! (cdr p) '()))
X		 (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b less?)
X  (let loop ((e dummy) (a a) (b b))
X   (cond ((null? a)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((null? b)
X	  (set-cdr! e a)
X	  (cdr dummy))
X	 ((less? (car a) (car b))
X	  (set-cdr! e a)
X	  (loop a (cdr a) b))
X	 ((less? (car b) (car a)) (loop e a (cdr b)))
X	 (else (loop e (cdr a) (cdr b))))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string<?))
X	(L2 (list->ordset! W2 string<?))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string<?))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528193797 'word-test-scheme-short.sc' &&
  chmod 0644 'word-test-scheme-short.sc' ||
  $echo 'restore of' 'word-test-scheme-short.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme-short.sc:' 'MD5 check failed'
c8e00f9a20845c8cb4cd7e12434d9a18  word-test-scheme-short.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme-short.sc'`"
    test 2737 -eq "$shar_count" ||
    $echo 'word-test-scheme-short.sc:' 'original size' '2737,' 'current size' "$shar_count!"
  fi
fi
# ============= word-test-scheme.sc ==============
if test -f 'word-test-scheme.sc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'word-test-scheme.sc' '(file already exists)'
else
  $echo 'x -' extracting 'word-test-scheme.sc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'word-test-scheme.sc' &&
(begin
X (define (read-word Buff Port)
X  (let loop ((Char (read-char Port)))
X   (cond ((eof-object? Char) Char)
X	 ((not (char-alphabetic? Char)) (loop (read-char Port)))
X	 (else (string-set! Buff 0 Char)
X	       (let loop ((I 1) (Char (peek-char Port)))
X		(if (and (not (eof-object? Char)) (char-alphabetic? Char))
X		    (begin (string-set! Buff I (read-char Port))
X			   (loop (+ I 1) (peek-char Port)))
X		    (substring Buff 0 I)))))))
X
X (define (words File)
X  (let ((Port (open-input-file File))
X	(Buff (make-string 80)))
X   (let loop ((Words '()))
X    (let ((Next (read-word Buff Port)))
X     (if (eof-object? Next)
X	 (begin (close-input-port Port)
X		Words)
X	 (loop (cons Next Words)))))))
X
X (define (ord-union! a b less?)
X  (define (loop r a b)
X   (cond ((less? (car a) (car b))
X	  (set-cdr! r a)
X	  (if (null? (cdr a)) (set-cdr! a b) (loop a (cdr a) b)))
X	 ((less? (car b) (car a))
X	  (set-cdr! r b)
X	  (if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b))))
X	 ((null? (cdr a))
X	  (set-cdr! r a)
X	  (set-cdr! a (cdr b)))
X	 ((null? (cdr b)) (set-cdr! r a))
X	 (else (set-cdr! r a)
X	       (loop a (cdr a) (cdr b)))))
X  (cond ((null? a) b)
X	((null? b) a)
X	((less? (car a) (car b))
X	 (if (null? (cdr a)) (set-cdr! a b) (loop a b (cdr a)))
X	 a)
X	((less? (car b) (car a))
X	 (if (null? (cdr b)) (set-cdr! b a) (loop b a (cdr b)))
X	 b)
X	((null? (cdr a))
X	 (set-cdr! a (cdr b))
X	 a)
X	((null? (cdr b))
X	 (set-cdr! b (cdr a))
X	 b)
X	(else (loop a (cdr b) (cdr a))
X	      a)))
X
X (define (list->ordset! seq less?)
X  (define (step n)
X   (cond ((> n 2)
X	  (let* ((j (quotient n 2))
X		 (a (step j))
X		 (k (- n j))
X		 (b (step k)))
X	   (ord-union! a b less?)))
X	 ((= n 2)
X	  (let ((x (car seq))
X		(y (cadr seq))
X		(p seq))
X	   (set! seq (cddr seq))
X	   (cond ((less? x y) (set-cdr! (cdr p) '()))
X		 ((less? y x)
X		  (set-car! p y)
X		  (set-car! (cdr p) x)
X		  (set-cdr! (cdr p) '()))
X		 (else (set-cdr! p '())))
X	   p))
X	 ((= n 1)
X	  (let ((p seq))
X	   (set! seq (cdr seq))
X	   (set-cdr! p '())
X	   p))
X	 (else '())))
X  (step (length seq)))
X
X (define (ord-difference! a b less?)
X  (define (loop r a b)
X   (cond ((null? a) (set-cdr! r a))
X	 ((null? b) (set-cdr! r a))
X	 ((less? (car a) (car b))
X	  (set-cdr! r a)
X	  (loop a (cdr a) b))
X	 ((less? (car b) (car a)) (loop r a (cdr b)))
X	 (else (loop r (cdr a) (cdr b)))))
X  (cond ((null? a) a)
X	((null? b) a)
X	((less? (car a) (car b))
X	 (loop a (cdr a) b)
X	 a)
X	((less? (car b) (car a)) (ord-difference! a (cdr b) less?))
X	(else (ord-difference! (cdr a) (cdr b) less?))))
X
X (define (time-in-seconds) (* ((foreign-procedure () int "clock")) 1.0e-2))
X
X (let* ((F1 (vector-ref ARGV 1))
X	(F2 (vector-ref ARGV 2))
X	(T0 (time-in-seconds))
X	(W1 (words F1))
X	(W2 (words F2))
X	(T1 (time-in-seconds))
X	(L1 (list->ordset! W1 string<?))
X	(L2 (list->ordset! W2 string<?))
X	(T2 (time-in-seconds))
X	(DF (ord-difference! L1 L2 string<?))
X	(T3 (time-in-seconds)))
X  (do ((W DF (cdr W))) ((null? W))
X   (display (car W))
X   (newline))
X  (let ((T4 (time-in-seconds)))
X   (display "reading     ") (write (- T1 T0)) (newline)
X   (display "sorting     ") (write (- T2 T1)) (newline)	
X   (display "matching    ") (write (- T3 T2)) (newline)
X   (display "writing     ") (write (- T4 T3)) (newline)
X   (display "TOTAL       ") (write (- T4 T0)) (newline))
X  0))
SHAR_EOF
  $shar_touch -am 0528193797 'word-test-scheme.sc' &&
  chmod 0644 'word-test-scheme.sc' ||
  $echo 'restore of' 'word-test-scheme.sc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'word-test-scheme.sc:' 'MD5 check failed'
661f37e0018cbd3c88e6b780bd25bdaa  word-test-scheme.sc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'word-test-scheme.sc'`"
    test 3270 -eq "$shar_count" ||
    $echo 'word-test-scheme.sc:' 'original size' '3270,' 'current size' "$shar_count!"
  fi
fi
rm -fr _sh10074
exit 0
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mh38q$31c$1@goanna.cs.rmit.edu.au>
···@research.att.com (Andrew Koenig) writes:
>But to dismiss the entire language because one implementation appears
>to have a performance bug that shows up in one test case is just silly.

It would be, but I haven't done any such thing.

First of all, *YOU* have provided no evidence whatsoever that this
is a 'performance bug'.  It would appear that any discrepancy between
the "C++ is fast" religion and practice will be dismissed as 'a
performance bug'.  Is there any conceivable measurement, involving
any C++ program and any *actual* compiler, that would lead someone
to decide against C++, which you could not similarly dismiss as
'just silly' because it's only due to 'a performance bug'?

Don't forget, I tried *TWO* independent implementations of C++.
One couldn't compile the program *AT ALL*.
The other one did, and it ran slow.

Now, it appears that a large part of the problem is due to the use of
the <string> header and the 'string' data type therein.  This is not
part of the compiler.  I suppose you could call it a 'performance bug'
in the library, and

*if* you could provide me with a version of <string> that came as close
to standard conformance as the one in libg++, and
*if* the program then ran faster, you would hvae *evidence* of a
'performance bug' in the library.  I'm quite willing to believe it.

*Some* C++ advocates in this thread have provided more than excuses.
I've forgotten who it was that tried the thing out using char* instead
of <string>.  THAT WAS WELL DONE!  That was USEFUL!  It did establish
that <string> is part of the problem in this test.

But where is the evidence that an efficient implementation of <string>
is actually *possible*?  There's a known performance design bug in
Scheme strings (strings are mutable, which forces (substring) to copy
instead of sharing).  C++ <string> has the same performance design bug.
That's not the only one.

Don't forget, it's not really a matter of 'one implementation, one bug,
one test" amongst many.  For *me* the actual experience was "the *BEST*
compiler I had access to, the *FIRST* serious test I did."  Do you call
someone 'just silly' who fears the flame after his fingers are burnt the
first time?  I have actually done several other tests since the first one,
and while they are not all as extreme, they all consistently show C++
to be more than a factor of 2 slower than C *IF* I use the features of
C++ that are not also in C.  If I use the C-like aspects of C++, then I
get C-like performance, which makes it rather hard to believe in
'performance bugs'.


Frankly, for me the really damning thing is CC, not g++.
I don't know when the feaures I have been trying were first put in
the C++ draft standard, but they were there in April 1995, and they
were still there looking just the same in December 1996, and yet the
latest C++ compiler from a major vendor, which we installed in
February 1997, WAS NOT ABLE TO COMPILE A PROGRAM USING <string> AT ALL.

Being unimpressed by a language on the basis of one bad benchmark might
be silly (though nowhere near as silly as trying to pretend that it has
no significance at all), but surely no-one in these closing years of the
20th century would want to deny that _dramatic_ differences in what
compilers for the 'same' langauge actually accept is cause for concern?
(After all, it _was_ the most commonly given excuse for not using Prolog.)

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Jay Martin
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mldgm$2bt8@uni.library.ucla.edu>
··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

>First of all, *YOU* have provided no evidence whatsoever that this
>is a 'performance bug'.  It would appear that any discrepancy between
>the "C++ is fast" religion and practice will be dismissed as 'a
>performance bug'.  Is there any conceivable measurement, involving

That g++ does not inline code correctly is well known bug in g++.
Read the FAQ. They have thrown away the current brain damaged template
implementation and have been completely rewriting it for the last 2
years.  (I really must question the previous implementers dedication
to abstraction if they don't even bother to properly implement
inlining)  Unfortunately, the release date for the new version is
unknown.  You may be able to play some tricks with instantiation to
force it to inline stuff but this is about as much fun as bashing your
head against a brick wall.

>Don't forget, I tried *TWO* independent implementations of C++.
>One couldn't compile the program *AT ALL*.
>The other one did, and it ran slow.

Its obvious that STL at this point is on the bleeding edge.  It
doesn't surprise me that Sun's compiler is behind, theirs and
IBM's compiler always seem way behind what is available for 
the PC.  

>Frankly, for me the really damning thing is CC, not g++.
>I don't know when the feaures I have been trying were first put in
>the C++ draft standard, but they were there in April 1995, and they
>were still there looking just the same in December 1996, and yet the
>latest C++ compiler from a major vendor, which we installed in
>February 1997, WAS NOT ABLE TO COMPILE A PROGRAM USING <string> AT ALL.

You are talking about a real problem with C++ right now.  There are
compilers by major vendors that extremely behind other implementations
to the point you have to wonder what the hell they are doing.  g++'s
current version is now like 2 years old and it was behind the PC
compilers when it came out.  Sun's CC is even less up to date than g++
and IBM xlC is totally ancient.  This seems to point to that a
language design flaw in C++ is that it is huge and extremely hard to
implement.  You would have thought the designers would have learned
this lesson from other behemoth languages.  Oh well, huge companies
like Microsoft can dedicate a bunch of Borg cubes, Uh I mean buildings of
programmers to work on those C++ compilers until they are done.

Jay
From: Bryan O'Sullivan
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <8767vztmzb.fsf@serpentine.com>
r> I don't know when the feaures I have been trying were first put in
r> the C++ draft standard, but they were there in April 1995, and they
r> were still there looking just the same in December 1996, and yet
r> the latest C++ compiler from a major vendor, which we installed in
r> February 1997, WAS NOT ABLE TO COMPILE A PROGRAM USING <string> AT
r> ALL.

In defence of the vendor in question, they presumably decided that
they had better things to do than track the latest draft du jour.
Once the standard is finalised, I'm sure they will produce an
implementation that conforms.

In case you think that implementing draft standards is of necessity a
good idea, I might point you at the experience of many vendors and
customers in the morld of multithreaded programming under Unix.
Several vendors went and packaged implementations of various drafts of
POSIX threads with their operating systems.  The result has by and
large been a disaster for customers, because the different drafts are
mutually incompatible, *all* of the draft implementations that vendors
have shipped are incompatible with the final standard, and customers
are perpetually confused as to whether their vendors implement the
final standard or not.

My sympathy for people who want to poke at the most recent tumours in
C++ is pretty limited.

	<b

-- 
Let us pray:
What a Great System.                   ···@eng.sun.com
Please Do Not Crash.                ···@serpentine.com
·····@P6                http://www.serpentine.com/~bos
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5n7vs4$4ee$1@goanna.cs.rmit.edu.au>
Bryan O'Sullivan <···@serpentine.com> writes:

>r> I don't know when the feaures I have been trying were first put in
>r> the C++ draft standard, but they were there in April 1995, and they
>r> were still there looking just the same in December 1996, and yet
>r> the latest C++ compiler from a major vendor, which we installed in
>r> February 1997, WAS NOT ABLE TO COMPILE A PROGRAM USING <string> AT
>r> ALL.

>In defence of the vendor in question, they presumably decided that
>they had better things to do than track the latest draft du jour.
>Once the standard is finalised, I'm sure they will produce an
>implementation that conforms.

Ahem.  <string> has been in the C++ draft standard since April 1995
*at least*.  That's two years ago.  I didn't notice any major changes
in <string> from April 1995 to December 1996.  I suspect <string> has
been there longer than that.  Dismissing a *stable* part of the draft
*TWO YEARS AGO* as "the latest draft du jour" is rather unfair.

>In case you think that implementing draft standards is of necessity a
>good idea, I might point you at the experience of many vendors and
>customers in the morld of multithreaded programming under Unix.

No, I don't.  I even believe that some standards should never be
implemented at all.  But 
 - we are talking about something that has been stable for a long time
 - we are talking about something that has a free implementation
 - we are talking about a vendor that already has a contrib/ directory.

Just how hard would it be for someone at Sun to take a copy of
libg++ <string> (well, std/bastring.h mostly), hack it a bit,
and stick it in the contrib/ directory with a note "here it is,
hope it helps, see the GPL"?

>Several vendors went and packaged implementations of various drafts of
>POSIX threads with their operating systems.

The innovative parts of POSIX were notoriously subject to change.
Whatever happened to contiguous files?

>My sympathy for people who want to poke at the most recent tumours in
>C++ is pretty limited.

The STL is just such a tumour.  It was presented as a successful tool
that vindicated the choice of C++.  If there is any "science" in
computer science, we ought to investigate such claims.

And honestly, calling <string> one of "the most recent tumours in C++"
is pretty far of the mark.

-- 
Four policemen playing jazz on an up escalator in the railway station.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Bryan O'Sullivan
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <87raefskf6.fsf@serpentine.com>
r> Ahem.  <string> has been in the C++ draft standard since April 1995
r> *at least*.  That's two years ago.

A decision was made to track approximately none of the draft.  If you
disagree with that, that is fine, but it seems defensible enough to me.

r> Just how hard would it be for someone at Sun to take a copy of
r> libg++ <string> (well, std/bastring.h mostly), hack it a bit, and
r> stick it in the contrib/ directory with a note "here it is, hope it
r> helps, see the GPL"?

It would certainly be practicable, but time is a consideration.  With
all the goodwill in the world on my side, I would not have enough time
to do all the random things my customers would find useful but that
don't need to be part of my base product; I do not believe that I am
alone in this.

If you wish to live on the bleeding edge, you are going to pay for
your decision.  You may pay because some vendors produce crappy
implementations, or because other vendors do not keep up to date with
the latest changes, or because the state of the world shifts so
frequently that keeping up with it becomes a major time sink, or for
some other reason, but you will surely pay.  Whether or not the price
seems acceptable depends on your needs and patience.

	<b

-- 
Let us pray:
What a Great System.                   ···@eng.sun.com
Please Do Not Crash.                ···@serpentine.com
·····@P6                http://www.serpentine.com/~bos
From: ···@teco.net
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <s6ywwo3kzfz.fsf@aalh02.alcatel.com.au>
Bryan O'Sullivan <···@serpentine.com> writes:

> r> Just how hard would it be for someone at Sun to take a copy of
> r> libg++ <string> (well, std/bastring.h mostly), hack it a bit, and
> r> stick it in the contrib/ directory with a note "here it is, hope it
> r> helps, see the GPL"?
> 
> It would certainly be practicable, but time is a consideration.  With
> all the goodwill in the world on my side, I would not have enough time
> to do all the random things my customers would find useful but that
> don't need to be part of my base product; I do not believe that I am
> alone in this.
> 
> If you wish to live on the bleeding edge, you are going to pay for
> your decision.  

A basic String class is "bleeding edge"??? I would have thought
providing a contrib String class with appropriate disclaimers would be
the *very least* I could expect from a compiler vendor. There isn't a
single customer who wouldn't at least consider using such a
thing. It's ridiculous to compare this to "random things customers
find useful".
From: Erik Naggum
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <3074924539193248@naggum.no>
* ···@teco.net
| A basic String class is "bleeding edge"???  I would have thought
| providing a contrib String class with appropriate disclaimers would be
| the *very least* I could expect from a compiler vendor.  There isn't a
| single customer who wouldn't at least consider using such a thing.  It's
| ridiculous to compare this to "random things customers find useful".

but don't you get it?  if C++ doesn't have something that somebody says is
super-duper and ultra-efficient and mega-neat, it must be denigrated,
ridiculed, scoffed at, because C++ is the very _embodiment_ of super-duper
and ultra-efficient and mega-neat.  nothing good can exist outside of the
C++ camp.  of course, a few select people are allowed to bring things in
from the Scary Outside World, but it's obvious that anybody with Lisp
experience is Not Allowed to even suggest what to look for.

if a C++ program takes two hours to run, it's efficient.  if a Lisp program
takes two hours to run, it's grossly inefficient and nobody should use any
other language than C++.  if a C++ program requires 28M of memory just to
read your mail, that's really cool.  if a Lisp program requires 28M of
memory just to read your mail, that's a ridiculous amount of memory and
nobody should use any other language than C++.  if a Lisp hacker says: "C++
really needs a basic string class that works right", the C++ community
laughs and has a another other-language-bashing party.  if Bjarne
Stroustrup says: "C++ really needs a basic string class that works right",
the C++ community rises in a unanimous "Yes, Massa!" and immediately
thereafter start to denigrate, ridicule and scoff at languages that don't
have a basic string class that works exactly the same way as C++'s, even
though the C++ way is of course different from every other basic string
class that works right.  this is called "progress".

it has been _most_ instructive to watch the greater C++ community try to
explain away their failure to be as efficient as their religion commanded
that C++ should be.  "C++ is efficient" is a myth.  it has been exploded.
guys, get over it.  C++ is _not_ efficient.  with intelligence and hard
work, you can write efficient programs in C++, too, but your code is not
efficient just because it's written in C++ and not some other language.

#\Erik
-- 
soon to enter the six-bit generation.  please do not be alarmed.
From: Hrvoje Niksic
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <kigk9k7gy76.fsf@jagor.srce.hr>
··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

> Just how hard would it be for someone at Sun to take a copy of
> libg++ <string> (well, std/bastring.h mostly), hack it a bit,
> and stick it in the contrib/ directory with a note "here it is,
> hope it helps, see the GPL"?

I don't think they are allowed to do that, unless they want to make
the whole compiler GPL-ed, too.

Not that this defends them, mind you.

-- 
Hrvoje Niksic <·······@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
* Vi is the God of editors.
* Emacs is the editor of Gods.
From: Fergus Henderson
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5natak$iac@mulga.cs.mu.OZ.AU>
Hrvoje Niksic <·······@srce.hr> writes:

>··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:
>
>> Just how hard would it be for someone at Sun to take a copy of
>> libg++ <string> (well, std/bastring.h mostly), hack it a bit,
>> and stick it in the contrib/ directory with a note "here it is,
>> hope it helps, see the GPL"?
>
>I don't think they are allowed to do that, unless they want to make
>the whole compiler GPL-ed, too.

They most certainly are allowed to do that.
You have misunderstood the GPL.

[Followups to gnu.misc.discuss, please!]

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Hans-Juergen Boehm
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <33910BD7.41C6@mti.sgi.com>
Richard A. O'Keefe wrote:
> 
> *if* you could provide me with a version of <string> that came as close
> to standard conformance as the one in libg++, and
> *if* the program then ran faster, you would hvae *evidence* of a
> 'performance bug' in the library.  I'm quite willing to believe it.
> 

I'll assert:

1. Basic_string in the draft standard is nearly useless.  I believe it
has no consistent design rationale.  It doesn't appear to solve any
problems that don't have much simpler solutions.  It is nearly
impossible to write an application that uses it in a conforming way. 
(s[0] == s[1] is not legal for nonconstant string.) It is hard to write
a multithreaded application that uses the existing implementations in a
correct way, though failures will be rare and probably unreproducible. I
think the committee understands that, and the final version will
hopefully be different.  It also happens to not perform well for this
application, but that would be far down along my list of complaints.  I
would not use a string class that claims to both reference count and
conform to CD2.

2. Scheme's lists are a better implementation of singly linked lists
than STL lists (which are in fact a different data structure).

3. There is no singly linked list container in the C++ standard. 
(Neither do the C nor Scheme standards define a very complete data
structure and algorithms library.  I'm not convinced that singly linked
lists are a particularly good way to solve this problem, but they are
certainly an important data structure.)

4. Current C++ compilers do a poor job of compiling certain features
important for STL.  For example, many of them treat structures
containing a single data member of type T less efficiently than a
variable of type T.

5. I don't recall seeing cases in which template instantiation per se
introduced a performance penalty with the SGI compiler.  I suspect other
compilers are similar, though g++ 2.7.x may have some problems here. 
(The template implementation is seriously incomplete in other ways.)

I claim these explain the benchmark results.  They do imply that you
don't always get the best possible performance with STL today.  Alex has
pointed that out repeatedly as well.  If that's all that was claimed,
then we agree.


-- 
These are my personal opinions ...
Hans-Juergen Boehm
·····@mti.sgi.com
From: Andrew Koenig
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <EBB8HB.Cpn@research.att.com>
In article <·························@riesbeck.ils.nwu.edu> ········@ils.nwu.edu (Chris Riesbeck) writes:

> This misses Richard's starting point. It all began with the claim that
> Scheme couldn't support the same level of efficiency in a STL-like 
> generic library as C++.

Actually, that was not the claim.  The claim was that Alex Stepanov
had implemented an STL-like library in Scheme before he implemented
it in C++, but he found that he could not get a generic library in
Scheme to be as efficient as a hand-coded library in Scheme.
This was years before he even knew any C++.  Moreover, I have
no doubt that Scheme compilers have greatly improved since then.

> Richard's point is that the data that currently exist don't
> support this claim.  Claims that these deficiencies can be fixed
> don't apply. Such arguments exist for virtually all language
> compilers. Some turn out to be right, many turn out to be
> true only in the lab.

Richard has shown one data point that supports his
claim, which is not related to the original claim.

> That's Richard's point. The original claim is unsubstantiated.

No, the original claim is a matter of historical fact.
Various people have restated it in various ways since then.

> That's it. Why is this so hard for everyone to follow?

I wish I knew.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Pierre Mai
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <m3pvu0ix6n.fsf@torus.cs.tu-berlin.de>
···@research.att.com (Andrew Koenig) writes:

> Actually, that was not the claim.  The claim was that Alex Stepanov
> had implemented an STL-like library in Scheme before he implemented
> it in C++, but he found that he could not get a generic library in
> Scheme to be as efficient as a hand-coded library in Scheme.

And there was also the (implicit?) claim that a) C++ allowed one to
write a generic library that was as efficient as a hand-coded library
in C++, and that b) the current STL was maybe an example of such a
generic library.

For the specific C++ Compiler/STL-Implementation combination used by
Richard at least claim b) has been found "not true in all cases".
Nothing more and nothing less in my eyes.

Or put into other words: The (never actually voiced, and never
seriously claimed) claim "C++ and STL are always as efficient as
hand-coded non-generic C++ code" has been proven incorrect by
supplying one counter-example.  Nothing earth shattering for
intelligent persons, but some fanatics (on both sides) might think
this important.

Let's move on to other, more interesting topics...

Regs, Pierre.
From: David Hanley
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <33981F2D.2862@nospan.netright.com>
Andrew Koenig wrote:
> 
> In article <·························@riesbeck.ils.nwu.edu> ········@ils.nwu.edu (Chris Riesbeck) writes:
> 
> > This misses Richard's starting point. It all began with the claim that
> > Scheme couldn't support the same level of efficiency in a STL-like
> > generic library as C++.
> 
> Actually, that was not the claim.  The claim was that Alex Stepanov
> had implemented an STL-like library in Scheme before he implemented
> it in C++, but he found that he could not get a generic library in
> Scheme to be as efficient as a hand-coded library in Scheme.

	Really?  I _never_ remember Mr Stepanov claiming this, and
I have a pretty good memory. He dis claim that he couldn't implement 
his generic library in any other language he knew ( aside from C++ ).
As far as I can tell, he never really said why, which is unfortunate, 
because I'd really like to know--it would be good to know what C++
has that other languages don't, WRT generic programming.  I am a 
pretty good C++ prgorammer and I can't think of any myself, aside from
efficency issues, and this has been the major speculation.

	It seems to be a spoecious claim that generics in scheme/lisp would
be much slower than 'general' code; with the overall language structure
there
shouldn't be much os a difference.  All code is generic, in a sense.


> > Richard's point is that the data that currently exist don't
> > support this claim.  Claims that these deficiencies can be fixed
> > don't apply. Such arguments exist for virtually all language
> > compilers. Some turn out to be right, many turn out to be
> > true only in the lab.
> 
> Richard has shown one data point that supports his
> claim, which is not related to the original claim.

	How so?  It implemented generic code in several languages.  
It is not conclusive, but it is not uninteresting either.  At some
point,
real programmers must write real code, and not spend 3 weeks tweaking
simple
programs.  A quick programming task is a good simulation of this.

> 
> > That's Richard's point. The original claim is unsubstantiated.
> 
> No, the original claim is a matter of historical fact.

	I'd like to see a reference to that, then.

    dave
From: Jens Kilian
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5ng9ro$l3d@isoit109.bbn.hp.com>
Hans-Juergen Boehm (·····@mti.sgi.com) wrote:
> 4. Current C++ compilers do a poor job of compiling certain features
> important for STL.  For example, many of them treat structures
> containing a single data member of type T less efficiently than a
> variable of type T.

Gee, welcome to the world of boxed objects and compilers which can't unbox
them automatically.

	Jens.
--
··········@acm.org                 phone:+49-7031-14-7698 (HP TELNET 778-7698)
                                     fax:+49-7031-14-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]
From: Fergus Henderson
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5nh3sr$njs@mulga.cs.mu.OZ.AU>
·····@bbn.hp.com (Jens Kilian) writes:

>Hans-Juergen Boehm (·····@mti.sgi.com) wrote:
>> 4. Current C++ compilers do a poor job of compiling certain features
>> important for STL.  For example, many of them treat structures
>> containing a single data member of type T less efficiently than a
>> variable of type T.
>
>Gee, welcome to the world of boxed objects and compilers which can't unbox
>them automatically.

The problem is not that C++ compilers box objects -- they don't.
The problem is usually just that the back-ends don't consider
structures to be candidates for register allocation, and instead
store them on the stack.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Boris Fomitchev
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <yfhd8qi8eb8.fsf@spirit.mcst.ru>
In article <············@goanna.cs.rmit.edu.au> 
··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:
>CC -I/public/224/STL -I/opt/SUNWspro/SC4.2/include/CC/rw7/rw -DRW wds.cpp
>"/public/224/STL/alloc.h", line 672: Warning (Anachronism):
>__default_alloc_template::obj is not accessible from file level.
>"/public/224/STL/alloc.h", line 672: Note: Type "CC -migration" for more
>on anachronisms.
>
>"/public/224/STL/algobase.h", line 188: Error: Too many arguments in call to
>operator new(unsigned).
>"wds.cpp",     Where: While instantiating "__list<RWCString,
>__default_alloc_template<0, 0>>::make_node(const RWCString&)".
>"wds.cpp",     Where: Instantiated from non-template code.
>1 Error(s) and 1 Warning(s) detected.
>
>With respect to the first message:
> - this version of the STL is *supposed* to have been ported to SunPro C++
>   4.2, and the accompanying documentation claims that it just works.

You just didn't configure with "-xwe" option to treat warnings as
errors at configure stage. So you have that warning after. You may
just not configure for SunPro - it's being auto-recognized fine.


>With respect to the second message:
> - ditto!  This is unmodified STL code.  I have no idea what's going on
>   or what I can do about this error message in what is *supposed* to be
>   code that works with this compiler.

That is strange - it obviously complains on placement new, defined in
<new.h>, _included_ by algobase.h. Check if RW provides (wrong?)
<new.h>.

I was able to run your code using simple bstring.h implementation
by Modena (available at my site). I must admit the results were still
poor - CC gave only ~30% speedup over gcc. I did ran gprof :

 21.92     10.40    10.40  6417599     0.00     0.00  __0fMbasic_string7c_Lcompare_strUiPCcNCBK
 20.99     20.36     9.96  6417599     0.00     0.00  __0fMbasic_string7c_HcompareRC6Mbasic_string7c_UiTCK
 19.14     29.44     9.08   368591     0.02     0.08  __0fG__list76Mbasic_string7c_6H__alloc74A4A__FmergeR6G__list76Mbasic_string7c_6H__alloc74A4A__
 13.26     35.73     6.29                             _mcount
  5.02     38.11     2.38                             oldarc
  4.13     40.07     1.96        2   980.00  2039.27  __0FKread_wordsPCcR6Elist76Mbasic_string7c__
  2.85     41.42     1.35 12187162     0.00     0.00  __0oP__list_iterator76Mbasic_string7c__ctRC6P__list_iterator76Mbasic_string7c__
.....

I suppose the system strcmp() performs far better than
basic_string::compare ;(. And, as it was mentioned already,
tristate comparison function is what the sort algorithms miss badly.

Best regards,
-- 
-Boris	*  [···@mcst.ru] * Opinions expressed here are mine alone.
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mbhl7$1ap$1@goanna.cs.rmit.edu.au>
···@spirit.mcst.ru (Boris Fomitchev) writes:

:In article <············@goanna.cs.rmit.edu.au> 
···@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:
:>CC -I/public/224/STL -I/opt/SUNWspro/SC4.2/include/CC/rw7/rw -DRW wds.cpp
:>"/public/224/STL/alloc.h", line 672: Warning (Anachronism):
:>__default_alloc_template::obj is not accessible from file level.
:>"/public/224/STL/alloc.h", line 672: Note: Type "CC -migration" for more
:>on anachronisms.
:>
:>"/public/224/STL/algobase.h", line 188: Error: Too many arguments in call to
:>operator new(unsigned).
:>"wds.cpp",     Where: While instantiating "__list<RWCString,
:>__default_alloc_template<0, 0>>::make_node(const RWCString&)".
:>"wds.cpp",     Where: Instantiated from non-template code.
:>1 Error(s) and 1 Warning(s) detected.
:>
:>With respect to the first message:
:> - this version of the STL is *supposed* to have been ported to SunPro C++
:>   4.2, and the accompanying documentation claims that it just works.

:You just didn't configure with "-xwe" option to treat warnings as
:errors at configure stage. So you have that warning after. You may
:just not configure for SunPro - it's being auto-recognized fine.

I can't quite parse this.
When I try the configure script that comes with the STL port that I tried,
it does NOT auto-recognise CC.  g++ is ahead of it in the list, and if I
don't explicitly
	setenv XCC CC
or whatever it was (I've forgotten now) configure always sets up for g++.

:>With respect to the second message:
:> - ditto!  This is unmodified STL code.  I have no idea what's going on
:>   or what I can do about this error message in what is *supposed* to be
:>   code that works with this compiler.

:That is strange - it obviously complains on placement new, defined in
:<new.h>, _included_ by algobase.h. Check if RW provides (wrong?)
:<new.h>.

There _is_ an /opt/SUNWspro/SC4.2/include/CC/rw7/rw/new.h header,
but it simply includes a workaround for Turbo C++ and then #includes
the normal system <new.h>

:I suppose the system strcmp() performs far better than
:basic_string::compare ;(. And, as it was mentioned already,
:tristate comparison function is what the sort algorithms miss badly.

And _that_ was the point I originally expected to make about the STL.
I *expected* to find the C++ code running twice as slowly as the C
code, solely for that cause.  I was *shocked* by the numbers I actually
got, and to understand where I'm coming from in this thread, you need to
understand that when I first heard about the STL a couple of years ago
I was really keen on the idea, and just wished I had access to a compiler
that supported it.  I was aware of the overheads of object-oriented 
programming (I've read papers and theses about that) and I was also
aware that the STL avoided precisely the things that were supposed to
cause those overheads.  I _did_ intend to provoke a debate on "why base
everything on "<" rather than 3-way comparison".  I did _not_ expect such
a huge difference.

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Michael Greenwald
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <michaelg.864283263@CS.Stanford.EDU>
··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

>Here's the algorithm:
>    read all the words from file A into a list La.
>    read all the words from file B into a list Lb.
>    sort La eliminating duplicates.
>    sort Lb eliminating duplicates.
>    find the set difference of La and Lb.
>    write that difference one word per line.

>...

>	 The Scheme and C versions use a sorting algorithm that discards
>	 duplicates as it goes; there being no such algorithm in <list>
>	 or <algorithm>, I had to use a .sort() (5.64 sec) followed by
>	 .unique() (1.52 sec).

Combining duplicate elimination with sorting can offer *substantial*
improvements if there are a reasonable number of duplicates (as one
would expect in English text).  Further, a primitive doing
set-difference might, itself, do the sort and duplicate elimination --
in which case the fair comparison would be to code that did *not* do
the sort and duplicate elimination.  set-difference in CommonLisp does
not assume that the lists are already ordered.  Does scheme provide an
ordered-difference or C?  If so, the scheme and C code would be much
faster than CommonLisp or C++.  The point is that although the *names*
are the same, a programmer might use these functions differently in
different languages.  In your case, the comparison might be fair, but
it would be interesting to know the real specs of these primitives in
each language.

But this only offers a possible explanation for the sorting numbers,
it doesn't explain the disparity in I/O.  Do you have an explanation?
(I'm behind on my mail/newsgroup reading, so this might already have
been addressed).  For the writing, I assume they all had the same
flush semantics, yes?

A little more detail about the I/O in each language would probably be
enlightening.

>The numbers (times in seconds as reported by clock()):

>    Results             Scheme1         Scheme2         C               C++
>    reading             1.68            1.70            0.56            2.15
>    sorting             2.99            2.75            0.77  5.64+1.52=7.16
>    matching            0.03            0.03            0.01            0.03
>    writing             0.00            0.00            0.00            0.24
>    total               4.70            4.48            1.34            9.58

>    Lines               57              124             233             92
From: Darin Johnson
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <slrn5o9gi7.b0r.darin@connectnet1.connectnet.com>
In article <············@goanna.cs.rmit.edu.au>, Richard A. O'Keefe wrote:
>This does not look like an advertisement for C++ ``efficiency'' to me.

It says almost nothign about C++.  Instead, you're just showing how
inefficient STL is.  The big drawback is that, when used in the
fashionably correct manner, STL spends lots of time copying values.
When those values are strings, the time taken to copy the values
becomes very noticable.  That is, List<string> is much less efficient
than List<char *> or even List<string *>.  I'm sure your Scheme or C
solution did not spend time copying around values, instead they
inserted references or pointers into the lists.

I know I grouse on this excessively, but I think that in the quest to
get all the high level library features of other languages, C++ has
ignored the low level efficiency part of its nature.  C++ became
popular, and is useful, because of this dual low-level/high-level
nature, if it abandons one or the other, it loses its main advantage
over pure high level or pure low level languages.

-- 
Darin Johnson
·····@usa.net.delete_me
From: Mike Coffin
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5m2iaf$h51@engnews1.Eng.Sun.COM>
In article <····················@connectnet1.connectnet.com>,
Darin Johnson <·····@usa.net.delete_me> wrote:
>In article <············@goanna.cs.rmit.edu.au>, Richard A. O'Keefe wrote:
>>This does not look like an advertisement for C++ ``efficiency'' to me.
>
>It says almost nothign about C++.  Instead, you're just showing how
>inefficient STL is.  The big drawback is that, when used in the
>fashionably correct manner, STL spends lots of time copying values.
>When those values are strings, the time taken to copy the values
>becomes very noticable.

But *why* do most C++ libraries and programs spend so much time
copying things?  Basically, because C++ lacks garbage collection.
If you pass references around, it's almost impossible to avoid memory
leaks.

-mike
From: Chris Bitmead uid(x22068)
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <BITMEADC.97May23175939@Alcatel.com.au>
In article <····················@connectnet1.connectnet.com> ·····@usa.net.delete_me (Darin Johnson) writes:

>In article <············@goanna.cs.rmit.edu.au>, Richard A. O'Keefe wrote:
>>This does not look like an advertisement for C++ ``efficiency'' to me.
>
>It says almost nothign about C++.  Instead, you're just showing how
>inefficient STL is.  

Assuming other aspects of the comparison are fair I think it says
plenty about C++. STL is touted as being as efficient as hand coded
algorithms, and STL is the only way to get some of the benifits of
generic programming in C++.

The fact is that C++ is so close to the hardware that it reduces the
compiler's ability to make assumptions about what's going on. That and
the fact that C++ compiler writers are spending so much time just
interpreting the syntax right that they have no time to do proper
optimisation anyway.
From: David Chase
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <338638F9.5E7E@world.std.com>
Chris Bitmead uid(x22068) wrote:

> The fact is that C++ is so close to the hardware that it reduces the
> compiler's ability to make assumptions about what's going on. That and
> the fact that C++ compiler writers are spending so much time just
> interpreting the syntax right that they have no time to do proper
> optimisation anyway.

Strictly speaking, only the first half is true, and no more than
is the case for ordinary old C.  Often, the people optimising
the code are not the people working about the syntax; I know, because
I once had the choice of working on (general, including C++)
optimization, or C++ syntax, and I chose optimization.  It was
the right choice.

I must say, it is a real hoot to read Richard O'Keefe's experiences
with STL and C++ and various compilers.  It pretty much parallels
my experience with C++ and templates.  Yes sir, it'll be a great
language, someday, when the standard is done, and when all the
vendors have spent more than lip service complying to it, and then
they get all the bugs out.

David Chase
From: ozan s. yigit
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <x6wwoov0wj.fsf@ds9.rnd.border.com>
David Chase:

> I must say, it is a real hoot to read Richard O'Keefe's experiences
> with STL and C++ and various compilers.  It pretty much parallels
> my experience with C++ and templates.  Yes sir, it'll be a great
> language, someday, when the standard is done, and when all the
> vendors have spent more than lip service complying to it, and then
> they get all the bugs out.

in all fairness, how is this any different than the experience we had for
years with various C compilers that could not implement the stdio properly
let alone the standard, or varieties of pascal (can you say vax pascal? :)
or too many dialects of lisp or many implementations of scheme or versions
of prolog? it seems that we have suffered many languages that are never quite
done, never quite stable, and won't let us do work portably and confortably
without a penalty for something or another. by my lights, his experience
is deja vous all over again. [hmm, maybe fortran and ada would be
exceptions but not sure.]

java is tempting, not for greatness but just for being there in one piece.

oz	[ oz at tor dot securecomputing dot com ]
---
Yes, evil comes in many forms, whether it be a man-eating cow
or Joseph Stalin, but you can't let the package hide the pudding!
Evil is just plain bad! You don't cotton to it. You gotta smack
it in the nose with the rolled-up newspaper of goodness!
Bad dog! Bad dog!              --The Tick
From: Thant Tessman
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <3389A77F.41C6@nospam.acm.org>
David Chase:

> I must say, it is a real hoot to read Richard O'Keefe's experiences
> with STL and C++ and various compilers.  It pretty much parallels
> my experience with C++ and templates.  Yes sir, it'll be a great
> language, someday, when the standard is done, and when all the
> vendors have spent more than lip service complying to it, and then
> they get all the bugs out.


ozan s. yigit wrote:

> in all fairness, how is this any different than the experience we 
> had for years with various C compilers that could not implement 
> the stdio properly let alone the standard [...]  it seems that we 
> have suffered many languages that are never quite done, never quite 
> stable, and won't let us do work portably and confortably without a 
> penalty for something or another.  [...]

Of course there's always room for improvement and people are always
going to be pushing the limits of compiler technology.  The issue
is a matter of what you get in return for your efforts.  (Oh boy,
soon C++ will have real strings!)

Besides, the single most bullet-proof well-documented works-as-
advertised piece of software I've ever used was Chez Scheme.  In 
contrast, I can make even my latest C++ compiler (SGI C++7.1) dump 
core on legal C++ code.  (And before someone from SGI e-mails me, 
the problem happens when I define a class constructor in the header 
that contains some particularly hairy template functions.  What dumps 
core is something called "inline".  I don't have time to narrow the 
example down and the workaround is simply not to put the constructor 
in the header file.  Yeah yeah, there's probably a patch I haven't 
installed yet, but it's a pain trying to keep track of them all.)


> Yes, evil comes in many forms, whether it be a man-eating cow
> or Joseph Stalin, but you can't let the package hide the pudding!
> Evil is just plain bad! You don't cotton to it. You gotta smack
> it in the nose with the rolled-up newspaper of goodness!
> Bad dog! Bad dog!              --The Tick

He he!

-thant
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mbe7m$s3f$1@goanna.cs.rmit.edu.au>
·····@usa.net.delete_me (Darin Johnson) writes:

>In article <············@goanna.cs.rmit.edu.au>, Richard A. O'Keefe wrote:
>>This does not look like an advertisement for C++ ``efficiency'' to me.

>It says almost nothign about C++.  Instead, you're just showing how
>inefficient STL is.

I can't win.  Some people bash me for not understanding that Stepanov
is one of the world's greatest programmers, so that any efficiency
problems _must_ be because I'm using a bad compiler.  Now you are bashing
me for not understanding that Stepanov is not a good programmer.

I've said it several times.  I don't *CARE* where the fault lies.
Whether it is C++ in general, the STL, the compiler, or invisible
blue monkeys stealing cycles, the question I was interested in was

"Stepanov wants to provide the world with an *efficient* generic
 library.  He claims that C++ is the only language available which
 comes close to letting him express his ideas (although he does NOT
 claim it is perfect).  Very well, *DID* C++ let him provide *ME*
 with an efficient library?"

The evidence is that it _didn't_.

And what _that_ means is that the dismissal of other languages as in
varying ways inadequate cannot any longer be accepted as evidence that
the other languages do not permit an efficient implementation of *some*
generic algorithm library (although that may well be true; I certainly
haven't proved that it isn't), but merely as evidence that they didn't
let Stepanov say what he wanted to say the way he wanted to say it.

>The big drawback is that, when used in the
>fashionably correct manner, STL spends lots of time copying values.

Not this test program, no.  Remember, it was sorting LISTS.  The bulk
of the time went on sorting a list.  There is no reason for it to do
ANY copying in that phase, and as far as I can tell from reading the
g++ headers, it doesn't.

>When those values are strings, the time taken to copy the values
>becomes very noticable.  That is, List<string> is much less efficient
>than List<char *> or even List<string *>.  I'm sure your Scheme or C
>solution did not spend time copying around values, instead they
>inserted references or pointers into the lists.

Now, if you had said that vector sorting in C++ is inefficient compared
with list sorting because of the need to call swap() operations, I'd
have gone along with that.


>I know I grouse on this excessively, but I think that in the quest to
>get all the high level library features of other languages, C++ has
>ignored the low level efficiency part of its nature.  C++ became
>popular, and is useful, because of this dual low-level/high-level
>nature, if it abandons one or the other, it loses its main advantage
>over pure high level or pure low level languages.

>-- 
>Darin Johnson
>·····@usa.net.delete_me
-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Darin Johnson
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <slrn5ojsmm.e74.darin@connectnet1.connectnet.com>
In article <············@goanna.cs.rmit.edu.au>, Richard A. O'Keefe wrote:
>>It says almost nothign about C++.  Instead, you're just showing how
>>inefficient STL is.
>
>I can't win.  Some people bash me for not understanding that Stepanov
>is one of the world's greatest programmers, so that any efficiency
>problems _must_ be because I'm using a bad compiler.  Now you are bashing
>me for not understanding that Stepanov is not a good programmer.

Um, a valid C program is a valid C++ program.  Your results showed
better results for C than for C++.  On many systems, the exact same
executable is used to compile C and C++.  The fault then probably does
not fall with the C++ language, but in how it is used.  My point is
that if a custom library were used instead of STL, that much better
performance could have resulted.

>I've said it several times.  I don't *CARE* where the fault lies.
>Whether it is C++ in general, the STL, the compiler, or invisible
>blue monkeys stealing cycles, the question I was interested in was
>
>"Stepanov wants to provide the world with an *efficient* generic
> library.  He claims that C++ is the only language available which
> comes close to letting him express his ideas (although he does NOT
> claim it is perfect).  Very well, *DID* C++ let him provide *ME*
> with an efficient library?"
>
>The evidence is that it _didn't_.

Again, my point is that the evidence isn't valid.  STL is arguably not
a part of C++; and even if it is, it's not mandatory that users use
it.  The evidence you have is that *one* library does not provide
efficiency, it says nothing about what other libraries might do, or
that the library could not be used in more efficient ways.

You didn't highlight the word "him".  Is your whole contention just
that he personally didn't do it?  I can agree with that.  But the way
things are worded, at least on first read, it sounded more like
you were saying that the evidence shows C++ was at fault.

>>The big drawback is that, when used in the
>>fashionably correct manner, STL spends lots of time copying values.
>
>Not this test program, no.  Remember, it was sorting LISTS.  The bulk
>of the time went on sorting a list.  There is no reason for it to do
>ANY copying in that phase, and as far as I can tell from reading the
>g++ headers, it doesn't.

Hmm, you could be right.  But there are a lot of places that do
copying or constructing behind the scenes that aren't readily
apparent.  Ie, moving an element from one list to another involves
copying!  It would be interesting to put some instrumentation into the
copy constructor and assignment operator to see how often they're
called, or to have a list of pointers and see if there's any
difference.

>Now, if you had said that vector sorting in C++ is inefficient compared
>with list sorting because of the need to call swap() operations, I'd
>have gone along with that.

I haven't spent the time to fully grok algo.h, but iter_swap appears
to do full copying when used with list iterators (ie, the nodes
themselves aren't swapped, the .data field is what's swapped); and
iter_swap appears essential to sort().

Iter_swap has
   T tmp = *a;
   *a = *b;
   *b = tmp;

Now, "*a" will be the iterator's operator*(), which returns a reference
to the node's data (of type T).  Expanding the inline functions, the compiler
is left with something like:
   T tmp = *a.data;
   *a.data = *b.data;
   *b.data = tmp;
And that has to do a copy three times.  This is reasonably efficient
if "T" is a pointer, but can be very slow if "T" is a class.  If "T"
is a string, it'll do allocation/deallocation as well.

I could be wrong, but this is what I get from reading the code quickly.

-- 
Darin Johnson
·····@usa.net.delete_me
From: Chris Bitmead uid(x22068)
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <BITMEADC.97May22145524@Alcatel.com.au>
In article <············@goanna.cs.rmit.edu.au> ··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

>	 The Scheme and C versions use a sorting algorithm that discards
>	 duplicates as it goes; there being no such algorithm in <list>
>	 or <algorithm>, I had to use a .sort() (5.64 sec) followed by
>	 .unique() (1.52 sec).

I think this bit is a little unfair. Change the programs so that
Scheme and C don't elimitate duplicates as they go. It would make a
fairer test.
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5m3fpq$712$1@goanna.cs.rmit.edu.au>
·············@Alcatel.com.au (Chris Bitmead uid(x22068)) writes:

>In article <············@goanna.cs.rmit.edu.au> ··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

>>	 The Scheme and C versions use a sorting algorithm that discards
>>	 duplicates as it goes; there being no such algorithm in <list>
>>	 or <algorithm>, I had to use a .sort() (5.64 sec) followed by
>>	 .unique() (1.52 sec).

>I think this bit is a little unfair. Change the programs so that
>Scheme and C don't elimitate duplicates as they go. It would make a
>fairer test.

This is rubbish.  In fact, it is silly rubbish.
Recall that I am not trying to evaluate *compilers* or *languages*,
but simply the claim that using C++ permitted the development of an
efficient *library*.

If the library forces me to take a detour, then that is a SALIENT
property of the library.  If I were comparing compilers, I would have
to do things in similar ways.  But since the question at issue is
whether C++-with-the-STL offers a worthwhile efficiency improvement
over Scheme-with-my-existing-library (slib + my own stuff), then
changing the Scheme and C programs would be a GROSSLY UNFAIR test
that was biased in favour of the STL.

If the STL doesn't give me the operation I want,
and synthesising the operation I want from the operations it DOES
provide is so inefficient that hand-writing new code instead pays
off, then to that extent the STL has failed me (even if it does
wonders for everyone else in the world).  Now, given the the STL
has sequences of several kinds, and that it has sets, and that it
offers algorithms for operating on sets represented as ordered
sequences, I think someone who is genuinely interested in fair
comparison will agree that converting a list to a set (represented
the way the STL set-as-sequence operations want it) is not an exotic
or unlikely operation.  What's more, it's an operation that COULD be
supported by the STL, quite easily.

Chris Bitmead, if you want to see a fair comparison, why don't you
provide a list::sort_nodups() or list::sort_unique() operation that
can be added to the STL?  Other contributions to the STL have been
received thankfully and made generally available, I'm sure yours would.

(I already _had_ this operation available in several languages, because
I have so often had need of it.  Prolog programmers will recognise sort/2.)

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Chris Bitmead uid(x22068)
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <BITMEADC.97May26124525@Alcatel.com.au>
In article <············@goanna.cs.rmit.edu.au> ··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

>>I think this bit is a little unfair. Change the programs so that
>>Scheme and C don't elimitate duplicates as they go. It would make a
>>fairer test.
>
>This is rubbish.  In fact, it is silly rubbish.
>Recall that I am not trying to evaluate *compilers* or *languages*,
>but simply the claim that using C++ permitted the development of an
>efficient *library*.

Well did STL prevent you from writing an algoritm to sort while
elimitating duplicates? Or did it just make it convenient to not
bother with the elimination, whereas Scheme didn't provide anything,
so you implemented it the best way?

I seek merely information, because I got the impression that it was
the latter, which doesn't seem fair. Maybe you are saying it was
easier to write the Scheme anyway. If so, perhaps provide more info on
the effort required.

>If the STL doesn't give me the operation I want,
>and synthesising the operation I want from the operations it DOES
>provide is so inefficient that hand-writing new code instead pays
>off, then to that extent the STL has failed me (even if it does
>wonders for everyone else in the world).  

Well I don't know that everybody knows how to write nice sorting
algorithms even if they want to. That's part of the point of generic
algorithms.

>Chris Bitmead, if you want to see a fair comparison, why don't you
>provide a list::sort_nodups() or list::sort_unique() operation that
>can be added to the STL?  Other contributions to the STL have been
>received thankfully and made generally available, I'm sure yours would.

I don't like C++, and wouldn't use it unless paid lots of money :-P I
might implement the Scheme sort and remove dups as separate phases
though ;-)
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mh0p1$srd$1@goanna.cs.rmit.edu.au>
·············@Alcatel.com.au (Chris Bitmead uid(x22068)) writes:

>In article <············@goanna.cs.rmit.edu.au> ··@goanna.cs.rmit.edu.au (Richard A. O'Keefe) writes:

>>>I think this bit is a little unfair. Change the programs so that
>>>Scheme and C don't elimitate duplicates as they go. It would make a
>>>fairer test.
>>
>>This is rubbish.  In fact, it is silly rubbish.
>>Recall that I am not trying to evaluate *compilers* or *languages*,
>>but simply the claim that using C++ permitted the development of an
>>efficient *library*.

>Well did STL prevent you from writing an algoritm to sort while
>elimitating duplicates? Or did it just make it convenient to not
>bother with the elimination, whereas Scheme didn't provide anything,
>so you implemented it the best way?

I have said it before:  the Scheme library I have had for years ALREADY
had a list->set function.  (So does the Prolog library I used to maintain.
So does my personal C library.)

In fact, using the STL data structures ***DID*** make it very very hard
to write an efficient algorithm to sort while eliminating duplicates.

>I seek merely information, because I got the impression that it was
>the latter, which doesn't seem fair.

Remember, the STL is supposed to be efficient.  The STL provides
 - a set abstraction with no batch operations on sets
 - a sequence abstraction which _does_ provide batch operations on sets
   encoded as sequences in a certain way
 - NO operation to convert a set to such a sequence (in the version I
   was using)
 - NO operation to convert a sequence to that form

Surely it is fair to point that out?  The corresponding Scheme/Prolog/C
code I've had for years _does_ have that missing operation.

And yes, once again I wills ay it:  it is _not_ possible to provide that
operation on top of the STL data structures without cracking open the
capsule and tinkering with the guts in entirely non-portable ways.
The point of something like the STL is that you don't do your own
pointer-bending code any more, you call the high level operations
provided, and in fact you don't even know what the names of the pointer
members (->next, ->prev, that kind of thing) _are_.

>Maybe you are saying it was
>easier to write the Scheme anyway. If so, perhaps provide more info on
>the effort required.

I cannot *believe* the hypocrisy of some people.  Am I to devote my
whole life to exploring the flaws in someone else's product?  And to
repeating myself?  I already *said* that it took several *hours* to try
to simply port the C++ code from g++ to CC, and that the attempt failed.
Years ago, there was Prolog code to do list->set.
Slightly fewer years ago, I translated that to C.  (A doddle.)
Slightly fewer years ago again, I translated it to Scheme.  (Also a doddle.)
The time it took to write the Scheme code is therefore uninformative,
because it was written by someone who already understood merge-based
sorting and this particular operation in some detail.  The time it took
to write the C++ code is also uninformative, because I was _not_ familiar
with the STL and had to spend a lot of time looking things up in the
draft standard, and a lot of time figuring out why the compilers I was
using didn't actually support them.


>Well I don't know that everybody knows how to write nice sorting
>algorithms even if they want to. That's part of the point of generic
>algorithms.

That's the bloody POINT!  And you *STILL* don't acknowledge that the
efficiency of the generic algorithm matters????  What the hell is the
use of 'generic algorithms' if they turn out to be so amazingly slow
(for whatever reason) that it pays you handsomely to write a
non-generic one?  (Heck, the C code is generic:  change one typedef
and one macro, and you can sort any singly linked list.)

>I don't like C++, and wouldn't use it unless paid lots of money :-P I
>might implement the Scheme sort and remove dups as separate phases
>though ;-)

That would be a big mistake.
-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Max Moroz
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <33860CF1.9EA0441A@ucla.edu>
New results on the tests point to much better C++ and STL efficiency.

I again rerun the test by Richard O'Keefe on my Solaris machine (1.2
times slower than Richard's), with (almost) the same input files, with
the SunOS CC 4.2, using SGI STL patch for SunOS by B. Fomitchev, and
RogueWave v. 7 for the String class.

My first test was with Richard's source code. I got the following
timing, which is very close to 1.2 times of what he reported on his
machine:

12:53pm MM_LEDA/tests> wc tmp/EM
   23977  154996 1034959 tmp/EM
12:54pm MM_LEDA/tests> wc tmp/GC
   27452  171275 1212644 tmp/GC

W1 has 160506 words
W2 has 176278 words
DF has 2797 words
reading        2.360
sorting        8.420
matching       0.030
writing        0.150
TOTAL         10.960

My second test was with the following changes:

(1) set used instead of list to store words into W1 and W2 (as proposed
by Helmut Zeisel, and as anyone who has some experience with STL would
have done in the first place)

(2) const char* used instead of RogueWave's CString. My sets store
pointers to memory where the string was initially read from the disk.
(If the string is repeated, I free the memory).

The result:

1:55pm MM_LEDA/tests> slow tmp/{EM,GC} | tail
zap
zone
W1 has 6257 words
W2 has 7478 words
DF has 2797 words
reading    3.250
sorting    0.000
matching   0.020
writing    0.010
TOTAL    3.280

It is 3.35 times faster. This brings the factor C++ : C reported by
Richard to approximately 2:1 (in favour of C), on assumption that C code
would run the same 1.2 times longer on my machine versus Richard's
machine.

Next step in optimizing the code is using hash_set instead of set. I
will report my results after I do this. (Note: set_difference is not yet
implemented for hash_set, as far as I know; unless someone refers me to
an existing implementation, I will write my own one.)

Richard, would you be so nice as to post you C code as well? Thanks!

Regards,

	-- Max

P.S. Here is the code with my changes. I commented with
// added
// removed
// changed
(hopefully) all changes in the code relative to Richard's.

#include <iostream.h>
#include <stdio.h>
//#include <string.h>
//#include <stdlib.h>
#include <ctype.h>
#include <set>
#include <list>
#include <time.h>
#include <iterator>
#include <algorithm>

struct strless { // added
  bool operator()(const char* lhs, const char* rhs) {
    while (*lhs && *rhs) {
      if ((*lhs)<(*rhs))
        return true;
      if ((*lhs++)>(*rhs++))
        return false;
    }
    return (*lhs)<(*rhs);
  }
};

typedef list<const char*> word_list; // changed string to const char*
typedef set<const char*, strless> word_set; // changed string to const
char*

void read_words(char const *File, word_set &result) {
  register FILE *f;
  register int c;
  register char *p;
//  char buff[81]; //removed

  f = fopen(File, "r");
  if (f == 0) {
    fprintf(stderr, "Cannot open %s\n", File);
    exit(EXIT_FAILURE);
  }
  for (;;) {
  char* const buff=new char[81]; // added
    do
      c = getc(f);
    while (c != EOF && !isalpha(c));
    if (c == EOF)
      break;
    p = buff;
    do
      *p++ = c, c = getc(f);
    while (c != EOF && isalpha(c));
    *p = '\0';
    if (!result.insert(buff).second)
      delete[] buff; // added
  }
  fclose(f);
}


inline double time_in_seconds(void) {
return clock()/(double)(CLOCKS_PER_SEC);
}

int main(int argc, char **argv) {
double T0 = time_in_seconds();

assert(argc==3); // added: to prevent warnings from my compiler
word_set W1;
  read_words(argv[1], W1);
word_set W2;
read_words(argv[2], W2);

double T1 = time_in_seconds();

double T2 = time_in_seconds();

word_list DF;

int main(int argc, char **argv) {
double T0 = time_in_seconds();

assert(argc==3); // added: to prevent warnings from my compiler
word_set W1;
  read_words(argv[1], W1);
word_set W2;
read_words(argv[2], W2);

double T1 = time_in_seconds();

double T2 = time_in_seconds();

word_list DF;

(void) set_difference(W1.begin(), W1.end(),
W2.begin(), W2.end(), back_inserter(DF), strless());

double T3 = time_in_seconds();

word_list::iterator W;
for (W = DF.begin(); W != DF.end(); W++)
  cout<<*W<<'\n'; // changed: endl into '\n' (saves time)

double T4 = time_in_seconds();

printf("W1 has %ld words\n", (long)W1.size());
printf("W2 has %ld words\n", (long)W2.size());
printf("DF has %ld words\n", (long)DF.size());

printf("reading %8.3f\n", T1-T0);
printf("sorting %8.3f\n", T2-T1);
printf("matching%8.3f\n", T3-T2);
printf("writing %8.3f\n", T4-T3);
printf("TOTAL%9.3f\n",T4-T0);
return 0;
}
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mbjag$2gs$1@goanna.cs.rmit.edu.au>
Max Moroz <······@ucla.edu> writes:

>New results on the tests point to much better C++ and STL efficiency.

Good!

>(1) set used instead of list to store words into W1 and W2 (as proposed
>by Helmut Zeisel, and as anyone who has some experience with STL would
>have done in the first place)

Come now.  How many times do I have to say that my aim was to test
doing something a certain _way_?  sort/sort/merge is a paradigm of
great importance.

But let me tell you the real reasons why I didn't do that
"in the first place".

1) I have repeatedly stated that the documention I was working from when
   I wrote my test code was the April 1995 draft of the C++ standard.
   When I wrote set-based code to that standard, g++ would not compile it.
   23.3 said
	template <
	    class Key,
	    class Compare = less<Key>,
	    class Allocator = allocator
	> class set;

    libg++ says instead

	template <
	    class Key,
	    class Compare
	> class set;

    and I didn't understand what I was supposed to do.  (Answer:
	#include <function.h>
	typedef set< string, less<string> > word_set;
    )

2) Anyone who has some experience with STL will be aware that the set
   class template, whatever its other merits, had at least in that draft
   very few operations on whole sets.  In particular, I want to take the
   difference of two sets.  The only way I have found to do that is to
   use *both* <set> and <list>:  to insert the words into sets as they
   are read, convert the sets to lists, and then take the set difference
   of the lists.  (Why the heck doesn't <set> offer operations on whole
   sets?)  From the documentation available to me, I didn't really know
   if I _could_ convert a set to a list the right way:  is it guaranteed
   that a forward iterator over a set will deliver elements in strictly
   increasing order?  If so, is it guaranteed to take O(N) time, or might
   it be O(NlgN) or what?

    The key step is that I have to do

	set_difference(set1.begin(), set1.end(),
		       set2.begin(), set2.end(),
		       back_inserter(DF));

    I don't know whether this _must_ work or just works by accident.
    I don't know whether there is some way for the last argument to
    say "insert into a set, not a sequence".  I would _much_ rather
    say
	DF = set_difference(set1, set2);
    or even,
	set1.difference(set2);


3) My original aim as stated was to try out the generic _sequence_
   operations in <algorithm>.  A program working on sets would not be
   testing those operations.




Ok, now I've managed to get it working.  Here are my results for
building a set as you go, flattening that to a list, and taking the
set difference of two lists.

/*              C       C++     Scheme
    reading     0.80    3.99    3.89            (+build set)
    sorting     0.01    0.04    0.01            (set->list)
    matching    0.00    0.01    0.01            (list diff)
    writing     0.00    0.00    0.00
    TOTAL       0.81    4.04    3.91

The time just to read the words and return empty sets is 0.22 seconds
in C (1.64 seconds in Scheme) so say
    build sets	0.58	3.77	2.25

Most of the time is going in the NlgN part (building the sets).
The C++ code uses red-black trees.  The C and Scheme code use simple BSTs.
The Scheme/C ratio is broadly compatible with a 4:1 overhead for string
comparison.

>It is 3.35 times faster. This brings the factor C++ : C reported by
>Richard to approximately 2:1 (in favour of C), on assumption that C code
>would run the same 1.2 times longer on my machine versus Richard's
>machine.

My code reported above still uses <string.h>.  But I repeat, that is
part of the draft standard for the language, and has been for more than
two years.  I don't _care_ whether the compilers aren't up to it, or the
libraries aren't any good yet, or whether the interface specified in the
draft standard necessitates high overheads, the C++ *systems* available
to me either don't conform to the standard or don't have efficient strings.

THIS MAKES THE TEST AGAINST THE STL UNFAIR, in that it isn't the STL's
fault if strings are slow.  But it _is_ a property of the STL that I have
to use C++ in order to use it, so to that extent it _is_ the STL's fault
if I have to use a language processor with slow strings.

>Next step in optimizing the code is using hash_set instead of set. I
>will report my results after I do this. (Note: set_difference is not yet
>implemented for hash_set, as far as I know; unless someone refers me to
>an existing implementation, I will write my own one.)

This time, I didn't have existing Scheme code for the dictionary structure
I used, but I _did_ have existing C code I could re-use.

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Max Moroz
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <3389DF6E.55FE753F@ucla.edu>
Richard A. O'Keefe wrote:

> Come now.  How many times do I have to say that my aim was to test
> doing something a certain _way_?  sort/sort/merge is a paradigm of
> great importance.

I agree that sort/sort/merge is a very important sequence and it must be
done efficiently in C++/STL. But you did NOT test this sequence. You
tested "sort & remove duplicates" in C/Scheme versus "sort with
duplicates" followed by "remove duplicates" in C++. Surely, you would
agree that the latter is much slower. You said you did it because STL
did not provide the means to do it in one step. This is *very wrong*.
STL not only provides such algorithm, but actually *encourages* users to
use this more efficient algorithms instead of the slower algorithm you
used. This feature is provided by the (sorted) set container. Set is
strictly better approach than list in this case because it has all
list's functionality plus efficiency for sorting with removal of
duplicates. STL design assumes that you always choose the best container
for your needs. Hence, it does not provide algorithms tailored
containers inappropriate for the task, but rather forces the user to
work with the correct container. If you *did need* a list in your
problem, use it. But before you do "sort removing duplicates", convert
list to set. And then, *if needed* convert it back.

As an example of how this approach works, see my posting about hash_sets
in this thread. When trying to rewrite your algorithm to use hash sets,
I made *exactly* the same error as you did running "sort-unique" on
list. I rewrote an algorithm set_difference to work on hash_sets, only
to see that STL's idea "convert to set, do set_difference, convert back
if you need" is more efficient. I have been using STL for 2 months only,
hence such errors.

> 1) I have repeatedly stated that the documention I was working from when
>    I wrote my test code was the April 1995 draft of the C++ standard.

Well, why do you work from a Draft Standard? You can refer to it in
cases of ambiguity about what is considered portable, and what is not.
In you normal work, however, you should use the documentation provided
by the vendor who supplied your library/compiler/etc (unless the vendor
guarantees full compliance with the standard, which no current compiler
does). GNU, being a free compiler, has limited documentation. If you use
it, you are supposed to either learn its features by trial and error, or
by reading newsgroups, etc. But even in the free domain, there is an
implementation of STL with very good quality documentation (SGI STL
adapted for various compilers- you have been already referred to it).

> 2) Anyone who has some experience with STL will be aware that the set
>    class template, whatever its other merits, had at least in that draft
>    very few operations on whole sets.

That is wrong. You have few *member functions* on sets. But several
generic algorithms work on sets. Particularly, set_difference works very
efficiently on sets (see 25.3.5.4, if you really want to use the
Standard).

>    sets?)  From the documentation available to me, I didn't really know
>    if I _could_ convert a set to a list the right way:  is it guaranteed
>    that a forward iterator over a set will deliver elements in strictly
>    increasing order?  If so, is it guaranteed to take O(N) time, or might
>    it be O(NlgN) or what?

Yes, it's said in any documentation on sets I've ever seen. Including in
Draft Standard, 23.3.3 (reversible container implies O(N) for traversal,
sorted container implies delivering elements in ascending order).


>     The key step is that I have to do
> 
>         set_difference(set1.begin(), set1.end(),
>                        set2.begin(), set2.end(),
>                        back_inserter(DF));
> 
>     I don't know whether this _must_ work or just works by accident.

You should use inserter initialised to end():

	..., inserter(setResult, setResult.end()))

instead of back_inserter. It's guaranteed to work because of what I said
above and because of the definition of inserter. It's also the first
example of usage of sets in at least one documentation and two tutorials
on STL. "RTFM" applies to libraries no less than to games.

>     I don't know whether there is some way for the last argument to
>     say "insert into a set, not a sequence".  I would _much_ rather
>     say
>         DF = set_difference(set1, set2);

Assignment is inefficient; you first build an object, and then copy it
to another. STL puts output directly to DF by asking you to supply to it
iterator to DF.

>     or even,
>         set1.difference(set2);

The algorithms set_difference is generic, and it is not intuitive to
define a generic algorithms as member fn.


> 
> 3) My original aim as stated was to try out the generic _sequence_
>    operations in <algorithm>.  A program working on sets would not be
>    testing those operations.

As I said above, STL does not have *sequence* operations for the purpose
of showing off how efficient it is with sequences. It has only those
sequence operations that make sense for real programming. If it knows
that an operation will be more efficient if you convert the sequence to,
say, a sorted container, do the operation, and convert back, it tries to
force the user to apply this approach.

This convert->run algorithm->convert is not *always* more efficient in
case of simple sort, so a version of sort *is* provided for lists. But
it is *always* more efficient for "sort&remove duplicates", where there
are many identical items. I ran my version of C++ code on 40 MB and 10
MB files, and got even stronger results in support of what I say than
with 1 MB files you use.

> 
> Ok, now I've managed to get it working.  Here are my results for
> building a set as you go, flattening that to a list, and taking the
> set difference of two lists.

You should not flatten to a list before taking set_difference. It would
only be a small improvement, though, since the results are already
rather small in size.


> My code reported above still uses <string.h>.  But I repeat, that is
> part of the draft standard for the language, and has been for more than
> two years.  I don't _care_ whether the compilers aren't up to it, or the
> libraries aren't any good yet, or whether the interface specified in the
> draft standard necessitates high overheads, the C++ *systems* available
> to me either don't conform to the standard or don't have efficient strings.

You should not use string.h strings. You should const char*. There is no
reason in the world to use complex strings in this case. string.h is
there for you when you need it. const char* has NOT been deprecated by
C++ standard, and it is even DIRECTLY supported by STL. Your usage of
string.h here is similar to using -g switch when compiling a program,
and then comparing it with ones compiled with -O5.

> 
> THIS MAKES THE TEST AGAINST THE STL UNFAIR, in that it isn't the STL's
> fault if strings are slow.  But it _is_ a property of the STL that I have
> to use C++ in order to use it, so to that extent it _is_ the STL's fault
> if I have to use a language processor with slow strings.

This is wrong. STL fully supports const char*, as just any other type.
Moreover, in SGI STL there are even predefined (for your convenience)
hash functions specifically for const char*.

	-- Max
From: Erik Naggum
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <3073702480536970@naggum.no>
* Max Moroz -> Richard A. O'Keefe
| Well, why do you work from a Draft Standard?  You can refer to it in
| cases of ambiguity about what is considered portable, and what is not.
| In you normal work, however, you should use the documentation provided by
| the vendor who supplied your library/compiler/etc (unless the vendor
| guarantees full compliance with the standard, which no current compiler
| does).

I can't speak for Richard, but I prefer to write my software in a language,
not a particular product.  I strongly prefer knowing how things should
work, what constructs should mean, etc, and then augment this by a list of
implementation restrictions, bugs, and other deviations.  plus a full
specification of the (inevitable) implementation-defined features.  if this
is impossible for some given language and one is expected to keep up with
an increasingly erratic set of random features, I consider it a waste of my
time to learn to use just a (buggy) product, except in some very special
cases (like Emacs and experimental languages).

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: Max Moroz
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <33862317.2C3FB403@ucla.edu>
And I have just finished rewriting Richard's code to use hash_set
instead of regular set. I am using SGI STL implementation of hash_set.

The code should be portable, as long as you use SGI STL patch by B.
Fomitchev (CORRECTLY configured for your particular compiler!).

Differences from Richard's initial code:

(1) I use regular C strings instead of C++ strings
(2) I use hash_set to remove duplicate words
(3) I copy hash_set into set to sort the thing
(4) I do set_difference on the sets (I still put result to the list)

Here is the timing report:

3:33pm MM_LEDA/tests> slow tmp/{EM,GC} | tail
DF has 2797 words
reading    1.960
sorting    0.000
matching   0.170
writing    0.010
TOTAL    2.140

For comparison, initial Richard's code had these times:

DF has 2797 words
reading        2.360
sorting        8.420
matching       0.030
writing        0.000
TOTAL         10.810

Thus, more than 5-fold improvement. Richard, you reported 7-fold
improvement when using C instead of C++. Could you post the C code,
please? And maybe rerun on your machine the C++ code I have posted in
this and previous messages.

Note: I am using hash_set here. It may seem to make comparison to C
somewhat unfair, since C used sorted sets. But then it IS the main
problem with C that you cannot easily incorporate powerful tools into
your code. I spent no time at all rewriting the C++ code to use
hash_set. There is nothing like the convenience of STL library for those
who use C. So, I think it's fair after all.

Anyway, in my previous posting I showed source code without hash_set,
just regular sorted set. It was total time 3.280, or 1.5 times worse.

Another note: I thought it would be better to have set_difference
algorithm applicable directly to hash_set. I wrote a quick version,
since it is not supplied by SGI STL. But then I found that converting
hash_set to set (sorting on the way), and doing set_difference on the
sets is more efficient! So, the reason SGI STL has no set_difference for
hash_sets is because it would be more efficient to sort and use regular
set_difference. (I wonder, is it true for ANY two hash_sets, however
large and however similar?)

Regards,

	-- Max

P.S. Here is the code:

#include <iostream.h>
#include <stdio.h>
#include <ctype.h>
#include <hash_set>
#include <set>
#include <list>
#include <time.h>
#include <iterator>
#include <algorithm>

struct strequal {
  bool operator()(const char* lhs, const char* rhs) const {
    while (*lhs && *rhs)
      if ((*lhs)<(*rhs)) return false;
      else if ((*lhs++)>(*rhs++)) return false;
    return (*lhs)==(*rhs);
  }
};

struct strless {
  bool operator()(const char* lhs, const char* rhs) const {
    while (*lhs && *rhs)
      if ((*lhs)<(*rhs)) return true;
      else if ((*lhs++)>(*rhs++)) return false;
    return (*lhs)<(*rhs);
  }
};

typedef list<const char*> word_list;
typedef hash_set<const char*, hash<const char*>, strequal> word_set;
typedef set<const char*, strless> word_sorted_set;

void read_words(char const *File, word_set &result) {
  register FILE *f;
  register int c;
  register char *p;

  f = fopen(File, "r");
  if (f == 0) {
    fprintf(stderr, "Cannot open %s\n", File);
    exit(EXIT_FAILURE);
  }
  for (;;) {
  char* const buff=new char[81]; // added
    do
      c = getc(f);
    while (c != EOF && !isalpha(c));
    if (c == EOF)
      break;
    p = buff;
    do
      *p++ = c, c = getc(f);
    while (c != EOF && isalpha(c));
    *p = '\0';
    if (!result.insert(buff).second)
      delete[] buff;
  }
  fclose(f);
}


inline double time_in_seconds(void) {
return clock()/(double)(CLOCKS_PER_SEC);
}

int main(int argc, char **argv) {
double T0 = time_in_seconds();

word_set W1;
read_words(argv[1], W1);
word_set W2;
read_words(argv[2], W2);

double T1 = time_in_seconds();
double T2 = time_in_seconds();

word_set W1;
read_words(argv[1], W1);
word_set W2;
read_words(argv[2], W2);

double T1 = time_in_seconds();
double T2 = time_in_seconds();

word_sorted_set S1;
word_sorted_set S2;
copy(W1.begin(), W1.end(), insert_iterator<word_sorted_set>(S1,
S1.begin()));
copy(W2.begin(), W2.end(), insert_iterator<word_sorted_set>(S2,
S2.begin()));

word_list DF;

(void) set_difference(S1.begin(), S1.end(),
S2.begin(), S2.end(), back_inserter(DF), strless());

double T3 = time_in_seconds();

word_list::iterator W;
for (W = DF.begin(); W != DF.end(); W++) cout<<*W<<'\n'; // changed:
endl into '\n' (saves time)

double T4 = time_in_seconds();

printf("S1 has %ld words\n", (long)S1.size());
printf("S2 has %ld words\n", (long)S2.size());
printf("DF has %ld words\n", (long)DF.size());

printf("reading %8.3f\n", T1-T0);
printf("sorting %8.3f\n", T2-T1);
printf("matching%8.3f\n", T3-T2);
printf("writing %8.3f\n", T4-T3);
printf("TOTAL%9.3f\n",T4-T0);
return 0;
}
From: Richard A. O'Keefe
Subject: Re: STL efficiency (Was: Re: C++ briar patch (Was: Object IDs are bad))
Date: 
Message-ID: <5mbk8q$3ah$1@goanna.cs.rmit.edu.au>
Max Moroz <······@ucla.edu> writes:

>And I have just finished rewriting Richard's code to use hash_set
>instead of regular set. I am using SGI STL implementation of hash_set.

>Thus, more than 5-fold improvement. Richard, you reported 7-fold
>improvement when using C instead of C++. Could you post the C code,
>please? And maybe rerun on your machine the C++ code I have posted in
>this and previous messages.

Here's what happened when I tried your code in the machine I used for
the earlier tests:

y% g++ -O6 wdhash.cpp
wdhash.cpp:56: hash_set: No such file or directory

OK, I've got the new STL port, which is configured for CC, not g++.
In order to run this test, I shall have to reconfigure it for g++.
Frankly, I have a lot of other things to do.


>Note: I am using hash_set here. It may seem to make comparison to C
>somewhat unfair, since C used sorted sets. But then it IS the main
>problem with C that you cannot easily incorporate powerful tools into
>your code.

This simply isn't true.  I have sets-as-hash table implementations
for C stacked up to here (points about 2 feet above top of head).
What's more, for _real_ speed, I have trie code, which I don't find
in the STL.

>I spent no time at all rewriting the C++ code to use
>hash_set. There is nothing like the convenience of STL library for those
>who use C. So, I think it's fair after all.

Replacing one ADT by another is simple in C if you follow consistent
naming conventions and interfaces.  _That_ is a great merit of the STL:
it provides naming conventions and interfaces, and conforming to them
offers high leverage compared with inventing your own.

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Peter da Silva
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5m46jb$2od@web.nmti.com>
In article <···············@kadath.ens.fr>,
Francois-Rene Rideau  <······@ens.fr> wrote:
>    I invite all sensible people to contribute to help making these
> better days happen sooner, to everyone's long-term benefit.

Two words:

	"GNU Smalltalk"

-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: Alaric B. Williams
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3378bcdb.6435974@news.demon.co.uk>
On Tue, 13 May 1997 16:49:16 GMT, ······@netcom.com (Henry Baker)
wrote:

>In article <··········@research.att.com>, ··@research.att.com (Bjarne
>Stroustrup) wrote:
>
>> I do not believe that for most people and organizations a radical break
>> with the past is the best or fastest way to progress.
>
>There's a big difference between a 'radical break with the past', and
>a 'regression into the past'.  I have a very difficult time understanding
>how you can put 'progress' and 'C++' in the same sentence.

Well, Henry, I think that although C++ is a poor /language/, it's
political goals as Bjarne stated are noble. C++ programmers have
abused this psychologically, giving us a generation of UNIX/C++
junkies who think they own the world (well, they do, come to think of
it!), but hey - I doubt that phsychological factors were major goals
for Bjarne :-)


ABW
            ##### UNIX IS LAME - EVEN LINUX! ##### 

(My previous nice signature file was just vapourised by
a Linux kernel crash that ate almost all of my main
partition, so we will have to make do with a boring and
slightly bitter .sig)

Alaric B. Williams, ······@abwillms.demon.co.uk

FUN: http://www.abwillms.demon.co.uk/alaric/wfewad.htm
INTERESTING: http://www.abwillms.demon.co.uk/os/
OTHER: http://www.abwillms.demon.co.uk/
From: Alaric B. Williams
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3378bd9b.6627279@news.demon.co.uk>
On Mon, 12 May 1997 18:08:17 GMT, ··@research.att.com (Bjarne
Stroustrup) wrote:

>We certainly do try to change programmers' tastes. That is why we
>teach new styles and techniques to make programmers more effective.
>We try to convince programmers to adopt these techniques where
>appropriate and as fast as the individuals and organizations can
>absorb the changes while remaining effective.

That, indeed, is a noble goal.

>I feel that C++ has contributed significantly to the much wider acceptance
>of data abstraction, object-oriented programming, and generic programming
>that we see today (compared to, say, ten years ago). I think it will continue
>to contribute significantly and positively for years to come.

This, too, is true; it is a sad side effect that religious C++
advocates think this makes C++ a really cool language. C++ is OKish
as a language; indeed, I would agree that it's true power is
political. I couldn't have done a better job - a compliment from an
egomaniac such as myself ;-)

>I think most people in the continuing language debates/wars agree that we
>want to use better programming and design techniques. Many also agree that
>better languages can help.

Some do... some have this pigheaded idea that THEIR language already
has everything :-(

>I do not believe that for most people and organizations a radical break
>with the past is the best or fastest way to progress. Sometimes and for
>some people a radical break works. However, when enthusiasm outstrips
>caution and experience it is easy to trigger a backlash. Lasting change
>on a large scale is far harder to achieve than most people seem willing
>to believe.

Yeah :-(


>	- Bjarne

>Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html

ABW (you have my undying respect, except that I really WOULD have done
something about C++ strings if I where you :-)

            ##### UNIX IS LAME - EVEN LINUX! ##### 

(My previous nice signature file was just vapourised by
a Linux kernel crash that ate almost all of my main
partition, so we will have to make do with a boring and
slightly bitter .sig)

Alaric B. Williams, ······@abwillms.demon.co.uk

FUN: http://www.abwillms.demon.co.uk/alaric/wfewad.htm
INTERESTING: http://www.abwillms.demon.co.uk/os/
OTHER: http://www.abwillms.demon.co.uk/
From: Matt Kennel (Remove 'nospam' to reply)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5nl199.cvo.kennel@lyapunov.ucsd.edu>
On Mon, 12 May 1997 18:08:17 GMT, Bjarne Stroustrup <··@research.att.com> wrote:
:experiences - even in cases where we don't share them. In particular,
:I do not subscribe to the popular theory that it is essential to force
:people to change and that a language should be designed to be a key part
:of an effort to enforce a style/paradigm/philosophy.

Well, I must disagree here, as I see computer language as by far
the most historically successful means of transmitting style, paradigm
and philosophy---in other words the product of computer science research
into economically significant practice. 

-- 
Matthew B. Kennel/Institute for Nonlinear Science, UCSD/
Don't blame me, I voted for Emperor Mollari. 
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <BITMEADC.97May13154854@Alcatel.com.au>
In article <·······················@10.0.2.1> ······@netcom.com (Henry Baker) writes:

In article <··········@research.att.com>, ···@research.att.com (Andrew
Koenig) wrote:

> Never -- but it doesn't matter, because the higher-order functional
> languages do not support -- and their communities consider irrelevant --
> other key aspects of programming languages that most commercial
> programmers consider indispensible.
> 
> For example, a good chunk of commercial programming practice today
> is related in some way to object-oriented design.  A key notion in
> object-oriented design is the use of objects to represent concepts
> in the program being designed.  An important characteristic of objects
> is their ability to store mutable state information.

Since when is mutable state information an essential characteristic of
OO?  Mutibility and object-orientation are completely orthoganal
issues.
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EA4D8J.1Ez@research.att.com>
In article <······················@Alcatel.com.au> ·············@Alcatel.com.au writes:

> Since when is mutable state information an essential characteristic of
> OO?  Mutibility and object-orientation are completely orthoganal
> issues.

Perhaps in theory, but certainly not in practice.  To see this,
look in your favorite book on OO design and see how many of the
designs there can be implemented using only immutable objects.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <BITMEADC.97May14121516@Alcatel.com.au>
In article <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

>In article <······················@Alcatel.com.au> ·············@Alcatel.com.au writes:
>
>> Since when is mutable state information an essential characteristic of
>> OO?  Mutibility and object-orientation are completely orthoganal
>> issues.
>
>Perhaps in theory, but certainly not in practice.  

Practice in the C++ and Smalltalk worlds perhaps, for the obvious
reason that they don't support functional programming very well.

>To see this,
>look in your favorite book on OO design and see how many of the
>designs there can be implemented using only immutable objects.

That is because most books are orientated towards the most popular
languages, of which functional don't rate too highly.

Another restatment of the argument that C++ is popular therefore it's
good?
From: Paul Prescod
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EA60pH.5zw@undergrad.math.uwaterloo.ca>
In article <······················@Alcatel.com.au>,
Chris Bitmead uid(x22068) <·············@Alcatel.com.au> wrote:
>>To see this,
>>look in your favorite book on OO design and see how many of the
>>designs there can be implemented using only immutable objects.
>
>That is because most books are orientated towards the most popular
>languages, of which functional don't rate too highly.
>
>Another restatment of the argument that C++ is popular therefore it's
>good?

Not good in some absolute, moral sense, just useful. I am not arguing this,
and am not really interested in discussing it. I am just trying to make 
clear the difference between what you claim the C++ advocates are saying
and what I hear them saying. Some careful listening might reduce noise.

 Paul Prescod
From: Graham Matthews
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <337BDA48.1820@maths.anu.edu.au>
Matt Kennel (Remove 'nospam' to reply) wrote:
> If you believe what Abelson and Sussman say, "object" goes along with
> stateful mutability.  Chapter 3, structure + interpretation of
> computer programs

Sorry but I don't believe them. I write OO code every day in a
functional language -- whats the problem. OO can be separated from
stateful mutability -- they are not one in the same.

Someone:
> :>To see this,
> :>look in your favorite book on OO design and see how many of the
> :>designs there can be implemented using only immutable objects.
Chris Bitmead uid(x22068) <·············@Alcatel.com.au> wrote:
> :That is because most books are orientated towards the most popular
> :languages, of which functional don't rate too highly.
Matt Kennel (Remove 'nospam' to reply) wrote:
> No, I believe is something more fundamental.  To be blunt, computers
> are not 'stateful' vs. 'stateless' agnostics:  they are intrinsically
> and overwhelmingly stateful.

I fail to see what your comment has to do with the issue. The word
"functional" in the phrase "functional programming" does not imply
"stateless computation", rather it implies computation in which all
state is EXPLICIT (eg. passed as parameters). Once you get your head
around that you will see that OO and "stateful mutability" are not tied
to one another.

Matt Kennel (Remove 'nospam' to reply) wrote:
> The interesting implementation of destructive mutability can be key to creative
> and efficient programming, and is a central concern of human endeavour.

The key word in this sentence is "implementation"! Why does mutability
at the language implementation level need to imply mutability at the
language semantics/constructs level?

Matt Kennel (Remove 'nospam' to reply) wrote:
> After all a 'functional language' is eventually stateful, but must rely
> on the sophistication of some highly generalized internal algorithms
> to express this statefullness in final code.  Or more frequently, the
> human programmer must know some common functional idioms which happen to
> result in the efficient mutable effect desired.

The flip side to this of course is that to compile an imperative
language to run efficiently on a PARALLEL processor requires highly
complex internal algorithms to detect invariances in the input
imperative code that can then be used to parallelise code. Indeed even
on a sequential processor invariance detection is necessary to make
optimisations like loop invariances, common sub-expression analysis,
aliasing removal etc. So I don't really see what your point is ...

graham

-- 
                 well alas we've seen it all before
                   knights in armour, days of yore
             the same old fears and the same old crimes 
               we haven't changed since ancient times
From: Fergus Henderson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5li5tu$j8k@mulga.cs.mu.OZ.AU>
Graham Matthews <···············@maths.anu.edu.au> writes:

>Matt Kennel (Remove 'nospam' to reply) wrote:
>> If you believe what Abelson and Sussman say, "object" goes along with
>> stateful mutability.  Chapter 3, structure + interpretation of
>> computer programs
>
>Sorry but I don't believe them. I write OO code every day in a
>functional language -- whats the problem. OO can be separated from
>stateful mutability -- they are not one in the same.

I suspect that you are using some strange definition of the term "OO"
that does not fit with common usage.  If so, this is not helpful.
"OO" is not just a buzzword synonym for "good", even if the term
does get misused a lot.

What language do you use and in what sense is your code OO?

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Patrick Logan
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5lndp1$sqh$1@nadine.teleport.com>
In comp.lang.functional Fergus Henderson <···@mundook.cs.mu.OZ.AU> wrote:
: Graham Matthews <···············@maths.anu.edu.au> writes:

: >OO can be separated from
: >stateful mutability -- they are not one in the same.

: I suspect that you are using some strange definition of the term "OO"
: that does not fit with common usage.  If so, this is not helpful.
: "OO" is not just a buzzword synonym for "good", even if the term
: does get misused a lot.

: What language do you use and in what sense is your code OO?

I have programmed in an OO style in Haskell, beyond Haskell's "type
classes". My definition of OO in this case is some mechanism that
supports "dynamic binding", as implemented typically using vtables
in C++ and message lookup in Smalltalk.

In Haskell (which I am just learning) I have found it useful to
define a record of functions. Then different "objects" have the
same type, but different functions as the values of the record.
Lists of these "objects" exhibit different, dynamically bound,
behaviors. This is the essence of OO.

-- 
Patrick Logan ·············@teleport.com
From: Fergus Henderson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5loknf$7hh@mulga.cs.mu.OZ.AU>
Patrick Logan <······@teleport.com> writes:

>Fergus Henderson <···@mundook.cs.mu.OZ.AU> wrote:
>>Graham Matthews <···············@maths.anu.edu.au> writes:
>
>>>OO can be separated from
>>>stateful mutability -- they are not one in the same.
...
>>What language do you use and in what sense is your code OO?
>
>I have programmed in an OO style in Haskell, beyond Haskell's "type
>classes". My definition of OO in this case is some mechanism that
>supports "dynamic binding", as implemented typically using vtables
>in C++ and message lookup in Smalltalk.
>
>In Haskell (which I am just learning) I have found it useful to
>define a record of functions. Then different "objects" have the
>same type, but different functions as the values of the record.
>Lists of these "objects" exhibit different, dynamically bound,
>behaviors. This is the essence of OO.

An "object" -- as I understand the term, and as defined in various
textbooks -- has identity, state and behaviour.
A record of functions has only behaviour.

Haskell can certainly give you dynamic binding,
and it is not too hard to simulate state and object identity.
However, it is difficult to combine dynamic binding and state,
unless your Haskell implementation supports existential types
(which are not a standard part of the language).

All this is not to say that Haskell is bad -- on the contrary,
I think Haskell is in many respects very good.  But without
existential types, it's pretty tricky to write what I would
call OO style code.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <BITMEADC.97May20103103@Alcatel.com.au>
In article <··········@mulga.cs.mu.OZ.AU> ···@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

>>In Haskell (which I am just learning) I have found it useful to
>>define a record of functions. Then different "objects" have the
>>same type, but different functions as the values of the record.
>>Lists of these "objects" exhibit different, dynamically bound,
>>behaviors. This is the essence of OO.
>
>An "object" -- as I understand the term, and as defined in various
>textbooks -- has identity, state and behaviour.
>A record of functions has only behaviour.

Are you confusing "state" with "mutable state"??

>Haskell can certainly give you dynamic binding,
>and it is not too hard to simulate state and object identity.
>However, it is difficult to combine dynamic binding and state,
>unless your Haskell implementation supports existential types
>(which are not a standard part of the language).
>
>All this is not to say that Haskell is bad -- on the contrary,
>I think Haskell is in many respects very good.  But without
>existential types, it's pretty tricky to write what I would
>call OO style code.
From: Patrick Logan
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5ls5l6$6u3$1@nadine.teleport.com>
In comp.lang.functional Fergus Henderson <···@mundook.cs.mu.OZ.AU> wrote:

: An "object" -- as I understand the term, and as defined in various
: textbooks -- has identity, state and behaviour.
: A record of functions has only behaviour.

: ...it is difficult to combine dynamic binding and state...

: All this is not to say that Haskell is bad [but]
: it's pretty tricky to write what I would call OO style code.

Again, I don't want to speak to authoritatively for Haskell, I am
just learning it. But this is what I am learning so far, after
programming in Lisp, Smalltalk, C++, and other languages for 18
years...

State can be combined with dynamic binding in Haskell by capturing
the state of an "object" via closures. The difference between an
object in a purely functional language and the other languages listed
above is that the objects in Haskell do not *change* state through
assignment.

I'll have to look into what existential types are to see what more they
provide. Any specific references?

-- 
Patrick Logan ·············@teleport.com
From: Fergus Henderson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5lsaja$qf8@mulga.cs.mu.OZ.AU>
Patrick Logan <······@teleport.com> writes:

>I'll have to look into what existential types are to see what more they
>provide. Any specific references?

Try

          Konstantin Laufer <······@math.luc.edu>, "Type Classes with
	  Existential Types", Loyola University of Chicago, 
	  November 1, 1995. <http://www.math.luc.edu/~laufer/ftp/papers/
	  abstracts/haskell+extypes.txt>

A quick web search for "existential types" also pulled up the following
(which I have not read):

          Michel Mauny, Fran�ois Pottier, "An implementation of Caml-Light
	  with existential types", INRIA Research Report #2183.
          <http://pauillac.inria.fr/~fpottier/publis/publications.html.en>

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Graham Matthews
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <337E7536.6B3D@maths.anu.edu.au>
Fergus Henderson wrote:
> I suspect that you are using some strange definition of the term "OO"
> that does not fit with common usage.  If so, this is not helpful.
> "OO" is not just a buzzword synonym for "good", even if the term
> does get misused a lot.
> 
> What language do you use and in what sense is your code OO?

OCAML

graham
-- 
                 well alas we've seen it all before
                   knights in armour, days of yore
             the same old fears and the same old crimes 
               we haven't changed since ancient times
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <BITMEADC.97May19102402@Alcatel.com.au>
In article <··········@mulga.cs.mu.OZ.AU> ···@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

>>Matt Kennel (Remove 'nospam' to reply) wrote:
>>> If you believe what Abelson and Sussman say, "object" goes along with
>>> stateful mutability.  Chapter 3, structure + interpretation of
>>> computer programs
>>
>>Sorry but I don't believe them. I write OO code every day in a
>>functional language -- whats the problem. OO can be separated from
>>stateful mutability -- they are not one in the same.
>
>I suspect that you are using some strange definition of the term "OO"
>that does not fit with common usage.  If so, this is not helpful.
>"OO" is not just a buzzword synonym for "good", even if the term
>does get misused a lot.
>
>What language do you use and in what sense is your code OO?

OO is synonymous with polymorphism as far as I'm concerned. And
polymorphism is completely orthogonal to mutibility.
From: Mike Haertel
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5o2270.cs6.mike@ducky.net>
In article <······················@Alcatel.com.au>, Chris Bitmead uid(x22068) wrote:
>Since when is mutable state information an essential characteristic of
>OO?  Mutibility and object-orientation are completely orthoganal
>issues.

As usual in computer science, we argue about names...

My definition of "object oriented programming" is roughly
"programming with entities of private mutable data packaged
with associated code".  By a weak analogy to conservation
of matter for physical objects, I'd argue that the rate
of nontrivial object (i.e. things more complicated than
integers, cartesian coordinates, and similar mathematical
primitives) creation and destruction ought to be relatively
low in an object oriented program.  Objects ought to be
things that tend to persist.

Now, you can combine immutable data with dynamic dispatch
and you'll get *something* (I'd call it functional
programming with generic functions) but if you can never
change object data the only way to compute is to constantly
be creating new objects.  At this point you've tossed
the conservation-of-mass principle out the window and
completely lost any resemblance to physical objects.
From: Graham Matthews
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3381345A.F68@maths.anu.edu.au>
Chris Bitmead uid(x22068) wrote:
>Since when is mutable state information an essential characteristic of
>OO?  Mutibility and object-orientation are completely orthoganal
>issues.
Mike Haertel wrote:
> As usual in computer science, we argue about names...

Unfortunately names are important since things live and die by what name
you can give them. For example these days if you can't call your
language OO you have no chance of selling it.

Mike Haertel wrote:
> My definition of "object oriented programming" is roughly
> "programming with entities of private mutable data packaged
> with associated code".

This is the standard definition of OO -- unfortunately its not a
definition of OO per se, but rather a characterisation of what
constitutes an imperative REALISATION of OO. There are of course other
ways to realise OO features.

Mike Haertel wrote:
> By a weak analogy to conservation
> of matter for physical objects,

Why would one want to make analogies with the physical world (analogies
with mathematics are more apt I would have thought).

Mike Haertel wrote:
> Now, you can combine immutable data with dynamic dispatch
> and you'll get *something* (I'd call it functional
> programming with generic functions) 

How about "functional OO" rather than programming with generic
functions.

Mike Haertel wrote:
> but if you can never
> change object data the only way to compute is to constantly
> be creating new objects. At this point you've tossed
> the conservation-of-mass principle out the window and
> completely lost any resemblance to physical objects.

So?

graham
-- 
                          So I turned around
                    And 40,000 headmen bit the dirt
                      Firing twenty shotguns each
                        And man it really hurt
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <BITMEADC.97May21100941@Alcatel.com.au>
In article <···················@ducky.net> ····@ducky.net (Mike Haertel) writes:

>>Since when is mutable state information an essential characteristic of
>>OO?  Mutibility and object-orientation are completely orthoganal
>>issues.
>
>As usual in computer science, we argue about names...
>
>My definition of "object oriented programming" is roughly
>"programming with entities of private mutable data packaged
>with associated code".  

Well that definition would be wrong. Prove it to yourself. Are you
saying that if I write vast hierarchies of objects with inheritance
and so on, but don't happen to need to mutate anything, that it is not
OO?

>Now, you can combine immutable data with dynamic dispatch
>and you'll get *something* (I'd call it functional
>programming with generic functions) but if you can never
>change object data the only way to compute is to constantly
>be creating new objects.  At this point you've tossed
>the conservation-of-mass principle out the window and
>completely lost any resemblance to physical objects.

What a lot of rot. Basicly there are two ways of modelling time with a
computer. Implicitely - by mutating things, and Explicitely, by
creating a new thing to model the new state of affairs.

Who was that philosopher who set out to prove that he was the same
person now as he was 10 years ago, and failed to do so?
From: Mike Haertel
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5o5fmd.ejk.mike@ducky.net>
In article <······················@Alcatel.com.au>, Chris Bitmead uid(x22068) wrote:
>>My definition of "object oriented programming" is roughly
>>"programming with entities of private mutable data packaged
>>with associated code".  
>
>Well that definition would be wrong. Prove it to yourself. Are you
>saying that if I write vast hierarchies of objects with inheritance
>and so on, but don't happen to need to mutate anything, that it is not
>OO?

Yes, that is precisely what I am saying.  Inheritance and vast hierarchies
of objects do not imply OO.

The most important aspects of OO programming are late binding of methods
and encapsulation of local state.

Inheritance is a fairly cool idea, but it's over hyped, and it
has very little to do with what's good about OO.
From: Graham Matthews
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3383E773.1585@maths.anu.edu.au>
Chris Bitmead uid(x22068) wrote:
> >Well that definition would be wrong. Prove it to yourself. Are you
> >saying that if I write vast hierarchies of objects with inheritance
> >and so on, but don't happen to need to mutate anything, that it is not
> >OO?
Mike Haertel wrote:
> Yes, that is precisely what I am saying.  Inheritance and vast hierarchies
> of objects do not imply OO.
> 
> The most important aspects of OO programming are late binding of methods
> and encapsulation of local state.

I am glad you said this. Any functional language with existential types
supports late binding of methods and state encapsulation (this is why
existential types were invented). I presume that you want more than
state encapsulation however, namely that you want MUTABLE state that is
encapsulated? If not then you have just agreed that OO can be done in a
functional language.

graham
-- 
             So we starve all the teachers
                And recruit more marines
      How come we don't even know what that means
                     Its obvious
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <BITMEADC.97May22143136@Alcatel.com.au>
In article <···················@ducky.net> ····@ducky.net (Mike Haertel) writes:

>In article <······················@Alcatel.com.au>, Chris Bitmead uid(x22068) wrote:
>>>My definition of "object oriented programming" is roughly
>>>"programming with entities of private mutable data packaged
>>>with associated code".  
>>
>>Well that definition would be wrong. Prove it to yourself. Are you
>>saying that if I write vast hierarchies of objects with inheritance
>>and so on, but don't happen to need to mutate anything, that it is not
>>OO?
>
>Yes, that is precisely what I am saying.  Inheritance and vast hierarchies
>of objects do not imply OO.
>
>The most important aspects of OO programming are late binding of methods
>and encapsulation of local state.

And a functional, non-mutating program can use late binding and
encapsulation of local state. So what are you talking about?

>Inheritance is a fairly cool idea, but it's over hyped, and it
>has very little to do with what's good about OO.

True, but neither does mutation have anything to do with it either.
From: Fergus Henderson
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5lv08p$no4@mulga.cs.mu.OZ.AU>
·············@Alcatel.com.au (Chris Bitmead uid(x22068)) writes:

>····@ducky.net (Mike Haertel) writes:
>
>>My definition of "object oriented programming" is roughly
>>"programming with entities of private mutable data packaged
>>with associated code".  
>
>Well that definition would be wrong. Prove it to yourself. Are you
>saying that if I write vast hierarchies of objects with inheritance
>and so on, but don't happen to need to mutate anything, that it is not
>OO?

If you're not mutating anything, then you have vast hierarchies of
values, not objects.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Richard A. O'Keefe
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5m0i95$o1p$1@goanna.cs.rmit.edu.au>
···@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
>If you're not mutating anything, then you have vast hierarchies of
>values, not objects.

As far as I can see, all of the alleged benefits of object orientation
are supposed to flow from >encapsulation< and >polymorphism<.  I myself
have used the slogan "object = identity + state in capsule" for years,
but mutation is not one of the benefits *added* by OOP.  (Note:  I have
a couple of 'OO Prolog' packages on my Mac; by the mutation criterion,
none of them is really OOP, but they _do_ provide the benefits of
encapsulation and polymorphism.)

As for the people who say inheritance isn't part of OOP, recall
Booch's distinction between "O-Oriented languages" which have it
and "O-Based languages" (like Ada 83) which lack it.  (Ada 83 had
identity, state, and encapsulation, but not inheritance.  That was
added in Ada 95.)

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Mike Haertel
Subject: thoughts on inheritance (was: Re: C++ briar patch (Was: ...))
Date: 
Message-ID: <slrn5o95bm.gov.mike@ducky.net>
In article <············@goanna.cs.rmit.edu.au>, Richard A. O'Keefe wrote:
>As for the people who say inheritance isn't part of OOP, recall
>Booch's distinction between "O-Oriented languages" which have it
>and "O-Based languages" (like Ada 83) which lack it.  (Ada 83 had
>identity, state, and encapsulation, but not inheritance.  That was
>added in Ada 95.)

It hit me just now that "inheritance" is a nebulous term.  It can mean
at least the following three things:

	(1) interface inheritance -- a way of expressing "is-a"
	    relationships about types, e.g. "type Foo can be used
	    anywhere type Bar is expected, since Foo inherits
	    from Bar"

	(2) implementation inheritance -- new types inherit their
	    methods from old types.  this is roughly a superset of (1).

	(3) embedding -- "every object of type Foo literally contains
	    an object of type Bar".  this is roughly a superset of (2).

C++ inheritance, for example, is of flavor (3).  CLOS inheritance
is closer to (2) -- life gets interesting if you inherit from unrelated
classes that happen to share the same slot name.  Java multiple
inheritance is of flavor (1).

So when we're talking about inheritance, which do we mean?  And which
do we deem most essential for "Object Oriented" programming?

In particular, if we're only concerned with "is-a" relationships
about types, I can imagine a lot more general ways to express "is-a"
than inheritance.  Consider the C++ template:

	template<class T> T& min(T& x, T& y) {
		if (x <= y)
			return x;
		else
			return y;
	}

This template implicitly requires that T is-a type which supports
a <= operation.  This is a more general definition than the inheritance
style which you might express (in C++) as as an abstract class:

	class OrderedEntity {
		...
		virtual int operator <= (OrderedEntity &y) = 0;
		...
	};
	OrderedEntity& min(OrderedEntity& x, OrderedEntity& y) {
		if (x <= y)
			return x;
		else
			return y;
	}

This version only works for things which inherit from OrderedEntity.

So, if all you're concerned with is expressing "is-a" relationships
about types, inheritance would seem to be a very weak mechanism indeed.
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <BITMEADC.97May22143519@Alcatel.com.au>
In article <··········@mulga.cs.mu.OZ.AU> ···@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

>·············@Alcatel.com.au (Chris Bitmead uid(x22068)) writes:
>
>>····@ducky.net (Mike Haertel) writes:
>>
>>>My definition of "object oriented programming" is roughly
>>>"programming with entities of private mutable data packaged
>>>with associated code".  
>>
>>Well that definition would be wrong. Prove it to yourself. Are you
>>saying that if I write vast hierarchies of objects with inheritance
>>and so on, but don't happen to need to mutate anything, that it is not
>>OO?
>
>If you're not mutating anything, then you have vast hierarchies of
>values, not objects.

So something doesn't become an object until you've mutated it? Get
real.

I suppose you're going to define an object as anything that can be
mutated? It's hard to win against such clever and insightful logic.
From: Anthony Shipman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5lbhim$fk9@ephor.tusc.com.au>
In <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

........

>For example, a good chunk of commercial programming practice today
>is related in some way to object-oriented design.  A key notion in
>object-oriented design is the use of objects to represent concepts
>in the program being designed.  An important characteristic of objects
>is their ability to store mutable state information.

>The higher-order functional languages generally do not support mutable
>state, because doing so would compromise referential transparency.  In
>particular, higher-order functions seem to be the most useful when
>combined with lazy evaluation, which in turn does not seem to combine
>well with the idea of mutable state.  So these well known and widely
>used design techniques simply do not apply in such languages.


The concurrent paradigm complements the functional paradigm.  People
claim that OO is great for real-world modelling because of its state but
it is just poor-man's concurrency.


>That means, in turn, that if you wish to program in functional style,
>you really have to change almost everything about how you think
>about programming.  It's not just a matter of using higher-order
>functions or not using them.

The same claim was made about the transition to OO from structured
programming (and just as truly) and the transition was certainly an
improvement, despite the effort of relearning.

-- 
Anthony Shipman                 "You've got to be taught before it's too late,
TUSC Computer Systems Pty Ltd    Before you are six or seven or eight,
                                 To hate all the people your relatives hate,
E-mail:  ···@tusc.com.au         You've got to be carefully taught."  R&H
From: Richard A. O'Keefe
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kph1v$74l$1@goanna.cs.rmit.edu.au>
···@research.att.com (Andrew Koenig) writes:
>Desparate?  Hardly.  It's an expression of the pragmatic observation
>that an awful lot of programs -- and programmers -- don't make a great
>deal of use of higher-order functions.  If they're important to you,
>then by all means choose a language that supports them the way you like.
>But don't assume that your taste is universal.

Very few tastes are universal.
A taste for programs that can visibly be seen to be correct is certainly
not one of them.  A great deal of programmers are very bad at what they
do.  We *cannot* measure the usefulness of a technique by counting noses.
(We *can* measure the profitability of a product that way, but that's a
quite different thing.)  We should measure the effectiveness of a tool
like higher order functions by lines _not_ written, lives _not_ lost.

And is Andrew Koenig actually right in his claim?  There seem to be a lot
of people who say they are using C++, and C++ templates surely have to
count as meta-functions.  (The C++ template language is computation-
universal; when you instantiate an innocent-looking library template,
an _amazing_ amount of compile-time computation may go on behind the
scenes, and I'm not talking about the innards of the compiler either,
I'm talking about computations _in_ the template language.)  If the
structuring of the library in the draft C++ standard doesn't prove the
usefulness of (compile-time) higher-order functions, what _does_ it prove?

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Matt Kennel (Remove 'nospam' to reply)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5mvvcc.t07.kennel@lyapunov.ucsd.edu>
On Mon, 05 May 1997 10:12:59 -0700, Thant Tessman <·····@nospam.acm.org> wrote:
:
:Alexander Stepanov wrote:
:
:> [...] the amazing fact is that I could not even do a slow
:> generic linear search in Scheme.

:Yeah, integers make crummy iterators.  So what?  

Why do people want an 'iterator', a noun, instead of 'iteration', a verb? 
-- 
Matthew B. Kennel/Institute for Nonlinear Science, UCSD/
Don't blame me, I voted for Emperor Mollari. 
From: M. Prasad
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <33707567.4972@nospam.polaroid.com>
Matt Kennel (Remove 'nospam' to reply) wrote:
> 
> On Mon, 05 May 1997 10:12:59 -0700, Thant Tessman <·····@nospam.acm.org> wrote:
> :
> :Alexander Stepanov wrote:
> :
> :> [...] the amazing fact is that I could not even do a slow
> :> generic linear search in Scheme.
> 
> :Yeah, integers make crummy iterators.  So what?
> 
> Why do people want an 'iterator', a noun, instead of 'iteration', a verb?

I believe the term "iterator" was introduced by some
experimental languages around early 80s or late 70s.

An "iterator" is a thing you can use to iterate.  For instance,
one iterator might allow you to iterate over numbers from
1 to 100 (the most common variety of iterator -- in many
programming languages, known as a "FOR" statement.)  Another
iterator might allow you to iterate over elements of
a list.  A third might allow you to iterate over all
the triangular decompositions of a polygon.

These experimental programming languages also allowed
users to write their own iterators.  "C"s for statement
uses a syntax so you can embed a "list iterator" right
in the for statement (though it is a bit cumbersome to
extend the concept to more complex iterations.)

The idea came from attempts to "abstract" the elements
of programming -- procedures and data.  (Of course,
OOP has become the popular modern way of abstracting
these.)
From: Michael Greenwald
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <michaelg.863019671@CS.Stanford.EDU>
"M. Prasad" <·······@nospam.polaroid.com> writes:

>Matt Kennel (Remove 'nospam' to reply) wrote:

>> Why do people want an 'iterator', a noun, instead of 'iteration', a verb?

Because there are languages where iterators *are* (first class)
objects that you can pass around and store.  You can apply an iterator
to a body (a.k.a a function or closure) providing a useful way of
abstracting control structure. A noun makes much more sense than a
verb in this case.  You can think of an iterator as a (possibly)
optimized form of co-routine.

>I believe the term "iterator" was introduced by some
>experimental languages around early 80s or late 70s.

CLU certainly used "iterator" in the 70s.  I don't know if it was the
first language to use it as a keyword.

>An "iterator" is a thing you can use to iterate.  For instance,
>one iterator might allow you to iterate over numbers from
>1 to 100 (the most common variety of iterator -- in many
>programming languages, known as a "FOR" statement.)  ...
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <EA3p3C.2Ms@research.att.com>
In article <·····················@lyapunov.ucsd.edu> ······@nospam.lyapunov.ucsd.edu writes:

> Why do people want an 'iterator', a noun, instead of 'iteration', a verb? 

`iteration' is a noun, too.

Anyway, an iterator is an object that iterates--that is, an object
that controls iteration.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Henry Baker
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <hbaker-1305970852060001@10.0.2.1>
In article <··········@research.att.com>, ···@research.att.com (Andrew
Koenig) wrote:

> `iteration' is a noun, too.
> 
> Anyway, an iterator is an object that iterates--that is, an object
> that controls iteration.
> -- 
>                                 --Andrew Koenig
>                                   ···@research.att.com
>                                   http://www.research.att.com/info/ark

Now that after 20 years we finally have that straight, can we move on
to 'recurseration', 'recurserators', etc.
From: Matt Kennel (Remove 'nospam' to reply)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5nl1s2.cvo.kennel@lyapunov.ucsd.edu>
On Tue, 13 May 1997 16:52:06 GMT, Henry Baker <······@netcom.com> wrote:
:In article <··········@research.att.com>, ···@research.att.com (Andrew
:Koenig) wrote:
:
:> `iteration' is a noun, too.
:> 
:> Anyway, an iterator is an object that iterates--that is, an object
:> that controls iteration.
:> -- 
:>                                 --Andrew Koenig
:>                                   ···@research.att.com
:>                                   http://www.research.att.com/info/ark

:Now that after 20 years we finally have that straight, can we move on
:to 'recurseration', 'recurserators', etc.

:)

My question 'why do we want an 'iterator' rather than iterating' was
meant to really pose the question:  

     Aren't there better ways of abstracting the generalized notion of
     iteration than the way these galumphingly unnatural "iterators" do?

{I know the answer must be 'yes'}  Analogy: it feels as if we have to
construct some normalized form of a finite state automation, set its
transition matrix, and let it rip, when all we really wanted to write
was various combinations of "if then else".

If we continue to nounify the question--as in construct a new 'thing' which
explicitly exists at run-time, we may lose sight of being able to do
something truly marvellous. 

-- 
Matthew B. Kennel/Institute for Nonlinear Science, UCSD/
Don't blame me, I voted for Emperor Mollari. 
From: Richard A. O'Keefe
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kmkcs$4ce$1@goanna.cs.rmit.edu.au>
Alexander Stepanov <········@mti.sgi.com> writes:

>While what you are saying is true, the amazing fact is that I could not even
>do a slow generic linear search in Scheme.

A generic linear search has the following form:

 - there is an abstract data type that represents
   (a position in) a sequence.
 - there is an operation ended? which tests whether
   such a position has reached its end.
 - there is an operation current which returns the element at a
   position which is not ended
 - there is an operation next which returns the next position
   after a position which is not ended


(define generic-linear-search
  (lambda (Ended? Current Next)
    (lambda (Position Test? Success-Continuation Failure-Continuation)
      (let loop ((P Position))
        (if (Ended? P)
	    (Failure-Continuation)
	    (let ((C (Current P)))
	      (if (Test? (Current P))
		  (Success-Continuation C)
		  (loop (Next P)) )) )) )) )

(define list-linear-search
  (generic-linear-search null? car cdr))

(define (vector-linear-search Vector)
  (let ((N (vector-length Vector)))
    (generic-linear-search
      (lambda (I) (>= I N))
      (lambda (I) (vector-ref V I))
      (lambda (I) (+ I 1)) )))

Now the operations used here are essentially the SAME (strictly, a subset)
of the operations the STL relies on.  If you have a Scheme system where
generic-linear-search can be declared integrable, what you get is precisely
what you need, and quite as efficient as directly hand-written code.

>Time after time, I tried
>to generalize over vectors and lists, and failed.

But
(1) As the STL itself so forcibly reminds us, lists and vectors are not
    the only kinds of sequences.  generic-linear-search as written above
    will work just fine for a sequence defined by reading lines from a
    file (although you really need a rewind operation; Scheme doesn't
    make transput as easy as one might wish).

(2) As the STL itself so forcibly reminds us, with those extremely
    useful cost tables in the draft C++ standard, the cost of an operation
    depends on the costs of the primitive operations provided by the
    underlying data structures.  The whole *reason* for having different
    list and vector data structures is to support different cost models
    for the sequence operations, to support different tradeoffs.

I've done a great deal of "sequence" stuff in Pascal (augmented by
Ada-style packages implemented using M4, gah!) and it just didn't seem
that hard.  The main thing that got in my way was the fact that Pascal
*DIDN'T* manage memory for me, so every single type had to have "make"
and "free" operations.

>Well, a world recognized ML authority spent some time working with me
>on - guess what - expressing linear search. I still have a long message from
>him explaining why it could not be done.

This would be an *EXTREMELY* useful thing to know.  I beg you to get that
person to publish the message or permit the publication of that message by
you.  Perhaps the two of you could jointly publish the result?  PLEASE do
it soon!

It would of course be even better if you and he could explain whether/why
not it can be done in Haskell, which has a form of inheritance/overloading
that may (or may not, I don't know what your problem was) be useful.

If you could do this, maybe we could get some real technical content into
this discussion.

One interesting thing about C++ templates is that the template language
is in itself a complete programming language.  I have seen some amazing
computations expressed that way.  (It's almost like a first order functional
language, in some ways.)  This fact alone makes the C++ template mechanism
more powerful than the Ada generic mechanism, which is not computation-
universal, or Scheme function inlining (ditto), or ML structures and
functors (again, ditto).  Myself, speaking as a programmer, I feel a lot
safer using a language where I know that compilation can always be done in
a finite time, but I have to admit the power of the C++ approach.  If the
reason for the STL needing C++ is due to that fact alone, I don't find it
terribly interesting, but if there is some much more fundamental problem,
I would VERY much like to understand it.

>I should add that I had been a proponent of functional programming for 
>more than a decade - one of my first papers was presented at the First
>Functional Programming Conference. I have acknowledged the power of higher
>order functions. My problem was that I was not interested in doing tail
>recursive factorials or memoizing Fibonacci numbers - I wanted to implement
>algorithms that people could use when they build their systems. And that
>forced me to use C++.

The trouble is, it's all very well saying "C++ can do this, C++ can do that",
but the STL has been out for a while, and there are still very few C++
compilers that can actually *compile* the model STL implementation.  As
soon as I heard about the STL, I grabbed the documentation and the model
implementation, and then had to face the fact that I *COULDN'T* use it.
In fact, on the machine where I do most of my work, which does have a
couple of C++ compilers, I *STILL* can't use the STL.

>And, believe me, my life would have been much easier if I stayed with 
>one of the officially approved religions. 

C++ *is* an officially approved religion.  It has *far* more clout than
any functional language.  Because of that fact alone, providing a C++
version of the STL was an exceptionally good thing to do.  I just wish
I could use it.

>I wish I could love Java...

Could Java-as-we-know it support the STL?  Does it have the same
mysterious problem that Scheme and ML are said to have?

-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Anthony Shipman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kmoc9$4e5@ephor.tusc.com.au>
In <·············@mti.sgi.com> Alexander Stepanov <········@mti.sgi.com> writes:

>Well, a world recognized ML authority spent some time working with me
>on - guess what - expressing linear search. I still have a long message from
>him explaining why it could not be done. I would gladly switch to ML if
>somebody can show me how I can express what I want to express in it. I have
>no personal stake in C++. I use it as a tool. And both Bjarne and Andy could
>attest to my long standing criticism of some of its main features. 

Can we have a specification of what you want to express please?
-- 
Anthony Shipman                 "You've got to be taught before it's too late,
TUSC Computer Systems Pty Ltd    Before you are six or seven or eight,
                                 To hate all the people your relatives hate,
E-mail:  ···@tusc.com.au         You've got to be carefully taught."  R&H
From: Alexander Stepanov
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336F91EC.7DE1@mti.sgi.com>
Anthony Shipman wrote:
> 
> Can we have a specification of what you want to express please?

You can take a look at:

http://www.sgi.com/Technology/STL/

to find what linear search in STL does (it is called find).

If you like a less formal set of requiremts it is:

1. Semantics:

	1. I would like to mutate what I find if the data structure
	is mutable;
	
	2. I would like to restart the search from the position I found.

	3. I would like multiple search paths through a data structure:
		reverse order, stride, etc;

	4. I would like it to work for subranges of a data structure;

	5. I would like to compare two positions for equality.

2. Complexity:

	1. I would like the generic code to be as fast as hand
	optimized code in the same language. (As a matter of fact,
	I would even like it to be as fast as hand optimized code
	written in assembly);

	2. I would like to be able to choose an algorithm that is
	optimized for a certain subtheory: e.g. I can find a maximum 			trip
count fast, I would like to do hand unrolling.





> --
> Anthony Shipman                 "You've got to be taught before it's too late,
> TUSC Computer Systems Pty Ltd    Before you are six or seven or eight,
>                                  To hate all the people your relatives hate,
> E-mail:  ···@tusc.com.au         You've got to be carefully taught."  R&H

-- 
Alexander Stepanov
········@mti.sgi.com

Silicon Graphics
2011 N. Shorline Boulevard
Mountain View, CA 94043-1389

tel.: (415)933-6121
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <s6yiv0ymz45.fsf@aalh02.alcatel.com.au>
···@research.att.com (Andrew Koenig) writes:

> Perhaps Alex will confirm the following:  He said that C++ was the only
> language in which he could implement linear search so that it would work
> on any reasonable data structure, but I suspect he may have omitted to
> add ``without substantial run-time overhead compared to a straightforward
> hand-coded solution.''

I still think this is wrong. A CLOS coded generic search algorithm
should be just as fast as a hand-coded Lisp search.

Of course C++ tends to be a little faster than Lisp anyway, but this
isn't an "ultimate performance" thread.
From: Greg Morrisett
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <01bc5988$ac3e2730$e5d35480@hickory>
Alexander Stepanov <········@mti.sgi.com> wrote in article
<·············@mti.sgi.com>...
>
> Well, a world recognized ML authority spent some time working with me
> on - guess what - expressing linear search. I still have a long message
from
> him explaining why it could not be done. I would gladly switch to ML if
> somebody can show me how I can express what I want to express in it. I
have
> no personal stake in C++. I use it as a tool. And both Bjarne and Andy
could
> attest to my long standing criticism of some of its main features. 

Erm, how's this?

exception NotFound

fun search {predicate : 'elt -> bool,
	       next : 'collection -> ('elt,'collection) option} =
let fun loop c = case next c of
		NONE => raise NotFound
                             | SOME(elt,rest) => if pred elt then elt else
loop rest
in
      loop
end

For the ML-impaired:  search is a polymorphic function that abstracts
the collection type and element type, takes two arguments, each
higher-order
functions, the first of which determines if the element is the one you're
looking for, the second just returns the first component of a collection
together with the "rest" of the collection.  The search function returns
a loop (as a higher-order function) which when given a collection,
walks through the collection and returns the first element matching
the predicate (if any), and raises the NotFound exception otherwise.

Let's see, to find the first element of a list of (int*string) pairs where
the
integer component is 5:

search {predicate = fn (x,_) => x = 5, next = fn [] => NONE | hd::tl =>
SOME(hd,tl)} 

To search an array A of bools for the last true element:

search {predicate = fn b => b, next = fn (A,i) => if i >= 0 then
SOME(Array.sub(A,i),i-1) else NONE} (A,Array.size(A)-1)

Other things you're looking for that this can't do?  I'm truly curious...

-Greg
From: Ramesh Bharadwaj
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5knrn0$724$1@ra.nrl.navy.mil>
Greg Morrisett <···@cs.cornell.edu> writes....

<ML code deleted>
> For the ML-impaired:  search is a polymorphic function that abstracts
> the collection type and element type, takes two arguments, each
> higher-order
> functions, the first of which determines if the element is the one you're
> looking for, the second just returns the first component of a collection
> together with the "rest" of the collection.  The search function returns
> a loop (as a higher-order function) which when given a collection,
> walks through the collection and returns the first element matching
> the predicate (if any), and raises the NotFound exception otherwise.

Phew!  Now *I'm* convinced that I've not been missing much by not using ML.
Do you seriously expect professional programmers to flock to ML just because
it is possible to code linear search in ML, moreover in such an elegant way :-)

--ramesh
From: Matthew Fuchs
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <336F8717.2781@wdi.disney.com>
Thant Tessman wrote:
> 
...
> 
> Alexander Stepanov's dissillusionment with OO reminds me of something
> I've been thinking about for a while.  Object-oriented methodology
> is a collection of techniques for managing program complexity.  A
> very large "a-ha" for me was that higher-order functions could be
> used to build OO systems.  Therefore, higher-order functions are
> a more fundamental/powerful concept than OO.
> 

Not just objects, but clients and servers are also trivially implemented
through higher-order functions, or closures.  This works really nice for
distributed systems with mobile objects (you can either look at my work
or at Luca Cardelli's Obliq).  Closures and objects are both implemented
the same way - an environment pointer and a function pointer (the latter
being somewhat optimized away by some compilers).

Closures are much more flexible than objects and classes (esp. in the
C++ sense) because there is much more flexibility on binding times.  
And closures are first class, which classes traditionally are not.

The "hard" part of implementing objects, from the point of view of
higher order functions, are instance variables, but they can be handled
with macros.

> 
> The strange thing is that I've never seen a defender of C++
> acknowledge the power of higher-order functions.  Higher-order
> functions are simply functions that build other functions.  But
> I can't help but get the impression that the defenders of C++ just
> don't get it.  This would explain why they feel it is necessary to
> build all this other complex machinery.
> 

But C++ is great -- for implementing Scheme ;-)

Matthew Fuchs
····@wdi.disney.com
http://cs.nyu.edu/phd_students/fuchs
From: Sean Doran
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <yt7mh6mo2a.fsf@solar.clock.org>
Matthew Fuchs <····@wdi.disney.com> writes:

> Not just objects, but clients and servers are also trivially implemented
> through higher-order functions, or closures.  This works really nice for
> distributed systems with mobile objects (you can either look at my work
> or at Luca Cardelli's Obliq).

Or Cejtin, Jagannathan and Kelsey's excellent paper
describing Kali Scheme and higher-order distributed objects
which can be found at http://www.neci.nj.nec.com/PLS/kali.html

	Sean.
From: David Halls
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5lfr2e$kb4@lyra.csx.cam.ac.uk>
In article <·············@wdi.disney.com>,
	Matthew Fuchs <····@wdi.disney.com> writes:
>
>Not just objects, but clients and servers are also trivially implemented
>through higher-order functions, or closures.  This works really nice for
>distributed systems with mobile objects (you can either look at my work
>or at Luca Cardelli's Obliq).

Indeed, one can do some v. nice distributed stuff, as Dreme and Kali show,
with closures/continuations. It's possible too to build a more conventional
(CORBA-like) distributed object system very cleanly once you've got the
ability to reify closures - even publishing them in traders for apps to
pick up. The Java RMI dynamic loading of proxies stuff comes pretty
naturally in such a system.

One can also update proxy behaviour and allow for "code injection"
that breaks O-O interfaces to let RPCs get right into a remote "object"
and allow multiple RPCs on a connection in both directions pretty
easily too. I'm not claiming that it's anything that can't be done
elsewhere, just that it comes out pretty cleanly, even with a typed
Scheme (which hopefully I should be able to expand on soon, if I get
a move on writing up).

The issue with this mobile code/closure/continuation/agent stuff right
now is to find some real apps. I hope my thesis (provisional title
"Applying Mobile Code to Distributed Systems) can demonstrate 3 or 4.
I'd like to carry on working with distributed Scheme when I start work,
but there has to be some real app, or large scale integration of Scheme
systems into existing (Web) infrastructure (which I can't see happening).

Comments? (perhaps the name of this thread should be changed).
I'll start by saying that client-side Web apps are/are about to change
and perhaps Java's main use (for applets) might disappear with the
Document Object Model?

Dave

-- 
David Halls, ·····@cl.cam.ac.uk
http://www.cl.cam.ac.uk/users/dah28  (bit out of date)
From: Jon S Anthony
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <JSA.97May3203022@alexandria>
In article <·············@mti.sgi.com> Alexander Stepanov <········@mti.sgi.com> writes:

> of types (iterators, for example). But I still do not know any other
> language in which I could express what I wanted to express. I teach
...
> Do I mean to say that C++ is the ultimate programming language? Perish the 
> thought! We do need a better programming language. But I do not believe that
> anything better already exists. And, yes, I tried Scheme, ML, Ada, Java...
> And I tried them quite seriously, spending years on every fad that comes out
> of POPL. 

How do you square this with the fact that STL has been implemented in
Ada95???  As the saying goes, "if it happens, it must be possible".

/Jon

-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
···@organon.com
From: Matt Austern
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <fxtzpubca5f.fsf@isolde.mti.sgi.com>
···@alexandria (Jon S Anthony) writes:

> In article <·············@mti.sgi.com> Alexander Stepanov <········@mti.sgi.com> writes:
> >
> > Do I mean to say that C++ is the ultimate programming language? Perish the 
> > thought! We do need a better programming language. But I do not believe that
> > anything better already exists. And, yes, I tried Scheme, ML, Ada, Java...
> > And I tried them quite seriously, spending years on every fad that comes out
> > of POPL. 
> 
> How do you square this with the fact that STL has been implemented in
> Ada95???  As the saying goes, "if it happens, it must be possible".

Are you referring to the original Musser-Stepanov "Ada Generic
Library", or to a more recent port of the STL to Ada?  

If the former, then I think it's quite clear to anyone who has
compared the two libraries that the STL is a vast improvement over the
AGL.

If the latter---if, that is, someone has recently ported the entire
STL to Ada 95---then I would be quite interested in seeing a detailed
description of the work.  Seeing the same concepts expressed in two
different ways can be very informative.
From: Jon S Anthony
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <JSA.97May5130221@alexandria>
In article <···············@isolde.mti.sgi.com> Matt Austern <·······@isolde.mti.sgi.com> writes:

> > How do you square this with the fact that STL has been implemented in
> > Ada95???  As the saying goes, "if it happens, it must be possible".
> 
> Are you referring to the original Musser-Stepanov "Ada Generic
> Library", or to a more recent port of the STL to Ada?  

The latter.  It has been developed at RPI.  The former used Ada83.


> If the latter---if, that is, someone has recently ported the entire
> STL to Ada 95---then I would be quite interested in seeing a detailed
> description of the work.  Seeing the same concepts expressed in two
> different ways can be very informative.

I will see if I still have the pointers to this stuff (I suppose if
you just went over to their web site and started rooting around [how
else can you find anything on the web?] you will find it.)

/Jon

-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
···@organon.com
From: ozan s. yigit
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <x6vi51eu0y.fsf@ds9.rnd.border.com>
Erik Naggum:

> the odd thing about energy and superiority is that more work is always
> _necessary_ on the inferior product than on the superior. 

taking something like lisp and building hardware, user interfaces, complex
environments etc. around it seems like lot more work than what was typically
expected for an average language; you have either just proven lisp machines
were somehow inferior, or the relationship between energy and superiority
is nowhere near as simple as you would prefer...

oz
From: ········@wat.hookup.net
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kg5d1$apm$1@nic.wat.hookup.net>
In <··············@ds9.rnd.border.com>, ··@ds9.rnd.border.com (ozan s. yigit) writes:
>Erik Naggum:
>
>> the odd thing about energy and superiority is that more work is always
>> _necessary_ on the inferior product than on the superior. 
>
>taking something like lisp and building hardware, user interfaces, complex
>environments etc. around it seems like lot more work than what was typically
>expected for an average language; you have either just proven lisp machines
>were somehow inferior, or the relationship between energy and superiority
>is nowhere near as simple as you would prefer...
>
>oz

From my understanding, the Lisp machines were built on an already existing
environment (that had been used at MIT for quite some time already).

Hartmann Schaffer
From: Barry Margolin
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5kgmo9$109@pasilla.bbnplanet.com>
In article <············@nic.wat.hookup.net>,
 <········@wat.hookup.net.this.should.stop.spam> wrote:
>From my understanding, the Lisp machines were built on an already existing
>environment (that had been used at MIT for quite some time already).

Nope, they were essentially built from scratch from the ground up.  The
people who wrote the LispM OS had previously implemented ITS, a timesharing
OS for PDP-6 and PDP-10 systems, and implemented ITS MacLisp.  So they had
experience in OS and Lisp design and implementation, but the LispM
environment is at all like ITS (in fact, it has more high-level conceptual
similarities with Multics than ITS).
-- 
Barry Margolin
BBN Corporation, Cambridge, MA
······@bbnplanet.com
(BBN customers, call (800) 632-7638 option 1 for support)
From: Andrew Koenig
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <E9K1Fs.Cy8@research.att.com>
In article <················@naggum.no> Erik Naggum <····@naggum.no> writes:

> * Andrew Koenig
> | Which suggests that perhaps your opinion of what is superior is not
> | universal.

> it is rather curious that someone who _must_ know better argues that the
> superiority of something and the energy poured into it are not inversely
> related.  or are you saying that C++ is a superior language for the same
> reason that MS-DOS is a superior operating system, Andrew?

I am saying just what I said before, which is that not everyone has the
same opinion about what is superior to what.  Such divergence of opinion
is usually called `personal taste,' and the more I see of the world,
the more I realize just how divergent people's tastes really are.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Matt Kennel (Remove 'nospam' to reply)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <slrn5mnptj.jct.kennel@lyapunov.ucsd.edu>
On Fri, 2 May 1997 12:59:52 GMT, Andrew Koenig <···@research.att.com> wrote:
:
:In article <················@naggum.no> Erik Naggum <····@naggum.no> writes:
:
:> * Andrew Koenig
:> | Which suggests that perhaps your opinion of what is superior is not
:> | universal.
:
:> it is rather curious that someone who _must_ know better argues that the
:> superiority of something and the energy poured into it are not inversely
:> related.  or are you saying that C++ is a superior language for the same
:> reason that MS-DOS is a superior operating system, Andrew?
:
:I am saying just what I said before, which is that not everyone has the
:same opinion about what is superior to what.  Such divergence of opinion
:is usually called `personal taste,' and the more I see of the world,
:the more I realize just how divergent people's tastes really are.

My opinion is that a properly designed langauge is the best and most effective
tool, and that alternate extra-language tools are often feeble makeups for
that tool's insufficiency. 


-- 
Matthew B. Kennel/Institute for Nonlinear Science, UCSD/
Don't blame me, I voted for Emperor Mollari. 
From: David Chase
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <E9oLLx.7Fo@world.std.com>
Matt Kennel (Remove 'nospam' to reply) wrote:

> My opinion is that a properly designed langauge is the best and most effective
> tool, and that alternate extra-language tools are often feeble makeups for
> that tool's insufficiency.

But not all tools are equal for that test.  Adding checking to
C++ (and retaining binary compatibility) is onerous and slow (I've
done it).  On the other hand, back in the early days before
Modula-3 had official generics, a tool was written to do "poor man's
generics" that worked quite well, and it was not onerous, and it
was not slow.  Right now, working in Java, we needed something like
generics, and one of the people in the company wrote some a perl (ick!)
script to crank out the generics for us.  The Modula-3 generics
were easier, and less disgusting, because Modula-3 is easy to parse,
and because one of the people working on the language felt that such
tools were often useful, and thus wrote a "toolkit" to make it easy.
I believe we also used this same toolkit to write a makefile generator
and the first pickler-generator (pickling is simply serialization
directed to a file) was probably written using this toolkit.

You can always quibble about whether or not these add-ons are officially
part of the language or not; in practice, I used them, they worked.

David Chase
From: Cyber Surfer
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <MPG.dd5451247e260489897b3@news.demon.co.uk>
With a mighty <··········@research.att.com>,
···@research.att.com uttered these wise words...

> Which suggests that perhaps your opinion of what is superior is not universal.

No opinions are universal.

Followups set to comp.lang.misc.
-- 
<URL:http://www.wildcard.demon.co.uk/> You can never browse enough
  Martin Rodgers | Programmer and Information Broker | London, UK
            Please note: my email address is gubbish.
From: Fergus Henderson
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5js6vq$8mm@mulga.cs.mu.OZ.AU>
···@research.att.com (Andrew Koenig) writes:

>Peter Ludemann <········@inxight.com> writes:
>
>> But let's suppose that you really really really do need to identify a
>> particular subtree.  In other words, you want to NAME it.  No problem:
>> just create a dictionary (hash table) that maps names to subtrees.
>> That'll let you have two differently named entries which might happen
>> to have the same values.  And it won't expose pointers.  And it'll be
>> efficient.
>
>Yes and no.  In a language that is completely referentially transparent,
>generating the names can be a problem, because there is no way to define
>a piece of code that represents the abstraction `Each time I build one of
>these nodes, I want it to have a globally unique label.'  The language
>wouldn't be referentially transparent if I could write such a program.
>So the knowledge of the labels now has to pervade the entire system.

Martin Odersky has a nice solution to this problem --
a way to get globally unique labels in a local scope
without violating referential transparency, so that you
can do this sort of thing without the entire system needing to
know about the labels.  See his paper on the lambda-nu calculus,
which is available from his home page (don't have a URL on-hand
right now, sorry).  Unfortunately this has not yet been incorporated
into any existing programming language implementation, as far as
I am aware...

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Bill House
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <01bc5255$dbbe2260$03d3c9d0@wjh_dell_133.dazsi.com>
Fergus Henderson <···@murlibobo.cs.mu.OZ.AU> wrote in article
<··········@mulga.cs.mu.OZ.AU>...
> 
> Martin Odersky has a nice solution to this problem --
> a way to get globally unique labels in a local scope
> without violating referential transparency, so that you
> can do this sort of thing without the entire system needing to
> know about the labels.  See his paper on the lambda-nu calculus,
> which is available from his home page (don't have a URL on-hand
> right now, sorry).  
>

Try http://wwwipd.ira.uka.de/Odersky/Archive

Bill House
-- 
http://www.dazsi.com
Note: my e-mail address has been altered to
confuse the enemy. The views I express are
mine alone (unless you agree with me).
From: Paul Wilson
Subject: Re: Object IDs are bad  (nuh-uh!)
Date: 
Message-ID: <5jpp6d$l2k@roar.cs.utexas.edu>
In article <··················@wistaria.i-have-a-misconfigured-system-so-shoot-me>,
Peter Ludemann  <········@inxight.com> wrote:
>
>Absolutely correct and correctly so.
>
>If two things LOOK the same, then they ARE the same.  It's called
>"referential transparency" and it's a Good Thing, as opposed to
>"pointers" which are a Bad Thing.  Why confuse your life with "object
>identity"?

Confusing pointers with addresses is a Bad Thing.  A pointer is 
language-level thing, and an address is an implementation-level
thing.  The mapping between them is often not simple.

>And why do you want to use the memory address for object identity to
>identify it --- an address can change during garbage collection.

Are there any garbage collectors that DON'T deal with this?  First off,
it's not an issue in non-copying GC, and copying GC's are highly
overrated.

As far as I know, every copying GC already deals with the issue of
updating addresses consistently to ensure that the pointer abstraction
is maintained at the language level.  And this isn't really much of an
added cost---even in pure, lazy FP languages you want to maintain
the reachability graph for efficiency reasons at the implemenation
level.  (E.g., you don't want to turn a general graph of of
unreduced combinators or closures into a tree, because then
memoization of lazily computed values may be defeated.)

>not use a time stamp of object creation?  Oh, it's for efficiency
>reasons, you say ... ah-ha!
>
>But let's suppose that you really really really do need to identify a
>particular subtree.  In other words, you want to NAME it.  No problem:
>just create a dictionary (hash table) that maps names to subtrees.

Wow.  You think it's a good idea to add a *hashing* cost to what's
conceptually a pointer traversal?  And to make more work for either
the programmer or the GC?  (Adding extra indexes to data structures
can cause retention of data that will never be used again.  If you
use plain tables, the programmer has to remember to remove the table
entries when the corresponding objects die---whenever that is;  if
you use weak tables understood by the GC, it adds significant
overhead.)

>That'll let you have two differently named entries which might happen
>to have the same values.  And it won't expose pointers.  And it'll be
>efficient.

Where's the win?  If my language has plain old pointers, it can
efficiently support the abstraction of object identity.  (It gets
harder in distributed systems, but still...)

In many cases, cobbling up your own notion of object identity is extra
hassle for the programmer, and quite inefficient to boot.

>Repeat after me: "if two things look the same and act the same, then
>they are the same".  Don't depend on some hidden property (pointer) to
>differentiate them.  If there are important differences, then don't be
>shy: bring them out in the open and NAME them.

Try repeating this: if identical twins are indistinguishable to me, 
then they must be the same person, and I don't need to distinguish 
between them.  Does that seem right?

The reason for object identity is that the identity of a language-level
object allows you to distinguish between objects known to represent the 
same conceptual object and objects which are not known to represent
the same conceptual object (but are otherwise indistinguishable,
given the attributes you've recorded).  Sometimes you can make
a safe closed-world assumption in which case a pointer comparison
makes exactly the distinction between sameness and difference
of what the program-level objects represent.

This comes up most clearly when you're representing knowledge about
the real world, but it also comes up in the internals of programs.
When conceptual object identity matters, and encodes useful
knowledge, then having object identity in the language can 
often be very useful.

>[I once took an object-oriented database that used object-IDs and
>translated it to a relational form which just used names for things;
>performace improved by about about an order of magnitude.  But that's
>another rant for another day ...]

This anecdote doesn't mean much without a lot more information.  I
know of programs that run a hundred to a thousand times faster in
some OODBs than in most commercial database systems, and I know
*why*.  For some things, a relational (value-oriented) language
works great, because the limitations of the model make life
easy for query optimizers.  In other cases, there are awkward
problems that no query optimizer in the world can optimize much,
and using a relational database where you need pointer semantics
just adds orders of magnitude of overhead.

Please don't insult our intelligence by saying "repeat after me:"
followed by something simplistic and poorly-argued.  It just acts
as flame bait.  The issue of object identity is an important
and deep one, intertwined with the meaning of "meaning".  There
are good arguments for it and some good arguments against it,
too.  This is not an area where simplistic maxims are useful.

Followups have been directed to comp.lang.misc.

-- 
| Paul R. Wilson, Comp. Sci. Dept., U of Texas @ Austin (······@cs.utexas.edu)
| Papers on memory allocators, garbage collection, memory hierarchies,
| persistence and  Scheme interpreters and compilers available via ftp from 
| ftp.cs.utexas.edu, in pub/garbage (or http://www.cs.utexas.edu/users/wilson/)      
From: Istvan.Simon
Subject: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <33607944.3852@ws6a17.gud.siemens.co.at>
Peter Ludemann wrote:
> If two things LOOK the same, then they ARE the same.  It's called
> "referential transparency" and it's a Good Thing, as opposed to
> "pointers" which are a Bad Thing.  Why confuse your life with "object
> identity"?

Even if two things LOOK the same then they are not the same. If they
were the same you could never make a copy from anything. If this is
true in reality then there is no reason to be untrue in programming
languages.

> And why do you want to use the memory address for object identity to
> identify it --- an address can change during garbage collection.  Why
> not use a time stamp of object creation?  Oh, it's for efficiency
> reasons, you say ... ah-ha!

You always have a memory address even you don't want to have one.
This address will identify your object even if you don't want it.

> But let's suppose that you really really really do need to identify a
> particular subtree.  In other words, you want to NAME it.  No problem:
> just create a dictionary (hash table) that maps names to subtrees.
> That'll let you have two differently named entries which might happen
> to have the same values.  And it won't expose pointers.  And it'll be
> efficient.

You are able to give the same name to different objects but you cannot
place two objects on the same place.

> Repeat after me: "if two things look the same and act the same, then
> they are the same".  Don't depend on some hidden property (pointer) to
> differentiate them.  If there are important differences, then don't be
> shy: bring them out in the open and NAME them.

I prefer not to repeat :-)

> [I once took an object-oriented database that used object-IDs and
> translated it to a relational form which just used names for things;
> performace improved by about about an order of magnitude.  But that's
> another rant for another day ...]

What was the OODB based on? Perhaphs on a relational db?

-- MfG/Bye/Udv - Simon Istvan - ···················@usa.net -
From: Matthias Blume
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <izhggvrukk.fsf@mocha.CS.Princeton.EDU>
In article <·············@ws6a17.gud.siemens.co.at> "Istvan.Simon" <····@ws6a17.gud.siemens.co.at> writes:

   Even if two things LOOK the same then they are not the same. If they
   were the same you could never make a copy from anything. If this is
   true in reality then there is no reason to be untrue in programming
   languages.

Several misconceptions:

   - There are things in the "real" world that don't have an "identity".
     Numbers are one example, and we generally don't expect to be able
     to distinguish between _this_ 1 and _that_ 1.  Another example is the
     electron (or other thingies that particle physicists might be interested
     in).

   - Things that _actually_ look the same in each and every
     respect_are_ the same.  Things that we can distinguish between
     do _not_ look the same (by definition -- this is what we mean by
     being able to distinguish).

   - Even if, for a moment, we assume that all "real world" things have an
     inherent identity (the electron is a nice counterexample), then
     it is _still_ a bad idea to extrapolate from this and make every
     value in a programming language the same. Abstract things (like
     numbers, functions, sets) do _not_ have an identity.

   - From a denotational point of view object identity doesn't matter
     for immutable things.

   - Exactly _because_ there is no notion of identity, and because
     things that look the same _are_ the same, it is possible for the
     compiler to make copies of things (or represent them differently
     at different times during execution).  This is of great value for
     optimizing compilers.

   You always have a memory address even you don't want to have one.
   This address will identify your object even if you don't want it.

See, here is the mistake.  If you don't have the concept of identity,
then the compiler can choose to duplicate things when it needs to, it
can keep things in registers instead of bundling them up and allocate
them on the heap, it can use a hash-consing GC that identifies
lookalikes the programmer didn't think of and represent them by the
same "pointer" internally, and so on.  Once you do any of this, you
don't have _one_ pointer that identifies your value -- there might be
two, or ten, or none at all.

-- 
-Matthias
From: Henry Baker
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <hbaker-2704970908050001@10.0.2.1>
This subject is dealt with at length in:

ftp://ftp.netcom.com/pub/hb/hbaker/ObjectIdentity.html  (also .ps.Z)

To summarize:

An 'object' that cannot change (has no 'state') can be replicated, but
the replicas can't be distinguished -- e.g., integer 3, coordinate (3,4), etc.

An 'object' that can change (has internal 'state') cannot be replicated,
so it has 'identity'.

So, in essence, _everything_ has 'identity', since any attempt to distinguish
the various copies of replicable items will fail!

ML and Algol-68 got this right, and Lisp, C, C++, Smalltalk, etc., etc., got
this wrong.

'Shallow-copy' and 'Deep-copy' are ill-defined and dangerous -- even more
dangerous as _concepts_ than as operations, because any attempt to understand
them in any important way will necessarily lead to greater confusion.

I don't expect many to be swayed by these arguments, because much money
is to be made keeping things very confused and mysterious.  Clarity makes
things simple so customers can go on to more productive work.
From: Patrick Doyle
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <E9AxB1.7nA@ecf.toronto.edu>
In article <··············@mocha.CS.Princeton.EDU>,
Matthias Blume <·····@mocha.cs.princeton.edu> wrote:
>
>   - Things that _actually_ look the same in each and every
>     respect_are_ the same.  Things that we can distinguish between
>     do _not_ look the same (by definition -- this is what we mean by
>     being able to distinguish).

I wouldn't necessarily agree.  The difficulty lies in mutable objects.  If
I have two mutable objects, alike in every way, and I change one, then the
other doesn't change.  If I have one mutable object with two references,
and I change one, the other reference reflects this change because it's
really the same object.  But the point is that mutability allows us to have
two things, alike in every way--until one of them changes.

I think if a language has the concept of mutability, then it should also
have the concept of object identity because both the cases presented in
the previous paragraph are very useful in different curcumstances.

Of course if a language has no mutability, then object identity is
unnecessary.

 -PD

-- 
--
Patrick Doyle
······@ecf.utoronto.ca
From: Matthias Blume
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <izpvvgcn5a.fsf@mocha.CS.Princeton.EDU>
In article <··········@ecf.toronto.edu> ······@ecf.toronto.edu (Patrick Doyle) writes:

   In article <··············@mocha.CS.Princeton.EDU>,
   Matthias Blume <·····@mocha.cs.princeton.edu> wrote:
   >
   >   - Things that _actually_ look the same in each and every
   >     respect_are_ the same.  Things that we can distinguish between
   >     do _not_ look the same (by definition -- this is what we mean by
   >     being able to distinguish).

   I wouldn't necessarily agree.  The difficulty lies in mutable objects.  If
   I have two mutable objects, alike in every way, and I change one, then the
   other doesn't change.  [ ... ]

Sorry, you are right, but you missed my point.  If there is an
operation (here: modify one object and observe the change -- or
rather: non-change -- in the other), that lets you distinguish between
the two things, then they don't look the same (and never did).  It's a
matter of what one means by "they look the same".

   I think if a language has the concept of mutability, then it should also
   have the concept of object identity because both the cases presented in
   the previous paragraph are very useful in different curcumstances.

   Of course if a language has no mutability, then object identity is
   unnecessary.

And moreover, if the language has both mutable _and_ immutable things,
then it should support the concept of identity for the former and not
for the latter.  Since that was what started the thread: ML is such a
language, and it gets this issue exactly right.

-- 
-Matthias
From: Patrick Doyle
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <E9Evs1.I4D@ecf.toronto.edu>
In article <··············@mocha.CS.Princeton.EDU>,
Matthias Blume <·····@mocha.cs.princeton.edu> wrote:
>In article <··········@ecf.toronto.edu> ······@ecf.toronto.edu (Patrick Doyle) writes:
>
>   In article <··············@mocha.CS.Princeton.EDU>,
>   Matthias Blume <·····@mocha.cs.princeton.edu> wrote:
>   >
>   >   - Things that _actually_ look the same in each and every
>   >     respect_are_ the same.  Things that we can distinguish between
>   >     do _not_ look the same (by definition -- this is what we mean by
>   >     being able to distinguish).
>
>   I wouldn't necessarily agree.  The difficulty lies in mutable objects.  If
>   I have two mutable objects, alike in every way, and I change one, then the
>   other doesn't change.  [ ... ]
>
>Sorry, you are right, but you missed my point.  If there is an
>operation (here: modify one object and observe the change -- or
>rather: non-change -- in the other), that lets you distinguish between
>the two things, then they don't look the same (and never did).  It's a
>matter of what one means by "they look the same".

  Sounds a bit Orwellian to me.  :-)

>And moreover, if the language has both mutable _and_ immutable things,
>then it should support the concept of identity for the former and not
>for the latter.  Since that was what started the thread: ML is such a
>language, and it gets this issue exactly right.

  Interesting.  I must look into that language.

 -PD
-- 
--
Patrick Doyle
······@ecf.utoronto.ca
From: Jeffrey Mark Siskind
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <xoh207phlrq.fsf@ai.emba.uvm.edu>
"Greg Morrisett" <···@cs.cornell.edu> writes:

   What a pain...  This is why ML got this right.
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Matthias Blume <·····@mocha.cs.princeton.edu> wrote:

   Since that was what started the thread: ML is such a
                                           ^^^^^^^^^^^^
   language, and it gets this issue exactly right.
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I'm not so sure. Let me give you some examples:

1. We all agree that that EQUAL? should not be defined on procedures. Because
EQUAL? is defined extensionally and equality of procedures is undecidable.
But it is nonetheless *useful* to compare *intensions* of procedures (i.e.
representations of procedures, in other words code pointers) for equality.
Inter alia, this arrises in the following situation. Suppose I had a
representation of logic variables. And I could attach constraints to them.
For efficiency, I would want to make sure that the same constraint doesn't get
attached multiple times.

   (define-structure logic-variable value constraints)

   (define (assert! constraint logic-variable)
    (unless (memq constraint (logic-variable-constraints logic-variable))
     (set-logic-variable-constraints!
      logic-variable
      (cons constraint (logic-variable-constraints logic-variable))))
    (for-each (lambda (constraint) (constraint logic-variable))
              (logic-variable-constraints logic-variable)))

Now, I can't do (MEMBER CONSTRAINT (LOGIC-VARIABLE-CONSTRAINTS LOGIC-VARIABLE))
because this uses EQUAL? which is undefined on procedures. But procedures
(at least ones without closures) are immutable. So I can't do
(MEMQ CONSTRAINT (LOGIC-VARIABLE-CONSTRAINTS LOGIC-VARIABLE)) either because
this uses EQ?. But I *want* to be able to do this. Because it is *useful*.
It can reduce the complexity class of many algorithms. IMHO, this is an issue
that ML gets dead wrong and Scheme gets almost right.

2. Scheme doesn't get this quite right either. In fact, no language that I
know of gets this right. As the following example shows. We already said that
EQUAL? is undefined on procedures. And EQ? only really works on procedures
without closures. (Ignore for the moment that it is undecidable whether a
procedure requires a closure:
   (lambda (x)
    (lambda ()
     (if (goldbachs-conjecture-is-true?)
         x
         #f))))
Suppose, using the above example, I wish to do:

   (define (assert->! x n) (assert! (lambda (y) (> y n)) x))
   (let ((x (create-logic-variable)))
    (assert->! x 1)
    (assert->! x 1))

In order to not redundantly assert the same constraint twice, I need to
compare closures for equivalence. I can't do that in Scheme (or ML, or any
language that I know of). Extending EQUAL? to compare closures is really not
the right thing to do because EQUAL? does a comparison of unbounded depth.
Often, I want to do something between EQ? and EQUAL?. Like:

   (define (list-contents-eq? l1 l2)
    (and (list? l1)
         (list? l2)
         (= (length l1) (length l2))
         (every eq? l1 l2)))

So I need to be able to build my own equality predicates. To do that I need
component accessors. In Scheme, I can access pair and structure slots, and I
can access vector and string elements. But I can't access closure slots.

3. This leads to a third example. One that doesn't involve procedural
equality. But does involve shallow versus deep comparisons. Suppose I wish
to represent sets as lists without duplicates. And I have the usual complement
of procedures to do so. Such procedures ultimately must compare objects for
equality to build the notion of duplicate. Now suppose I wish to have sets of
circular objects. In most existing implementations, the only way to create
circular objects is by mutation. But one could imagine situations where I only
mutated objects to create circular representations and then never mutated them
again. And one could imagine a language that allowed me to declare such
objects as immutable after their creation. Or one could imagine an
implementation that infered that such objects were immutable after their
creation. I can't compare such objects for equality using EQUAL? because
EQUAL? won't terminate on circular objects. (Though I could make a version of
EQUAL? that did work.) So I might want to use EQ?. But I can only do so if EQ?
works on immutable objects. And even if I could use EQUAL? (either because I
made a circular version or because I wasn't using circular object), I might
have large objects and I might intern them precisely so I could later compare
them with EQ? instead of EQUAL?

    Jeff (home page http://www.emba.uvm.edu/~qobi)
From: Greg Morrisett
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <01bc573d$89e3cac0$e5d35480@hickory>
Jeffrey Mark Siskind <····@ai.emba.uvm.edu> wrote in article
<···············@ai.emba.uvm.edu>...
> 1. We all agree that that EQUAL? should not be defined on procedures.
Because
> EQUAL? is defined extensionally and equality of procedures is
undecidable.
> But it is nonetheless *useful* to compare *intensions* of procedures
(i.e.
> representations of procedures, in other words code pointers) for
equality.

Let me clarify.  Pointer-equality is a useful thing -- I didn't contest
that.  I claimed
that the ability to write code that specifies that a value (be it a
cons-cell, closure, or integer)
is immutable is an important thing to have, be it for program reasoning
purposes or
for optimization.  

As long as Pointer-equality is defined as in languages like O'Caml,
it disrupts neither reasoning nor optimization, simply because the compiler
is
free to return "false" even if two references appear to be pointing to the
same object 
at the source-level (e.g., "let x = (a,b) in x == x end" may evaluate to
true or false, 
depending upon the implementation.)  

> 2. Scheme doesn't get this quite right either. In fact, no language that
I
> know of gets this right. 

Agreed.  Non-deterministic semantics aside, a general conservative pointer
equality predicate (in the style of O'Caml but extended to cover all
values)
is generally useful.  A hash function or in general, an order on all values
would also be useful, but requires considerably more support in the
presence 
of a copying garbage collector.  

It's truly ironic that Scheme requires a non-deterministic semantics in
order
to deal with the argument evalution order issue, but doesn't extend eq to
closures.

-Greg
From: Matthias Blume
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <izg1w3gccf.fsf@mocha.CS.Princeton.EDU>
In article <···············@ai.emba.uvm.edu> Jeffrey Mark Siskind <····@ai.emba.uvm.edu> writes:

   [ example illustrating occasional need for some form of intensional
     equality ... ]

   [EQ? on procedures] Because it is *useful*.
   It can reduce the complexity class of many algorithms. IMHO, this is an issue
   that ML gets dead wrong and Scheme gets almost right.

When you need this sort of equality of procedures you can always
attach a unique tag to your constraint functions explicitly.  This
works in Scheme as well as ML.

Incidentally (and not surprisingly) this is exactly how the Scheme
report's denotational semantics section describes how EQ? works on
procedures. (The tags are locations there.)  What I find bothersome is
that such a device was added to pervade the entire language definition
when there are only relatively few occasions where it comes in handy.
It is even more bothersome, when the same sort of trick can easily be
played explicitly on a per-need basis.

By the way, in SML there is this great little gadget called a "unit
ref".  Its whole purpose in life is to embody the concept of
identity.  So when I want to have functions with identity I implement
them (for example) as a pair of the original function type and unit
ref.  Or, one can go a step further and define a datatype:

	type function = ... -> ...
	datatype function'id = FID of function * unit ref

Since operations over the unit ref type are all no-ops one could
imagine a compiler that recognizes such an idiom and gets rid of the
unit ref, represents the function'id type as an ordinary function for
which the optimizer is bound to preserve identity in Scheme's sense.
So there isn't even a need for an additional language feature here --
a clever compiler will do the trick.  (I have my doubts about whether
it would be worth the trouble, though.)

-- 
-Matthias
From: Jeffrey Mark Siskind
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <xohafm936uy.fsf@ai.emba.uvm.edu>
·····@mocha.cs.princeton.edu (Matthias Blume) writes:

> When you need this sort of equality of procedures you can always
> attach a unique tag to your constraint functions explicitly.  This
> works in Scheme as well as ML.
>
> Incidentally (and not surprisingly) this is exactly how the Scheme
> report's denotational semantics section describes how EQ? works on
> procedures. (The tags are locations there.)  What I find bothersome is
> that such a device was added to pervade the entire language definition
> when there are only relatively few occasions where it comes in handy.
> It is even more bothersome, when the same sort of trick can easily be
> played explicitly on a per-need basis.
>
> By the way, in SML there is this great little gadget called a "unit
> ref".  Its whole purpose in life is to embody the concept of
> identity.  So when I want to have functions with identity I implement
> them (for example) as a pair of the original function type and unit
> ref.  Or, one can go a step further and define a datatype:
>
> 	type function = ... -> ...
> 	datatype function'id = FID of function * unit ref
>
> Since operations over the unit ref type are all no-ops one could
> imagine a compiler that recognizes such an idiom and gets rid of the
> unit ref, represents the function'id type as an ordinary function for
> which the optimizer is bound to preserve identity in Scheme's sense.
> So there isn't even a need for an additional language feature here --
> a clever compiler will do the trick.  (I have my doubts about whether
> it would be worth the trouble, though.)

Your scheme won't work. Because procedures can be either closures or
nonclosures. And I want EQ? between closures to be true iff both the code
pointers are the same and the closure record pointers are the same. I want EQ?
between nonclosures to be true iff just the code pointers are the same. I
can't blindly wrap a unit ref around a lambda expression because I don't know
(without some inspection and inference) whether it has a closure or not. If I
do blindly wrap, then EQ? nonclosures become non-EQ? closures and this foils
my previous example.

Ultimately, any wrap operation has to generate a unique index for each
distinct argument. And it has to be able to determine whether an argument has
been seen before (i.e. hash-cons or interning) to know whether to generate a
new index. And this requires the ability to ask EQ? on its argument. You can
build hash-consing or interning around objects that are already wrapped with
an ID, or objects that have an exogenous notion of equality. But it must
ultimately be grounded on that exogenous notion of equality. For procedures,
there is no such thing. Which is why your language must provide a notion of
EQ? between procedures.

Note that EQ? between procedures is not just necessary for my constraint
example. It also is needed if you wish to implement an object system out of
closures.

    Jeff (home page http://www.emba.uvm.edu/~qobi)
From: Nick Barnes
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <j9wwpd7ybz.fsf@harlequin.co.uk>
Jeffrey Mark Siskind <····@ai.emba.uvm.edu> writes:

> ·····@mocha.cs.princeton.edu (Matthias Blume) writes:
[...]
> > By the way, in SML there is this great little gadget called a "unit
> > ref".  Its whole purpose in life is to embody the concept of
> > identity.  So when I want to have functions with identity I implement
> > them (for example) as a pair of the original function type and unit
> > ref.  Or, one can go a step further and define a datatype:
> >
> > 	type function = ... -> ...
> > 	datatype function'id = FID of function * unit ref
[...]

> Your scheme won't work. Because procedures can be either closures or
> nonclosures.

[... implementation stuff snipped ...]

Well, this sentence doesn't make much sense with reference to ML. All
functions are closures, there's no such thing as a "non-closure" (or,
for that matter, a "procedure"). Can you clarify exactly what you want
in an ML context?

> I can't blindly wrap a unit ref around a lambda expression because I
> don't know (without some inspection and inference) whether it has a
> closure or not.

That's exactly what you can do in ML, because all lambda expressions
have a closure.

Nick Barnes
From: Paul Wilson
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <5k1j3f$fp3@roar.cs.utexas.edu>
In article <··········@ecf.toronto.edu>,
Patrick Doyle <······@ecf.toronto.edu> wrote:
>
>I think if a language has the concept of mutability, then it should also
>have the concept of object identity because both the cases presented in
>the previous paragraph are very useful in different curcumstances.
>
>Of course if a language has no mutability, then object identity is
>unnecessary.

I'm not sure that even the latter is right.  It seems to me that it
can be reasonable to use object identity to represent conceptual-level
identities, even in purely functional programs.

This isn't to say that FP langauge designers are unreasonable when
they make no-object-ID's the default in pure functional languages.  It
just doesn't seem like a necessary connection.  If you want to
encode the fact that two conceptual entities are known to be the
same entity, you can ensure that the corresponding object identities
are the same.   (Like the use of symbols in Scheme, which are
different from Lisp symbols in that they have no state whatesoever.
Still, the fact that they're unique is what makes them really useful
and different from strings.)  Conversely, if you want to represent
the fact that two conceptual objects are not known to be the same object,
you can use different language-level objects to encode that.

-- 
| Paul R. Wilson, Comp. Sci. Dept., U of Texas @ Austin (······@cs.utexas.edu)
| Papers on memory allocators, garbage collection, memory hierarchies,
| persistence and  Scheme interpreters and compilers available via ftp from 
| ftp.cs.utexas.edu, in pub/garbage (or http://www.cs.utexas.edu/users/wilson/)      
From: Patrick Doyle
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <E9Evv0.I8z@ecf.toronto.edu>
In article <··········@roar.cs.utexas.edu>,
Paul Wilson <······@cs.utexas.edu> wrote:
>In article <··········@ecf.toronto.edu>,
>Patrick Doyle <······@ecf.toronto.edu> wrote:
>>
>>I think if a language has the concept of mutability, then it should also
>>have the concept of object identity because both the cases presented in
>>the previous paragraph are very useful in different curcumstances.
>>
>>Of course if a language has no mutability, then object identity is
>>unnecessary.
>
>I'm not sure that even the latter is right.  It seems to me that it
>can be reasonable to use object identity to represent conceptual-level
>identities, even in purely functional programs.

  Can you give an example of two immutable objects, alike in every way,
which need to be distinguished?

 -PD
-- 
--
Patrick Doyle
······@ecf.utoronto.ca
From: Andrew Bromage
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <5k67a4$nit@mulga.cs.mu.OZ.AU>
G'day all.

······@ecf.toronto.edu (Patrick Doyle) writes:

>  Can you give an example of two immutable objects, alike in every way,
>which need to be distinguished?

They may need to be distinguished for the purpose of compile-time
garbage collection.  If you create two immutable identical objects,
it may be easier to discover when they become garbage because the
references to them are unique, than if they were one object with
a shared reference.

Admittedly the programmer does not necessarily need to see this.

Cheers,
Andrew Bromage
From: Patrick Doyle
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <E9GJ9z.Ety@ecf.toronto.edu>
In article <··········@mulga.cs.mu.OZ.AU>,
Andrew Bromage <·······@cs.mu.OZ.AU> wrote:
>
>······@ecf.toronto.edu (Patrick Doyle) writes:
>
>>  Can you give an example of two immutable objects, alike in every way,
>>which need to be distinguished?
>
>They may need to be distinguished for the purpose of compile-time
>garbage collection.  If you create two immutable identical objects,
>it may be easier to discover when they become garbage because the
>references to them are unique, than if they were one object with
>a shared reference.
>
>Admittedly the programmer does not necessarily need to see this.

  Neither does the GC.  It can simply throw away one of the objects
immediately and use the other, can't it?

 -PD
-- 
--
Patrick Doyle
······@ecf.utoronto.ca
From: Andrew Bromage
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <5k8mut$fj7@mulga.cs.mu.OZ.AU>
G'day all.

In article <··········@mulga.cs.mu.OZ.AU>,
Andrew Bromage <·······@cs.mu.OZ.AU> wrote:

>>They may need to be distinguished for the purpose of compile-time
>>garbage collection.  If you create two immutable identical objects,
>>it may be easier to discover when they become garbage because the
>>references to them are unique, than if they were one object with
>>a shared reference.
>>
>>Admittedly the programmer does not necessarily need to see this.

······@ecf.toronto.edu (Patrick Doyle) writes:

>  Neither does the GC.  It can simply throw away one of the objects
>immediately and use the other, can't it?

Not always.

In some languages (Clean and Mercury spring to mind immediately)
you can mark some objects as being "unique" or "linear" in either the
type system, or the mode system if it's a language which supports
multiple modes of procedures.  Such objects are not mutable, but it
is possible for the compiler to know when all references to such an
object are dead and you can generate code to reuse or reclaim the
object, saving the overhead of reclaiming, and potentially the cost
of reallocating, the object.

Cheers,
Andrew Bromage
From: Stan
Subject: Where does the share.exe load?
Date: 
Message-ID: <3368996A.5137@meinc.com>
when I start ms word6.0 
it says restart windows and load share.exe
i'm using win3.1
-- 
Stan's Short Stories

http://www.meinc.com/stan
From: Henry Baker
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <hbaker-3004971730230001@10.0.2.1>
In article <··········@ecf.toronto.edu>, ······@ecf.toronto.edu (Patrick
Doyle) wrote:

> >>  Can you give an example of two immutable objects, alike in every way,
> >>which need to be distinguished?
> 
>   Neither does the GC.  It can simply throw away one of the objects
> immediately and use the other, can't it?

Indeed.  One could do this trivially by means of a 'hash-consing' copying
GC.  The idea is that when you 'copy' the node, you hash-cons it in the
new space.  Since hash-consing uniquizes the object recursively, any 'like'
objects will find themselves EQ after the GC.

Your mileage will vary on circular immutable objects.
From: Wolfgang Grieskamp
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <1og1w9apz9.fsf@cs.tu-berlin.de>
······@ecf.toronto.edu (Patrick Doyle) writes:

>   Can you give an example of two immutable objects, alike in every way,
> which need to be distinguished?

Two read-only windows in a GUI with the same contents (and
the application doesn't know about internal WM information such as position
or other attributes which may distinguish them).

Two outgoing socket connections to the same destination (and the
application again doesn't know about internal states of the sockets).

In general, this situation is quite common in modelling input/output,
since in this case applications tend to have an incomplete or `loose'
view on the outside world.

Wolfgang

-- 
··@cs.tu-berlin.de  http://uebb.cs.tu-berlin.de/~wg/
From: Chris Bitmead uid(x22068)
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <s6y911zn6sk.fsf@aalh02.alcatel.com.au>
Wolfgang Grieskamp <··@cs.tu-berlin.de> writes:

> >   Can you give an example of two immutable objects, alike in every way,
> > which need to be distinguished?
> 
> Two read-only windows in a GUI with the same contents (and
> the application doesn't know about internal WM information such as position
> or other attributes which may distinguish them).

The program must have something to distinguish the windows to be able
to talk to them, like an window ID. Otherwise how can you talk to your
window system to close the right window?
 
> Two outgoing socket connections to the same destination (and the
> application again doesn't know about internal states of the sockets).
> 
> In general, this situation is quite common in modelling input/output,
> since in this case applications tend to have an incomplete or `loose'
> view on the outside world.
From: Patrick Doyle
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <E9HJ2B.Dyv@ecf.toronto.edu>
In article <··············@cs.tu-berlin.de>,
Wolfgang Grieskamp  <··@cs.tu-berlin.de> wrote:
>······@ecf.toronto.edu (Patrick Doyle) writes:
>
>>   Can you give an example of two immutable objects, alike in every way,
>> which need to be distinguished?
>
>Two read-only windows in a GUI with the same contents (and
>the application doesn't know about internal WM information such as position
>or other attributes which may distinguish them).
>
>Two outgoing socket connections to the same destination (and the
>application again doesn't know about internal states of the sockets).

  Ok, so these are examples of two objects, alike in every way that is
observable through a given interface, which need to be distinguished
by the client of that same interface.  This is important indeed.  It is
a case I hadn't thought of.

>In general, this situation is quite common in modelling input/output,
>since in this case applications tend to have an incomplete or `loose'
>view on the outside world.

  It's like looking at two objects and they both seem to be circles.
However, we're just looking at them from the bottom--one is actually a
cone, while the other is a cylinder.  So it's important to make references
to this circle or that circle, even though we cannot otherwise distinguish
them because of our limited view.

 -PD

-- 
--
Patrick Doyle
······@ecf.utoronto.ca
From: Fergus Henderson
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <5k758d$eko@mulga.cs.mu.OZ.AU>
······@ecf.toronto.edu (Patrick Doyle) writes:

>Paul Wilson <······@cs.utexas.edu> wrote:
>
>>I'm not sure that even the latter is right.  It seems to me that it
>>can be reasonable to use object identity to represent conceptual-level
>>identities, even in purely functional programs.
>
>  Can you give an example of two immutable objects, alike in every way,
>which need to be distinguished?

Immutable objects don't need to be distinguished by object ids for
correctness, but sometimes this is quite important for performance.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Paul Wilson
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <5k1fg3$fl3@roar.cs.utexas.edu>
In article <··············@mocha.CS.Princeton.EDU>,
Matthias Blume <·····@mocha.cs.princeton.edu> wrote:
>In article <·············@ws6a17.gud.siemens.co.at> "Istvan.Simon" <····@ws6a17.gud.siemens.co.at> writes:
>
>   Even if two things LOOK the same then they are not the same. If they
>   were the same you could never make a copy from anything. If this is
>   true in reality then there is no reason to be untrue in programming
>   languages.
>
>Several misconceptions:
>
>   - There are things in the "real" world that don't have an "identity".
>     Numbers are one example, and we generally don't expect to be able
>     to distinguish between _this_ 1 and _that_ 1.  Another example is the
>     electron (or other thingies that particle physicists might be interested
>     in).

Hmmm... I dunno about electrons, and I'm not sure it's relevant,
but I'd say that for most purposes 1 *does* have an identity.  It's
1, you know, the number 1.  The reason why you can't copy the number
1 and distinguish between the copies is that it makes no sense
mathematically.  But that doesn't mean there isn't a single,
distinguished conceptual object 1.

If Lisp and Scheme had completely wonderful type systems, you would
be able to ensure that 1 is always eq? to 1.  The reason why you
can't is just an efficiency hack---you don't want to have to have
a hash table of all numeric values to maintain object identity,
the way you do with symbols.  It'd just be too slow.  That's
why Scheme has the predicate eqv? and CL has an equivalent
predicate.  (eql? ?  I forget.)  These predicates smoothover
the fact that an implementation is allowed to make multiple
copies of a numeric value, and make it appear that multiple
copies are the same value.

I'm not saying that the default, language-supported notion of
object identity is always the right one for your purposes, but
it often is for mine.  I'd say ML and Scheme both made reasonable
choices on this.  It's nice to have both, whichever is the default.

>   - Things that _actually_ look the same in each and every
>     respect_are_ the same.

No.  This is bad philosopy.  Things that are indistinguishable
given a certain subjective point of view may become distinguishable
when you learn more about them.

(For example, I once learned that I'd been corresponding with two
different people named David Chapman.  Likewise, things that are
indistingishable at one time may later become distinguishable,
as when it was realized that the morning star and the evening
star were the same object.)

>Things that we can distinguish between
>     do _not_ look the same (by definition -- this is what we mean by
>     being able to distinguish).

I think this is simplistic.  I may be able to distinguish between
two identical twins based on their social security numbers, and
that may be my only means of knowing they're two separate people,
at some point in time.  Similar things come up in programming
tasks.

>   - Even if, for a moment, we assume that all "real world" things have an
>     inherent identity (the electron is a nice counterexample), then
>     it is _still_ a bad idea to extrapolate from this and make every
>     value in a programming language the same. Abstract things (like
>     numbers, functions, sets) do _not_ have an identity.

I don't think "counterexamples" are the right thing to work from
here.  I wouldn't deny that often the language-supported notion of
object identity is often the wrong one for representing conceptual
object identity.  But it is often useful, even if you can always
hack up something to do the job in a language without object
identity.

>   - From a denotational point of view object identity doesn't matter
>     for immutable things.

It depends on the semantics you need.  For example, if I'm representing
two individuals who are parents of a third individual, and I don't
really know anything else about them, I do not want to make the mistake
of thinking that they're the same person---one may be the father,
and the other the mother, so that they're entirely different
individuals.

Similar things come up all the time internally to programs, typically
when you come up with an abstraction. 

>   - Exactly _because_ there is no notion of identity, and because
>     things that look the same _are_ the same, it is possible for the
>     compiler to make copies of things (or represent them differently
>     at different times during execution).  This is of great value for
>     optimizing compilers.

I think this has much more to do with immutability than with object
identity (or the lack of it).

>   You always have a memory address even you don't want to have one.
>   This address will identify your object even if you don't want it.
>
>See, here is the mistake. 

I think the issue here is not so much that you have an object identity
when you don't want one, but that you've got to know whether you want
one, for the semantics you're imposing on your data structures.
If an eq? (object identity) test isn't want you want, _don't_use_it_.
Cobble up your own predicates, as you'd do in a language without
object identity.   (Either way, don't confuse a memory address with
a language-level pointer.  They're not the same idea at all, even
though there's often a convenient mapping that the language implementation
*may* choose to do.)

>If you don't have the concept of identity,
>then the compiler can choose to duplicate things when it needs to, it
>can keep things in registers instead of bundling them up and allocate
>them on the heap,

Again, I think this is more of a point about immutability rather
than object identity.  You can have both in one language.

> it can use a hash-consing GC that identifies
>lookalikes the programmer didn't think of and represent them by the
>same "pointer" internally, and so on.  Once you do any of this, you
>don't have _one_ pointer that identifies your value -- there might be
>two, or ten, or none at all.

I think we have a high-level vs. low-level thing going on here.
If I want to efficiently implement exactly the memoization and
hash-consing I want for my application, I'd like to have a language
with pointers so that I can do it very efficiently.  Then I can
proceed to program with those pieces I built, construing object
identity or the lack of it any way that makes sense.  Usually I
don't want a language that tells me there's no such thing as object
identity.  I can hack around it, but why bother?  

BTW, I'm not at all convinced that a language-level pointer abstraction
is at all expensive to implement.  If I was, I might lean more toward
forcing the programmer to cobble one up as necessary.

>-- 
>-Matthias


-- 
| Paul R. Wilson, Comp. Sci. Dept., U of Texas @ Austin (······@cs.utexas.edu)
| Papers on memory allocators, garbage collection, memory hierarchies,
| persistence and  Scheme interpreters and compilers available via ftp from 
| ftp.cs.utexas.edu, in pub/garbage (or http://www.cs.utexas.edu/users/wilson/)      
From: Thomas Beale
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <33644C78.607D@invest.amp.com.au>
Paul Wilson wrote:
> 
> In article <··············@mocha.CS.Princeton.EDU>,
> Matthias Blume <·····@mocha.cs.princeton.edu> wrote:
> >In article <·············@ws6a17.gud.siemens.co.at> "Istvan.Simon" <····@ws6a17.gud.siemens.co.at> writes:
> >   - Even if, for a moment, we assume that all "real world" things have an
> >     inherent identity (the electron is a nice counterexample), then
> >     it is _still_ a bad idea to extrapolate from this and make every
> >     value in a programming language the same. Abstract things (like
> >     numbers, functions, sets) do _not_ have an identity.

My 5c worth: I suggest you are confusing an implicit idea of identity
for abstract objects (in a pure maths/logic sense) with the need to have 
identity for pieces of information in a computational information
system. 
They are not the same problem.

In an information system, you potentially want to be able to 
distinguish  any object spatially (i.e. in the value-space) and
temporally, 
except those objects which are embedded unambiguously into a parent
object.
This happens to include objects of "simple" types such as Integers
etc in many PLs, but if it didn't, you might want identification for
them as well, depending on the context of usage. 

It is the context (i.e. what the information model and software is
about)
which will determine the meaning of two objects conincidentally having
the
same value at some point in time: perhaps they are the same object -
e.g.
if two objects representing the evaluation result of an equation in an
equation-solving system, it seems reasonable that they be treated as the
same object. But two string objects conincidentally having the same
value
such as "John Smith" is most likely to be .... coincidental.

- thomas beale
From: Lennart Augustsson
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <pog1wbcuqw.fsf@dogbert.cs.chalmers.se>
······@cs.utexas.edu (Paul Wilson) writes:
> Matthias Blume <·····@mocha.cs.princeton.edu> wrote:
> >   - Things that _actually_ look the same in each and every
> >     respect_are_ the same.
> 
> No.  This is bad philosopy.  Things that are indistinguishable
> given a certain subjective point of view may become distinguishable
> when you learn more about them.
Do you have a problem with reading? :-)
Matthias Blume wrote "in each and every respect"; how can something
look the same "in each and every respect" and then be "distinguishable
when you learn more about them"?  If objects can be distinguished when
you learn more about them then they were not equal in each and every
respect.

-- 

	-- Lennart Augustsson
[This signature is intentionally left blank.]
From: ········@wat.hookup.net
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <5k2lq4$deh$1@nic.wat.hookup.net>
In <··············@dogbert.cs.chalmers.se>, Lennart Augustsson <········@cs.chalmers.se> writes:
> ...
>Do you have a problem with reading? :-)
>Matthias Blume wrote "in each and every respect"; how can something
>look the same "in each and every respect" and then be "distinguishable
>when you learn more about them"?  If objects can be distinguished when
>you learn more about them then they were not equal in each and every
>respect.

Depends.  Often computer programs are set up to model an approximation of
the real world, with some selected attributes of the real world objects
used in the description.  Depending on what you model, it might be useful
to distinguish between different objects that are identical in all selected
criteria, if only to answer the question "how many different identical
looking objects do I get with this attribute selection".

Hartmann Schaffer
From: Wolfgang Grieskamp
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <1oohaybwhv.fsf@cs.tu-berlin.de>
········@wat.hookup.net writes:

> In <··············@dogbert.cs.chalmers.se>, Lennart Augustsson <········@cs.chalmers.se> writes:
> > ...
> >If objects can be distinguished when
> >you learn more about them then they were not equal in each and every
> >respect.
> 
> Depends.  Often computer programs are set up to model an approximation of
> the real world, with some selected attributes of the real world objects
> used in the description.  

Actually, this kind of ``fuzzy'' modeling isn't supported explicitly
in pure functional languages, though it is surely relevant in praxis.

Pure FP's are useful if you have a formal model at hand (as in
compiler construction), or if you need one (as in safety-critical
systems). 

Anything else can be done in pure FP's by using monads. But thats not
``referential transparency'' in the pragmatic sense discussed in this
thread. 

Wolfgang

-- 
··@cs.tu-berlin.de  http://uebb.cs.tu-berlin.de/~wg/
From: Barry Margolin
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <5k2lt1$4f9@tools.bbnplanet.com>
In article <··············@dogbert.cs.chalmers.se>,
Lennart Augustsson  <········@cs.chalmers.se> wrote:
>
>······@cs.utexas.edu (Paul Wilson) writes:
>> Matthias Blume <·····@mocha.cs.princeton.edu> wrote:
>> >   - Things that _actually_ look the same in each and every
>> >     respect_are_ the same.
>> 
>> No.  This is bad philosopy.  Things that are indistinguishable
>> given a certain subjective point of view may become distinguishable
>> when you learn more about them.
>Do you have a problem with reading? :-)
>Matthias Blume wrote "in each and every respect"; how can something
>look the same "in each and every respect" and then be "distinguishable
>when you learn more about them"?  If objects can be distinguished when
>you learn more about them then they were not equal in each and every
>respect.

"In each and every respect" must be understood in the context of the
information available.  When we're programming, we are necessarily dealing
with abstractions and (often) approximations.  The data type in the
programming language almost always doesn't include all the information
about the corresponding object in the real world.  For instance, the IRS's
database doesn't have my fingerprints, DNA sequence, or complete quantum
state (the latter is probably the closest thing there is to "object
identity" for tangible objects in the real world -- object identity for
abstract concepts (e.g. numbers, imaginary objects, counterfactual
proposals) is still the subject of philosophical debate).

Someone else wrote that distinction after mutation is one way that objects
might "look different".  The problem with including this as part of how an
object "looks" is that you may not want to modify an object just to find
out if it's the same as another object; it's like determining whether
someone is a witch by submerging them in water: if they're a witch they'll
survive (in which case you'll burn them), but if they're not they'll drown.
 
Functions that test for object identity equivalence answer the question
"would object A change if I modify object B?" without actually performing
the modification.  In languages with mutation and multiple references to
objects, this is a useful question to ask.
-- 
Barry Margolin
BBN Corporation, Cambridge, MA
······@bbnplanet.com
(BBN customers, call (800) 632-7638 option 1 for support)
From: Mohammed Shoaib
Subject: BITMAPS & Backgrounds
Date: 
Message-ID: <33657016.7BB@nortel.com>
Hi All:

Is there a way in tk that I can use say a gif or bmp file as my
background to frame or canvas.

I would like to create a chart that has the company logo in the
backgroung, The chart ofcourse is automated where bunch of items/tags
are generated and plotted against an (X,Y) scale on-top of the gif file.

I hope I did not confuse anyone

Thanks in advance

/MrAs
From: Donal K. Fellows
Subject: Re: BITMAPS & Backgrounds
Date: 
Message-ID: <5k78fo$lml@m1.cs.man.ac.uk>
In article <············@nortel.com>,
Mohammed Shoaib  <·······@nortel.com> wrote:
> Is there a way in tk that I can use say a gif or bmp file as my
> background to frame or canvas.

Yes for canvases.  Create an image item with the picture as its
contents, and then place that item underneath all the other objects on
the canvas.  Simple!

Donal.
--
Donal K. Fellows   http://r8h.cs.man.ac.uk:8000/  (SAY NO TO COMMERCIAL SPAMS!)
(work) ········@cs.man.ac.uk     Dept. Comp. Sci, Univ. Manchester, U.K.
 |     ·····@ugglan.demon.co.uk  6,Randall Place, Heaton, Bradford, U.K. (home)
 +-> ++44-161-275-6137  Send correspondence to my office  ++44-1274-401017 <-+
From: Chris Bitmead uid(x22068)
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <BITMEADC.97Apr29132824@Alcatel.com.au>
In article <··········@tools.bbnplanet.com> Barry Margolin <······@bbnplanet.com> writes:

>"In each and every respect" must be understood in the context of the
>information available.  When we're programming, we are necessarily dealing
>with abstractions and (often) approximations.  The data type in the
>programming language almost always doesn't include all the information
>about the corresponding object in the real world.  For instance, the IRS's
>database doesn't have my fingerprints, DNA sequence, or complete quantum
>state.

Don't be so silly. The IRS has had your DNA and complete quantum state
on file for quite a while now. They already know how you're going to
fudge your 2003 tax return deductions based on complex mathematical
models.
From: Peter G. Martin
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <336835C9.9B1@zeta.org.au>
Chris Bitmead uid(x22068) wrote:

> Don't be so silly. The IRS has had your DNA and complete quantum state
> on file for quite a while now. They already know how you're going to
> fudge your 2003 tax return deductions based on complex mathematical
> models.

I hope and fondly assume they're as good at that as the economists
who presumably use much the same complex mathematical models...
(probably stored in a certain OOPS database, Chris...)

-- 
Peter G. Martin, Contract Tech Writer
······@zeta.org.au  ······@shl.dec.com
From: Paul Wilson
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <5k574d$rln@roar.cs.utexas.edu>
In article <··············@dogbert.cs.chalmers.se>,
Lennart Augustsson  <········@cs.chalmers.se> wrote:
>
>······@cs.utexas.edu (Paul Wilson) writes:
>> Matthias Blume <·····@mocha.cs.princeton.edu> wrote:
>> >   - Things that _actually_ look the same in each and every
>> >     respect_are_ the same.
>> 
>> No.  This is bad philosopy.  Things that are indistinguishable
>> given a certain subjective point of view may become distinguishable
>> when you learn more about them.
>Do you have a problem with reading? :-)

I don't think so.  But would I necessarily know if I did?

>Matthias Blume wrote "in each and every respect"; how can something
>look the same "in each and every respect" and then be "distinguishable
>when you learn more about them"?  If objects can be distinguished when
>you learn more about them then they were not equal in each and every
>respect.

I think this has been answered sufficiently by other posters (correct
me if I'm wrong), but I'm not sure exactly what you mean here, and
how it relates to programming languages.

"learn more about" doesn't necessarily mean "mutate".  Depending on
how I choose to map the application semantics onto the language
semantics, I may or may not modify language-level objects when
I learn more about the conceptual objects they represent.  Often,
I just make a notation in a table off to the side, rather than
modifying the object itself.  The objects may in fact be immutable.
Nonetheless, I may want to distinguish between two immutable objects
that are *local* equal in every respect except object identity---so
that I *can* have different information recorded about them "off
to the side".

I'm not sure why people think this is an easy issue with a single
answer.  There's no good, fixed mapping from application-level
concepts to langauge-level objects, so whatever the default in your
language is w.r.t. object identity, you'll often have to fake something
else.  Which is the default is less interesting than the fact that no
language can solve all the problems for you automatically.  Matthias
likes ML's default, which is an entirely reasonable attitude.  I like
Scheme and Smalltalk and C's default, which lets me either use or
ignore object identity without any special hacking of tags, etc.
It's a handy kind of polymorphism.

-- 
| Paul R. Wilson, Comp. Sci. Dept., U of Texas @ Austin (······@cs.utexas.edu)
| Papers on memory allocators, garbage collection, memory hierarchies,
| persistence and  Scheme interpreters and compilers available via ftp from 
| ftp.cs.utexas.edu, in pub/garbage (or http://www.cs.utexas.edu/users/wilson/)      
From: Matthias Blume
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <izafmjru25.fsf@mocha.CS.Princeton.EDU>
In article <··········@roar.cs.utexas.edu> ······@cs.utexas.edu (Paul Wilson) writes:

   Hmmm... I dunno about electrons, and I'm not sure it's relevant,
   but I'd say that for most purposes 1 *does* have an identity.

Actually, I have meanwhile asked a physicist friend of mine, and I
must admit that I somewhat confused the issues here.  Electrons are
fermions, so swapping two of them would result in a change of the
system (the wave function changes sign).  Electrons can be in states,
which then could be used to distinguish (in some sense) between them.

However, there are some peculiar things about particles, which are not
captured by our intuitive notion of "identity".  Bosons, for example,
can be swapped without any observable change.  If you swap two Cooper
pairs (each composed of two electrons), then nothing changes
(actually, by that very fact one can argue that it doesn't even make
sense to talk about "swapping" them, because there is no physical
evidence of such an "event").  A bunch of bosons in ground state can
not be distinguished between (but there is a quantity, which describes
how many of them there are).  If I remember correctly, then this leads
to counterintuitive statistical properties for the resulting system
(Einstein-Bose-statistics).

Anyway, as irrelevant as it may be, we should remember not to make the
mistake of sticking too closely to "intuition" when making models.

   It's 1, you know, the number 1.  The reason why you can't copy the number
   1 and distinguish between the copies is that it makes no sense
   mathematically.  But that doesn't mean there isn't a single,
   distinguished conceptual object 1.

In the sense that it is different from 2, yes.  But 1 is always just 1
-- conceptually. Isn't that exactly what I said?  In implementation
terms, however, we can "distinguish" between "different" copies of 1:
The 1 in register r5 as opposed to the 1 at memory location 0x338A0,
and so forth.  Still, we tend to think of 1 as just 1 -- we think of 1
is a _value_, not an _object_.

   >   - Things that _actually_ look the same in each and every
   >     respect_are_ the same.

   No.  This is bad philosopy.  Things that are indistinguishable
   given a certain subjective point of view may become distinguishable
   when you learn more about them.

Lennart Augustsson already gave a perfectly fine answer to this.

   I think this is simplistic.  I may be able to distinguish between
   two identical twins based on their social security numbers, and
   that may be my only means of knowing they're two separate people,
   at some point in time.

But the two of them probably remember their SSNs, so they are actually
different (because their memories are different).  (If they don't
remember it, then they must have it tattooed somewhere -- otherwise
how would one know which of the SSNs goes with which person.)

   >   - From a denotational point of view object identity doesn't matter
   >     for immutable things.

   It depends on the semantics you need.  For example, if I'm representing
   two individuals who are parents of a third individual, and I don't
   really know anything else about them, I do not want to make the mistake
   of thinking that they're the same person---one may be the father,
   and the other the mother, so that they're entirely different
   individuals.

Well, they are like fermions then -- swapping them around changes a
sign somewhere -- otherwise the situation is the same. :)

   >   - Exactly _because_ there is no notion of identity, and because
   >     things that look the same _are_ the same, it is possible for the
   >     compiler to make copies of things (or represent them differently
   >     at different times during execution).  This is of great value for
   >     optimizing compilers.

   I think this has much more to do with immutability than with object
   identity (or the lack of it).

Mutability immediately gives you object identity. But even without
mutability, if you are required (by the language) to maintain object
identity, then you can't make copies (unless you can prove that the
program in question never asks about object identity).  In Scheme this
comes up in the case of procedure objects, which are required to
compare "eq?" to "themselves".  This is (IMO) a major nuisance for an
optimizing compiler, because many otherwise legal beta-reductions
become potentially illegal because of that.

   I think the issue here is not so much that you have an object identity
   when you don't want one, but that you've got to know whether you want
   one, for the semantics you're imposing on your data structures.
   If an eq? (object identity) test isn't want you want, _don't_use_it_.

Well, but the compiler cannot (in general) take advantage of this,
unless your type system somehow tracks the fact that there are no eq?
comparisons for a given object.  Without a type system you loose,
because then you need some sort of global analysis, which defeats
things like separate compilation.
-- 
-Matthias
From: Christopher Eltschka
Subject: Re: Object IDs are good ( was: Object IDs are bad )
Date: 
Message-ID: <3367620D.22F6E2BE@physik.tu-muenchen.de>
Matthias Blume wrote:
> 
> In article <·············@ws6a17.gud.siemens.co.at> "Istvan.Simon" <····@ws6a17.gud.siemens.co.at> writes:
> 
>    Even if two things LOOK the same then they are not the same. If they
>    were the same you could never make a copy from anything. If this is
>    true in reality then there is no reason to be untrue in programming
>    languages.
> 
> Several misconceptions:
> 
>    - There are things in the "real" world that don't have an "identity".
>      Numbers are one example, and we generally don't expect to be able
>      to distinguish between _this_ 1 and _that_ 1.  Another example is the
>      electron (or other thingies that particle physicists might be interested
>      in).

Nice analogy - especially as it can be used to prove that is *does* make
sense to obtain a pointer to an object:

While electrons are indistinguishable (and this is an important concept
in
quantum mechanics), it *does* make sense to speak of "the electron in
the 1s
state" vs. "the electron in the 2p state", because there is the
so-called
Pauli principle, that no two electrons can be in the same state
(ironically
this is true *only* for identical particles). In the same sense it makes
sense
to speak of "the object at this place" and "the object at that place",
as
again no two objects can be at the same place. Of course, if you would
exchange
those identical objects in memory (without updating references to them),
you
would see no difference - just as you would see no difference if you
exchanged
the two electrons above. It's the electrons "identified" by their state,
and
the objects "identified" by their address.

> 
>    - Things that _actually_ look the same in each and every
>      respect_are_ the same.  Things that we can distinguish between
>      do _not_ look the same (by definition -- this is what we mean by
>      being able to distinguish).
> 

Even identical objects may be distinguished by their relationship to the
rest
of the world. For example replace the two electrons of the example by
two
myons. Then it *would* make a difference, if the 1s myon or the 2p myon
decayed (although both are "identical"). In the same sense it makes a
difference
f. ex. *which* of the identical subtrees you replace - you just get
different
trees by removing different subtrees, even if they are identical. Or,
simpler,
take the following list: (1, 1, 2, 3). Now it *does* make a difference
if I
replace the first 1 or the second 1 by 2. So we *can* distinguish
between
*this* 1 and *that* 1 (this 1 being the first in the list, that 1 being
the
second)

>    - Even if, for a moment, we assume that all "real world" things have an
>      inherent identity (the electron is a nice counterexample), then
>      it is _still_ a bad idea to extrapolate from this and make every
>      value in a programming language the same. Abstract things (like
>      numbers, functions, sets) do _not_ have an identity.
> 

Such like the first 1 and the second 1 in the list above?

>    - From a denotational point of view object identity doesn't matter
>      for immutable things.
> 

Ok, then I'll change the task: Create a new list with the first 1 or the
second 1 replaced by 2. Now, no difference?

>    - Exactly _because_ there is no notion of identity, and because
>      things that look the same _are_ the same, it is possible for the
>      compiler to make copies of things (or represent them differently
>      at different times during execution).  This is of great value for
>      optimizing compilers.
> 

But *because* there is an identity, the compiler is not free to move
things
around without updating all references to them (else it could happen
that
composed objects *do* change by accident). And this in turn means that
the
objects from the program view are *not* moved around.
Or to say it a different way: A pointer is an object that *points* to
another
object. By doing this, it produces a *relationship* between itself and
this
object. And this relationship makes the object distuingishable from
other
"identical" objects. The fact that pointers are most easily are
implemented as
physical memory address does nothing to the concept (in fact, the
"address"
in modern processors isn't really the address in memory - the object
might
even be swapped out of memory).

For this reason, a perfectly valid C++ implementation would be allowed
to
store f.ex. names in pointers, which then could be looked up in a hash
table
to find the object itself (does this sound somewhat familiar?). The
reason
this is not done is that it would be much slower than the simple
implementation
to store just the address.

>    You always have a memory address even you don't want to have one.
>    This address will identify your object even if you don't want it.
> 
> See, here is the mistake.  If you don't have the concept of identity,
> then the compiler can choose to duplicate things when it needs to, it
> can keep things in registers instead of bundling them up and allocate
> them on the heap, it can use a hash-consing GC that identifies
> lookalikes the programmer didn't think of and represent them by the
> same "pointer" internally, and so on.  Once you do any of this, you
> don't have _one_ pointer that identifies your value -- there might be
> two, or ten, or none at all.
> 

But the compiler still has to keep track of which things belong to the
same
object - i.e. the object identity.
And C++ compilers also are allowed to optimize this way - storing values
in
registers is a common optimization technique in C++ compilers. And all
objects - including pointers - may be optimized away if the compiler
can prove that it doesn't need them to be there. And different variables
may
be stored in the same place under the as-if rule as well, if the
compiler
can proof that it won't change the program's behaviour. Under the as-if
rule,
pointers to different objects may even have the same physical value, if
the
compiler can proof that this won't change program behaviour.

I think the problem is just the (unfortunately very common)
misunderstanding
that a pointer *is* a memory address - it's not more of a memory address
than
the letter 'A' is the number 65: it's how it is (usually) implemented.

A pointer is an abstraction, just as a letter or a number is an
abstraction.
A pointer is the abstraction of the concept "that one".
From: Antoun Kanawati
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <m24tctuaiu.fsf@cybercom.net>
Peter Ludemann <········@inxight.com> writes:
: ...
: But let's suppose that you really really really do need to identify a
: particular subtree.  In other words, you want to NAME it.  No problem:
: just create a dictionary (hash table) that maps names to subtrees.
: That'll let you have two differently named entries which might happen
: to have the same values.  And it won't expose pointers.  And it'll be
: efficient.

I don't get it.  Object identity is "bad", but when we need it, and
very often, we do, we must go through hoops and program against a
small in-memory relational database instead?

Pointers are bad, but pointers are not "object identity".  Identity is
available in languages like LISP, Smalltalk, and Java which have
garbage collection, and is quite reliable too.

: Repeat after me: "if two things look the same and act the same, then
: they are the same".  Don't depend on some hidden property (pointer) to
: differentiate them.  If there are important differences, then don't be
: shy: bring them out in the open and NAME them.

So, if you need identity, you should implement it yourself.
Furthermore, you should insure not only that your implementation is
correct, but also that every usage is correct!

The implications of your statement, stated in quasi-religious tones,
are as follows:

1. Without identity, you need to lookup every object by name.
2. And, when the object state changes, you must shove that named
   object back into the table because you can't be sure that the new
   state is the "same" object you've looked up from the table.
3. Furthermore, since you don't have identity, your object lookup data
   structure must go through the same hoops as the application, or
   ... it must be based on object identity.
4. And, now, the lookup strcuture must be passed as an argument to
   everything you call, since subjecting it to mutations while
   avoiding object identity means that you have to name it too.
5. And, now, your program must be written in strict continuation
   passing style, because you want to make sure that the lookup
   structure is the most current at any point in time.

Or, in much simpler words, the implication is: program in purely
functional style.  Not a bad thing by itself, but a much bigger
statement than "object identity is bad".

: [I once took an object-oriented database that used object-IDs and
: translated it to a relational form which just used names for things;
: performace improved by about about an order of magnitude.  But that's
: another rant for another day ...]

Well, your little story simply indicates that you had a bad OODB
and/or an excellent RDB.  It is hard to imagine the general case where
table lookups from a relational database can be inherently faster than
the traversal of a persistent pointer.
-- 
Antoun (Tony) Kanawati
·····@cybercom.net
http://www.cybercom.net/~tonyk
From: Erik Naggum
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3071056971024295@naggum.no>
* Andrew Koenig
| But now suppose we want to be able to identify a specific subtree of a
| tree.  If I had gone to the trouble of creating a tree abstraction in
| C++, I could identify a particular subtree by the address of its root.
| But there's no corresponding facility in ML.  Trees are values, and
| although one can compare them for equality, there is no notion of object
| identity.

* Peter Ludemann
| Absolutely correct and correctly so.
| 
| If two things LOOK the same, then they ARE the same.  It's called
| "referential transparency" and it's a Good Thing, as opposed to
| "pointers" which are a Bad Thing.  Why confuse your life with "object
| identity"?

it seems to me that there is some confusion between two meanings of "object
identity".  one meaning is that you can test for object identity with an
operator of some kind.  in Lisp, that's `eq'.  C has `=' when applied to
pointers.  this meaning implies that "object identity" is a value of some
sort, but in Lisp this value _is_ the object as far as the language is
concerned.  in C, the object identity _is_ a pointer, and the value is
something it points to.  this leads to the other meaning, that object
identity is a separate _type_ apart from objects, such as pointers in C.
the distinction may be useful in smoe situations, but those mostly have to
do with the allocation of objects in memory.  but regardless of how memory
is organized and used, an object is itself, and it is useful to know
whether two objects are identical, provided you can get more than one
handle on an object in the first place.  Peter Ludemann seems to think that
something other than the memory address of the object should be used for
this purpose, and that is a perfectly legitimate point, however silly.

part of the problem with pointers is that languages such as C and C++ force
you to remember the difference between a pointer and a pointed-to-value,
even though the language is supposedly strongly typed and the compiler
perfectly well knows when you get it wrong.  e.g., if you declare struct
foo *bar;, it should not be a terribly hard task for the compiler to
understand that bar.zot means the field "zot" of the structure _pointed_to_
by bar, but oddly enough, you have to write bar->zot or (*bar).zot to do
that, which is just idiotic.  such is what you get when you combine "the
compiler shouldn't be smarter than its users" with the artificial
distinction between values and pointers to them.  however, this is _not_
because of "object identity", but rather because the language conflates
object identity with the pointer type and exposes the latter to the
programmer in a way that destroys any concept of "object" and just leaves
"untyped block of memory" in its place.

I have no idea whether Peter Ludemann had a third meaning of "object
identity" in mind, and I don't know whether Andrew Koenig knows ML well
enough that it is true that ML doesn't offer object identity, but it seems
rather obvious to offer object identity if you offer composite types.  what
little I know about ML suggsts that ML _must_ offer object identity.  (how
else would you be able to talk about the constituent objects of a composite
object?)  anybody knowledgeable in ML want to explain this further?

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: ozan s. yigit
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <x6wwpp48w3.fsf@ds9.rnd.border.com>
Erik Naggum writes [amongst other things]:

> part of the problem with pointers is that languages such as C and C++ force
> you to remember the difference between a pointer and a pointed-to-value,
> even though the language is supposedly strongly typed and the compiler
> perfectly well knows when you get it wrong.  e.g., if you declare struct
> foo *bar;, it should not be a terribly hard task for the compiler to
> understand that bar.zot means the field "zot" of the structure _pointed_to_
> by bar, but oddly enough, you have to write bar->zot or (*bar).zot to do
> that, which is just idiotic. [...]

bar->zot is a shorthand for a troubling indirection operator that ritchie
regards as an accident of syntax. it also goes to show that consequences
of early mistakes can be indistinguishable from something idiotic to
anyone who sees them in a vacuum.

see "The Development of the C Language" included the "History
of Programming Languages." 

send your language fixes to C9X...

oz
From: Andrew Koenig
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9Apos.DLI@research.att.com>
In article <················@naggum.no> Erik Naggum <····@naggum.no> writes:

> I have no idea whether Peter Ludemann had a third meaning of "object
> identity" in mind, and I don't know whether Andrew Koenig knows ML well
> enough that it is true that ML doesn't offer object identity, but it seems
> rather obvious to offer object identity if you offer composite types.  what
> little I know about ML suggsts that ML _must_ offer object identity.  (how

ML does not offer object identity, because it doen't have objects.
The closes it has is references, which are mutable cells that contain
values.  Two references have the same value iff they are the same reference
(although two distinct references can contain the same value).  Example:

	val x = ref 3;

Now x is bound to a reference that contains the value 3.

	val y = ref 3;

Now y is bound to a different reference that contains the value 3.

Therefore, x = x is true, x = y is false, and !x = !x and !x = !y are both true
(! is the dereferencing operator in ML).

If you do not references, values are all you have.  So, for example

	val p = [3, 4, 5];

	val q = [3, 4, 5];

Now p = q because p and q have the same value, and there is no way to determine
whether p and q are the same list because even the question is meaningless in ML.
(The implementation might store p and q as pointers to the same memory,
or it might not.  There is no way to tell.)
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Fergus Henderson
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5jvk1l$4bu@mulga.cs.mu.OZ.AU>
···@research.att.com (Andrew Koenig) writes:

>ML does not offer object identity, because it doen't have objects.

Hmm... aren't ML references objects? 
If not, why not?

They seem to me to have at least some of the necessary characteristics
for object-hood, namely state and identity; that's as much as the "objects"
described in the C standard have (although the terminology there is also
different: the C names for state and identity are "storage" and "address").

If "reference" and "object" are the same in all but name, then aren't they
really equal?  Oh... that brings us back to our original question ;-)

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Tony Finch
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <5k02gh$jhj@lyra.csx.cam.ac.uk>
···@research.att.com (Andrew Koenig) wrote:
>
>If you do not references, values are all you have.  So, for example
>
>	val p = [3, 4, 5];
>
>	val q = [3, 4, 5];
>
>Now p = q because p and q have the same value, and there is no way to
>determine whether p and q are the same list because even the question
>is meaningless in ML. (The implementation might store p and q as
>pointers to the same memory, or it might not. There is no way to
>tell.)

Why do you need to know where things are stored in memory? It is
irrelevant if the things are immutable. Worrying about the fine
details of implementation is the disease of the C programmer. ML is a
higher level language, so the sordid practicalities of whether
comparing two lists will traverse the whole structure or not is left
entirely to the compiler.

In the tree example that you started with, what is wrong with just
passing round the whole subtree so that it can be compared with as
necessary? Any reasonable implementation will only be passing round a
pointer so you lose nothing.

Tony.
-- 
   o
 o o o                               [[Question: What is special about 1681?]]
o o o o
From: Andrew Koenig
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9B862.Jry@research.att.com>
In article <··········@lyra.csx.cam.ac.uk> Tony Finch <····@lspace.org> writes:

> In the tree example that you started with, what is wrong with just
> passing round the whole subtree so that it can be compared with as
> necessary? Any reasonable implementation will only be passing round a
> pointer so you lose nothing.

Because it will compare equal with any other subtree that happens to
have the same structure, which is not what I want.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Chris Bitmead uid(x22068)
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <s6yg1wclykz.fsf@aalh02.alcatel.com.au>
···@research.att.com (Andrew Koenig) writes:

> > In the tree example that you started with, what is wrong with just
> > passing round the whole subtree so that it can be compared with as
> > necessary? Any reasonable implementation will only be passing round a
> > pointer so you lose nothing.
> 
> Because it will compare equal with any other subtree that happens to
> have the same structure, which is not what I want.

So all you have to do is generate a unique name for each node, right?
Just an incremental number perhaps.
From: Jacques GARRIGUE
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <l2ohazp5q4.fsf@safran.kurims.kyoto-u.ac.jp>
·············@alcatel.com.au (Chris Bitmead uid(x22068)) writes:

> ···@research.att.com (Andrew Koenig) writes:
> 
> > > In the tree example that you started with, what is wrong with just
> > > passing round the whole subtree so that it can be compared with as
> > > necessary? Any reasonable implementation will only be passing round a
> > > pointer so you lose nothing.
> > 
> > Because it will compare equal with any other subtree that happens to
> > have the same structure, which is not what I want.
> 
> So all you have to do is generate a unique name for each node, right?
> Just an incremental number perhaps.

All languages are equivalent, so there is certainly a way to encode
any language in another. But this is not the point here. The point is
that physically those trees are represented by pointers, and the
question is whether you should be able to access this pointer in some
way or not. In terms of efficiency, there is a difference.

Remark that being able to acceed a pointer is not anecdotical. For
instance, being able to compare physically pointers with < or > means
restrictions on the garbage collector, that should keep these
inequalities when moving values around. Most GC's don't. C's pointer
arithmetic is even worse. On the other hand, GC's do keep pointer
identity. So being able to compare pointers for == and != should not
be so harmful. This is a constraint for the language: pointer identity
should be defined in some way, and some abstract operations might
become invalid.

It seems that SML chose not to allow pointer comparisons (you have to
explicitely buld a ref), while CAML does allow them (== and != do
compare pointers, not values, those being compared with = and
<>). This may be seen as a question of taste. I prefer the last one,
since anyway ML is a strict language, and all implementations that I
know of do satisfy the requisite to make it meaningful. But people may
prefer to be forced to write thing in a functional way, and not be
implementation dependent. By the way, since most implementations of
SML do allow you to make unsafe casts, you can perfectly convert your
trees to integers, and then compare them!

Finally, all this is a problem of how far a language is specified. C
is specified to such a level that you cannot touch anything without
observable change. Abstractly specified language allow potentially a
lot to the implementation, but this is rarely used. In the middle,
languages like Lisp, Scheme and CAML, allow almost anything to the
user, while defining what is unsafe, to give more power to the
implementation.

Also, do not criticize a paradigm based on properties of a
language. This is only an instance of this paradigm, and other
instances may have other properties. Finally, you choose your language
based on the paradigm and the properties you like to have.

	Jacques

---------------------------------------------------------------------------
Jacques Garrigue	Kyoto University      ········@kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>
From: Matthias Blume
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <izbu6zrwft.fsf@mocha.CS.Princeton.EDU>
In article <··············@safran.kurims.kyoto-u.ac.jp> Jacques GARRIGUE <········@safran.kurims.kyoto-u.ac.jp> writes:

   [ ... ] The point is
   that physically those trees are represented by pointers, and the
   question is whether you should be able to access this pointer in some
   way or not.

This is simply not true, as I have tried to explain in earlier articles.

   It seems that SML chose not to allow pointer comparisons (you have to
   explicitely buld a ref), while CAML does allow them (== and != do
   compare pointers, not values, those being compared with = and
   <>). This may be seen as a question of taste. I prefer the last one,
   since anyway ML is a strict language, and all implementations that I
   know of do satisfy the requisite to make it meaningful.

Well, SML/NJ doesn't.  I assume you've heard of it. Representation
analysis may choose to duplicate values in physical memory (resulting
in more than one "pointer" for one value) or represent things in
registers (i.e., there is no pointer for the value at all).

   But people may
   prefer to be forced to write thing in a functional way, and not be
   implementation dependent. By the way, since most implementations of
   SML do allow you to make unsafe casts, you can perfectly convert your
   trees to integers, and then compare them!

This is irrelevant, because it is not in the scope of the language's
definition.  Casts are inherently non-portable (for precisely the
reasons stated).

[ newsgroups trimmed ]

-- 
-Matthias
From: Paul Wilson
Subject: Object identity and optimizations Re: Object IDs are bad
Date: 
Message-ID: <5k68sk$373@roar.cs.utexas.edu>
In article <··············@mocha.CS.Princeton.EDU>,
Matthias Blume <·····@mocha.cs.princeton.edu> wrote:
>In article <··············@safran.kurims.kyoto-u.ac.jp> Jacques GARRIGUE <········@safran.kurims.kyoto-u.ac.jp> writes:
>
>   It seems that SML chose not to allow pointer comparisons (you have to
>   explicitely buld a ref), while CAML does allow them (== and != do
>   compare pointers, not values, those being compared with = and
>   <>). This may be seen as a question of taste. I prefer the last one,
>   since anyway ML is a strict language, and all implementations that I
>   know of do satisfy the requisite to make it meaningful.
>
>Well, SML/NJ doesn't.  I assume you've heard of it. Representation
>analysis may choose to duplicate values in physical memory (resulting
>in more than one "pointer" for one value) or represent things in
>registers (i.e., there is no pointer for the value at all).

This can often be done in a language that does support pointer
semantics.  In Lisp and Scheme implementations, it's common for
small immutable values to be represented as "immediates", where
the conceptual pointer is collapsed out.  (The tag is in the
value representation itself, and essentially acts as a compressed
pointer that says that the real value is "right here" in the same 
word.)

Also, local analyses can get rid of most of the need for boxing
values that won't fit in a word.  A little dataflow analysis
is sufficient to detect that most values are intermediate values
that don't escape as first-class values passed to other procedures.

Even our RScheme compiler---which has a fairly lame back end right
now---does a trivial bottom-up type inference and dataflow analysis
so that many intermediate values are used in their raw form.  This
is especially important in avoiding tag overhead and heap allocation
of most floating-point values.

This kind of thing has been done for decades (and better) in many
serious Lisp compilers, since MacLisp showed it was a good idea
decades ago.

Such a scheme is not perfect in a dynamically-typed langauge,
but it can be pretty good with good optimizing compilers, and
in a statically typed language, it's easy to do better.

It seems to me that the basic idea is that unnecessary tagging,
boxing, and indirections can generally avoided if the compiler 
can see where the values are coming from and where they're going.

What I don't know is how often it matters that these techniques
are limited by how much the compiler can analyze nonlocal
properties.  Does SML get big wins by replicating data outside of
registers, where pointers are passed around beyond what the compiler's
field of view?  If so, that would be a good performance argument
for having types that can't be identity-tested.  

My intuition is that having the type system rule out identity
comparisons for most types is not actually a big win, because
a big majority of the benefit of optimizations comes from 
relatively local analyses.  (I'd think immutability would
be a much bigger win, because it makes common subexpression
detection much easier.)  I could be wrong, though.

>   But people may
>   prefer to be forced to write thing in a functional way, and not be
>   implementation dependent. By the way, since most implementations of
>   SML do allow you to make unsafe casts, you can perfectly convert your
>   trees to integers, and then compare them!
>
>This is irrelevant, because it is not in the scope of the language's
>definition.  Casts are inherently non-portable (for precisely the
>reasons stated).

I don't think this is irrelevant, but I think there may be some
confusion about what people mean.  I'm a little confused, at least.

If I can unsafely cast any value I want, then I'll defeat the
compiler's ability to optimize in ways that require replication and
using different pointers to represent the same value, for essentially
the same reasons that the possibility of an identity (language-level
pointer comparision) test does.  I have a back door through which
I can do pointer comparisons.  In general, the only way to avoid
this is to restrict either the use of unsafe casts, or the semantics
of unsafe casts.

(E.g., we may have module and scoping features that the compiler knows
will keep me from seeing certain values in a separately-compiled module,
so that it can use a local analysis instead of a global one.  Or we can
say that you can cast pointers and get raw virtual addresses, but not
provide object identity guarantees for such raw pointers.  We might 
only guarantee that when you cast two langauge-equal values to raw
pointers, they'll point at storage holding the same values---not
necessarily the same storage.)

So a relevant question is whether the good SML compilers do in fact
perform the replication-based optimizations across analysis boundaries
(e.g., separately-compiled modules, or just escapes from scopes that
the compiler doesn't do inter-scope analysis of), using type-system-imposed
constraints on identity tests.  Or do they restrict unsafe casts to
keep from blowing their analyses away?

I, for one, don't know enough about SML and its implementations to assess
the arguments here.  Explanations welcome.

>[ newsgroups trimmed ]

>-Matthias

-- 
| Paul R. Wilson, Comp. Sci. Dept., U of Texas @ Austin (······@cs.utexas.edu)
| Papers on memory allocators, garbage collection, memory hierarchies,
| persistence and  Scheme interpreters and compilers available via ftp from 
| ftp.cs.utexas.edu, in pub/garbage (or http://www.cs.utexas.edu/users/wilson/)      
From: Fergus Henderson
Subject: Re: Object identity and optimizations Re: Object IDs are bad
Date: 
Message-ID: <5k85sr$ef7@cantaloupe.srv.cs.cmu.edu>
······@cs.utexas.edu (Paul Wilson) writes:

>Matthias Blume <·····@mocha.cs.princeton.edu> wrote:
>>Jacques GARRIGUE <········@safran.kurims.kyoto-u.ac.jp> writes:
>>
>>   It seems that SML chose not to allow pointer comparisons (you have to
>>   explicitely buld a ref), while CAML does allow them (== and != do
>>   compare pointers, not values, those being compared with = and
>>   <>). This may be seen as a question of taste. I prefer the last one,
>>   since anyway ML is a strict language, and all implementations that I
>>   know of do satisfy the requisite to make it meaningful.

What do you mean by meaningful?  What exactly does CAML guarantee about
the results of `==' and `!='?

For example, if I construct two terms and then compare them for equality,
does CAML specify what the results will be?  Must the following expression

	let x = cons(1, nil)
	and y = cons(1, nil)
	in x == y

always return false?  If so, then the compiler can't do common subexpression
elimination.

If not, then `==' has unspecified behaviour. 
It will still be useful, but this sort of "weak" object identity
is not the same as the "strong" (fully specified) object identity
in languages such as C++.

Also, unspecified behaviour for `==' breaks referential transparency. 
It is possible to provide the same functionality without breaking referential
transparency -- for example, I have an implementation of this in Mercury --
but it requires some language features that SML doesn't have.
Of course, SML references also break referential transparency, as does
I/O in SML, so perhaps this is not much of an issue for SML.

>>   But people may
>>   prefer to be forced to write thing in a functional way, and not be
>>   implementation dependent.

Yep.

>>   By the way, since most implementations of
>>   SML do allow you to make unsafe casts, you can perfectly convert your
>>   trees to integers, and then compare them!

That's how my Mercury implementation of this stuff works.

>>This is irrelevant, because it is not in the scope of the language's
>>definition.  Casts are inherently non-portable (for precisely the
>>reasons stated).

The guarantee you need for weak object identity is just that `x == y'
(equality of object identities) implies `x = y' (equality of object values).
Using casts is to implement `==' is indeed non-portable, but I suspect that
it would satisfy this guarantee for most implementations.

--
Fergus Henderson <···@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger ···@128.250.37.3         |     -- the last words of T. S. Garp.
From: Xavier Leroy
Subject: Re: Object identity and optimizations Re: Object IDs are bad
Date: 
Message-ID: <5kb4a5$5s4@cantaloupe.srv.cs.cmu.edu>
···@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

> What do you mean by meaningful?  What exactly does CAML guarantee about
> the results of `==' and `!='?

Physical equality in Caml is partially specified as follows:

- it implies structural equality, i.e. if x == y, then x = y;

- if x and y belong to a mutable type (references, arrays, records
  with mutable fields), then x == y if and only if any assignment on x
  also affects y.

As a consequence, the Caml compilers are 100% free to share or unshare
immutable objects -- and you can be sure they do in a number of
beneficial ways.

Of course, using == in your program makes it non-deterministic
strictly speaking (changes in the compiler might change the outcome of
the program), but so do many other interesting features, e.g. threads.

Also, the definition of == above is exactly what you need (no more, no
less) to implement hash-consing.

> It will still be useful, but this sort of "weak" object identity
> is not the same as the "strong" (fully specified) object identity
> in languages such as C++.

Caml, like Scheme and probably other high-level languages, takes the
view that "object identity" is meaningful only on mutable objects.
Given the amount of bandwidth wasted in other newsgroup to discuss
whether immutable objects have identities or not (a bit like
discussing whether angels are male, female, or neither), I believe
it's the only reasonable view.

- Xavier Leroy
-- 
Valid e-mail address (without the underscores): ············@i_n_r_i_a.f_r
This is a protection against junk mail. Apologies for the inconvenience.
Home page: http://pauillac.inria.fr/~xleroy/
From: Jeffrey Mark Siskind
Subject: Re: Object identity and optimizations Re: Object IDs are bad
Date: 
Message-ID: <5kd04u$2hp@cantaloupe.srv.cs.cmu.edu>
> Caml, like Scheme and probably other high-level languages, takes the
> view that "object identity" is meaningful only on mutable objects.

This is not true for Scheme. EQ? works on symbols and symbols are immutable.
That issue aside, R4RS 6.2 gives a number of examples of other immutables
objects for which EQ? has a defined value:

(eq? 'a 'a) ==> #t
(eq? '() '()) ==> #t
(eq? car car) ==> #t
(let ((x '#())) (eq? x x)) ==> #t
(let ((p (lambda (x) x))) (eq? p p)) == #t

There is another more subtle issue. One can make a distinction between whether
an object can be mutated and whether an object is mutated. Usually, the term
`mutable' refers to the `can be' notion but one can alternately think of it
refering to the `is' notion. R4RS uses the `can be' notion. In R4RS, pairs and
nonempty vectors are mutable. And there is no way to create immutable pairs
and nonempty vectors. But one can imagine a language R4RS' just like R4RS
except that it adopts the `is' notion. Now, the `is' notion is undecidable.
But one can imagine decidable conservative approximations to the `is' notion.
And one could ask whether such a language should allow EQ? on objects that the
compiler determines will never be mutated. So for example, R4RS 6.2 also
includes the example:

(eq? (list 'a) (list 'a)) ==> #f

It doesn't take a very clever compiler to determine that each instance of
the result of (list 'a) in the above can never be mutated. And one could
imagine a language design that disallowed EQ? on such objects. (I have thought
about making Stalin accept such a langauge.) But R4RS doesn't take that
approach.

In summary, should a language allow EQ? on objects that could in principle be
mutated but that actually aren't? I can think of arguments both for and
against. It is not so simple. And this issue is independent of whether your
language has objects for which mutation is disallowed and whether your
language allows EQ? on such objects. I.e. this issue arrises in ML just as
much as it arrises in Scheme.

    Jeff (home page http://www.emba.uvm.edu/~qobi)
From: Jacques GARRIGUE
Subject: Re: Object identity and optimizations Re: Object IDs are bad
Date: 
Message-ID: <5kd06o$2kc@cantaloupe.srv.cs.cmu.edu>
···@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

> >>Jacques GARRIGUE <········@safran.kurims.kyoto-u.ac.jp> writes:
> >>
> >>   It seems that SML chose not to allow pointer comparisons (you have to
> >>   explicitely buld a ref), while CAML does allow them (== and != do
> >>   compare pointers, not values, those being compared with = and
> >>   <>). This may be seen as a question of taste. I prefer the last one,
> >>   since anyway ML is a strict language, and all implementations that I
> >>   know of do satisfy the requisite to make it meaningful.
> 
> What do you mean by meaningful?  What exactly does CAML guarantee about
> the results of `==' and `!='?

The definition of Caml only guarantees weak object identity, as you
define in your post, except for mutable data-structures for which it
is strong object identity.

[from O'Caml's manual]
val (==) : 'a -> 'a -> bool

     e1 == e2 tests for physical equality of e1 and e2. On integers
     and characters, it is the same as structural equality. On mutable
     structures, e1 == e2 is true if and only if physical modification
     of e1 also affects e2. On non-mutable structures, the behavior of
     (==) is implementation-dependent, except that e1 == e2 implies e1
     = e2.

> For example, if I construct two terms and then compare them for equality,
> does CAML specify what the results will be?  Must the following expression
> 
> 	let x = cons(1, nil)
> 	and y = cons(1, nil)
> 	in x == y
> 
> always return false?  If so, then the compiler can't do common subexpression
> elimination.

Following the above definition, the result is not guaranteed.

I believe the current implementation does not do common subexpression
elimination.  As a result, the above _happens_ to always return false. 
Also, since O'Caml does not duplicate representations for the same
object, comparing pysically an object with itself also _happens_ to be
always true.

But indeed, after reading this definition I realize that if you build
trees in Caml, you're only sure to get weak identity on your nodes...
So what I wrote was only true for the current implementation.

As you write,

> If not, then `==' has unspecified behaviour. 
> It will still be useful, but this sort of "weak" object identity
> is not the same as the "strong" (fully specified) object identity
> in languages such as C++.

Yes, you may use weak identity as a simplification case when you want
to compare values in an unusual way. If this is the same object, they
are equal, otherwise start an heavy check.

Jacques
---------------------------------------------------------------------------
Jacques Garrigue	Kyoto University      ········@kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>
From: Greg Morrisett
Subject: Re: Object identity and optimizations Re: Object IDs are bad
Date: 
Message-ID: <01bc55a9$dea0ded0$e5d35480@hickory>
The problem with Scheme-like languages is that you cannot express
a value WITHOUT giving it a unique identity (i.e., ref).  As Matthias Blume
points out,
this seriously hampers optimization as well as program reasoning.
I cannot assert, for instance, that when I bind 3 to x, x will not be
mutated
so that it becomes 4.  (For that matter, in many Lisps, you couldn't be
sure
that "3" wouldn't be mutated to "4").  If I can't assert it, a compiler
will not
in general be able to figure this out -- especially across compilation
boundaries.  There is no construct in the language that allows me to 
do this.

To understand why this is important, look at every Scheme compiler that
does a half-way decent job of optimization (including RScheme).  The first
thing it does is convert the external language to an internal language that
makes a distinction between values (e.g., 3) and pointers to such values
(e.g., ref 3).  The same is true for a C compiler.  Now, an analysis is
done
in order to prevent, for instance, having to stack or heap allocate a cell
for 3, because you're able to determine that the "ref 3" isn't mutated or
does not escape.    

When you write a function in ML that takes multiple arguments
or returns multiple results, those are expressed as a tuple of arguments
(simplifying the programming considerably and doing away with stupid
ad-hoc constructs like the proposed multiple-return values of R5RS. 
Consider
writing a general-purpose composition function in Scheme vs. ML).
ML compilers, such as TIL and SML/NJ, unbox the tuples
and place them in registers -- and they do it across compilation boundaries
because they know that the tuples cannot be mutated  and hence need
not be allocated in memory.  If the tuples escape (a rare situation), then
the tuples can be recreated -- WITH A DIFFERENT ADDRESS, because
the program cannot observe that this is a different address.  The savings
in allocation and the run-time performance are remarkable (I found a 60%
reduction in allocation and a 40% improvement in running times pulling
these and similar representation transformations with datatypes)..  
For more information, I suggest you read Zhong Shao's disseration
and my own.  

These sorts of transformations are effectively impossible for Scheme
without a global, conservative analysis (think expensive and not practical
in a real setting of dynamically loaded applets, dynamically linked
libraries,
or just plain old separate compilation.)  

Now, there's no reason that "value" as the default is better than "ref
value"
as the default.  However, you just can't express "value" in Scheme.  If I
could write "letimmutable x = 3" where x cannot be modified, then I'd be
happy.  But I can't.  What a pain...  This is why ML got this right.

-Greg Morrisett
 ···@cs.cornell.edu
From: Chris Bitmead uid(x22068)
Subject: Re: Object identity and optimizations Re: Object IDs are bad
Date: 
Message-ID: <s6y7mhjn62r.fsf@aalh02.alcatel.com.au>
"Greg Morrisett" <···@cs.cornell.edu> writes:

> Now, there's no reason that "value" as the default is better than "ref
> value"
> as the default.  However, you just can't express "value" in Scheme.  If I
> could write "letimmutable x = 3" where x cannot be modified, then I'd be
> happy.  But I can't.  What a pain...  This is why ML got this right.

It never seemed important to me that I couldn't express values in
Scheme. It would concern me though if I couldn't express values
because that prevents the sort of coding I am used to.

I'm not too concerned about which decision results in the most
potential for optimisation, I'm more concerned about which paradigm,
makes it easiest to express correct computer programs.

I'm finding it hard to visualise writing a program without pointer
semantics, so I guess I will have to learn more about ML to fully
understand the issues.
From: Henry Baker
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <hbaker-2804972116020001@10.0.2.1>
In article <··············@safran.kurims.kyoto-u.ac.jp>, Jacques GARRIGUE
<········@safran.kurims.kyoto-u.ac.jp> wrote:

> Remark that being able to acceed a pointer is not anecdotical. For
> instance, being able to compare physically pointers with < or > means
> restrictions on the garbage collector, that should keep these
> inequalities when moving values around. Most GC's don't.

I know of one important instance where comparing pointers with < and > is
important --- 'genetic order' (birth order) comparisons.  In addition to
having a stable sorting order for things like merging ordered lists, genetic
orderings can have other uses.  Eiichi Goto of the U. of Tokyo studied this
in the early 1970's.  There are a number of GC's that preserve birth order
by squeezing out the garbage even when they relocate objects.

Thus, comparisons of this sort do not require (stable) object id's.
From: Andrew Koenig
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9CKEG.Jxx@research.att.com>
In article <···············@aalh02.alcatel.com.au> ·············@alcatel.com.au (Chris Bitmead uid(x22068)) writes:

> So all you have to do is generate a unique name for each node, right?
> Just an incremental number perhaps.

Sure, but then I lose the ability to tell whether two trees
have the same value, because they no longer do.  So I have to
write a value-comparison routine that ignores the tags.

Of course, I can solve that problem too.  But that's not the point.

The point is this:  Someone suggested that if we were just to use
a language with a particular set of features (high-order functions,
closures, and something else that I forget at the moment), we would
all realize how horrible C++ was.  So I picked one example of such
a language and gave an example of a problem that is not easy to solve
directly in that language.  I intended that example (and still do)
as an existence proof that that particular language is not perfect,
thereby gainsaying the claim that the mere existence of these particular
features will show that languages without them are wretched.

Now, of course I can solve these problems in that language if I change
the problems appropriately.  That will be true of any language that is
Turing-complete.  But the fact is that some languages encourage particular
ways of thinking about programming and other languages encourage
other ways, and I do not believe that any particular way of thinking
about programming styles has an absolute moral superiority over any other.

As yet another example of this, I imagine that an experienced Haskell
programmer would say that generating unique names for each node is
tricky, because doing so is not referentially transparent unless the
serial number of the next node to be generated is passed around the whole
program (I do not think Haskell has global variables, or any way of
imitating them, because they are not referentially transparent).  So
I would probably be urged to adopt yet another solution in the name of
referential transparency.

Now, referential transparency is very nice indeed, especially when you're
trying to reason about programs and prove their properties.  But
writing substantial programs that are referentially transparent requires
yet another dramatically different way of thinking about programming,
which carries its own set of advantages and disadvantages.

In practice, which of those disadvantages you are willing to accept in
trade for which of those advantages should depend on the context, which
includes the problems you're trying to solve, the problems you might
be trying to solve in the future, the support structure that is available,
the local culture, your own experience and taste, and so on.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Peter Ludemann
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <wuju3kovv83.fsf@wistaria.i-have-a-misconfigured-system-so-shoot-me>
···@research.att.com (Andrew Koenig) writes:

> In article <··········@lyra.csx.cam.ac.uk> Tony Finch <····@lspace.org> writes:
> 
> > In the tree example that you started with, what is wrong with just
> > passing round the whole subtree so that it can be compared with as
> > necessary? Any reasonable implementation will only be passing round a
> > pointer so you lose nothing.
> 
> Because it will compare equal with any other subtree that happens to
> have the same structure, which is not what I want.

But in that case, they are not the *same* subtree; they are different
in some way that you haven't bothered to specify.

Unless, that is, you intend to modify the subtree.  In my experience,
that is almost never a good thing; the potential confusion of updating
a complex structure in-place seldom is worth the small speed-up (some
years ago I talked with the people who built an optimizing compiler
with all kinds of live-dead analysis, reordering of statements, and
register coloring; and that was their opinion also).

-- 
Peter Ludemann		+1.415.813.6806  (fax: +1.415.813.7499)
Software Architect	········@inxight.com
InXight Software, Inc.	http://www.inxight.com
PAHV 105, 3400 Hillview Ave., Palo Alto, CA 94304 
From: Andrew Koenig
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <E9Iu44.AxE@research.att.com>
In article <···············@wistaria.i-have-a-misconfigured-system-so-shoot-me> Peter Ludemann <········@inxight.com> writes:

> > In article <··········@lyra.csx.cam.ac.uk> Tony Finch <····@lspace.org> writes:

> > Because it will compare equal with any other subtree that happens to
> > have the same structure, which is not what I want.

> But in that case, they are not the *same* subtree; they are different
> in some way that you haven't bothered to specify.

Exactly.  They are two different objects with the same value.

Whether or not that is an easy concept to live with seems to depend
on the local culture.

Which is the main point I was trying to make.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: Peter Ludemann
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <wujyb9txqjd.fsf@wistaria.i-have-a-misconfigured-system-so-shoot-me>
···@research.att.com (Andrew Koenig) writes:

> Exactly.  They are two different objects with the same value.
> 
> Whether or not that is an easy concept to live with seems to depend
> on the local culture.
> 
> Which is the main point I was trying to make.

And your point is...?

As I don't belong to your local culture, such beliefs are irrelevant
to our discussion, which is a bit more about Truth & Beauty rather
than local culture or lack thereof.

There are "local cultures" where anything not mentioned in the Bible
is disallowed (e.g., electricity and motor cars); other "local
cultures" believe that discrimination based on skin color is good.
These beliefs are irrelevant to any discussion about the merits of
electricity and racial discrimination.

So ...

If there are two different objects with the same value there must be
some reason for that.  Otherwise it is easy to become confused and
update the wrong object (there's no way to tell them apart ... they
look the same).  A particularly nasty version of this is when the
compiler quietly creates a copy of a parameter during a function call.
[Not that updating-in-place is a good idea, if it can be avoided.  But
that's a separate issue, which other people are happily discussing
very well without my help or hindrance.]

It seems that you live in a culture that thinks two different objects
with exactly the same value are OK.  So, please tell my *why* you
think this is a good thing.  After all, the people who live without
electricity have their reasons ... but I have not yet heard your
reasons for not wanting what my experience has taught me is a
wonderful thing: referential transparency.

-- 
Peter Ludemann		+1.415.813.6806  (fax: +1.415.813.7499)
Software Architect	········@inxight.com
InXight Software, Inc.	http://www.inxight.com
PAHV 105, 3400 Hillview Ave., Palo Alto, CA 94304 
From: Cliff Hall
Subject: Re: Object IDs are bad (was: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <336F3BEA.ABD@tricon.net>
Peter Ludemann wrote:
> 
> ···@research.att.com (Andrew Koenig) writes:
> 
> > Exactly.  They are two different objects with the same value.
> >
> > Whether or not that is an easy concept to live with seems to depend
> > on the local culture.
> >
> > Which is the main point I was trying to make.
> 
> And your point is...?
> 
> ...snip...
> It seems that you live in a culture that thinks two different objects
> with exactly the same value are OK.  So, please tell my *why* you
> think this is a good thing.  After all, the people who live without
> electricity have their reasons ... but I have not yet heard your
> reasons for not wanting what my experience has taught me is a
> wonderful thing: referential transparency.


hmmm, perhaps referential opaqueness is the one true path to becoming
one with $_
From: Chris Bitmead uid(x22068)
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <s6y67xdm9dt.fsf@aalh02.alcatel.com.au>
···@research.att.com (Andrew Koenig) writes:

> In article <·············@nospam.acm.org> Thant Tessman <·····@nospam.acm.org> writes:
> 
> > And I recommend folks learn *any* language that supports higher-order 
> > functions, automatic memory management, and incremental compilation
> > to see how truly wretched C++ is, regardless of whatever claims 
> > Stroustrup makes for it.
> 
> I learned Standard ML, which has all three of these properties,
> several years ago, and I can say with confidence that from where
> I sit, C++ is not wretched by comparison -- just different.
> Each language has its strengths and weaknesses.

><snip goes on to explain a particular problem with the ML language>

I can't speak for ML since I've never used it. The problem you
describe with ML has nothing whatsoever to do with automatic memory
management, higher order functions or incrememental compilation. I
think Thant's comment still stands. The problem you describe with ML
does not exist in the Lisp languages for example.

Yes C++ is wretched. I too was an early adopter of C++. I really liked
it at the time. I thought it was the bees-knees. Now having worked on
lots of major projects using it, I know that C++ has set back
commercial software development practice by at least a decade, maybe
more.

> Incidentally, this whole discussion talks only about language.  In deciding
> what programming tools to use, there is more than that to consider.  After
> all, if all you care about is how easy the language is for you to use, why not
> just invent your own language?  You won't have a compiler for it unless you
> write one, but if ease of programming is all you care about, that doesn't
> matter.  Of course, this facetious remark is intended to illustrate that
> having a compiler that works well in your context matters too.  But even that
> is not all that matters.  There is also the question of what tools your colleagues
> use, and what tools the people might be using who will be maintaining your
> code, and what machines you might be called on to support in the future.

I'd swap every "tool" and code generator and visual do-dad in the
world for a good language any day of the week. I'd rather do a project
in basic Lisp than C++ with every imaginable tool, class library and
visual whatever in the world. C++ is simply not productive, end of
story.
 
> C++ built on C precisely so that it would appeal to the existing C community.
> As a result, support tools, a body of knowledge, and a community came along
> more readily than they would have if the language had been designed totally
> from scratch.  

Yes, the community came along readily. It's a tradgedy isn't it?

> And that knowledge and community, and those tools, are among
> the main reasons why C++ is now in widespread commercial use and so many
> of the designed-from-scratch languages are not.
From: Jon S Anthony
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <JSA.97Apr24204757@alexandria>
In article <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

> C++ built on C precisely so that it would appeal to the existing C community.
> As a result, support tools, a body of knowledge, and a community came along
> more readily than they would have if the language had been designed totally
> from scratch.  And that knowledge and community, and those tools, are among
> the main reasons why C++ is now in widespread commercial use and so many
> of the designed-from-scratch languages are not.

I would go further and say this is pretty much the _only_ reason why
C++ has such widespread use.  But, in the current context, this is
really just the same tired old claim that "C++ is better than X,
because C++ is more popular than X".  A claim that was always dubious
and which has certainly long since lost any plausibility that it might
have ever had.

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
···@organon.com
From: Andrew Koenig
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <E9734v.BFF@research.att.com>
In article <·················@alexandria> ···@alexandria (Jon S Anthony) writes:
> In article <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

> > C++ built on C precisely so that it would appeal to the existing C community.
> > As a result, support tools, a body of knowledge, and a community came along
> > more readily than they would have if the language had been designed totally
> > from scratch.  And that knowledge and community, and those tools, are among
> > the main reasons why C++ is now in widespread commercial use and so many
> > of the designed-from-scratch languages are not.

> I would go further and say this is pretty much the _only_ reason why
> C++ has such widespread use.  But, in the current context, this is
> really just the same tired old claim that "C++ is better than X,
> because C++ is more popular than X".  A claim that was always dubious
> and which has certainly long since lost any plausibility that it might
> have ever had.

Not at all.  Rather, it is a claim that programming is a human phenomenon,
and there can be a huge difference between how useful a tool -- especially
a language -- is in theory and how useful it is in practice.

Several years ago, I was on vacation in Norway and overheard a conversation
in a hotel between an English woman and a member of the hotel staff.  It
went something like this:

	`I've come here for a week every year for many years,
	 but I've never been able to learn Norwegian.  I'm terribly
	 sorry about that.'

	`Don't be sorry.  If you learned Norwegian, who would you
	 speak it to when you were outside Norway?  There are only
	 about five million speakers of Norwegian in the world.
	 We know that if we don't want to isolate ourselves, we have
	 to learn English.'

Now, English is a mess of a language.  Its spelling rules are atrocious,
its grammar is unruly, it has far too many ways to say the same thing,
and even so, it is hard to talk about people without revealing information
about them, such as their gender, that may be irrelevant.

I have no doubt that speakers of many languages consider their languages
to be superior to English.  They may even be right.  But for many people,
especially those who live in or near English-speaking communities,
English is more useful.

So it is also with programming languages.  If C++ had not built on C, it
would never have gotten out of the starting gate.  So it had no choice
but to inherit its computational model from C.  Many people consider other
computational models better, but there is far from a consensus as to
which one to use.  So the C model, which C++ uses, remains the common tongue.

This is a behaviorial observation, not a value judgement.
-- 
				--Andrew Koenig
				  ···@research.att.com
				  http://www.research.att.com/info/ark
From: ········@wat.hookup.net
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <5jqsfc$8s7$1@nic.wat.hookup.net>
In <··········@research.att.com>, ···@research.att.com (Andrew Koenig) writes:
> ...
>Now, English is a mess of a language.  Its spelling rules are atrocious,
>its grammar is unruly, it has far too many ways to say the same thing,
>and even so, it is hard to talk about people without revealing information
>about them, such as their gender, that may be irrelevant.
>
>I have no doubt that speakers of many languages consider their languages
>to be superior to English.  They may even be right.  But for many people,
>especially those who live in or near English-speaking communities,
>English is more useful.
>
>So it is also with programming languages.  If C++ had not built on C, it
>would never have gotten out of the starting gate.  So it had no choice
>but to inherit its computational model from C.  Many people consider other
>computational models better, but there is far from a consensus as to
>which one to use.  So the C model, which C++ uses, remains the common tongue.
>
>This is a behaviorial observation, not a value judgement.
>-- 
>				--Andrew Koenig
>				  ···@research.att.com
>				  http://www.research.att.com/info/ark

Also, C++ came out before the ANSI C standard, and the non OO part of C++
was such an improvement over C that it heavily influenced the standard.

Another thing about language popularity:  it must be available at a time
where suitable hardware is available.  For all practical purposes, C was a
big improvement over Basic and Pascal, and I languages like Lisp were
always too resource hungry to run on PDP 11s.  Once thr hardware became
suitable for Lisp systems, C/C++ had a big advantage in popularity.

Hartmann Schaffer
From: Richard A. O'Keefe
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <5k42sq$1c$1@goanna.cs.rmit.EDU.AU>
········@wat.hookup.net writes:
>big improvement over Basic and Pascal, and I languages like Lisp were
>always too resource hungry to run on PDP 11s.

When I was a student at Edinburgh we had a Pop-2 system (think "Lisp data
structures (before Lisp had them) with Pascalish syntax") running quite
happily on a PDP-11.  It was *less* resource hungry than the C compiler.

Lisp has been used quite successfully on 16-bit machines.
-- 
Will maintain COBOL for money.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
From: Jon S Anthony
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <JSA.97Apr25193032@alexandria>
In article <··········@research.att.com> ···@research.att.com (Andrew Koenig) writes:

> > I would go further and say this is pretty much the _only_ reason why
> > C++ has such widespread use.  But, in the current context, this is
> > really just the same tired old claim that "C++ is better than X,
> > because C++ is more popular than X".  A claim that was always dubious
> > and which has certainly long since lost any plausibility that it might
> > have ever had.
> 
> Not at all.  Rather, it is a claim that programming is a human phenomenon,
> and there can be a huge difference between how useful a tool -- especially
> a language -- is in theory and how useful it is in practice.

Well, OK, but that is exactly tied up in the "chicken/egg" problem of
"popularity".  So, under the interpretation you give here, I don't see
how you can say much of anything wrt the issue under the current
context - i.e., what is "technically better or more correct or more
efficacious or etc."

> Several years ago, I was on vacation in Norway and overheard a conversation
> in a hotel between an English woman and a member of the hotel staff.  It
> went something like this:

This little story sez a lot more about interoperability requirements
of "less popular" things than it does about what is or isn't popular
or whether that popularity is deserved or anything of the sort.  I
don't think anyone would really disagree with any of this, it's just
irrelevant here.

> Now, English is a mess of a language.  Its spelling rules are atrocious,
> its grammar is unruly, it has far too many ways to say the same thing,

Well, actually, I very much disagree with this assesment.  It's based
on a set of irrelevant criteria.  It is a well known fallacy
attempting to draw conclusions about the "correctness/goodness" of
natural languages by comparing them with "formal languages" - or to
even try to judge natural languages with any of the criteria normally
used for formal languages.  So, this little bit is really off target.


> So it is also with programming languages.  If C++ had not built on C, it
> would never have gotten out of the starting gate.

Here, we are in definite agreement.

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
···@organon.com
From: Chris Bitmead uid(x22068)
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <s6yohb0m0xe.fsf@aalh02.alcatel.com.au>
···@research.att.com (Andrew Koenig) writes:

> So it is also with programming languages.  If C++ had not built on C, it
> would never have gotten out of the starting gate.  So it had no choice
> but to inherit its computational model from C.  Many people consider other
> computational models better, but there is far from a consensus as to
> which one to use.  So the C model, which C++ uses, remains the common tongue.
> 
> This is a behaviorial observation, not a value judgement.

It is a correct observation, but by the same token I think it is a
big-time myth that computer programmers are too slow to learn new
languages, or that it is uneconomic to teach a new language rather
than plough ahead with what you already know.
From: Karl Lehenbauer
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <335DD2D4.167EB0E7@NeoSoft.com>
Bjarne Stroustrup wrote:

>         The furthest I go is to claim that unless C++ had at least some
>         of the virtues I claim for it, it would have died during the
>         early years where there were essentially no C++ marketing and
>         alternatives languages with marketing dollars behind them existed.

Hear, hear!

Likewise corporate backing of Tcl is a very recent thing.  For a long
time it was just a few enthusiasts with a mailing list and then later a
few thousand enthusiasts with a newsgroup.  Getting your company to use
Tcl was as hard a fight as getting most companies to try any other new
thing.

I think it's interesting that where one LISP guy's list of essentials
were "full dynamism, introspection, procedural macros, lexically-scoped
closures and generic functions and no static typing", mine, when I was
looking for a scripting language back in 1988, were that it be
embeddable, interpreted, have a reasonably small footprint, be good with
text, and be easy to plug C code into.

LISP had a 25 year headstart and a hell of lot more funding.  Tcl's
competition, in terms of what languages people use instead of Tcl to do
the sorts of things that people do in Tcl, has mainly been PERL, IMHO,
with a bit of ksh, awk, Python, etc., as well.

This has not stopped the periodic trolling through comp.lang.tcl by LISP
and Scheme weenies trying to pick a fight.

I think Tcl is popular because a lot of programmers found that scripting
languages were powerful and useful additions to applications, and that
Tcl was free and pretty easy to pick up and plug into an app.

So anyone who wants to say Tcl's marketing is what has made it
successful, well, old timers just have to laugh.  And these threads seem
be an argument between the theorists who love LISP and the pragmatists
who have an app and a deadline and want to find something that works and
use it and ship the thing and move on to the next project.

I can guess how the scathing rebuttal will go...  "It's precisely the
crap foisted on everyone by the pragmatists that we LISP weenies are
trying to fix.  But look at these two dead company's most excellent LISP
machines.  Etc."

The "battle" is a battle for mindshare.  That battle is fought one
mind... one program... at a time.  So we Tcl weenies just keep on
chooglin'.  If you're a committed bike rider and you turn into a strong
headwind, you don't get mad, you just downshift, put your head down, and
pedal.  And before too long, you've ridden pretty far.  You want LISP's
influence to increase, you're not going to get people to do it your way
by flaming them.  You've gotta remove obstacles to its use, pump out
tools and apps, help people who run into problems, and push out the
examples and games and clever little hacks that pique peoples'
curiosity.  You gotta sell it to the people who would use it.  And make
sure it really is as general purpose as you say... Like rewrite some
shell scripts in it.  But a lot it seems like the attitude of the LISP
camp toward workaday programmers ranges from condecension to derision to
outright contempt.  You want LISP to do better? Lose the attitude, and
make sure you have a good, free implementation that runs real well on
Windows 95.
From: Kelly Murray
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <5jlmam$r2a$1@sparky.franz.com>
> The "battle" is a battle for mindshare.  That battle is fought one
> mind... one program... at a time.  So we Tcl weenies just keep on
> chooglin'.  If you're a committed bike rider and you turn into a strong
> headwind, you don't get mad, you just downshift, put your head down, and
> pedal.  And before too long, you've ridden pretty far.  You want LISP's
> influence to increase, you're not going to get people to do it your way
> by flaming them.  You've gotta remove obstacles to its use, pump out
> tools and apps, help people who run into problems, and push out the
> examples and games and clever little hacks that pique peoples'
> curiosity.  You gotta sell it to the people who would use it.  And make
> sure it really is as general purpose as you say... Like rewrite some
> shell scripts in it.  But a lot it seems like the attitude of the LISP
> camp toward workaday programmers ranges from condecension to derision to
> outright contempt.  You want LISP to do better? Lose the attitude, and
> make sure you have a good, free implementation that runs real well on
> Windows 95.

I absolutely agree.
This "MIT" attitude has continued to linger.
But if I have my way, those days are OVER.   

The view that Lisp must be an order of magnitude better to win, 
ends up with making it be an order of magnitude more complex, 
and those who don't need nor understand this complexity are viewed as
"not worthy" --- is it any wonder why Lisp won't be widely used?

If one reads my first CLOS column in JOOP, it is titled,
"Invitation to CLOS", where I invite everyone to join the party,
not make it the exclusive club with secret parenthesized handshakes,
which has been its history.

I'll make this concrete:
  
I propose a new dialect which has a simplified syntax, that makes it accessible,
but without losing it's power, by adding a few simple keywords
to replace parenthesis.  It isn't (foo 1 2) vs foo(1,2) that's the barrier
or problem, it is having this:

  (let ((x 10) (y 20))
    (do ((i 0 (+ i 1)))
        ((> i 10) x)
     (cond ((> x y) 10) 
           ((< x 0) 20))))
           
When it is much clearer and accessible if it is written like this:

 (let x = 10
      y = 20
    do
    (loop for i from 1 to 10
      do
      (if (> x y)
        then 
          10
       elseif (< x 0)
        then 
          20
        else
         nil)

And has no less power than the more parenthesized version: 
The functional view is just the same, and macros are no less powerful.
        
-Kelly Murray  (speaking for myself) 

      
      
     






 
From: Henry Baker
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <hbaker-2304971253180001@10.0.2.1>
In article <············@sparky.franz.com>, ···@franz.com wrote:

> When it is much clearer and accessible if it is written like this:
> 
>  (let x = 10
>       y = 20
>     do
>     (loop for i from 1 to 10
>       do
>       (if (> x y)
>         then 
>           10
>        elseif (< x 0)
>         then 
>           20
>         else
>          nil)
> 
> And has no less power than the more parenthesized version: 
> The functional view is just the same, and macros are no less powerful.

Do this on your own time if you wish (that's the whole point of Lisp,
isn't it?), but please don't waste anyone's time standardizing this.  The
'standard' Lisp should be somewhat smaller than Scheme, with the basic
engine defined.  _Everything_ else should be libraries, packages, etc.
The various libraries and packages can be separately standardized, if you
want, but don't bog down the basic engine with this stuff.
From: tomlinson
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <5jlqar$2kd$1@hole.sdsu.edu>
Kelly Murray (···@franz.com) wrote:

<snip>

:   (let ((x 10) (y 20))
:     (do ((i 0 (+ i 1)))
:         ((> i 10) x)
:      (cond ((> x y) 10) 
:            ((< x 0) 20))))

: When it is much clearer and accessible if it is written like this:

:  (let x = 10
:       y = 20
:     do
:     (loop for i from 1 to 10
:       do
:       (if (> x y)
:         then 
:           10
:        elseif (< x 0)
:         then 
:           20
:         else
:          nil)

I think that I just might be in my "Lisp mindset"--a mindset
necessitated by a class in AI which I am taking at the moment,
which requires that I write large amounts of Lisp code every
week.[1]  In any case, _at this particular moment in time_, the
top version, with all the nasty parentheses, I find easier
to read and more understandable than the bottom version, with
all these silly, unnecessary little words everywhere, that
take up valuable keystrokes and lines.  Anyway.  After the
class is over and I'm back to C and C++ all the time, Version
B will begin to look better than Version A.

Cheers,
-et

[1]  Aside:  as an experiment I tried rewriting one of my Lisp
examples into Java, just to see how long it would take.  It took
perhaps twice as long--not so good as Lisp with respect to
speed of coding, but pretty good.
--
Ernest S. Tomlinson     | "For every Government consists of mere men and is, 
········@rohan.sdsu.edu | strictly viewed, a makeshift; if it adds to its 
------------------------+ commands 'Thus saith the Lord', it lies, and lies
                          dangerously."  - C. S. Lewis 
From: Erik Naggum
Subject: New and Improved Lisp Syntax (was: Re: Ousterhout and Tcl lost the plot with latest paper)
Date: 
Message-ID: <3070821916847636_-_@naggum.no>
[relieved comp.lang.tcl, comp.lang.functional, comp.lang.c++,
comp.lang.perl.misc, comp.lang.python, comp.lang.eiffel]

* Kelly Murray
| I propose a new dialect which has a simplified syntax, that makes it
| accessible, but without losing it's power, by adding a few simple
| keywords to replace parenthesis.  It isn't (foo 1 2) vs foo(1,2) that's
| the barrier or problem, it is having this:
| 
|   (let ((x 10) (y 20))
|     (do ((i 0 (+ i 1)))
|         ((> i 10) x)
|      (cond ((> x y) 10) 
|            ((< x 0) 20))))
|            
| When it is much clearer and accessible if it is written like this:

[ ugh! ]

| And has no less power than the more parenthesized version: 
| The functional view is just the same, and macros are no less powerful.

I don't think that "noise words" is the way to go.  I do think the problem
illustrated in the first version is legitimate, however.  only _slightly_
more syntax would have helped.  here's a shot:

    (let [x 10]
	 [y 20]
      (do [i 0 (1+ i)]
        (until (> i 10)
          (cond [(> x y) 10]
	        [(< x 0) 20]))
        x))

note that the "[]-thingies" mix and repeat (unambiguously) with function
calls in the body of the forms.  I think the `until' form should have a
parallell in `while', and both could of course be on their own as ordinary
conditional loops.  inside a `do', however, they would behave differently
in that the looping would involve the step-forms of the `do'.  I have never
been comfortable with the ability to include return-forms just after the
test, so I moved that after the looping construct.

the "[]-thingies" could be read as vectors, for instance.  the principle in
whether something that is enclosed in parentheses today should be in
parentheses or in brackets in this new syntax would be that parentheses be
used for forms, that is, whose first element indicate evaluation, while
brackets be used for lists that are not to be evaluated, but aid the
evaluation of the enclosing form.  the main argument for this syntax is
that (x ...) could be recognized context-freely as a _form_ and easily
differentiated from binding and constituent s-expressions.

the obvious downside of this syntax is that it would require knowledge of
the special form in which the brackets occur to be parsed correctly into
the standard Common Lisp forms.  a compiler would not have this problem.
(note that the backquote reader accepts vectors just like lists.)

hm.  now that I look at this idea that I just got while composing this
response to Kelly, I think it's good enough that I'll write a specification
and a reader for this language over the weekend.  very few forms in Common
Lisp are actually affected by it, but the extra clarity may be worth taking
a serious look at.  (yeah, so I called it NILS, sue me.)

#\Erik
-- 
if we work really hard, will obsolescence be farther ahead or closer?
From: Kelly Murray
Subject: Re: New and Improved Lisp Syntax
Date: 
Message-ID: <5jmdip$mek$1@sparky.franz.com>
>    (let [x 10]
>	 [y 20]
>      (do [i 0 (1+ i)]
>        (until (> i 10)
>          (cond [(> x y) 10]
>	        [(< x 0) 20]))
>        x))

I don't see this as any different or "better" than using parenthesis, 
it's still very different than what most C/JAVA/BASIC/et al programmers are used to.
Using all parenthesis reads as lists, which makes macros work as expected.

It may interest you to know I've written a lot of code using my proposed syntax,
and have been very happy and prefer it greatly.

You ready for more? 

Balanced single quotes:  'foo'  instead of 'foo  
      'foo' => (quote foo)
I'll go even further:  'foo bar'  => '(foo bar)  => (quote (foo bar))

after using balanced quotes, I'm disturbed seeing unbalanced ones.

I propose the use of [] brackets, but for argument lists specifications.
The old CL &stuff would still be supported so macros can generate them. 

 OldSyntax         NewSyntax

 (a &optional b)      (a [b])
 (a &optional (b 10)) (a [b 10])      ;; some suggest   (a [b = 10])  is better
 (a &key c d)         (a [:c] [:d])
 (a &rest r)          (a [r]*)
 
The use of [] for optional arguments is commonly used in documentation
and specifications.

I also propose massive simplification of argument lists from Common Lisp.
rest,optional and keywords args are great, the full spec is crazy.
Scheme went overboard and threw out too much.

** In particular I note that there is a trivial mapping to Lisp functions
** from HTTP URL GET syntax, e.g.  foo?required+optional+&key1=val+&key=val2

I would eliminate &aux, special bindings, 
serial binding semantics, supplied-p parameters, alternative keywords,
:allow-other-keys, &allow-other-keys, multiple keyword values.

  ** did you realize that any Common Lisp function which takes keywords
  ** must accept an arbitrarily number of arguments? 
  ** since 1. AT RUNTIME, it can be passed a NON-NIL keyword argument
  ** of :allow-other-keys and the function must accept random keywords arguments?  
  ** and 2. you can pass multiple keyword args, e.g. (foo  :key1 10 :key1 20)  
  ** and only the last value is used
  ** 
  ** and that a parameter can be defined as *special*, and then this special
  ** variable referenced deep within a function that is computing the value
  ** for an unsupplied optional or keyword argument?  

-Kelly Murray  
  
From: Andrew P. Mullhaupt
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <335EEA76.5433@ix.netcom.com>
Kelly Murray wrote:
> 
> I propose a new dialect which has a simplified syntax, that makes it accessible,
> but without losing it's power, by adding a few simple keywords
> to replace parenthesis.

Readers in comp.lang.python who are subjected to this relentlessly
Lisp-ish thread via crossposting will no doubt rejoice that at least
someone, somewhere, wants to get rid of some parentheses....

Later,
Andrew "We don't need no steenkin' Dyck languages" Mullhaupt
From: Paul Wilson
Subject: Chomsky, Languages, etc. (was Re: Ousterhout and Tcl...)
Date: 
Message-ID: <5k40pm$pho@roar.cs.utexas.edu>
NOTE: followups have been redirected to comp.lang.misc

In article <·······································@shellx.best.com>,
Brian Rogoff  <···@best.com> wrote:
>On Fri, 18 Apr 1997, James Logajan wrote:
>> 
>> NOTE TO LISP AND FORTH FANS: one important reason your languages
>> have never caught on may be due to the fact that many natural languages
>> follow the "subject verb object" form. Usage of SOV, OSV, VSO, and VOS
>> are less likely (I don't have any references in front of me; if anybody
>> wants details, I'll try to locate what I have). They also lack visual
>> redundancy (they aren't alone in this short-coming of course).

(I think this has been answered adequately in other postings.)

>Best quote on this topic I've read lately
>
>	The use of the Chomsky formalism is also responsible for the term 
>	"programming language", because programming languages seemed to
>	exhibit a strucure similar to spoken languages. We believe that
>	this term is rather unfortunate on the whole, because a programming 
>	language is not spoken, and therefore is not a language in the true
>	sense of the word. Formalism or formal notation would have been
>	more appropriate terms. 
>
>	Niklaus Wirth
>
>In Wirth's opinion, and the opinion of many reputable linguists like
>Steven Pinker, the analogy betweem formal notations :-) and human
>languages is bogus. "Spoken" is the key point to consider.

I'd have to disagree somewhat with Wirth and Pinker.  There are
big differences between programming languages and natural languages,
but there's also a basic similarity.  It shouldn't be overstressed,
but it shouldn't be overlooked, either.

If they're going to disagree with this, they have to go back and
disagree with Chomsky, who defined the Chomsky hierarchy that forms
the basis for most programming language syntax---but which was designed 
for natural linguistics.  The Chomsky hierarchy is based on fundamental
constraints on processing of streams of tokens.  He thought there
were interesting relationships between the formal categories and
the syntax "faculty" we're born with.

Very roughly, his language hierarchy is:
   regular < context-free < context-sensitive < transformational,
 where these things correspond to the complexity of machines
 required to recognize all of the languages within a category:
   finite state machine < FSA with a stack <
   linear-bounded automata < pretty-much-a-Turing-machine
(Corrections welcome. I'm not a formal syntax guy.)

There are many people who think that the Chomsky framework is too
simplistic for natural languages, but much better suited to programming
languages because we can intentionally engineer PL's to be parsable
both by humans and by well-understood automata.

(I'd be surprised if Pinker said that the analogy between human
language and formal notations is *entirely* bogus.  He's a big
Chomsky fan.  Chomsky is very much into the "autonomy of syntax",
and believes that syntax recognition is something different from
real semantic recognition, even though they're clearly correlated
because it's very useful.  I wouldn't be too surprised if Pinker said
that there's more going on than *just* the simple formal syntactic 
properties.)

Personally,  I think the CS community screwed up bigtime when it
decided that context-free grammars were the _sine_qua_non_ of programming
language syntax.  Chomsky laid out nice hierarchy and explained
why context-sensitive and transformational grammars are far more
interesting than regular expressions and context-free grammars.

Unfortunately computer scientists decided in the 60's that 
context-sensitive and transformational grammars were Too Hard,
and focused on the easy stuff---context free grammars.  What
they generally failed to recognize was that there are SOME
context-sensitive and transformational grammars that are
quite easy to parse.  They didn't understand what Lisp was
about. They thought that Lisp's s-expression surface syntax
was trivial, and that its macro system was "just a hack."  They 
were wrong.  They didn't recognize that the constraints on Lisp
surface syntax made it really easy to rise above context-free grammars
and do interesting and sane context-sensitive and transformational
things.  (Lately a lot of people have been doing transformational
programming in languages that are much more awkward for that
purpose---that's one of the main things Lisp and Scheme were
designed for.  I've seen Lisp macros reinvented several times---sometimes
knowingly, sometimes unknowingly---in different languages.  Unfortunately,
I've only seen Scheme macros reinvented once or twice. :-)

Now that things have been "cleaned up" a bit with Scheme macros, maybe 
language theorists will realize that what's going on is both deep and
elegant, and re-examine some fundamental assumptions about syntax made
in the 1960's.  For example, Scheme macros can easily encode
context-sensitivites, because they're lexically scoped---you can have
a macro that introduces a local macro, changing the grammar of the language
within a local scope.  Many kinds of so-called "static semantics"
processing fall out of this framework for free, because they're really
just syntactic properties, and fundamentally scoped.  You've just got to
have a parser that understands lexical scope.

(After all, lexical scope was designed precisely so that scope would
correspond unambiguously to an easily detectable syntactic property.  It's
time parsers got the hang of it making "troublesome" context-sensitivities
like Pascal's define-before-use and C's typedefs into trivialities.)

Some of this stuff has already been transferred to a more conventional
LL(1) grammar framework by Cardelli, Abadi, and Matthes at DEC SRC, and
is actually available in Matthes et al.'s Tycoon database programming
language.  (Cardelli, Abadi, and Matthes have a tech report available
from the DEC SRC TR server, but the notation is a bit thick for 
people who don't know lambda calculus.  Too bad, because it's basically
a simple idea.)  Going LL(1)-ish loses a little of the expressiveness
of Scheme macros, but makes it much easier to make a language look
"familiar".  So maybe the non-Lisp world will start to notice.

-- 
| Paul R. Wilson, Comp. Sci. Dept., U of Texas @ Austin (······@cs.utexas.edu)
| Papers on memory allocators, garbage collection, memory hierarchies,
| persistence and  Scheme interpreters and compilers available via ftp from 
| ftp.cs.utexas.edu, in pub/garbage (or http://www.cs.utexas.edu/users/wilson/)      
From: Peter Ludemann
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <wuj20822627.fsf@wistaria.i-have-a-misconfigured-system-so-shoot-me>
······@netcom.com (James Logajan) writes:

> NOTE TO LISP AND FORTH FANS: one important reason your languages
> have never caught on may be due to the fact that many natural languages
> follow the "subject verb object" form. Usage of SOV, OSV, VSO, and VOS
> are less likely 
[snip]

So, FORTH should be extremely popular in Japan, because Japanese is
very much SOV.

And your theory doesn't account for the popularity of the WIMP
interface, which is basically OV (select object, select action).

(A nice theory shot down by dirty facts.)

-- 
Peter Ludemann		+1.415.813.6806  (fax: +1.415.813.7499)
Software Architect	········@inxight.com
InXight Software, Inc.	http://www.inxight.com
PAHV 105, 3400 Hillview Ave., Palo Alto, CA 94304 
From: David Combs
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <dkcombsE94Jx6.q4@netcom.com>
> TO LISP AND FORTH FANS: one important reason your languages
> have never caught on may be due to the fact that many natural languages
> follow the "subject verb object" form. Usage of SOV, OSV, VSO, and VOS
> are less likely ...

Spanish, I believe, often uses VSO and VOS, even.
From: Richard Cobbe
Subject: Re: Ousterhout and Tcl lost the plot with latest paper
Date: 
Message-ID: <5jvngj$ckr$1@joe.rice.edu>
James Logajan (······@netcom.com) wrote:

> NOTE TO LISP AND FORTH FANS: one important reason your languages
> have never caught on may be due to the fact that many natural languages
> follow the "subject verb object" form. Usage of SOV, OSV, VSO, and VOS
> are less likely (I don't have any references in front of me; if anybody
> wants details, I'll try to locate what I have). They also lack visual
> redundancy (they aren't alone in this short-coming of course).

Nice theory, but it fails to explain a lot.

A) It might interest you to hear that "The three most comon word
orders (in descending order of frequency) are SOV, SVO, and VSO."
(O'Grady, Dobrovolsky, and Aronoff, Contemporary Linguistics: An
Introduction, 2nd ed, p 316) So: languages like Turkish, Latin, and
several others which use SOV are in fact MORE common than English,
which uses SVO.  Plus, there are other languages which use Vxx orders:
Malagasy (VOS), Irish and Hebrew (VSO), and so forth.

B) It's really sort of irrelevant, anyway.  Let's take a programming
language with "more traditional", Algol-based syntax, like C or
Pascal.  Here, you essentially have 2 basic constructions: applying a
function to arguments, and applying binary or unary operators (leaving
C's ?: out for the moment).  Applying a function to arguments seems to
me to be VO, with an understood subject -- this isn't normal English
word order.  (Procedures work the same way.)  Unary ops are also VO.
Binary ops seem to be OVO, *maybe* SVO in cases like i = 4 or
something like that.

So, when you move to a functional language, you shift emphasis away
from the only PL construct I can think of that's SVO, and just make
everything VO for consistency's sake.  Since both the Lisp and Algol
families are both VO (or slight derivatives) anyway, I'm afraid your
argument doesn't hold water.

I'm still a student, though, so I'm somewhat limited in the number of
PL's I know.  It might be interesting to compare some other languages
which *aren't* descendents of Lisp or Algol.

Richard