From: Doug Morgan
Subject: Re: Why Commit to Eiffel?
Date: 
Message-ID: <DOUG.94Sep6154321@monet.ads.com>
In article <··········@disuns2.epfl.ch> ········@di.epfl.ch (Fernando Mato Mira) writes:
   ...
   CLOS (Common Lisp):
     Reasons:
       ...1-17...
     Cons:
       1. Lightweight processes not standard (but almost identical across 
	  implementations). More seriously, not generally implemented as
	  Unix threads (want to push POSIX with me?).
       2. Highly optimized lisp code might be "only" 0.9X as fast as C
	  (yes, that _is_ 0.9, check your vendor, though). 
       3. Areas of optimization varies among implementations ("Know
	  thy compiler").
       4. You have to avoid highly expressive constructs sometimes ("Hey,
	  but can't you recode that thing in your critical path
	  as a simple function instead of a generic one with a user-defined
	  method combination?").
       5. Might have to pay/buyout run-time fees (but they are usually negotiable).
       6. Oh, yeah, "all those parenthesis" (hey, have you heard about Emacs?
	  What about some syntactic sugar with macros? (but you _really_ need it?)
	  There's even an "infix.lisp" PD read-macro package, for real paren-haters).

I like Lisp, but this list seems to be make light of real problems
with the Common Lisp standard (e.g., "Know thy compiler" can easily
become an unproductive full-time job.)  Here is a sampling of details
(possibly a few years out of date):

 7. No commercial shared library implementations. (How big is a
    hello-world Lisp process? How many run simultaneously on your
    computer and still start up in under a second?  I think some
    vendor's delivery techniques may have made some gains here, but
    don't know the details.)
 8. No standard interface with UNIX signals (and the ones that exist
    can be like pulling teeth).
 9. No free down-to-the-hardware full-up compilers.
10. No standard interface to non-Lisp languages.
11. No standard way (often no way) to link lisp into (not around) a C
    program.
12. Often no way to effectively debug foreign loaded C/C++
13. No standard way to access C structs (let alone C++ structs).
14. Extremely limited binary I/O and no standard extensions.
15. No static name overloading.  Wart-filled name selections and
    argument conventions haphazardly developed through 40 years of
    growth and merge.
16. The spec allows dynamic-extent (stack processing) to be ignored by
    the compiler.
17. The spec allows declared types and optimizations to be ignored by
    the compiler.  (Not even an implicit order of magnitude guarantee
    on execution speed.)
18. No standard way to find the declared type of a symbol.  (Also,
    can't macro expand a declare, must expand an entire construct.)
19. CLOS has no provisions for optimizing methods for special cases
    like
        O single argument dispatch
        O classes with no further (or with restricted) sub classes
        O I know the class is *exactly* such-and-such right here.
    (Calling upon meta-object protocol doesn't really count.)
20. It is often pain to interface a copying GC with C.  (A standard
    way of setting up some amount of space with non-copying GC or even
    manual heap management might help.)
21. Last time I looked, CLIM had no provisions for full control of
    color display lookup table hardware.  Hopefully, it has gotten
    better.
22. Built-in functions have no guarantees against cons'ing.
23. Maybe Dick Gabriel had a good point in saying that Lisp is "the
    right thing" but that the "worse-is-better" C++ approach is
    destined to win.  Of course, Lucid lost on both big-time, so maybe
    there is a grain of salt to be taken with his assessment.  Also,
    if the vendor-base isn't shrinking, it sure doesn't look like new
    Lisp vendors are brewing up like storm clouds before the downpour.

Doug
--------------------------------------------------------------------
Doug Morgan, ····@ads.com, (415) 960-7444
Advanced Decision Systems (a division of Booz-Allen & Hamilton Inc.)
1500 Plymouth St., Mountain View, CA 94043-1230
--------------------------------------------------------------------

From: Marco Antoniotti
Subject: Re: Why Commit to Eiffel?
Date: 
Message-ID: <MARCOXA.94Sep6203917@mosaic.nyu.edu>
In article <·················@monet.ads.com> ····@monet.ads.com (Doug Morgan) writes:

   From: ····@monet.ads.com (Doug Morgan)
   Newsgroups: comp.object,comp.lang.lisp
   Date: 6 Sep 94 15:43:21
   Organization: Advanced Decision Systems, Mountain View, CA 94043, +1 (415)
	   960-7300
   Xref: thecourier.cims.nyu.edu comp.object:8978 comp.lang.lisp:4135

   In article <··········@disuns2.epfl.ch> ········@di.epfl.ch (Fernando Mato Mira) writes:
      ...
      CLOS (Common Lisp):
	Reasons:
	  ...1-17...
	Cons:
	  1. Lightweight processes not standard (but almost identical across 
	     implementations). More seriously, not generally implemented as
	     Unix threads (want to push POSIX with me?).
	  2. Highly optimized lisp code might be "only" 0.9X as fast as C
	     (yes, that _is_ 0.9, check your vendor, though). 
	  3. Areas of optimization varies among implementations ("Know
	     thy compiler").
	  4. You have to avoid highly expressive constructs sometimes ("Hey,
	     but can't you recode that thing in your critical path
	     as a simple function instead of a generic one with a user-defined
	     method combination?").
	  5. Might have to pay/buyout run-time fees (but they are usually negotiable).
	  6. Oh, yeah, "all those parenthesis" (hey, have you heard about Emacs?
	     What about some syntactic sugar with macros? (but you _really_ need it?)
	     There's even an "infix.lisp" PD read-macro package, for real paren-haters).

   I like Lisp, but this list seems to be make light of real problems
   with the Common Lisp standard (e.g., "Know thy compiler" can easily
   become an unproductive full-time job.)  Here is a sampling of details
   (possibly a few years out of date):

    7. No commercial shared library implementations. (How big is a
       hello-world Lisp process? How many run simultaneously on your
       computer and still start up in under a second?  I think some
       vendor's delivery techniques may have made some gains here, but
       don't know the details.)

True. As far as I know only Franz/Allegro uses them. In the PD domain
there is WCL. Yet, most of the questions are better "unasked". You do
not dump a Lisp image to run "Hello World". You type '(print "Hello
World") at the listener. This is faster than writing the equivalent C
program, compiling it, and launching it.

    8. No standard interface with UNIX signals (and the ones that exist
       can be like pulling teeth).

True, but once again up to a certain point.

    9. No free down-to-the-hardware full-up compilers.

Bogus statement. Check CMUCL.

   10. No standard interface to non-Lisp languages.

True. Neither C nor C++ define a "standard interface" to non-Lisp
languages. C++ even makes it practically impossible to link in modules
produced by other compilers, by (almost) requiring different name
mangling schemes. Check the ARM under the 'extern "Borland C" ...' stuff.

   11. No standard way (often no way) to link lisp into (not around) a C
       program.

See above.

   12. Often no way to effectively debug foreign loaded C/C++
   13. No standard way to access C structs (let alone C++ structs).

The standard FFI problem.

   14. Extremely limited binary I/O and no standard extensions.

True. But the "lack of standard extensions" does not mean that each
implementation does not provides any form of it.

	...

   20. It is often pain to interface a copying GC with C.  (A standard
       way of setting up some amount of space with non-copying GC or even
       manual heap management might help.)

Stroustroup writes in the ARM: C programmers think that memory
allocation is too important to be left to the computer, Lisp
programmers think that memory allocation is too important to be left
to the programmer.

I get pretty soon tired of chasing pointers here and there.

   21. Last time I looked, CLIM had no provisions for full control of
       color display lookup table hardware.  Hopefully, it has gotten
       better.

Neither does Xlib in C.

   22. Built-in functions have no guarantees against cons'ing.

User defined functions in C have almost no guarantee against memory
leaks if the program uses pointers extensively (e.g. it uses strings).

   23. Maybe Dick Gabriel had a good point in saying that Lisp is "the
       right thing" but that the "worse-is-better" C++ approach is
       destined to win.  Of course, Lucid lost on both big-time, so maybe
       there is a grain of salt to be taken with his assessment.  Also,
       if the vendor-base isn't shrinking, it sure doesn't look like new
       Lisp vendors are brewing up like storm clouds before the
       downpour.

According to recent postings in comp.lang.lisp, Lucid lost *because*
of its C++ business, *not* because of the Lisp side.
Apart from this, starting up a Lisp company is not a very wise
investment today. But it might be the case that in not too long it
will make a lot of sense to develop Lisp applications for Computers
that have dropping hardware costs and rising memory sizes. After all
the speed of development with a good Lisp environment is still faster
than the typical development cycle with C/C++. Of course I do not have
data to support this statement. It is just hacker-lore. But how many
of the pro-C/Common-Lisp-bashing flames are not? :)

Happy Lisping
--
Marco Antoniotti - Resistente Umano
-------------------------------------------------------------------------------
Robotics Lab		| room: 1220 - tel. #: (212) 998 3370
Courant Institute NYU	| e-mail: ·······@cs.nyu.edu

...e` la semplicita` che e` difficile a farsi.
...it is simplicity that is difficult to make.
				Bertholdt Brecht
From: Doug Morgan
Subject: Re: Why Commit to Eiffel?
Date: 
Message-ID: <DOUG.94Sep9075752@monet.ads.com>
In article <············@wildcard.demon.co.uk> ············@wildcard.demon.co.uk (Cyber Surfer) writes:
>In article <·················@monet.ads.com>
>····@monet.ads.com "Doug Morgan" writes:
>...
>> 10. No standard interface to non-Lisp languages.
>
>That's ok. I don't know of too many languages which do this. For example,
>VB has a non-standard way of linking to functions in a DLL. It would be
>handy to have a standard means of doing this, but every language I've
>used other than C uses a different way of doing it.

The language definitions of C++, Eiffel, and Sather all define the
standard way to interface to C (and perhaps other languages).

>> 11. No standard way (often no way) to link lisp into (not around) a C
>>     program.
>
>See above.

Most OOPLs are designed to start up only by immediately taking over a
new process.  I think this is easy, traditional, but also limiting.
I'm sorry to see that Lisp usually goes along with the crowd on this.

>
>> 12. Often no way to effectively debug foreign loaded C/C++
>
>Under Windows this is done just like with any other C/C++ code. There's
>nothing special about calling a C function.

I know nothing about Allegro CL for Windows.  In it, do stack traces,
inspectors and whatnot work across the C stack and (if different) the
Lisp stack?  Sounds interesting.

>> 20. It is often pain to interface a copying GC with C.  (A standard
>>     way of setting up some amount of space with non-copying GC or even
>>     manual heap management might help.)
>
>Why is this necessary? _Is_it_ necessary with Allegro CL for Windows?
>I don't know, as I've yet to use it.

From Lisp, you pass by value to C a pointer to the data portion of a
Lisp array (or whatever).  In the meantime, your C routine either
calls back to Lisp or another Lisp thread executes.  In either case,
Lisp kicks off a copying garbage collection and moves the referenced
data.  C dereferences the pointer.  Oops!  Solutions involve locking
out Lisp execution (and therefore GC) during the use of a C pointer
and possibly passing data that is never subject to copying GC.
Indirect references through non-copied pointers to GC-aware pointers
can sometimes greatly reduce the time during which copying GC must be
locked out (consider putting a pointer to Lisp data into a C static
variable that hangs around for the life of the process --- it's better
to block GC just when the static variable as actually being used in a
computation, than for the life of the program).

Doug
From: David Weller
Subject: Re: Why Commit to Eiffel?
Date: 
Message-ID: <34qaoc$700@Starbase.NeoSoft.COM>
In article <·················@monet.ads.com>,
Doug Morgan <····@monet.ads.com> wrote:
>>
>>That's ok. I don't know of too many languages which do this. For example,
>>VB has a non-standard way of linking to functions in a DLL. It would be
>>handy to have a standard means of doing this, but every language I've
>>used other than C uses a different way of doing it.
>
>The language definitions of C++, Eiffel, and Sather all define the
>standard way to interface to C (and perhaps other languages).
>
Yup.  Ada 9X defines standard interfacing to C, Fortran, and (gasp!)
COBOL :-)



-- 
Proud (and vocal) member of Team Ada! (and Team OS/2)        ||This is not your
             Ada 9X -- It doesn't suck                       ||  father's Ada
For all sorts of interesting Ada 9X tidbits, run the command:||________________
"finger ·······@starbase.neosoft.com | more" (or e-mail with "finger" as subj.)
From: Jeff Dalton
Subject: Re: Why Commit to Eiffel?
Date: 
Message-ID: <Cvx5Ir.MwD@cogsci.ed.ac.uk>
In article <·················@monet.ads.com> ····@monet.ads.com (Doug Morgan) writes:

>From Lisp, you pass by value to C a pointer to the data portion of a
>Lisp array (or whatever).  In the meantime, your C routine either
>calls back to Lisp or another Lisp thread executes.  In either case,
>Lisp kicks off a copying garbage collection and moves the referenced
>data.  C dereferences the pointer.  Oops!  Solutions involve locking
>out Lisp execution (and therefore GC) during the use of a C pointer
>and possibly passing data that is never subject to copying GC.

There's also "conservative" garbage collection.

-- jd
From: Paul Prescod
Subject: Re: Why Commit to Eiffel?
Date: 
Message-ID: <Cw3FH6.LwK@undergrad.math.uwaterloo.ca>
In article <·····················@mosaic.nyu.edu>,
Marco Antoniotti <·······@mosaic.nyu.edu> wrote:

>As long as it is C everything on a UN*X box is fine. As soon as you
>move to MSDOS or Windows things get hairy. You need a *Vendor* based
>`extern' declaration in order to link in other functions. For C++ the
>situation is even worse. It is conceivable that GNU G++ will never be
>able to link in Borland code, unless Borland decides to make public
>their complete demangling scheme (maybe they did - the issue here is
>not Borland).

Demangling is not the problem.  Completely different runtime architectures 
is.  There is no standard for _implementing_ exceptions, objects, RTTI,
even memory management.

Paul Prescod
From: Jeff Dalton
Subject: Re: Why Commit to Eiffel?
Date: 
Message-ID: <Cw30D5.63q@cogsci.ed.ac.uk>
In article <·················@monet.ads.com> ····@monet.ads.com (Doug Morgan) writes:

>I like Lisp, but this list seems to be make light of real problems
>with the Common Lisp standard (e.g., "Know thy compiler" can easily
>become an unproductive full-time job.)  Here is a sampling of details
>(possibly a few years out of date):

Most of them I agree with, but ...

9. No free down-to-the-hardware full-up compilers.

CMU CL?

>15. No static name overloading.  Wart-filled name selections and
>    argument conventions haphazardly developed through 40 years of
>    growth and merge.

That's not really so.  Common Lisp was a tremendous cleanup
compared to a number of earlier Lisps.  I'm not sure what you
have in mind by "argument conventions".

>16. The spec allows dynamic-extent (stack processing) to be ignored by
>    the compiler.

So?  Virtually all language definitions allow inefficient,
even perverse, implementations.

>17. The spec allows declared types and optimizations to be ignored by
>    the compiler.  (Not even an implicit order of magnitude guarantee
>    on execution speed.)

But so do most specs.  Nothing says a C implementations can't
be just as inefficient, for instance.

>18. No standard way to find the declared type of a symbol.  (Also,
>    can't macro expand a declare, must expand an entire construct.)

Presumably you mean: a macro can't expand to a declare.

They used to be able to.  There were reasons for changing the spec.
I don't think it's fair to call this a defect w/o taking those reasons
into account.

>19. CLOS has no provisions for optimizing methods for special cases
>    like
>        O single argument dispatch
>        O classes with no further (or with restricted) sub classes
>        O I know the class is *exactly* such-and-such right here.
>    (Calling upon meta-object protocol doesn't really count.)

Implementations can do much of this themsleves.  A number of them
optimize single-arg dispatch, for instance.

>21. Last time I looked, CLIM had no provisions for full control of
>    color display lookup table hardware.  Hopefully, it has gotten
>    better.

CLIM isn't part of Common Lisp.

>23. Maybe Dick Gabriel had a good point in saying that Lisp is "the
>    right thing" but that the "worse-is-better" C++ approach is
>    destined to win.  Of course, Lucid lost on both big-time,

They did?  That's not what I've heard.  (But I could easily be
wrong.)
From: Doug Morgan
Subject: Re: Why Commit to Eiffel?
Date: 
Message-ID: <DOUG.94Sep13175937@monet.ads.com>
In article <··········@cogsci.ed.ac.uk> ····@aiai.ed.ac.uk (Jeff Dalton) writes:
|In article <·················@monet.ads.com> ····@monet.ads.com (Doug Morgan) writes:
|
|>I like Lisp, but this list seems to be make light of real problems
|>with the Common Lisp standard (e.g., "Know thy compiler" can easily
|>become an unproductive full-time job.)  Here is a sampling of details
|>(possibly a few years out of date):
|
|Most of them I agree with, but ...
|
|9. No free down-to-the-hardware full-up compilers.
|
|CMU CL?

I'm still confused about how I ever wrote this.  Also, GCL and
ECoLisp, perhaps.

|>15. No static name overloading.  Wart-filled name selections and
|>    argument conventions haphazardly developed through 40 years of
|>    growth and merge.
|
|That's not really so.  Common Lisp was a tremendous cleanup
|compared to a number of earlier Lisps.  I'm not sure what you
|have in mind by "argument conventions".

I was thinking about things like:

(aref	     thing index)
(get	     thing index)
(gethash     index thing)
(nth	     index thing)
(assoc	     index thing)
(elt	     thing index)
(getf	     thing index)
(find	     index thing)
(member	     index thing)
(nthcdr	     index thing)
(rassoc	     index thing)
(slot-value  thing index)
(intern      index thing)
(find-symbol index thing)

14 names with no pattern to show they all do some kind of lookup.  5
have the "mapping" as the first argument, 9 as the second.  Maybe
having the unrelated names can be justified, but I doubt that the
various argument orders can.

|>16. The spec allows dynamic-extent (stack processing) to be ignored by
|>    the compiler.
|
|So?  Virtually all language definitions allow inefficient,
|even perverse, implementations.
|
|>17. The spec allows declared types and optimizations to be ignored by
|>    the compiler.  (Not even an implicit order of magnitude guarantee
|>    on execution speed.)
|
|But so do most specs.  Nothing says a C implementations can't
|be just as inefficient, for instance.

I must have listened too much to my mother who told me just because
every one else does it...

|>18. No standard way to find the declared type of a symbol.  (Also,
|>    can't macro expand a declare, must expand an entire construct.)
|
|Presumably you mean: a macro can't expand to a declare.

Yes.  (And I also meant variable name, not symbol.)

|They used to be able to.  There were reasons for changing the spec.
|I don't think it's fair to call this a defect w/o taking those reasons
|into account.

I do assume there were good reasons.  I just don't like the results.

|>19. CLOS has no provisions for optimizing methods for special cases
|>    like
|>        O single argument dispatch
|>        O classes with no further (or with restricted) sub classes
|>        O I know the class is *exactly* such-and-such right here.
|>    (Calling upon meta-object protocol doesn't really count.)
|
|Implementations can do much of this themsleves.  A number of them
|optimize single-arg dispatch, for instance.

For multiargument generic functions that just happen to only
specialize on one argument?  If so, that's pretty good.  I would have
thought that this optimization (and the other ones) would be too
expensive without some mechanism for the user to "tell" CLOS about
expected usage.

|>21. Last time I looked, CLIM had no provisions for full control of
|>    color display lookup table hardware.  Hopefully, it has gotten
|>    better.
|
|CLIM isn't part of Common Lisp.

CLIM was in the plusses of the message I responded to.

|
|>23. Maybe Dick Gabriel had a good point in saying that Lisp is "the
|>    right thing" but that the "worse-is-better" C++ approach is
|>    destined to win.  Of course, Lucid lost on both big-time,
|
|They did?  That's not what I've heard.  (But I could easily be
|wrong.)

Somehow my jab at the worse-is-better idea missed the mark here.  I
hope the idea is completely wrong and Lisp does wonderfully.

Doug
From: Jeff Dalton
Subject: Re: Why Commit to Eiffel?
Date: 
Message-ID: <Cw4q13.25I@cogsci.ed.ac.uk>
In article <··················@monet.ads.com> ····@monet.ads.com (Doug Morgan) writes:
>In article <··········@cogsci.ed.ac.uk> ····@aiai.ed.ac.uk (Jeff Dalton) writes:
>|In article <·················@monet.ads.com> ····@monet.ads.com (Doug Morgan) writes:
>|
>|>I like Lisp, but this list seems to be make light of real problems
>|>with the Common Lisp standard (e.g., "Know thy compiler" can easily
>|>become an unproductive full-time job.)  Here is a sampling of details
>|>(possibly a few years out of date):
>|
>|Most of them I agree with, but ...
>|
>|9. No free down-to-the-hardware full-up compilers.
>|
>|CMU CL?
>
>I'm still confused about how I ever wrote this.  Also, GCL and
>ECoLisp, perhaps.

KCL and hence presumably GCL compile via C.  I wasn't sure that
counted, since it prevents optimizations not expressible in C
(ok, may be some in-line assembler, but that's not what KCL
does at least).

>|>15. No static name overloading.  Wart-filled name selections and
>|>    argument conventions haphazardly developed through 40 years of
>|>    growth and merge.
>|
>|That's not really so.  Common Lisp was a tremendous cleanup
>|compared to a number of earlier Lisps.  I'm not sure what you
>|have in mind by "argument conventions".
>
>I was thinking about things like:
>
>(aref        thing index)
>(get         thing index)
>(gethash     index thing)
>(nth         index thing)
>(assoc       index thing)
>(elt         thing index)
>(getf        thing index)
>(find        index thing)
>(member      index thing)
>(nthcdr      index thing)
>(rassoc      index thing)
>(slot-value  thing index)
>(intern      index thing)
>(find-symbol index thing)
>
>14 names with no pattern to show they all do some kind of lookup.  5
>have the "mapping" as the first argument, 9 as the second.  Maybe
>having the unrelated names can be justified, but I doubt that the
>various argument orders can.

Those are good examples.  But note that asymmetries and the like
are possible (indeed common) in a single Lisp.  It isn't necessary
to have years of buildup.  Consider e.g. PLUS and TIMES vs QUOTIENT 
and DIFFERENCE in early Lisps.  Also, your examples mostly fall 
into two groups which we might call: indexing (aref, elt, slot-value)
and lookup (gethash, assoc, find, member, intern, find-symbol),
where lookup is more like searching.  Oddities are then nth, nthcdr,
get, and getf.  (I've written assoc for assoc and rassoc and may have
missed some here or there.)

This i far from perfect, but it makes sense for array indexes
and the like to be last.  But then, member, find, and some others
seem reasonably natural the other way around.  Natural languages
are often full of such stuff, so it's presumably not too hard
for people to deal with.

I think it's pretty easy for languages and libraries of procedures
to turn out this way w/o any help from "backwards compatibility"
unless a deliberate and determined effort is made to stop it.
That's the main reason Scheme is more regular (following Yale's T).

>|They used to be able to.  There were reasons for changing the spec.
>|I don't think it's fair to call this a defect w/o taking those reasons
>|into account.
>
>I do assume there were good reasons.  I just don't like the results.

I've sometimes been annoyed by it as well, and by some other
X3J13 decisions.  In this case, deftype is often useful.

>|>19. CLOS has no provisions for optimizing methods for special cases
>|>    like
>|>        O single argument dispatch
>|>        O classes with no further (or with restricted) sub classes
>|>        O I know the class is *exactly* such-and-such right here.
>|>    (Calling upon meta-object protocol doesn't really count.)
>|
>|Implementations can do much of this themsleves.  A number of them
>|optimize single-arg dispatch, for instance.
>
>For multiargument generic functions that just happen to only
>specialize on one argument?  If so, that's pretty good.  I would have
>thought that this optimization (and the other ones) would be too
>expensive without some mechanism for the user to "tell" CLOS about
>expected usage.

Humm.  I suppose I should try to check exactly what various
implementations do (if the implementors will say), but it's
pretty to see some possibilities once you start to think about it.

For instance, what usually happens when a generic function is
called is that it (a) computes an "effective" method for the
argument classes in question (combining befores, afters, etc)
and (b) caches it for quick lookup the next time.  The cache
can be a decision tree (or think of a finite state machine)
with one step/link for each arg.  So if only the first arg
is ever specialized, the cache would go directly to a method
rather than to another branching node.  It's also possible
to notice that all methods are like that (spec only on 1st arg)
and replace the generic's lookup code with code that's more 
specialized, if that would help.

In addition it's possible to optimize cases such as: only one method
exists (check the class and go) and all methods are slot accessors
(do the access rather than call a method that does it).

These techniques rely on adjusting things at run time.  Such
optimizations might be cleared if a new method is defined for
a gf (or if a class is redefined) and then built up again when
the gf is next called.  (More sophisticated versions are possible.)
So it may be that the first call to a gf, or the first call for
a given combination of arg classes, is slow.  For most applications,
that's ok.

>|>23. Maybe Dick Gabriel had a good point in saying that Lisp is "the
>|>    right thing" but that the "worse-is-better" C++ approach is
>|>    destined to win.  Of course, Lucid lost on both big-time,
>|
>|They did?  That's not what I've heard.  (But I could easily be
>|wrong.)
>
>Somehow my jab at the worse-is-better idea missed the mark here.  I
>hope the idea is completely wrong and Lisp does wonderfully.

I meant that I'd heard they were done in by the C++ side.
I was the "both" I was questioning, rather than anything else.

-- jeff