From: David Douthitt
Subject: Stop thinking in C
Date: 
Message-ID: <654320187bac3t1as330qfitv556hi0roh@4ax.com>
I hadn't heard this complaint before, but ran across it recently in a
different discussion thread here.

I've used many languages of different odd-ball sorts - the strangest
ones being Forth and Smalltalk - so I'm probably not going to try and
shoehorn things into C.

However, as I've always wanted to learn LISP, and am earnestly trying
now (using CLISP) I'd like to know how to avoid this.

If you had to finish this sentence: "Newbies often try to think in C;
they make the mistake of ...."

How would you finish it?  Should there be a FAQ - "A LISPers Guide to
Thinking in LISP"?

There was a book (very good one!) titled "Thinking in FORTH" - perhaps
there should be a "Thinking in LISP" eh?

David Douthitt (·····@douthitt.net)
UNIX System Administrator
HP-UX, Unixware, Linux
Linux+, LPIC-1

From: Thomas F. Burdick
Subject: Re: Stop thinking in C
Date: 
Message-ID: <xcvy8riat4c.fsf@famine.OCF.Berkeley.EDU>
David Douthitt <·····@mailbag.com> writes:

> I hadn't heard this complaint before, but ran across it recently in a
> different discussion thread here.
> 
> I've used many languages of different odd-ball sorts - the strangest
> ones being Forth and Smalltalk - so I'm probably not going to try and
> shoehorn things into C.
> 
> However, as I've always wanted to learn LISP, and am earnestly trying
> now (using CLISP) I'd like to know how to avoid this.
> 
> If you had to finish this sentence: "Newbies often try to think in C;
> they make the mistake of ...."

If you can think in Smalltalk, (ie, you didn't hear complaints about
your non-ST-y style), you're probably safe.  Both languages share a
similar dynamic-language, semi-functional (as in FP) approach.  You
can write C or FORTRAN in any language, but it takes a lot of effort
to write ST in most languages -- the fact that Lisp makes it easy is a
hint that it's not so bad :-).

If you're interested in object-oriented programming, I suggest you
ditch CLISP, for now.  In most respects, it's a fine implementation,
but it doesn't implement all of the object system, and doesn't support
the MOP.  If you think you know about object-oriented programming, be
prepared to have your mind blown ... CLOS subsumes Aspect-oriented
programming, and Allen Kay's wish for ST to me message-oriented (CLOS
is generic-function oriented, which is even better than messages).
User-defined method combinations are the shit.  And they don't even
require a MOP.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: David Douthitt
Subject: Re: Stop thinking in C
Date: 
Message-ID: <0qn420plm63ghetaebq7d5ek608tkvm4s7@4ax.com>
On 04 Feb 2004 23:21:55 -0800, ···@famine.OCF.Berkeley.EDU (Thomas F.
Burdick) wrote:

>David Douthitt <·····@mailbag.com> writes:

>> I've used many languages of different odd-ball sorts - the strangest
>> ones being Forth and Smalltalk - so I'm probably not going to try and
>> shoehorn things into C.
>> 
>> However, as I've always wanted to learn LISP, and am earnestly trying
>> now (using CLISP) I'd like to know how to avoid this.

>If you can think in Smalltalk, (ie, you didn't hear complaints about
>your non-ST-y style), you're probably safe.  Both languages share a
>similar dynamic-language, semi-functional (as in FP) approach.

Actually, my Smalltalk experience is limited.  I still want to get up
to speed on PocketSmalltalk and develop with it for the Palm.

I have programmed a lot in C, BASIC, COBOL, and FORTH.  My most
in-depth object oriented experience is in Ruby, which I use almost
daily - only language I use more is ksh.

>If you're interested in object-oriented programming, I suggest you
>ditch CLISP, for now.  In most respects, it's a fine implementation,
>but it doesn't implement all of the object system, and doesn't support
>the MOP.

I am, but I'm actually more interested in "Classic LISP" than
object-orientation.  I figure there's more LISP than there is Object
Orientation.

My limited attempts at LISP have always been CLISP or the Macintosh
PowerLISP.  I tried the Apple II PLISP ages ago, but never got very
far.

I've the Winston & Horn books (2nd and 3rd editions) and the Little
Schemer and Little Lisper books.  So you see, I really DO want to
learn :-)

My biggest complaints so far is that even the most detailed books will
show you how to write an interpreter but don't show you something as
simple as numbering the lines in a text file - or of counting words in
a text file - or running OS commands like 'ls'.

David Douthitt (·····@douthitt.net)
UNIX System Administrator
HP-UX, Unixware, Linux
Linux+, LPIC-1
From: Thomas F. Burdick
Subject: Re: Stop thinking in C
Date: 
Message-ID: <xcv8yjgbw85.fsf@famine.OCF.Berkeley.EDU>
David Douthitt <·····@mailbag.com> writes:

> On 04 Feb 2004 23:21:55 -0800, ···@famine.OCF.Berkeley.EDU (Thomas F.
> Burdick) wrote:
> 
> >If you're interested in object-oriented programming, I suggest you
> >ditch CLISP, for now.  In most respects, it's a fine implementation,
> >but it doesn't implement all of the object system, and doesn't support
> >the MOP.

 [ Looks like the next version of CLISP will have addressed most or
   all of my issues recommending it, nice! ]

> I am, but I'm actually more interested in "Classic LISP" than
> object-orientation.  I figure there's more LISP than there is Object
> Orientation.

There is, but generic functions are the cornerstone of CLOS, and a big
part of modern Lisp.  Nothing wrong with putting it off for later,
though, you gotta start somewhere :-)

> My biggest complaints so far is that even the most detailed books will
> show you how to write an interpreter but don't show you something as
> simple as numbering the lines in a text file - or of counting words in
> a text file -

For the record, you want to look at WITH-OPEN-FILE, and READ-LINE.
The spec would be a horrible way to learn Lisp, but it can be a good
way to find specific functionality.  And this forum is a good place to
learn the more practical aspects of the language; if you can't figure
it out, ask here, and you'll most likely get a helpful response.

> or running OS commands like 'ls'.

Common Lisp is meant to be able to run on most any operating system
that has been or is lokely to come along soon -- which means an OS
interface is out of the scope of the language; calling DIRECTORY on a
pathname that names a directory will give you its contents.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Stefan Scholl
Subject: Re: Stop thinking in C
Date: 
Message-ID: <hjc65fde8k3y.dlg@parsec.no-spoon.de>
On 2004-02-06 01:34:14, David Douthitt wrote:

> My most in-depth object oriented experience is in Ruby,
> which I use almost daily

The accessors in Ruby come directly from CLOS. Ruby is inspired by
many nice languages.
From: Marco Antoniotti
Subject: Re: Stop thinking in C
Date: 
Message-ID: <n3OVb.39$xV.17382@typhoon.nyu.edu>
Stefan Scholl wrote:
> On 2004-02-06 01:34:14, David Douthitt wrote:
> 
> 
>>My most in-depth object oriented experience is in Ruby,
>>which I use almost daily
> 
> 
> The accessors in Ruby come directly from CLOS. Ruby is inspired by
> many nice languages.

... and is another application of Greenspun's Tenth Rule of Programming.

Cheers
--
marco
From: Bijan Parsia
Subject: Re: Stop thinking in C
Date: 
Message-ID: <Pine.A41.4.44+UNC.0402091217100.27506-100000@login7.isis.unc.edu>
On Mon, 9 Feb 2004, Marco Antoniotti wrote:

> Stefan Scholl wrote:
> > On 2004-02-06 01:34:14, David Douthitt wrote:
> >
> >
> >>My most in-depth object oriented experience is in Ruby,
> >>which I use almost daily
> >
> >
> > The accessors in Ruby come directly from CLOS. Ruby is inspired by
> > many nice languages.
>
> ... and is another application of Greenspun's Tenth Rule of Programming.

Not quite, right? There perhaps should be another variant: Any interesting
dynamically typed language will asymptotically approach the Common Lisp
feature set.

Hmm. That has the virtue of not really being true :)

It's not clear that one should regard such language designs as *buggy*
implementation of Common Lisp rather than *interesting* (or underpowered)
subsets thereof :)

Cheers,
Bijan Parsia.
From: Adam Warner
Subject: Re: Stop thinking in C
Date: 
Message-ID: <pan.2004.02.05.09.57.11.462432@consulting.net.nz>
Hi Thomas F. Burdick,

> If you're interested in object-oriented programming, I suggest you
> ditch CLISP, for now.  In most respects, it's a fine implementation,
> but it doesn't implement all of the object system, and doesn't support
> the MOP.

Guess what the CLISP news is for today!
<http://article.gmane.org/gmane.lisp.clisp.devel/10903>

Regards,
Adam
From: Nils Gösche
Subject: Re: Stop thinking in C
Date: 
Message-ID: <873c9qmjk3.fsf@darkstar.cartan.de>
David Douthitt <·····@mailbag.com> writes:

> There was a book (very good one!) titled "Thinking in FORTH" -
> perhaps there should be a "Thinking in LISP" eh?

I would say Peter Norvig's Paradigms of Artificial Intelligence
Programming does just that.  I teaches Lisp by applying it to some
classical AI problems.  Highly recommended.

Regards,
-- 
Nils G�sche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID #xEEFBA4AF
From: Espen Vestre
Subject: Re: Stop thinking in C
Date: 
Message-ID: <kwoesd6fj2.fsf@merced.netfonds.no>
···@cartan.de (Nils G�sche) writes:

> I would say Peter Norvig's Paradigms of Artificial Intelligence
> Programming does just that.  I teaches Lisp by applying it to some
> classical AI problems.  Highly recommended.

I second that. An excellent book!

The only thing I miss: More CLOS. Nowadays, I think that a beginner
should forget about structures until (s)he might eventually need them,
and start out with very simple CLOS usage instead.
-- 
  (espen)
From: Marco Gidde
Subject: Re: Stop thinking in C
Date: 
Message-ID: <lzy8rhke8r.fsf@tristan.br-automation.de>
Espen Vestre <·····@*do-not-spam-me*.vestre.net> writes:

> The only thing I miss: More CLOS. Nowadays, I think that a beginner
> should forget about structures until (s)he might eventually need them,
> and start out with very simple CLOS usage instead.

I did it the other way round. I started with defstruct, added a few
generic functions here and there and try to do more with CLOS now. Why
do you think it's better to learn CLOS right in the beginning? 
(Just curious)

-- 
Marco Gidde
From: Johan Kullstam
Subject: Re: Stop thinking in C
Date: 
Message-ID: <87n07xa7f8.fsf@sysengr.res.ray.com>
Marco Gidde <···········@tiscali.de> writes:

> Espen Vestre <·····@*do-not-spam-me*.vestre.net> writes:
> 
> > The only thing I miss: More CLOS. Nowadays, I think that a beginner
> > should forget about structures until (s)he might eventually need them,
> > and start out with very simple CLOS usage instead.
> 
> I did it the other way round. I started with defstruct, added a few
> generic functions here and there and try to do more with CLOS now. Why
> do you think it's better to learn CLOS right in the beginning? 
> (Just curious)

Speaking for myself, CLOS seems to be a hole in my Lisp knowledge and
it is not addressed by my library of lisp books.

Neither PAIP, nor the two Graham books spend any significant amount of
time on CLOS.  I suppose I should pick up the Keene book which is CLOS
specific (monographs on various topics of my interest have been very
valuable, I should listen to this experience).  Nonetheless, an
introductory type book on Lisp could still beneficially contain more
CLOS.

I must admit that I do not really understand what all the
object-oriented fuss is about.  My exposure consists of a little C++
(I figure I am a competant C programmer and use some of the non-object
oriented features of C++ when I like.)  and what scraps I've seen
about CLOS.  My (naive and hence probably wrong) feeling is that it's
an emporer without clothes; I wish to be informed enough to make a
decent evaulation.  More exposure is good.

> -- 
> Marco Gidde

-- 
Johan KULLSTAM <··········@comcast.net> sysengr
From: Greg Menke
Subject: Re: Stop thinking in C
Date: 
Message-ID: <m3hdy5pdlk.fsf@europa.pienet>
Johan Kullstam <··········@comcast.net> writes:

> Marco Gidde <···········@tiscali.de> writes:
> 
> > Espen Vestre <·····@*do-not-spam-me*.vestre.net> writes:
> > 
> > > The only thing I miss: More CLOS. Nowadays, I think that a beginner
> > > should forget about structures until (s)he might eventually need them,
> > > and start out with very simple CLOS usage instead.
> > 
> > I did it the other way round. I started with defstruct, added a few
> > generic functions here and there and try to do more with CLOS now. Why
> > do you think it's better to learn CLOS right in the beginning? 
> > (Just curious)
> 
> Speaking for myself, CLOS seems to be a hole in my Lisp knowledge and
> it is not addressed by my library of lisp books.
> 
> Neither PAIP, nor the two Graham books spend any significant amount of
> time on CLOS.  I suppose I should pick up the Keene book which is CLOS
> specific (monographs on various topics of my interest have been very
> valuable, I should listen to this experience).  Nonetheless, an
> introductory type book on Lisp could still beneficially contain more
> CLOS.
> 
> I must admit that I do not really understand what all the
> object-oriented fuss is about.  My exposure consists of a little C++
> (I figure I am a competant C programmer and use some of the non-object
> oriented features of C++ when I like.)  and what scraps I've seen
> about CLOS.  My (naive and hence probably wrong) feeling is that it's
> an emporer without clothes; I wish to be informed enough to make a
> decent evaulation.  More exposure is good.

It seems that way until you start to get the hang of CLOS, then I
think you may start to view C++ OO as the emperor with really ugly
clothes.  In a sense, CLOS turns the C++ object model inside out, and
learning it is a little subtle when coming from C++ where the "right
way" is very different.  This is not to say CLOS is bizarre, however
it does take a different view of what goes where and how you
manipulate it.

I think you'll have to use CLOS for a while until it starts to sink
in, but please do try.

Gregm
From: Hrvoje Blazevic
Subject: Re: Stop thinking in C
Date: 
Message-ID: <bvtogi$9gt$1@ls219.htnet.hr>
Johan Kullstam wrote:
> Marco Gidde <···········@tiscali.de> writes:
> 
> Speaking for myself, CLOS seems to be a hole in my Lisp knowledge and
> it is not addressed by my library of lisp books.
> 
> Neither PAIP, nor the two Graham books spend any significant amount of
> time on CLOS.  I suppose I should pick up the Keene book which is CLOS
> specific (monographs on various topics of my interest have been very
> valuable, I should listen to this experience).  Nonetheless, an
> introductory type book on Lisp could still beneficially contain more
> CLOS.

That's probably because Paul Graham himself considers OOP to be "useful 
technique in some cases, but not something that has to pervade every 
program you write." www.paulgraham.com/noop.html

-- Hrvoje
From: Frank A. Adrian
Subject: Re: Stop thinking in C
Date: 
Message-ID: <pan.2004.02.05.16.58.37.916567@ancar.org>
On Thu, 05 Feb 2004 16:43:03 +0100, Hrvoje Blazevic wrote:

> That's probably because Paul Graham himself considers OOP to be "useful 
> technique in some cases, but not something that has to pervade every 
> program you write." www.paulgraham.com/noop.html

He's quite probably right about this.  I find that, as I get older (and
further away from my Smalltalk heritage), my use of objects has been
declining.  I now tend to use them only if I see a need for inheritance
and otherwise I use structs. But I also notice that I still use GF's when
they make sense (i.e., when I need multimethods and/or when the built-in
classes have a nice hierarchical relation to the code).

Most intros to CLOS describe classes first and then move on to GF's. I
think that introducing GF's first, using examples based in the built-in
class hierarchy, would be pedagogically more sound, as I believe it is the
GF that is the salient feature of CLOS and user-defined classes are only a
seldom needed thing upon which they can also be hung.

faa
From: Joe Marshall
Subject: Re: Stop thinking in C
Date: 
Message-ID: <isilb203.fsf@ccs.neu.edu>
"Frank A. Adrian" <·······@ancar.org> writes:

> Most intros to CLOS describe classes first and then move on to GF's. I
> think that introducing GF's first, using examples based in the built-in
> class hierarchy, would be pedagogically more sound, as I believe it is the
> GF that is the salient feature of CLOS and user-defined classes are only a
> seldom needed thing upon which they can also be hung.

That's the approach I used.
From: Pascal Costanza
Subject: Re: Stop thinking in C
Date: 
Message-ID: <bvtqh2$pqn$1@newsreader2.netcologne.de>
Johan Kullstam wrote:

> I must admit that I do not really understand what all the
> object-oriented fuss is about.  My exposure consists of a little C++
> (I figure I am a competant C programmer and use some of the non-object
> oriented features of C++ when I like.)  and what scraps I've seen
> about CLOS.  My (naive and hence probably wrong) feeling is that it's
> an emporer without clothes; I wish to be informed enough to make a
> decent evaulation.  More exposure is good.

The gist of OOP, from a CLOS perspective, is this:

Consider a function foo defined as follows.

(defun foo (an-object)
   (cond ((typep an-object 'number) (do-something ...))
         ((typep an-object 'string) (do-something-else ...))
	((eql an-object 'some-symbol) (do-something-special ...))
         ...))

CLOS allows you to define that function like this.

(defmethod ((an-object number))
   (do-something ...))

(defmethod ((an-object string))
   (do-something-else ...))

(defmethod ((an-object (eql 'some-symbol)))
   (do-something-special ...))

The important point here is that you can spread the definition of a 
single function across many places, for example in different modules 
that are written by different programmers. Furthermore, you can extend 
such functions without modifying a single place, thereby avoiding 
conflicts. You can even do this as late as runtime. Such functions are 
called generic functions.

Classes allow you to introduce new types on which you can specialize 
methods, making generic functions even more expressive.

To put it differently, generic functions allow you to arrange the code 
you write according to semantically related concepts instead of 
accidental arrangements imposed by some underlying stricter language 
construct.

Again, note that this is a CLOS perspective. "Pure" paradigms promote 
their respective "right" ways to arrange source code, independent of the 
natural relations inherent in the models that you try to implement.

Another view on OOP is that programs consist of "autonomous" entities 
that communicate with each other via messages. This view stems from 
Simula, a simulation language that has tried to simulate "real" objects, 
which is generally referred to as the first example of an 
object-oriented programming language. Smalltalk has taken over this view 
and was the first language to be actually called object-oriented by its 
inventors.

CLOS goes beyond that view by providing means to define multimethods 
that specialize on more than one argument. This makes objects less 
"autonomous", but it is clear that such a puristic view of OOP doesn't 
work anyway, even not in Smalltalk. In pure OOP languages (without 
multimethods) you usually need idioms to simulate what can easier be 
achieved with multimethods.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Marco Gidde
Subject: Re: Stop thinking in C
Date: 
Message-ID: <lzk731jx4p.fsf@tristan.br-automation.de>
Johan Kullstam <··········@comcast.net> writes:

> I must admit that I do not really understand what all the
> object-oriented fuss is about.  My exposure consists of a little C++
> (I figure I am a competant C programmer and use some of the non-object
> oriented features of C++ when I like.)  and what scraps I've seen
> about CLOS.  My (naive and hence probably wrong) feeling is that it's
> an emporer without clothes; I wish to be informed enough to make a
> decent evaulation.  More exposure is good.

This again raises the often discussed question what OO is about. I
think if you use structs in C, define functions to allocate and free
the memory and a few functions that operate on these structs, it is
already some kind of OO. If you then consider that a C++ class is
(as a first approximation) a struct with some protection, you can use
C++ as a C with some syntactic sugar :-)

The CLOS aproach is quite different and this is probably the reason,
why I ignored it for a while. I'm still thinking too much in C and C++.

-- 
Marco Gidde
From: Johan Kullstam
Subject: Re: Stop thinking in C
Date: 
Message-ID: <87isil9ous.fsf@sysengr.res.ray.com>
Marco Gidde <···········@tiscali.de> writes:

> Johan Kullstam <··········@comcast.net> writes:
> 
> > I must admit that I do not really understand what all the
> > object-oriented fuss is about.  My exposure consists of a little C++
> > (I figure I am a competant C programmer and use some of the non-object
> > oriented features of C++ when I like.)  and what scraps I've seen
> > about CLOS.  My (naive and hence probably wrong) feeling is that it's
> > an emporer without clothes; I wish to be informed enough to make a
> > decent evaulation.  More exposure is good.
> 
> This again raises the often discussed question what OO is about. I
> think if you use structs in C, define functions to allocate and free
> the memory and a few functions that operate on these structs, it is
> already some kind of OO. If you then consider that a C++ class is
> (as a first approximation) a struct with some protection, you can use
> C++ as a C with some syntactic sugar :-)

Well yes.  This is what I use C++ for.  I create classes as a function
with state (kind of a poor man's closure).  The only advantage I see
in the C++ setup is that I can easily make more functions with their
own state.  Five minutes (I am slow) and a macro and this is solved in
Lisp too.  In my work I am making a simulation of some hardware, e.g.,
a satcom modem.  A low pass filter is a typical part.  I store the
accumulator values in the class and then feed it with input and get
output.

I never understood how it was supposed to usefully make use of the
inheritance or why it would be great for making a GUI.  Objects might
be good, but I can't see them being enough.  Having been exposed to
emacs, I figured that having first-class, explicit (lambda rather than
defun) functions/closures would be esential.  In emacs you associate a
keypress with a function and off you go.  Is this the reason emacs
seems to do so much with what is now a modest amount of resource and
those C++ GUI apps are so gargantuan?

> The CLOS aproach is quite different and this is probably the reason,
> why I ignored it for a while. I'm still thinking too much in C and
> C++.

Exactly.  I keep hearing about that CLOS is good.  I should get up off
my lazy behind and learn it.

> -- 
> Marco Gidde

-- 
Johan KULLSTAM <··········@comcast.net> sysengr
From: Marco Gidde
Subject: Re: Stop thinking in C
Date: 
Message-ID: <lzwu70csq3.fsf@tristan.br-automation.de>
Johan Kullstam <··········@comcast.net> writes:

> I never understood how it was supposed to usefully make use of the
> inheritance or why it would be great for making a GUI.  Objects might
> be good, but I can't see them being enough.  Having been exposed to
> emacs, I figured that having first-class, explicit (lambda rather than
> defun) functions/closures would be esential. In emacs you associate a
> keypress with a function and off you go.

Well, object inheritance, vitual (or generic) functions and such are
very useful in GUI development. Just imagine the drawing of a frame,
that looks the same for different kind of widgets. Take this frame as
the base class, inherit some other class from this one that handles
mouse press and release events and you get a button with a frame for
free.

Emacs hides a lot of this stuff from the user, but it uses a C GUI
internally. I do a lot of GUI development on the job and am quite
happy with C++ there. Using X11/Xt/Motif years ago was a pain for me
because it "simulates" OO and developing a new widget means filling
some structs with function pointers or strange defines to use the
method of the superclass.

As soon as I feel more familiar with CLOS I will take a look at CLIM
to compare it to C/C++ GUIs.

> Is this the reason emacs
> seems to do so much with what is now a modest amount of resource and
> those C++ GUI apps are so gargantuan?

I dont's think so. Where most of the more "modern" applications focus
on neat visual effects, dialogs and what else people call user-friendly
today (no flame war please), emacs chooses simplicity for the GUI and
the most possible power for everything else. 


-- 
Marco Gidde
From: Adrian Kubala
Subject: Re: Stop thinking in C
Date: 
Message-ID: <slrnc2ddpl.9v8.adrian@sixfingeredman.net>
Marco Gidde <···········@tiscali.de> schrieb:
> Johan Kullstam <··········@comcast.net> writes:
>
>> I must admit that I do not really understand what all the
>> object-oriented fuss is about.  My exposure consists of a little C++
>> (I figure I am a competant C programmer and use some of the non-object
>> oriented features of C++ when I like.)  and what scraps I've seen
>> about CLOS.  My (naive and hence probably wrong) feeling is that it's
>> an emporer without clothes; I wish to be informed enough to make a
>> decent evaulation.  More exposure is good.
>
> This again raises the often discussed question what OO is about. I
> think if you use structs in C, define functions to allocate and free
> the memory and a few functions that operate on these structs, it is
> already some kind of OO. If you then consider that a C++ class is
> (as a first approximation) a struct with some protection, you can use
> C++ as a C with some syntactic sugar :-)

I don't see that just using struct values is different from using any
other kind of values in a procedural or functional style. I think that
only dynamic dispatch -- where the object operated upon determines the
operator -- can truly be said to be "oriented" around objects.
From: Henrik Motakef
Subject: Re: Stop thinking in C
Date: 
Message-ID: <x7y8rd5fs8.fsf@crocket.internal.henrik-motakef.de>
Adrian Kubala <······@sixfingeredman.net> writes:

> > This again raises the often discussed question what OO is about. I
> > think if you use structs in C, define functions to allocate and free
> > the memory and a few functions that operate on these structs, it is
> > already some kind of OO. If you then consider that a C++ class is
> > (as a first approximation) a struct with some protection, you can use
> > C++ as a C with some syntactic sugar :-)
> 
> I don't see that just using struct values is different from using any
> other kind of values in a procedural or functional style. I think that
> only dynamic dispatch -- where the object operated upon determines the
> operator -- can truly be said to be "oriented" around objects.

If you'd change that to "...the objects operated upon..." (note the
plural), you'd have what CLOS is about, IMHO. Multi-methods
specialized on arbitrary classes, be it builtin-, structure-,
condition- or standard-classes (not to mention individual
objects). You can write pretty cool programms using CLOS without a
single defclass, only using generic functions and methods.

OK, you can also write programs that define lots of deep class
hierarchies and don't use any generic functions, but I cannot remember
ever having seen one. CLOS might be object-oriented, but it is
certainly not class-oriented in the way of other languages that make
defining class hierarchies the primary focus of design. The advantages
of defgeneric/defmethod over defun seem to be far more significant
than the ones of defclass over defstruct to me.
From: Frode Vatvedt Fjeld
Subject: Re: Stop thinking in C
Date: 
Message-ID: <2hn07xxxrx.fsf@vserver.cs.uit.no>
Johan Kullstam <··········@comcast.net> writes:

> I must admit that I do not really understand what all the
> object-oriented fuss is about.  My exposure consists of a little C++
> (I figure I am a competant C programmer and use some of the
> non-object oriented features of C++ when I like.)  and what scraps
> I've seen about CLOS.  My (naive and hence probably wrong) feeling
> is that it's an emporer without clothes; I wish to be informed
> enough to make a decent evaulation.  More exposure is good.

I think perhaps the most important aspect of "OO" (as in the 90's
fashion wave) is the method-call syntax. Not because it's really
anything but sugaring of some basic concepts, but because it allows a
call-site to signal that one of the parameters can be expected to be
side-effected by that call.

-- 
Frode Vatvedt Fjeld
From: Frode Vatvedt Fjeld
Subject: Re: Stop thinking in C
Date: 
Message-ID: <2hisilxxjg.fsf@vserver.cs.uit.no>
Frode Vatvedt Fjeld <······@cs.uit.no> writes:

> I think perhaps the most important aspect of "OO" (as in the 90's
> fashion wave) is the method-call syntax. Not because it's really
> anything but sugaring of some basic concepts, but because it allows
> a call-site to signal that one of the parameters can be expected to
> be side-effected by that call.

Oh, and I forgot to say: This particular aspect of "OO" I think CL
solves much more beautifully with setf.

-- 
Frode Vatvedt Fjeld
From: Espen Vestre
Subject: Re: Stop thinking in C
Date: 
Message-ID: <kwptct4tcx.fsf@merced.netfonds.no>
Marco Gidde <···········@tiscali.de> writes:

> I did it the other way round. I started with defstruct, added a few
> generic functions here and there and try to do more with CLOS now. Why
> do you think it's better to learn CLOS right in the beginning? 

Mainly because I don't see any need for defstruct anymore except 
(sometimes) when doing heavy optimizing.
-- 
  (espen)
From: Espen Vestre
Subject: Re: Stop thinking in C
Date: 
Message-ID: <kwn07x4t92.fsf@merced.netfonds.no>
Marco Gidde <···········@tiscali.de> writes:

> I did it the other way round. I started with defstruct, added a few
> generic functions here and there and try to do more with CLOS now. Why
> do you think it's better to learn CLOS right in the beginning? 

Two reasons:

 - To encourage the use of CLOS
 - Because defstruct is something you won't need until you either
   maintain old code or have some very strong optimizing need.
-- 
  (espen)
From: Christopher C. Stacy
Subject: Re: Stop thinking in C
Date: 
Message-ID: <ufzdp8yk7.fsf@news.dtpq.com>
>>>>> On Thu, 05 Feb 2004 13:15:37 +0100, Espen Vestre ("Espen") writes:

 Espen> Marco Gidde <···········@tiscali.de> writes:
 >> I did it the other way round. I started with defstruct, added a few
 >> generic functions here and there and try to do more with CLOS now. Why
 >> do you think it's better to learn CLOS right in the beginning? 

 Espen> Two reasons:

 Espen>  - To encourage the use of CLOS
 Espen>  - Because defstruct is something you won't need until you either
 Espen>    maintain old code or have some very strong optimizing need.

Are structures in fact guaranteed to be more efficient than CLOS
instances? I thought it was just a suggested place to optimize;
somewhat of a historical artifact that they are more lightweight.
I thought implementations are allowed to implement structures as
full-fledged CLOS objects (they just have to have a particularly
specified class, which is not named STANDARD-OBJECT.)

I hardly ever use DEFSTRUCT, and when I used to start objects as 
structuress, 99% of the time I ended up "promoting" them to CLOS anyway.
From: Paul Dietz
Subject: Re: Stop thinking in C
Date: 
Message-ID: <402262E2.F5AC873B@motorola.com>
"Christopher C. Stacy" wrote:

> Are structures in fact guaranteed to be more efficient than CLOS
> instances?

No, but in practice they usually are.

	Paul
From: Joe Marshall
Subject: Re: Stop thinking in C
Date: 
Message-ID: <4qu58p2l.fsf@comcast.net>
Paul Dietz <············@motorola.com> writes:

> "Christopher C. Stacy" wrote:
>
>> Are structures in fact guaranteed to be more efficient than CLOS
>> instances?
>
> No, but in practice they usually are.

I don't think that structures themselves are more efficient.  They
need a slot per field and a slot for the type descriptor, and CLOS
instances need no more than that.  The type descriptor for a structure
may be smaller than the class structure for a CLOS object, but that is
a one-time cost per type.  The accessors for CLOS objects, however,
are more likely to be more time consuming than the accessors for
structures.

-- 
~jrm
From: Paul Dietz
Subject: Re: Stop thinking in C
Date: 
Message-ID: <40227C53.BC5E7F8D@motorola.com>
Joe Marshall wrote:

> I don't think that structures themselves are more efficient.  They
> need a slot per field and a slot for the type descriptor, and CLOS
> instances need no more than that.  The type descriptor for a structure
> may be smaller than the class structure for a CLOS object, but that is
> a one-time cost per type.  The accessors for CLOS objects, however,
> are more likely to be more time consuming than the accessors for
> structures.

CLOS standard objects need to have the hooks for redefinition,
which (in PCL, at least, and probably elsewhere) means an extra
level of indirection.

And, as you say, there's the overhead of the accessors.  There's
also the potential overhead at object creation time (at the least,
the allocator is difficult to inline without having the ability
to recompile everything when the class definition changes).

	Paul
From: Joe Marshall
Subject: Re: Stop thinking in C
Date: 
Message-ID: <65el762z.fsf@comcast.net>
Paul Dietz <············@motorola.com> writes:

> Joe Marshall wrote:
>
>> I don't think that structures themselves are more efficient.  They
>> need a slot per field and a slot for the type descriptor, and CLOS
>> instances need no more than that.  The type descriptor for a structure
>> may be smaller than the class structure for a CLOS object, but that is
>> a one-time cost per type.  The accessors for CLOS objects, however,
>> are more likely to be more time consuming than the accessors for
>> structures.
>
> CLOS standard objects need to have the hooks for redefinition,
> which (in PCL, at least, and probably elsewhere) means an extra
> level of indirection.

Good point.

-- 
~jrm
From: Espen Vestre
Subject: Re: Stop thinking in C
Date: 
Message-ID: <kwr7x939p4.fsf@merced.netfonds.no>
······@news.dtpq.com (Christopher C. Stacy) writes:

> somewhat of a historical artifact that they are more lightweight.

Sure. That's why I said "very strong optimizing need", because if you
have that, you want to try everything, including trying out whether
your lisp of choice actually _does_ structures faster than clos
objects. 
-- 
  (espen)
From: Raymond Wiker
Subject: Re: Stop thinking in C
Date: 
Message-ID: <867jz1n1p8.fsf@raw.grenland.fast.no>
Espen Vestre <·····@*do-not-spam-me*.vestre.net> writes:

> Marco Gidde <···········@tiscali.de> writes:
>
>> I did it the other way round. I started with defstruct, added a few
>> generic functions here and there and try to do more with CLOS now. Why
>> do you think it's better to learn CLOS right in the beginning? 
>
> Two reasons:
>
>  - To encourage the use of CLOS
>  - Because defstruct is something you won't need until you either
>    maintain old code or have some very strong optimizing need.

        - you cannot redefine a struct, which makes CLOS a much better
choice for development.

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Espen Vestre
Subject: Re: Stop thinking in C
Date: 
Message-ID: <kw65el4s6n.fsf@merced.netfonds.no>
Raymond Wiker <·············@fast.no> writes:

>         - you cannot redefine a struct, which makes CLOS a much better
> choice for development.

Thanks, a very good point I forgot about (since I haven't actively
used structs for _ages_ myself).
-- 
  (espen)
From: Marco Gidde
Subject: Re: Stop thinking in C
Date: 
Message-ID: <lzsmhpk7a9.fsf@tristan.br-automation.de>
Raymond Wiker <·············@fast.no> writes:

>         - you cannot redefine a struct, which makes CLOS a much better
> choice for development.

I guess you don't mean the redefinition of the struct, which should be
possible, but the update of all existing instances?

-- 
Marco Gidde
From: Raymond Wiker
Subject: Re: Stop thinking in C
Date: 
Message-ID: <863c9pn05l.fsf@raw.grenland.fast.no>
Marco Gidde <···········@tiscali.de> writes:

> Raymond Wiker <·············@fast.no> writes:
>
>>         - you cannot redefine a struct, which makes CLOS a much better
>> choice for development.
>
> I guess you don't mean the redefinition of the struct, which should be
> possible, but the update of all existing instances?

        I mean the redefinition of the struct, which is illegal.

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Paul Dietz
Subject: Re: Stop thinking in C
Date: 
Message-ID: <40226290.596152E4@motorola.com>
Raymond Wiker wrote:

>         I mean the redefinition of the struct, which is illegal.

It's undefined in the ANSI CL spec.  It is not explicitly
prohibited, although no conforming program may do it.

	Paul
From: Joe Marshall
Subject: Re: Stop thinking in C
Date: 
Message-ID: <8yjh8pbu.fsf@comcast.net>
Marco Gidde <···········@tiscali.de> writes:

> Why do you think it's better to learn CLOS right in the beginning? 

It is no more complicated that defstruct in the simple case, and a lot
simpler than defstruct in the complicated case.  The sooner that
someone sees that CLOS objects are more or less structures (and don't
encapsulate code), the easier time they will have learning it.

-- 
~jrm
From: Christopher Browne
Subject: Re: Stop thinking in C
Date: 
Message-ID: <bvuaf3$10ueki$4@ID-125932.news.uni-berlin.de>
The world rejoiced as Marco Gidde <···········@tiscali.de> wrote:
> Espen Vestre <·····@*do-not-spam-me*.vestre.net> writes:
>
>> The only thing I miss: More CLOS. Nowadays, I think that a beginner
>> should forget about structures until (s)he might eventually need them,
>> and start out with very simple CLOS usage instead.
>
> I did it the other way round. I started with defstruct, added a few
> generic functions here and there and try to do more with CLOS now. Why
> do you think it's better to learn CLOS right in the beginning? 
> (Just curious)

If you're doing the 'simple' stuff with DEFCLASS that _could_ be done
with DEFSTRUCT, then you'll find that there is not much burden of
complexity.  That part of CLOS is no tougher to learn than DEFSTRUCT.

I would only use DEFSTRUCT if I had already prototyped using DEFCLASS,
and discovered that I had a specific performance bottleneck that
dictated that I throw away flexibility in favor of solving the
immediate problem with a "DEFSTRUCT tune-up."
-- 
If this was helpful, <http://svcs.affero.net/rm.php?r=cbbrowne> rate me
http://cbbrowne.com/info/
Despite the high cost of living, it remains very popular. 
From: Marco Gidde
Subject: Re: Stop thinking in C
Date: 
Message-ID: <lzwu71kwfh.fsf@tristan.br-automation.de>
Christopher Browne <········@acm.org> writes:

> If you're doing the 'simple' stuff with DEFCLASS that _could_ be done
> with DEFSTRUCT, then you'll find that there is not much burden of
> complexity.  That part of CLOS is no tougher to learn than DEFSTRUCT.

As I found out while reading Keene's book, this is probably true. 
One thing that holds me back from using DEFCLASS is its
talkativeness. DEFSTRUCT is much more compact and has useful defaults
for constructors and accesors. Is this the price for the greater
flexibility, that one has to pay or do you use some macros on top of
DEFCLASS? 

> I would only use DEFSTRUCT if I had already prototyped using DEFCLASS,
> and discovered that I had a specific performance bottleneck that
> dictated that I throw away flexibility in favor of solving the
> immediate problem with a "DEFSTRUCT tune-up."

I had not expected that the Lisp community prefers DEFCLASS over
DEFSTRUCT almost in unison. So far the flexibility was not so
important for me because of my C/C++ thinking (edit/compile/test), but
since I use the REPL more and more, it will become an issue soon. 

Ok, you are the experts and I'm learning and proselytised. As from now
I'll use DEFCLASS.


-- 
Marco Gidde
From: Joe Marshall
Subject: Re: Stop thinking in C
Date: 
Message-ID: <ekt9b1qd.fsf@ccs.neu.edu>
Marco Gidde <···········@tiscali.de> writes:

> One thing that holds me back from using DEFCLASS is its
> talkativeness. DEFSTRUCT is much more compact and has useful defaults
> for constructors and accesors. Is this the price for the greater
> flexibility, that one has to pay or do you use some macros on top of
> DEFCLASS? 

It isn't *that* much more talkative, and the flexibility has allowed
me to get out of tight situations in the past, so I like it.
From: Timothy Moore
Subject: Re: Stop thinking in C
Date: 
Message-ID: <wdr8yjhb1wc.fsf@trousse.labri.fr>
Marco Gidde <···········@tiscali.de> writes:

> As I found out while reading Keene's book, this is probably true. 
> One thing that holds me back from using DEFCLASS is its
> talkativeness. DEFSTRUCT is much more compact and has useful defaults
> for constructors and accesors. Is this the price for the greater
> flexibility, that one has to pay or do you use some macros on top of
> DEFCLASS? 

I wrote a macro to make defclass forms less verbose. I used it
once. I found it made my code too eccentric; I had a hard time reading
the result. I'm used to all the verbiage in DEFCLASS now; anything
else looks strange.

Tim
From: Alan Crowe
Subject: Re: Stop thinking in C
Date: 
Message-ID: <86oescpm7m.fsf@cawtech.freeserve.co.uk>
Marco Gidde wrote:
> One thing that holds me back from using DEFCLASS is its
> talkativeness. DEFSTRUCT is much more compact and has
> useful defaults for constructors and accesors.

I believed that until last week. Now I'm not so sure. What
has unsettled me is realising that class accessors are
generic functions, but structure accessors are ordinary
functions. So structures /need/ the structure name prepended
to the slot name, and structure users need to line it all up
right.

Here are my notes to myself from last week. They are
intended to be run as well as read. I hope I
understood this correctly. Some-one on c.l.l. will be sure
to say if I've got it wrong

;;;; Accessors are generic functions

;;;; Structures miss a trick

(defstruct one (a 1) (b 1))
(defstruct two (a 2) (b (expt 2 2)))

(dolist (accessor '(one-a two-a))
	  (dolist (structure '(make-one make-two))
	    (let ((form `(,accessor (,structure))))
	      (format t "The form ~A yields values:~%  ~A~%"
		      form
		      (multiple-value-list
		       (ignore-errors
			(eval form)))))))

(defclass three ()
  ((field :accessor name-clash
	  :initform 3)))

(defclass four ()
  ((field :accessor name-clash
	  :initform 4)))

(format t "~%But with classes names may clash:~%   ~A~%"
	(mapcar #'name-clash
		(list
		 (make-instance 'three)
		 (make-instance 'four))))

; Since structure accessors are functions
; the programmer must use distince names 
; to access the corresponding fields in
; different structures

; Since slot accessors are generic functions
; clos will chose the right method for the class
; allowing corresponding accessors for different classes
; to be given the same name, even when there isn't a slot

(defclass spherical ()
  (r
   theta
   phi))

(defclass cylindrical ()
  (r
   theta
   (z :accessor z)))

(defclass rectangular()
  (x y (z :accessor z) ))

(defmethod z ((point spherical))
  (* (slot-value point 'r)
     (sin (slot-value point 'phi))))
	
From: Espen Vestre
Subject: Re: Stop thinking in C
Date: 
Message-ID: <kwhdy4cywf.fsf@merced.netfonds.no>
Alan Crowe <····@cawtech.freeserve.co.uk> writes:

> I believed that until last week. Now I'm not so sure. What
> has unsettled me is realising that class accessors are
> generic functions, but structure accessors are ordinary
> functions. So structures /need/ the structure name prepended
> to the slot name, and structure users need to line it all up
> right.

Btw, I don't like the habit (of many programmers) of using the
same naming habit for clos accessors. If you have a large class
hiearchy, it's simply difficult to remember the name of the
accessors when they are defined high in the hierarchy. Besides,
you often want a GF - and even an accessor! - to "cut through" 
several otherwise unrelated classes, which don't share a common
superclass.
-- 
  (espen)
From: Joe Marshall
Subject: Re: Stop thinking in C
Date: 
Message-ID: <ad3w5ua0.fsf@comcast.net>
Espen Vestre <·····@*do-not-spam-me*.vestre.net> writes:

> Btw, I don't like the habit (of many programmers) of using the same
> naming habit for clos accessors. ... Besides, you often want a GF -
> and even an accessor! - to "cut through" several otherwise unrelated
> classes, which don't share a common superclass.

Yes!  You do *not* want to write things like

(defclass foo ()
  ((x :initarg :x :accessor foo-x)))

Because it is going to look awfully dumb when you create a subclass:

(defclass bar (foo)
  ())

(setq my-bar (make-instance 'bar :x 22))

(foo-x my-bar) ;; huh?


-- 
~jrm
From: Christopher C. Stacy
Subject: Re: Stop thinking in C
Date: 
Message-ID: <uisikwhts.fsf@news.dtpq.com>
>>>>> On Fri, 06 Feb 2004 11:20:24 GMT, Joe Marshall ("Joe") writes:

 Joe> Espen Vestre <·····@*do-not-spam-me*.vestre.net> writes:
 >> Btw, I don't like the habit (of many programmers) of using the same
 >> naming habit for clos accessors. ... Besides, you often want a GF -
 >> and even an accessor! - to "cut through" several otherwise unrelated
 >> classes, which don't share a common superclass.

 Joe> Yes!  You do *not* want to write things like

 Joe> (defclass foo ()
 Joe>   ((x :initarg :x :accessor foo-x)))

 Joe> Because it is going to look awfully dumb when you create a subclass:

 Joe> (defclass bar (foo)
 Joe>   ())

 Joe> (setq my-bar (make-instance 'bar :x 22))

 Joe> (foo-x my-bar) ;; huh?

(defclass student ()
   ((name :accessor student-name :initarg :name)))

(defclass grad (student) ())

(student-name (make-instance 'grad-student :name "Fred"))
From: Thomas F. Burdick
Subject: Re: Stop thinking in C
Date: 
Message-ID: <xcv1xp8axqw.fsf@famine.OCF.Berkeley.EDU>
······@news.dtpq.com (Christopher C. Stacy) writes:

> >>>>> On Fri, 06 Feb 2004 11:20:24 GMT, Joe Marshall ("Joe") writes:
> 
>  Joe> Espen Vestre <·····@*do-not-spam-me*.vestre.net> writes:
>  >> Btw, I don't like the habit (of many programmers) of using the same
>  >> naming habit for clos accessors. ... Besides, you often want a GF -
>  >> and even an accessor! - to "cut through" several otherwise unrelated
>  >> classes, which don't share a common superclass.
> 
>  Joe> Yes!  You do *not* want to write things like
> 
>  Joe> (defclass foo ()
>  Joe>   ((x :initarg :x :accessor foo-x)))
> 
>  Joe> Because it is going to look awfully dumb when you create a subclass:
> 
>  Joe> (defclass bar (foo)
>  Joe>   ())
> 
>  Joe> (setq my-bar (make-instance 'bar :x 22))
> 
>  Joe> (foo-x my-bar) ;; huh?
> 
> (defclass student ()
>    ((name :accessor student-name :initarg :name)))
> 
> (defclass grad (student) ())
> 
> (student-name (make-instance 'grad-student :name "Fred"))

Is this student's STUDENT-NAME different from his PERSON-NAME?  Or his
CITIZEN-NAME?  Because I might want to inherit from your grad student
class.

These pseudo-real-world OOP examples get pretty stupid pretty quickly, though.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Christopher C. Stacy
Subject: Re: Stop thinking in C
Date: 
Message-ID: <uvfmjc29c.fsf@news.dtpq.com>
>>>>> On 06 Feb 2004 10:06:31 -0800, Thomas F Burdick ("Thomas") writes:

 Thomas> ······@news.dtpq.com (Christopher C. Stacy) writes:
 >> >>>>> On Fri, 06 Feb 2004 11:20:24 GMT, Joe Marshall ("Joe") writes:
 >> 
 Joe> Espen Vestre <·····@*do-not-spam-me*.vestre.net> writes:
 >> >> Btw, I don't like the habit (of many programmers) of using the same
 >> >> naming habit for clos accessors. ... Besides, you often want a GF -
 >> >> and even an accessor! - to "cut through" several otherwise unrelated
 >> >> classes, which don't share a common superclass.
 >> 
 Joe> Yes!  You do *not* want to write things like
 >> 
 Joe> (defclass foo ()
 Joe> ((x :initarg :x :accessor foo-x)))
 >> 
 Joe> Because it is going to look awfully dumb when you create a subclass:
 >> 
 Joe> (defclass bar (foo)
 Joe> ())
 >> 
 Joe> (setq my-bar (make-instance 'bar :x 22))
 >> 
 Joe> (foo-x my-bar) ;; huh?
 >> 
 >> (defclass student ()
 >> ((name :accessor student-name :initarg :name)))
 >> 
 >> (defclass grad (student) ())
 >> 
 >> (student-name (make-instance 'grad-student :name "Fred"))

 Thomas> Is this student's STUDENT-NAME different from his
 Thomas> PERSON-NAME?  Or his CITIZEN-NAME?  Because I might want
 Thomas> to inherit from your grad student class.


(defclass person ((name :accessor person-name :initarg :name)))

(defclass student (person) ()
(defclass grad (student) ())

(person-name (make-instance 'grad-student :name "Fred"))

What's your point?
From: Henrik Motakef
Subject: Re: Stop thinking in C
Date: 
Message-ID: <x77jyz97rx.fsf@crocket.internal.henrik-motakef.de>
······@news.dtpq.com (Christopher C. Stacy) writes:

>>> (defclass student ()
>>> ((name :accessor student-name :initarg :name)))
>>> 
>>> (defclass grad (student) ())
>>> 
>>> (student-name (make-instance 'grad-student :name "Fred"))
> 
>> Is this student's STUDENT-NAME different from his
>> PERSON-NAME?  Or his CITIZEN-NAME?  Because I might want
>> to inherit from your grad student class.
> 
> (defclass person ((name :accessor person-name :initarg :name)))
> 
> (defclass student (person) ()
> (defclass grad (student) ())
> 
> (person-name (make-instance 'grad-student :name "Fred"))
> 
> What's your point?

Um, wasn't the difference between (student-name *must-be-a-student*)
and (name *any-object-that-might-have-a-name*) exactly the point here?
The difference between "student-name" and "name" seems to be rather
significant to me.
From: Pascal Costanza
Subject: Re: Stop thinking in C
Date: 
Message-ID: <c013pi$p4h$1@newsreader2.netcologne.de>
Henrik Motakef wrote:
> ······@news.dtpq.com (Christopher C. Stacy) writes:
> 
> 
>>>>(defclass student ()
>>>>((name :accessor student-name :initarg :name)))
>>>>
>>>>(defclass grad (student) ())
>>>>
>>>>(student-name (make-instance 'grad-student :name "Fred"))
>>
>>>Is this student's STUDENT-NAME different from his
>>>PERSON-NAME?  Or his CITIZEN-NAME?  Because I might want
>>>to inherit from your grad student class.
>>
>>(defclass person ((name :accessor person-name :initarg :name)))
>>
>>(defclass student (person) ()
>>(defclass grad (student) ())
>>
>>(person-name (make-instance 'grad-student :name "Fred"))
>>
>>What's your point?
> 
> Um, wasn't the difference between (student-name *must-be-a-student*)
> and (name *any-object-that-might-have-a-name*) exactly the point here?
> The difference between "student-name" and "name" seems to be rather
> significant to me.

(defclass object-with-a-name ()
   ((name :accessor name
          :initarg :name
          :initform (progn
                      (cerror "read a name" "no name provided")
                      (read)))))

(defclass person (object-with-a-name)
   ((name :accessor person-name
          :initarg :person-name
          :initform (progn
                      (cerror "read a name" "no person-name provided")
                      (read)))))

(defclass student (person)
   ((name :accessor student-name
          :initarg :student-name
          :initform (progn
                      (cerror "read a name" "no student-name provided")
                      (read)))))

? (setf s (make-instance 'student))
 > Error: no student-name provided
 > While executing: #<Anonymous Function #x2424046>
 > Type Command-/ to continue, Command-. to abort.
 > If continued: read a name
See the Restarts� menu item for further choices.
1 > "Pascal"
#<STUDENT #x24289E6>
? (name s)
"Pascal"
? (person-name s)
"Pascal"
? (student-name s)
"Pascal"


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Christopher C. Stacy
Subject: Re: Stop thinking in C
Date: 
Message-ID: <uekt7bwty.fsf@news.dtpq.com>
>>>>> On 06 Feb 2004 23:12:50 +0100, Henrik Motakef ("Henrik") writes:

 Henrik> ······@news.dtpq.com (Christopher C. Stacy) writes:
 >>>> (defclass student ()
 >>>> ((name :accessor student-name :initarg :name)))
 >>>> 
 >>>> (defclass grad (student) ())
 >>>> 
 >>>> (student-name (make-instance 'grad-student :name "Fred"))
 >> 
 >>> Is this student's STUDENT-NAME different from his
 >>> PERSON-NAME?  Or his CITIZEN-NAME?  Because I might want
 >>> to inherit from your grad student class.
 >> 
 >> (defclass person ((name :accessor person-name :initarg :name)))
 >> 
 >> (defclass student (person) ()
 >> (defclass grad (student) ())
 >> 
 >> (person-name (make-instance 'grad-student :name "Fred"))
 >> 
 >> What's your point?

 Henrik> Um, wasn't the difference between (student-name *must-be-a-student*)
 Henrik> and (name *any-object-that-might-have-a-name*) exactly the point here?
 Henrik> The difference between "student-name" and "name" seems to be rather
 Henrik> significant to me.

It seems to me that the point is that one should name their accessors
so that it describes the data being provided in a way that will make
sense for subclasses.  This is a very different rule from something like,
"Never use <class>-<slot> for a slot's accessor method", because often
that's exactly what will make the most sense.
From: Thomas F. Burdick
Subject: Re: Stop thinking in C
Date: 
Message-ID: <xcvvfmj9y54.fsf@famine.OCF.Berkeley.EDU>
······@news.dtpq.com (Christopher C. Stacy) writes:

> It seems to me that the point is that one should name their accessors
> so that it describes the data being provided in a way that will make
> sense for subclasses.  This is a very different rule from something like,
> "Never use <class>-<slot> for a slot's accessor method", because often
> that's exactly what will make the most sense.

Even then, <class> better be an extremely abstract class name, because
if you want to factor the slot up in the class heirarchy, or if you
want to have the accessor implemented for disjoint classes, it should
still make sense as a name.  Ie, STUDENT-NAME is a bad name, because
although it makes sense as is, NAME is exactly the kind of thing you
might want to factor out later.  Well chosen names and naming
conventions don't force you to predict the future.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Christopher C. Stacy
Subject: Re: Stop thinking in C
Date: 
Message-ID: <uhdy3493e.fsf@news.dtpq.com>
>>>>> On 06 Feb 2004 22:55:35 -0800, Thomas F Burdick ("Thomas") writes:

 Thomas> ······@news.dtpq.com (Christopher C. Stacy) writes:
 >> It seems to me that the point is that one should name their accessors
 >> so that it describes the data being provided in a way that will make
 >> sense for subclasses.  This is a very different rule from something like,
 >> "Never use <class>-<slot> for a slot's accessor method", because often
 >> that's exactly what will make the most sense.

 Thomas> Even then, <class> better be an extremely abstract class name, because
 Thomas> if you want to factor the slot up in the class heirarchy, or if you
 Thomas> want to have the accessor implemented for disjoint classes, it should
 Thomas> still make sense as a name.  

That's right, which is why the base class in application we saw
was STUDENT, not PERSON.

 Thomas> Ie, STUDENT-NAME is a bad name, because although it makes
 Thomas> sense as is, NAME is exactly the kind of thing you might want
 Thomas> to factor out later.  Well chosen names and naming
 Thomas> conventions don't force you to predict the future.

Since we don't know what application I was writing or anything 
more than the 4 lines of code we saw, it's impossible to say 
whether STUDENT-NAME is a good name or whether some more 
abstract equivalent NAME frob will be factored out.
From: Joe Marshall
Subject: Re: Stop thinking in C
Date: 
Message-ID: <znbv4tm3.fsf@comcast.net>
······@news.dtpq.com (Christopher C. Stacy) writes:

> It seems to me that the point is that one should name their accessors
> so that it describes the data being provided in a way that will make
> sense for subclasses.  This is a very different rule from something like,
> "Never use <class>-<slot> for a slot's accessor method", because often
> that's exactly what will make the most sense.

I agree.  I was trying to say ``Decide on the name, don't
automatically write <class>-<slot>.''  Often it makes sense, but often
it does not.

-- 
~jrm
From: Stefan Scholl
Subject: Re: Stop thinking in C
Date: 
Message-ID: <cwdb42gwogbu.dlg@parsec.no-spoon.de>
On 2004-02-07 01:32:21, Joe Marshall wrote:
> I agree.  I was trying to say ``Decide on the name, don't
> automatically write <class>-<slot>.''  Often it makes sense, but often
> it does not.

One of the first examples in Keene's "Object-Oriented Programming in
Common Lisp" uses something like <baseclass>-<slot>. simple-lock is
a subclass of lock, which hasn't an owner-slot. simple-lock defines
an accessor lock-owner for the slot owner.
From: Joe Marshall
Subject: Re: Stop thinking in C
Date: 
Message-ID: <isiheaex.fsf@comcast.net>
Stefan Scholl <······@no-spoon.de> writes:

> One of the first examples in Keene's "Object-Oriented Programming in
> Common Lisp" uses something like <baseclass>-<slot>. simple-lock is
> a subclass of lock, which hasn't an owner-slot. simple-lock defines
> an accessor lock-owner for the slot owner.

Let me give a concrete example of what I meant.  This is from a
project I worked on.  The VP of engineering had designed his own
define-class macro that expanded into a defclass with automatically
generated <class>-<slot> accessors and <class>-<slot> initargs.  He
was very adamant that we use this.

In the file-system abstraction, the BASE-FILE-DESCRIPTOR was the root
class for objects that referred to files.  It had three slots:
file-system, path, and modification-date.  From BASE-FILE-DESCRIPTOR
there were three subclasses:  DIRECTORY-DESCRIPTOR, LINK-DESCRIPTOR,
and FILE-DESCRIPTOR.  

When creating a file-descriptor, you'd have to do this:
(make-instance 'file-descriptor
   :base-file-descriptor-file-system file-system
   :base-file-descriptor-path path
   :base-file-descriptor-modification-date modification-date
   :file-descriptor-size size
   :file-descriptor-mode-list mode-list)

and when printing one, you'd do this:

(format stream ··@<#<~;~W~2I ~_~/pprint-fill/~;>~:>"
   (type-of descriptor)
   (list  
     (base-file-descriptor-file-system descriptor)
     (base-file-descriptor-path descriptor)
     (file-descriptor-size descriptor)
     (file-descriptor-mode-list descriptor)
     (base-file-descriptor-modification-date descriptor)))

As you can see, the fact that file-descriptor was a subclass of
base-file-descriptor is echoed again and again all over the code.  The
entire point of inheritance is that you can abstract out the common
code so that you don't have to be concerned whether you are using a
base or a derived class in the common case.  But everywhere in the
code you are reminded that some parts of the object are defined in one
class, some parts in another.

Maintenance is a pain as well:  if you decide to move a field from a
derived class to a base class, all the accessors will have a name
change.

Sure there are many cases where <class>-<slot> happens to be the
appropriate name for an accessor, but there are also many cases where
it is completely inappropriate.  The more difficult cases crop up when
you start doing more difficult things.  Rather than blindly generate
names via a macro, or apply strict rules, it is better to come up with
an appropriate name at the beginning.  It involves a tiny bit more
typing in the defclass form, but it can save so much trouble later.

-- 
~jrm
From: Rahul Jain
Subject: Re: Stop thinking in C
Date: 
Message-ID: <8765ehro4r.fsf@nyct.net>
Joe Marshall <·············@comcast.net> writes:

> Sure there are many cases where <class>-<slot> happens to be the
> appropriate name for an accessor, but there are also many cases where
> it is completely inappropriate.

I think naming accessors <protocol>-<slot> makes sense. Note that a
protocol isn't a class, in my terminology. I have a small library for
defining protocols and verifying that implementations of the protocol
are complete, but I haven't bothered to release it yet.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Joe Marshall
Subject: Re: Stop thinking in C
Date: 
Message-ID: <ekt85udv.fsf@comcast.net>
Alan Crowe <····@cawtech.freeserve.co.uk> writes:

> What has unsettled me is realising that class accessors are generic
> functions, but structure accessors are ordinary functions.  So
> structures /need/ the structure name prepended to the slot name, and
> structure users need to line it all up right.

Exactly so.  The generation of symbol names in structure accessors is
problematic.

-- 
~jrm
From: Marco Gidde
Subject: Re: Stop thinking in C
Date: 
Message-ID: <lz1xp8eaqn.fsf@tristan.br-automation.de>
Alan Crowe <····@cawtech.freeserve.co.uk> writes:

> Marco Gidde wrote:
> > One thing that holds me back from using DEFCLASS is its
> > talkativeness. DEFSTRUCT is much more compact and has
> > useful defaults for constructors and accesors.
> 
> I believed that until last week. Now I'm not so sure. What
> has unsettled me is realising that class accessors are
> generic functions, but structure accessors are ordinary
> functions. So structures /need/ the structure name prepended
> to the slot name, and structure users need to line it all up
> right.
> 
> Here are my notes to myself from last week. They are
> intended to be run as well as read. I hope I
> understood this correctly. Some-one on c.l.l. will be sure
> to say if I've got it wrong
> 
> ;;;; Accessors are generic functions
> 
> ;;;; Structures miss a trick
> 
> (defstruct one (a 1) (b 1))
> (defstruct two (a 2) (b (expt 2 2)))
> 
> (dolist (accessor '(one-a two-a))
> 	  (dolist (structure '(make-one make-two))
> 	    (let ((form `(,accessor (,structure))))
> 	      (format t "The form ~A yields values:~%  ~A~%"
> 		      form
> 		      (multiple-value-list
> 		       (ignore-errors
> 			(eval form)))))))
> 
> (defclass three ()
>   ((field :accessor name-clash
> 	  :initform 3)))
> 
> (defclass four ()
>   ((field :accessor name-clash
> 	  :initform 4)))
> 
> (format t "~%But with classes names may clash:~%   ~A~%"
> 	(mapcar #'name-clash
> 		(list
> 		 (make-instance 'three)
> 		 (make-instance 'four))))

I'm not sure wether it is wishful to use the same accessor on two
completely distinct types, but this is more a question of style and
was discussed a few months ago.

> ; Since structure accessors are functions
> ; the programmer must use distince names 
> ; to access the corresponding fields in
> ; different structures
> 
> ; Since slot accessors are generic functions
> ; clos will chose the right method for the class
> ; allowing corresponding accessors for different classes
> ; to be given the same name, even when there isn't a slot
> 
> (defclass spherical ()
>   (r
>    theta
>    phi))
> 
> (defclass cylindrical ()
>   (r
>    theta
>    (z :accessor z)))
> 
> (defclass rectangular()
>   (x y (z :accessor z) ))
> 
> (defmethod z ((point spherical))
>   (* (slot-value point 'r)
>      (sin (slot-value point 'phi))))

These classes seem to be distinct, but they are all geometric objects
and I would make this commonness more explicit by defining a base
class, e.g. GEOM-OBJ, and define Z as a generic function in the same
context, that is near GEOM-OBJ: 

(defclass geom-obj () ())

(defgeneric z (obj)
  (:documentation "blah"))


;;; somewhere else

(defclass spherical (geom-obj)
  (r
   theta
   phi))

...

This is of cause very crude :-)

What convinced me to use DEFCLASS in future are its dynamic aspects
(the result of redefining a structure is undefined), and the simple
fact, that most people here prefer it. Probably my insight will get
deeper by just trying it.

-- 
Marco Gidde
From: Tayssir John Gabbour
Subject: Re: Stop thinking in C
Date: 
Message-ID: <866764be.0402051139.3f41c9a1@posting.google.com>
Espen Vestre <·····@*do-not-spam-me*.vestre.net> wrote in message news:<··············@merced.netfonds.no>...
> ···@cartan.de (Nils G�sche) writes:
> > I would say Peter Norvig's Paradigms of Artificial Intelligence
> > Programming does just that.  I teaches Lisp by applying it to some
> > classical AI problems.  Highly recommended.
> 
> I second that. An excellent book!
> 
> The only thing I miss: More CLOS. Nowadays, I think that a beginner
> should forget about structures until (s)he might eventually need them,
> and start out with very simple CLOS usage instead.

The problem is reading from a stream is not covered anywhere, at least
not in a simple, safe and portable way like a structure.  It sucks for
a beginner to lose their objects at the end of a session.

Am I wrong?
From: Pascal Costanza
Subject: Re: Stop thinking in C
Date: 
Message-ID: <bvub97$ltk$1@newsreader2.netcologne.de>
Tayssir John Gabbour wrote:

> The problem is reading from a stream is not covered anywhere, at least
> not in a simple, safe and portable way like a structure.  It sucks for
> a beginner to lose their objects at the end of a session.
> 
> Am I wrong?

I don't quite understand your question here, but most CL environments 
provide a way to save and load images. You don't really need streams to 
save and load objects. Initial values can usually be encoded in source code.

An image is a snapshot of your environment. When you load it later on 
you will be exactly where you were when you saved it. This is not unlike 
saving the state of a game in many computer games. ;)


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Pascal Bourguignon
Subject: Re: Stop thinking in C
Date: 
Message-ID: <87znbxcier.fsf@thalassa.informatimago.com>
Pascal Costanza <········@web.de> writes:

> Tayssir John Gabbour wrote:
> 
> > The problem is reading from a stream is not covered anywhere, at least
> > not in a simple, safe and portable way like a structure.  It sucks for
> > a beginner to lose their objects at the end of a session.
> > Am I wrong?
> 
> I don't quite understand your question here, but most CL environments
> provide a way to save and load images. You don't really need streams
> to save and load objects. Initial values can usually be encoded in
> source code.
> 
> An image is a snapshot of your environment. When you load it later on
> you will be exactly where you were when you saved it. This is not
> unlike saving the state of a game in many computer games. ;)

Images  are  not  always  (perhaps  not even  often)  compatible  with
ulterior versions of the lisp  program.  Even going from clisp 2.30 to
clisp 2.32  I have to  throw away images.   And I'd say that  the fact
that  images   are  implementation  dependent   (not  compatible  with
different implementations)  is also a down point:  I frequently switch
between  openmcl,  cmucl,  sbcl   and  clisp,  to  profit  from  their
respective strong points.

Perhaps  one  could   develop  a  world  "dumping-and-reloading"  pure
Common-Lisp program that  could be used to transfer  an image contents
from one implementation/version to the  other. In the mean time, let's
stay with unix files (and some unix/C mindset, sorry).

I find structures useful  for quick-and-dirty storage of configuration
data.

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Henrik Motakef
Subject: Re: Stop thinking in C
Date: 
Message-ID: <x7y8rh8ae3.fsf@crocket.internal.henrik-motakef.de>
Pascal Costanza <········@web.de> writes:

> > The problem is reading from a stream is not covered anywhere, at least
> > not in a simple, safe and portable way like a structure.  It sucks for
> > a beginner to lose their objects at the end of a session.
> > Am I wrong?
> 
> I don't quite understand your question here, but most CL environments
> provide a way to save and load images. You don't really need streams
> to save and load objects. Initial values can usually be encoded in
> source code.
> 
> An image is a snapshot of your environment. When you load it later on
> you will be exactly where you were when you saved it. This is not
> unlike saving the state of a game in many computer games. ;)

One problem of CL images, as compared to Smalltalk images for example,
is that you generally do not have an equivalent of the "file-out"/
"file-in" commands , i.e. while you can keep your changes alive
through several sessions, there is not neccessarily a good way to
export the interesting parts of the image to a format that can be
easily imported into other images, especially not into images for
other implementations and/or architectures (CLISP images are at least
platform independent, IIRC). That is, there is no easy way to get an
(ideally portable, but whether that is possible obviously depends on
the things you changed) source file that will recreate the parts of
your image's state you care about while keeping other modifications
of the target image impact.

(I think it would be a lot harder to do in Lisp than in Smalltalk by
the way, especially given macros. Ideally, such a file-out would be
human-understandable, and hence it should, for example, better not be
macro-expanded. That means that if you want to keep the original
sources of functions that use a certain macro, you have to make sure
that exactly the right macro definition is used for each of them since
it might have changed between usages. In the extreme case, your
file-out would look a lot like a dribble file (which would be OK, but
I don't know an implementation that gives you such a thing without
explicitly calling DRIBBLE - sane decision in general, but not helping
with an image-centric development style).)

If all your important objects (where "object" is "anything of type T")
would be printable/readable, it should be easier to create such a
file-out yourself, you'd "only" have to find all relevant objects
somehow. CLOS objects, however, are generally not printable/readable,
while structures are.

On the other hand, this problem might not be a good justification to
use defstruct because 1) you could probably use
MAKE-LOAD-FORM-SAVING-SLOTS for something nearly as good as directly
printable structure objects, 2) you could easily define a syntax for
standard objects (a ready-made "save-object" library is mentioned in
the cliki, but the link seems to be dead) and 3) even while structure
objects are printable, reading them requires the structure class to be
defined, and structure classes are not any more printable/readable
than standard classes, let alone many other important objects as
functions, for example.
From: Tayssir John Gabbour
Subject: Re: Stop thinking in C
Date: 
Message-ID: <866764be.0402061423.42871f7e@posting.google.com>
Pascal Costanza <········@web.de> wrote in message news:<············@newsreader2.netcologne.de>...
> Tayssir John Gabbour wrote:
> > The problem is reading from a stream is not covered anywhere, at least
> > not in a simple, safe and portable way like a structure.  It sucks for
> > a beginner to lose their objects at the end of a session.
> > 
> > Am I wrong?
> 
> I don't quite understand your question here, but most CL environments 
> provide a way to save and load images. You don't really need streams to 
> save and load objects. Initial values can usually be encoded in source code.

Thanks for making me rethink my fear of straying from the spec.  I've
avoided images.

However, it seems that writing a readable clos object to stream is
something a person would legitimately want to do, if people frequently
do this with non-clos objects.

Let's forget I mentioned beginners losing "their objects at the end of
a session"; that was imprecise.
From: Pascal Costanza
Subject: Re: Stop thinking in C
Date: 
Message-ID: <c0197b$34j$1@newsreader2.netcologne.de>
Tayssir John Gabbour wrote:

> However, it seems that writing a readable clos object to stream is
> something a person would legitimately want to do, if people frequently
> do this with non-clos objects.
> 
> Let's forget I mentioned beginners losing "their objects at the end of
> a session"; that was imprecise.

I don't know the details, but I think that MAKE-LOAD-FORM and 
MAKE-LOAD-FORM-SAVING-SLOTS provide what you are looking for.

Section 3.2.4 in the HyperSpect ("Literal Objects in Compiled Files") 
also looks interesting.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Tayssir John Gabbour
Subject: Re: Stop thinking in C
Date: 
Message-ID: <866764be.0402061556.4acb7d2d@posting.google.com>
Pascal Costanza <········@web.de> wrote in message news:<············@newsreader2.netcologne.de>...
> Tayssir John Gabbour wrote:
> > The problem is reading from a stream is not covered anywhere, at least
> > not in a simple, safe and portable way like a structure.  It sucks for
> > a beginner to lose their objects at the end of a session.
> > 
> > Am I wrong?
> 
> I don't quite understand your question here

Ah, I see what you don't get.  I was pointing out that no lisp book
I'm aware of actually covers how one would write a readable clos
object to a stream.  In a portable way.  So that tempts people to
simply use structures, which by default are read/writable.

But I didn't necessarily contradict Joe; I'm just pointing out what I
believe is the barrier for clos adoption, whereas he was stating his
wish that people started with clos in preference to structures.  It's
possible he knew this barrier and I just stated the obvious.
From: Joe Marshall
Subject: Re: Stop thinking in C
Date: 
Message-ID: <d68t8per.fsf@comcast.net>
Espen Vestre <·····@*do-not-spam-me*.vestre.net> writes:

> Nowadays, I think that a beginner should forget about structures
> until (s)he might eventually need them, and start out with very
> simple CLOS usage instead.

I agree.

-- 
~jrm
From: André Thieme
Subject: CLOS, OOP (was: Re: Stop thinking in C)
Date: 
Message-ID: <c016pm$skp$1@ulric.tng.de>
Espen Vestre wrote:

> ···@cartan.de (Nils G�sche) writes:
> 
> 
>>I would say Peter Norvig's Paradigms of Artificial Intelligence
>>Programming does just that.  I teaches Lisp by applying it to some
>>classical AI problems.  Highly recommended.
> 
> 
> I second that. An excellent book!
> 
> The only thing I miss: More CLOS. Nowadays, I think that a beginner
> should forget about structures until (s)he might eventually need them,
> and start out with very simple CLOS usage instead.

Some people seem to like CLOS very much and use it often. Some others 
don't like OOP very much and therefore don't use CLOS, like Paul Graham:

"With macros, closures, and run-time typing, Lisp transcends
object-oriented programming.  If you understood the preceding
sentence, you probably should not be reading this book.  You would
have to know Lisp pretty well to see why it's true."

http://lib1.store.vip.sc5.yahoo.com/lib/paulgraham/acl1.txt
First chapter of his book "Ansi Common Lisp"


And http://www.paulgraham.com/noop.html which explains, why Arc isn't 
especially object oriented.
From: Kaz Kylheku
Subject: Re: Stop thinking in C
Date: 
Message-ID: <cf333042.0402050430.631baf0a@posting.google.com>
David Douthitt <·····@mailbag.com> wrote in message news:<··································@4ax.com>...
> I hadn't heard this complaint before, but ran across it recently in a
> different discussion thread here.
> 
> I've used many languages of different odd-ball sorts - the strangest
> ones being Forth and Smalltalk - so I'm probably not going to try and
> shoehorn things into C.
> 
> However, as I've always wanted to learn LISP, and am earnestly trying
> now (using CLISP) I'd like to know how to avoid this.
> 
> If you had to finish this sentence: "Newbies often try to think in C;
> they make the mistake of ...."

Newbies who think in C don't actually think in C. They think in a
language that they think is C, which is consists of whatever syntax is
accepted by their C compiler, and the structure and behavior of the
resulting code.

Short integers are 16 bits, and long integers are 32. So the
thinking-in-C newbie   saves machine cycles by doing things like:

  short array[2];

  *((long *) array) = 0;  /* clear 'em both in 1 instruction! */

Understanding the actual C language with its abstract semantics,
sequence points, and other bizarre rules would make their head
explode, so they mentally translate to the machine code of the most
widely installed architecture of the day.

In this regard, Lisp is different from C in two important ways. Lisp
implementations for the same machine architecture can vary
dramatically in even the ways they represent rudimentary data
structures such as integers. But on the other hand, the semantics of
Lisp have much fewer undefined behaviors. So if you were to assume,
say, that integers have a particular machine representation, it would
not only make your code far less portable than if you made the same
assumption in C, it would also make your life harder, rather than
easier.

In Lisp you don't have stupidities like unspecified evaluation orders
and sequence points. The naive left-to-right assumptions which would
trip up a C newbie will work in Lisp. So actually *some* of the
incorrect thinking-in-C business actually works better when
transplanted into the Lisp environment.

If your thinking-in-C leads you to believe that a[i] = ++i works in
some particular way, like by incrementing the i first, before
computing the a[i] displacement, and you convince yourself by trying
it on your compiler, then you are actually thinking a lot like a
Lisper, only without the rational justification from your programming
language.

In Lisp, if you try something, chances are much higher that it
actually works that way everywhere. The equivalent of a[i] = i++ is
something like:

  (setf (aref a i) (incf i))

this works in an orderly way, left to right. First A and I are
evaluated to determine the assignment place. Then (incf i) is
evaluated which updates i to the new value and returns it. Then the
new value is stored into the array. It works like the imaginary
function call:

  (store-into-array a i (incf i))

arguments are evaluated left to right. The side effects of any
expression happen   during the evaluation of that expression.
Similarly, whereas you get into trouble if you write

  (printf "%d %d %d\n", ++i, ++i, ++i);

oops, I mean

   printf("%d %d %d\n", ++i, ++i, ++i);

in Lisp you get consistent, well-defined behavior:

   (format t "~a ~a ~a~%" (incf i) (incf i) (incf i))

In C, even the same compiler can produce different results. Some years
ago, I found that using the same version of GCC on x86 and SPARC the
above printf would produce, with i starting at 0, "1 2 3" on x86 and
"3 2 1" on SPARC.

If thinking in C leads you to believe that it should be "1 2 3", you
are not really thinking in C. One of the two of you (you or your
programming language) have to be replaced with something smarter. :)

> How would you finish it?  Should there be a FAQ - "A LISPers Guide to
> Thinking in LISP"?

One way to start thinking in any language is to read its
specification, and any of the important satellite texts which are
accepted by the culture which surrounds that language as
second-to-best to the specification.
From: Jeremy Yallop
Subject: Re: Stop thinking in C
Date: 
Message-ID: <slrnc24kg0.33j.jeremy@hehe.cl.cam.ac.uk>
Kaz Kylheku wrote:
> In Lisp you don't have stupidities like unspecified evaluation orders

That's not strictly true: for example, it's unspecified whether the
function name in a call is evaluated before the arguments.  Of course,
that's unlikely to trip up a newbie.

Jeremy.
From: Duane Rettig
Subject: Re: Stop thinking in C
Date: 
Message-ID: <4wu71tt2c.fsf@franz.com>
Jeremy Yallop <······@jdyallop.freeserve.co.uk> writes:

> Kaz Kylheku wrote:
> > In Lisp you don't have stupidities like unspecified evaluation orders
> 
> That's not strictly true: for example, it's unspecified whether the
> function name in a call is evaluated before the arguments.  Of course,
> that's unlikely to trip up a newbie.

I think Kaz was talking about CL.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Jeremy Yallop
Subject: Re: Stop thinking in C
Date: 
Message-ID: <slrnc24qv9.3pk.jeremy@hehe.cl.cam.ac.uk>
Duane Rettig wrote:
> Jeremy Yallop <······@jdyallop.freeserve.co.uk> writes:
> 
>> Kaz Kylheku wrote:
>> > In Lisp you don't have stupidities like unspecified evaluation orders
>> 
>> That's not strictly true: for example, it's unspecified whether the
>> function name in a call is evaluated before the arguments.  Of course,
>> that's unlikely to trip up a newbie.
> 
> I think Kaz was talking about CL.

I think so too;  so was I:

   [3.1.2.1.2.3 Function Forms]

   Although the order of evaluation of the argument subforms
   themselves is strictly left-to-right, it is not specified whether
   the definition of the operator in a function form is looked up
   before the evaluation of the argument subforms, after the
   evaluation of the argument subforms, or between the evaluation of
   any two argument subforms if there is more than one such argument
   subform. For example, the following might return 23 or 24.

   (defun foo (x) (+ x 3))
   (defun bar () (setf (symbol-function 'foo) #'(lambda (x) (+ x 4))))
   (foo (progn (bar) 20))

IIRC, in Scheme the order of evaluation of the arguments is
unspecified as well.

Jeremy.
From: Duane Rettig
Subject: Re: Stop thinking in C
Date: 
Message-ID: <4r7x9tqv9.fsf@franz.com>
Jeremy Yallop <······@jdyallop.freeserve.co.uk> writes:

> Duane Rettig wrote:
> > Jeremy Yallop <······@jdyallop.freeserve.co.uk> writes:
> > 
> >> Kaz Kylheku wrote:
> >> > In Lisp you don't have stupidities like unspecified evaluation orders
> >> 
> >> That's not strictly true: for example, it's unspecified whether the
> >> function name in a call is evaluated before the arguments.  Of course,
> >> that's unlikely to trip up a newbie.
> > 
> > I think Kaz was talking about CL.
> 
> I think so too;  so was I:
> 
>    [3.1.2.1.2.3 Function Forms]
> 
>    Although the order of evaluation of the argument subforms
>    themselves is strictly left-to-right, it is not specified whether
>    the definition of the operator in a function form is looked up
>    before the evaluation of the argument subforms, after the
>    evaluation of the argument subforms, or between the evaluation of
>    any two argument subforms if there is more than one such argument
>    subform. For example, the following might return 23 or 24.
> 
>    (defun foo (x) (+ x 3))
>    (defun bar () (setf (symbol-function 'foo) #'(lambda (x) (+ x 4))))
>    (foo (progn (bar) 20))

Thanks, Edi and Jeremy, I hadn't seen this one.

However, I see this less as an evaluation-order issue than as an
issue of a higher order, which then happens to force the lack of
a guarantee in evaluation order.  Can you guess what it is?
Hint:  If you evaluate the last form a second time, are you
guaranteed a 24 result?

> IIRC, in Scheme the order of evaluation of the arguments is
> unspecified as well.

I believe that CL is the first Lisp to attempt a guarantee of argument
evaluation order.  But I'm sure if there were others, someone will
correct me :-)

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Jeremy Yallop
Subject: Re: Stop thinking in C
Date: 
Message-ID: <slrnc26u13.93s.jeremy@hehe.cl.cam.ac.uk>
Duane Rettig wrote:
> Jeremy Yallop <······@jdyallop.freeserve.co.uk> writes:
>>    [3.1.2.1.2.3 Function Forms]
>> 
>>    Although the order of evaluation of the argument subforms
>>    themselves is strictly left-to-right, it is not specified whether
>>    the definition of the operator in a function form is looked up
>>    before the evaluation of the argument subforms, after the
>>    evaluation of the argument subforms, or between the evaluation of
>>    any two argument subforms if there is more than one such argument
>>    subform. For example, the following might return 23 or 24.
>> 
>>    (defun foo (x) (+ x 3))
>>    (defun bar () (setf (symbol-function 'foo) #'(lambda (x) (+ x 4))))
>>    (foo (progn (bar) 20))
[...]
> However, I see this less as an evaluation-order issue than as an
> issue of a higher order, which then happens to force the lack of
> a guarantee in evaluation order.  Can you guess what it is?
> Hint:  If you evaluate the last form a second time, are you
> guaranteed a 24 result?

The answer to the latter is "yes", of course, but I still don't know
what the higher order issue is.  Could you explain, please?

Jeremy.
From: Duane Rettig
Subject: Re: Stop thinking in C
Date: 
Message-ID: <4llnghzcf.fsf@franz.com>
Jeremy Yallop <······@jdyallop.freeserve.co.uk> writes:

> Duane Rettig wrote:
> > Jeremy Yallop <······@jdyallop.freeserve.co.uk> writes:
> >>    [3.1.2.1.2.3 Function Forms]
> >> 
> >>    Although the order of evaluation of the argument subforms
> >>    themselves is strictly left-to-right, it is not specified whether
> >>    the definition of the operator in a function form is looked up
> >>    before the evaluation of the argument subforms, after the
> >>    evaluation of the argument subforms, or between the evaluation of
> >>    any two argument subforms if there is more than one such argument
> >>    subform. For example, the following might return 23 or 24.
> >> 
> >>    (defun foo (x) (+ x 3))
> >>    (defun bar () (setf (symbol-function 'foo) #'(lambda (x) (+ x 4))))
> >>    (foo (progn (bar) 20))
> [...]
> > However, I see this less as an evaluation-order issue than as an
> > issue of a higher order, which then happens to force the lack of
> > a guarantee in evaluation order.  Can you guess what it is?
> > Hint:  If you evaluate the last form a second time, are you
> > guaranteed a 24 result?
> 
> The answer to the latter is "yes", of course, but I still don't know
> what the higher order issue is.  Could you explain, please?

Actually, the answer to the latter question is "no".  If you look in
3.2.2.3 "Semantic Constraints", the fifth bullet says

  "A call within a file to a named function that is defined in the
   same file refers to that function, unless that function has been
   declared notinline.  The consequences are unspecified if functions
   are redefined individually at runtime or multiply defined in the
   same file."

So if the above sequence were placed into a file and compiled,
it would not be guaranteed that a second call to foo would return
24.  Of course, placing two calls: (foo (progn (bar) 20)) into a
file would be useless when looking for a return value, but it is
easy enough to fix things so that the results would be significant
without actually changing the essence of the question:

(defvar *x*)
(defvar *y*)
(defun foo (x) (+ x 3))
(defun bar () (setf (symbol-function 'foo) #'(lambda (x) (+ x 4))))
(setq *x* (foo (progn (bar) 20)))
(setq *y* (foo (progn (bar) 20)))

if the above were placed into a file and compiled, then when the file
is loaded there is no guarantee that (eq *x* *y*) ==> T



On the surface, this seems like an arcane and highly exceptional
rule.  However, I believe that it is only one of a few features
in CL that make for a higher-level feature.  You've heard in this
newsgroup many times that CL is a general-purpose language, and that
it has never had the goal to be "pure" wrt any concept, but instead
its goal is to be as useful as possible.  Among examples of these
impurities are the fact that CL allows functional programming, but
is not purely functional, and that it allows OO programming, but
is not strictly OO.  Well, we also tend to regard CL to be purely
dynamic, but it isn't, really.  CL does indeed encourage dynamicity,
but it also allows staticity, as well.  Let me explain:

If you define a function called PLUS, and then compile a call
to PLUS in a function called MYAPP, then you might expect that
when you then redefine PLUS that the behavior changes in MYAPP
as well.  But if before you had compiled MYAPP you had _also_
defined a compiler-macro for PLUS, then the compilation of MYAPP
would not necessarily involve a run-time call to the function PLUS,
and thus a change to PLUS's definition would not affect MYAPP.
This has both positive and negative connotations, which I won't
go into here.  But the effect is that there is a certain level
of "statification" support in CL, and compilr-macros are one aspect
of this support, and the explicit non-guarantee in the above ANS
reference is another aspect of this support (i.e. that users
must not count on a dynamic-redefinition within a file to have
an effect, because some kinds of statification, including block
compilation or optimized calling sequences, might have occurred).


-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Jeremy Yallop
Subject: Re: Stop thinking in C
Date: 
Message-ID: <slrnc29h3e.gg9.jeremy@hehe.cl.cam.ac.uk>
Duane Rettig wrote:
[...]

Thanks, that was extremely helpful!

Jeremy.
From: Edi Weitz
Subject: Re: Stop thinking in C
Date: 
Message-ID: <m3smhpfqr1.fsf@bird.agharta.de>
On 05 Feb 2004 08:00:27 -0800, Duane Rettig <·····@franz.com> wrote:

> Jeremy Yallop <······@jdyallop.freeserve.co.uk> writes:
>
>> Kaz Kylheku wrote:
>> > In Lisp you don't have stupidities like unspecified evaluation
>> > orders
>> 
>> That's not strictly true: for example, it's unspecified whether the
>> function name in a call is evaluated before the arguments.  Of
>> course, that's unlikely to trip up a newbie.
>
> I think Kaz was talking about CL.

I think Jeremy too. He was probably referring to CLHS 3.1.2.1.2.3:

  "Although the order of evaluation of the argument subforms
   themselves is strictly left-to-right, it is not specified whether
   the definition of the operator in a function form is looked up
   before the evaluation of the argument subforms, after the
   evaluation of the argument subforms, or between the evaluation of
   any two argument subforms if there is more than one such argument
   subform. For example, the following might return 23 or 24.

     (defun foo (x) (+ x 3))
     (defun bar () (setf (symbol-function 'foo) #'(lambda (x) (+ x 4))))
     (foo (progn (bar) 20))"

Cheers,
Edi.
From: ··········@YahooGroups.Com
Subject: Re: Stop thinking in C
Date: 
Message-ID: <REM-2004feb14-001@Yahoo.Com>
> From: Jeremy Yallop <······@jdyallop.freeserve.co.uk>
> Kaz Kylheku wrote:
> > In Lisp you don't have stupidities like unspecified evaluation orders
> That's not strictly true: for example, it's unspecified whether the
> function name in a call is evaluated before the arguments. ...

I've always wondered about that, and your article above provoked me to
do an experiment, which produced strange results. I distilled it down
to the following puzzle:

This is in a virgin: CMU Common Lisp 18b
         running on: FreeBSD 4.9-STABLE

* (foo (defun foo (a b) (list b a)) 5)
Converted FOO.
Error in KERNEL:%COERCE-TO-FUNCTION:  the function FOO is undefined.
0] q

* (fboundp 'foo)
NIL

* (foo (defun foo (a b) (list b a)) 5)
(5 FOO)

;Why did it fail the first time but succeed the second
; time, given that FOO remained undefined all the time?
;Did almost but not quite defining FOO the first time
; cause some side-effect that affected later behaviour?
;What global property, other than fboundp, should I be
; checking for, to uncover what is affecting behaviour?
From: Tim Daly Jr.
Subject: Re: Stop thinking in C
Date: 
Message-ID: <87bro17qb6.fsf@hummer.intern>
··········@YahooGroups.Com writes:

> > From: Jeremy Yallop <······@jdyallop.freeserve.co.uk>
> > Kaz Kylheku wrote:
> > > In Lisp you don't have stupidities like unspecified evaluation orders
> > That's not strictly true: for example, it's unspecified whether the
> > function name in a call is evaluated before the arguments. ...
> 
> I've always wondered about that, and your article above provoked me to
> do an experiment, which produced strange results. 
...
> ;Why did it fail the first time but succeed the second
> ; time, given that FOO remained undefined all the time?
> ;Did almost but not quite defining FOO the first time
> ; cause some side-effect that affected later behaviour?
> ;What global property, other than fboundp, should I be
> ; checking for, to uncover what is affecting behaviour?

You're invoking behavior that is not specified.  The implementation is
allowed to cause demons to fly out of your nose.  It's not very
important to understand why CMUCL behaves that way, since another
Lisp, indeed, another version of CMUCL, might act differently.

I believe this is the most relevant HyperSpec section:

http://www.lispworks.com/reference/HyperSpec/Body/03_ababc.htm

In particular, 

   "Although the order of evaluation of the argument subforms
    themselves is strictly left-to-right, it is not specified whether
    the definition of the operator in a function form is looked up
    before the evaluation of the argument subforms, after the
    evaluation of the argument subforms, or between the evaluation of
    any two argument subforms if there is more than one such argument
    subform."



-Tim

-- 
Who you calling a programmer, code monkey?
                                         -- Lupo LeBoucher on c.l.l
From: David Douthitt
Subject: Re: Stop thinking in C
Date: 
Message-ID: <ldo520h8mhv4lk6gn78kouatv7kdqcde18@4ax.com>
On 5 Feb 2004 04:30:18 -0800, ···@ashi.footprints.net (Kaz Kylheku)
wrote:

>One way to start thinking in any language is to read its
>specification [...]

I keep hearing that.  However, I would never recommend anyone read the
ANSI C standard in order to learn C (or ANSI FORTH, or ANSI COBOL for
that matter).  The K&R C standard is no better.

Last time I looked at the LISP standard it made my head swim.  At
least the Little Lisper and Winston & Horn were readable ;-)

David Douthitt (·····@douthitt.net)
UNIX System Administrator
HP-UX, Unixware, Linux
Linux+, LPIC-1
From: Fred Gilham
Subject: Re: Stop thinking in C
Date: 
Message-ID: <u7ad3xmtrr.fsf@snapdragon.csl.sri.com>
> If you had to finish this sentence: "Newbies often try to think in C;
> they make the mistake of ...."

Thinking integers are 32 bits.

Thinking macros are weak and painful to use.

Thinking C is better because it has infix notation for some of its
operators (such people often have pg, 49 from K&R 1st edition taped to
their terminals).

Thinking moving the parenthesis after the name of the function and
using commas to delimit the arguments is more readable than moving it
before the name and using spaces.

Thinking explicit pointers are essential.

Wondering why Lisp can't create executables. :-)

-- 
Fred Gilham                                         ······@csl.sri.com
The opponents of income taxation in 1912 said that we would see the
day when taxes would extract 25% of people's income. Such Cassandras
were ridiculed.                                        -- Gary North
From: Petter Gustad
Subject: Re: Stop thinking in C
Date: 
Message-ID: <m3ptctttkm.fsf@scimul.dolphinics.no>
Fred Gilham <······@snapdragon.csl.sri.com> writes:

> Thinking C is better because it has infix notation for some of its
> operators (such people often have pg, 49 from K&R 1st edition taped
> to their terminals).

Haha - I don't have my K&R handy, but page 49 must be the operator
precedence table, right?

Petter
-- 
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
From: Frank A. Adrian
Subject: Re: Stop thinking in C
Date: 
Message-ID: <pan.2004.02.05.16.35.20.873012@ancar.org>
On Thu, 05 Feb 2004 16:49:29 +0100, Petter Gustad wrote:

> Haha - I don't have my K&R handy, but page 49 must be the operator
> precedence table, right?

Nail, meet Head.  It boggles my mind that people still find infix so easy,
though my relation to arithmetic expressions has been hideously warped by
Lisp hacking and use of RPN calculators.

faa
From: Jeff Massung
Subject: Re: Stop thinking in C
Date: 
Message-ID: <10258qqreqbek09@corp.supernews.com>
"Frank A. Adrian" <·······@ancar.org> wrote in
···································@ancar.org: 

> On Thu, 05 Feb 2004 16:49:29 +0100, Petter Gustad wrote:
> 
>> Haha - I don't have my K&R handy, but page 49 must be the operator
>> precedence table, right?
> 
> Nail, meet Head.  It boggles my mind that people still find infix so
> easy, though my relation to arithmetic expressions has been hideously
> warped by Lisp hacking and use of RPN calculators.
> 
> faa
> 

Postfix (RPN) is far easier for me than prefix. It just makes more sense 
to me to load the data, then act on it. The only advantage of prefix 
(from a programming point of view) is knowing how many arguments are to 
be expected given an operator.

-- 
Best regards,
 Jeff			jma[at]mfire.com
 http://www.jm-basic.com
From: Dave Roberts
Subject: Re: Stop thinking in C
Date: 
Message-ID: <i6EUb.232270$xy6.1203720@attbi_s02>
Jeff Massung wrote:

> "Frank A. Adrian" <·······@ancar.org> wrote in
> ···································@ancar.org:
> 
>> On Thu, 05 Feb 2004 16:49:29 +0100, Petter Gustad wrote:
>> 
>>> Haha - I don't have my K&R handy, but page 49 must be the operator
>>> precedence table, right?
>> 
>> Nail, meet Head.  It boggles my mind that people still find infix so
>> easy, though my relation to arithmetic expressions has been hideously
>> warped by Lisp hacking and use of RPN calculators.
>> 
>> faa
>> 
> 
> Postfix (RPN) is far easier for me than prefix. It just makes more sense
> to me to load the data, then act on it. The only advantage of prefix
> (from a programming point of view) is knowing how many arguments are to
> be expected given an operator.
> 

Try FORTH. You'll love it.

I'm the same way as you are. I find RPN calculators tremendously easy (the
"Right Way"). Prefix is much more difficult for me.
From: Petter Gustad
Subject: Re: Stop thinking in C
Date: 
Message-ID: <878yjgptzc.fsf@zener.home.gustad.com>
Dave Roberts <·····@re-move.droberts.com> writes:

> I'm the same way as you are. I find RPN calculators tremendously
> easy (the "Right Way"). Prefix is much more difficult for me.

You mean infix don't you? On a prefix calculator you would type + 1
ENTER 2 =. On a postfix (RPN) you type 1 ENTER 2 +.

Petter
-- 
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
From: Brian Downing
Subject: Re: Stop thinking in C
Date: 
Message-ID: <D6QUb.240106$na.397078@attbi_s04>
In article <··············@zener.home.gustad.com>,
Petter Gustad  <·············@gustad.com> wrote:
> You mean infix don't you? On a prefix calculator you would type + 1
> ENTER 2 =. On a postfix (RPN) you type 1 ENTER 2 +.

I'm not sure whether the grandparent poster meant prefix or infix, but I
for one would not like to use a prefix calculator.

In Lisp notation you don't see the answer interactively; you're building
up the whole problem which will get run later.  Prefix (and even infix,
sort of) are good at representing that.

For immediate use, postfix is very good, because you see the
intermediate results as you go.  Also, you can just sort of jump into a
complex equation, go to a term that's deep inside, and start, and more
than likely you will be able to do it, possibly with various stack
manipulations along the way.  With a prefix calculator, you'd need to
start from the outside of the equation and work outside-in, and the
order of entry would be much more strictly defined.  You'd lose the
seat-of-the-pants feel that I really like about RPN calcs.

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Dave Roberts
Subject: Re: Stop thinking in C
Date: 
Message-ID: <oLZUb.189765$5V2.1014584@attbi_s53>
Brian Downing wrote:

> In article <··············@zener.home.gustad.com>,
> Petter Gustad  <·············@gustad.com> wrote:
>> You mean infix don't you? On a prefix calculator you would type + 1
>> ENTER 2 =. On a postfix (RPN) you type 1 ENTER 2 +.
> 
> I'm not sure whether the grandparent poster meant prefix or infix, but I
> for one would not like to use a prefix calculator.

I meant prefix. Yes, there is no prefix calculator that I know of, but there
is Lisp. ;-) Seriously, my dad worked at HP for multiple decades and the
first calculator I ever saw was, well, the first calculator model that ever
was. And it was RPN. Everything else is just, well, wrong... ;-) Of course
that always kept my business-major room mates from borrowing my calculator
for finals week at university. After two minutes looking for the "=" key,
they would give up and hand it back.

> In Lisp notation you don't see the answer interactively; you're building
> up the whole problem which will get run later.  Prefix (and even infix,
> sort of) are good at representing that.

I find prefix great for representing what I would consider function calls
and such. For whatever reason, when it comes to expressions, I find RPN
easier. Go figure. I suppose I could reprogram something in Lisp to create
a postfix Lisp or something. That would be fun... ;-)

-- Dave
From: David Douthitt
Subject: Re: Stop thinking in C
Date: 
Message-ID: <ml6820lrit9609rhmcqkl6ip73i9nb900n@4ax.com>
On Fri, 06 Feb 2004 03:46:22 GMT, Dave Roberts
<·····@re-move.droberts.com> wrote:

>Jeff Massung wrote:
>
>> "Frank A. Adrian" <·······@ancar.org> wrote in
>> ···································@ancar.org:

>> Postfix (RPN) is far easier for me than prefix. It just makes more sense
>> to me to load the data, then act on it. The only advantage of prefix
>> (from a programming point of view) is knowing how many arguments are to
>> be expected given an operator.

>Try FORTH. You'll love it.

I second that.  I love FORTH, but haven't made the jump to a new
compiler.

Maybe some day.... after I learn LISP ;-)

David Douthitt (·····@douthitt.net)
UNIX System Administrator
HP-UX, Unixware, Linux
Linux+, LPIC-1
From: Jeff Massung
Subject: Re: Stop thinking in C
Date: 
Message-ID: <1027kjjtgjjgsfd@corp.supernews.com>
Dave Roberts <·····@re-move.droberts.com> wrote in
·····························@attbi_s02: 

> Try FORTH. You'll love it.

I've written several Forth compilers... but thanks :) IMHO, Lisp and Forth 
are the two grand-daddies of programming languages -- and are still the two 
best!

-- 
Best regards,
 Jeff			jma[at]mfire.com
 http://www.jm-basic.com
From: Pascal Bourguignon
Subject: Re: Stop thinking in C
Date: 
Message-ID: <87vfmlci39.fsf@thalassa.informatimago.com>
Fred Gilham <······@snapdragon.csl.sri.com> writes:
> Thinking moving the parenthesis after the name of the function and
> using commas to delimit the arguments is more readable than moving it
> before the name and using spaces.

They're the same who use coma-space instead of coma to separate the arguments!

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Tayssir John Gabbour
Subject: Re: Stop thinking in C
Date: 
Message-ID: <866764be.0402050908.3e0f814f@posting.google.com>
David Douthitt <·····@mailbag.com> wrote in message news:<··································@4ax.com>...
> If you had to finish this sentence: "Newbies often try to think in C;
> they make the mistake of ...."
> 
> How would you finish it?  Should there be a FAQ - "A LISPers Guide to
> Thinking in LISP"?

I might point out to a pre-lisp Tayssir that lisp's symbolic
expressions can also encode data well, more clearly than XML. 
Therefore many data techniques like normalization can be used.  Never
need to bore yourself through repetition.

Also, in some senses lisp has a plumbing language which allows you to
build the notation you really want.  Here's something that looks
nearly like what you'd write on a napkin:

(automaton init
  (init : (c -> more))
  (more : (a -> more)
          (d -> more)
          (r -> end))
  (end  : (r -> end)))

This is in PLT Scheme from a talk I'll cite below.  The plumbing
Shriram needed to make the computer understand it was about 15-20
lines.  There's actually a bug here, it seems to me.  If this had been
embedded in XML or Java, I probably wouldn't have noticed.  You can
show it to five people in your office, and someone would point it out
even if they don't know lisp.

(The bug was that he intended it to accept the regex c[ad]+r , but it
seems to really accept c[ad]*r+ .  I assume end is the accept state. 
If I'm wrong, grab a cluestick and get in line.)

I hope this helps demonstrate to a nonlisper how much their
programming skill can extend to writing programs for them, getting to
the very heart of what they wish to describe.


- - - -
cite:
Shriram's talk and slides of "The Swine Before Perl" are available at
 ftp://ftp.ddj.com/technetcast/mp3/tnc-0644-24.mp3
 http://ll1.ai.mit.edu/agenda.html
From: Daniel Barlow
Subject: Re: Stop thinking in C
Date: 
Message-ID: <87n07x323s.fsf@noetbook.telent.net>
David Douthitt <·····@mailbag.com> writes:

> If you had to finish this sentence: "Newbies often try to think in C;
> they make the mistake of ...."

thinking each closing brace is important enough to need its own
newline and whitespace to separate it from all the other closing
braces.


-dan

-- 
"please make sure that the person is your friend before you confirm"
From: Plamen Stamov
Subject: Re: Stop thinking in C
Date: 
Message-ID: <402378ed@news01.datazug.ch>
David Douthitt wrote:
> If you had to finish this sentence: "Newbies often try to think in C;
> they make the mistake of ...."

I think that such sentence would be really meaningfull only in the 
context of a specific solution to a specific problem.

Instead I would suggest the study of the Lisp-solution of a sufficiently 
large/complex problem whose design decisions are well documented. The 
highest educational value in this respect and in my knowledge has the 
book "The Art of the Metaobject Protocol" 
(http://www.amazon.com/exec/obidos/tg/detail/-/0262610744/104-9584226-8264707?v=glance).

Regards
Plamen Stamov
From: Stefan Scholl
Subject: Re: Stop thinking in C
Date: 
Message-ID: <8gmiahml3usg$.dlg@parsec.no-spoon.de>
On 2004-02-06 12:17:25, Plamen Stamov wrote:
> David Douthitt wrote:
>> If you had to finish this sentence: "Newbies often try to think in C;
>> they make the mistake of ...."
> 
> I think that such sentence would be really meaningfull only in the 
> context of a specific solution to a specific problem.

I don't have the experience to answer the original question but I
know that there are some idioms in other languages which aren't uses
by newbies with a C background.

Iterating over an array. C people use a for-loop with an index from
0 to n. In languages like Ruby or Perl you have other methods to
work with arrays. But you can still use the C way, which looks
really ugly in the eyes of an experienced programmer of Ruby or
Perl.
From: Plamen Stamov
Subject: Re: Stop thinking in C
Date: 
Message-ID: <40269bdf@news01.datazug.ch>
Stefan Scholl wrote:
> On 2004-02-06 12:17:25, Plamen Stamov wrote:
> 
>>David Douthitt wrote:
>>
>>>If you had to finish this sentence: "Newbies often try to think in C;
>>>they make the mistake of ...."
>>
>>I think that such sentence would be really meaningfull only in the 
>>context of a specific solution to a specific problem.
> 
> 
> I don't have the experience to answer the original question but I
> know that there are some idioms in other languages which aren't uses
> by newbies with a C background.
> 
> Iterating over an array. C people use a for-loop with an index from
> 0 to n. In languages like Ruby or Perl you have other methods to
> work with arrays. But you can still use the C way, which looks
> really ugly in the eyes of an experienced programmer of Ruby or
> Perl.

My idea was, that, to just iterate over an array, in Lisp you have may 
be more possibilities (do, do*, loop, all the map- functions, you can 
create you own C-like "for"-macro, or even you could use gatherers, 
generators, series, the iterate-package etc.) and all are equal. Because 
to just iterate is a too simple requirement. The difference between the 
  descibed possibilites (and with that the recipe for not using this C 
or that Perl idiom) comes when you decide what do you want to do during 
the iteration, or when you iterate (may be for example lazy) over a a 
more complex data structure, or would you like to pass the iteration 
code to a code-walker, or should it be a CL-defined form (not like 
Series for example) etc. etc.

I propsed the AMOP book, because it includes also the source code of an 
example implementation, and if you look there, (if I remember well) you 
will not find a single array there (not because arrays are bad, just 
they are not needed in most cases) - which I suppose would not be the 
case if the problem had to be solved by a C-programmer (who has usually 
very few options). But it is plenty with idioms and explanations, which 
would help more.
From: David Combs
Subject: Re: Stop thinking in C
Date: 
Message-ID: <c1rm26$f80$1@reader2.panix.com>
In article <········@news01.datazug.ch>,
Plamen Stamov  <········@stamov.ch> wrote:

SNIP


>I propsed the AMOP book, because it includes also the source code of an 
>example implementation, and if you look there, (if I remember well) you ...

Would be nice if there were some *additional* introductions,
tutorials, etc, to MOP, written by other people -- as there
of course are for lisp, CL, etc -- so if you find one approach
to learning difficult, perhaps a different author will have
an approach more suited to one's particular makeup or history
or top-down vs bottom-up way of thinking, etc.

*Is* there anything other than the AMOP book?

Are there books that even have a *chapter* or two
on the subject?

David
From: Pascal Costanza
Subject: Re: Stop thinking in C
Date: 
Message-ID: <c1sm78$sfv$1@newsreader2.netcologne.de>
David Combs wrote:

> Would be nice if there were some *additional* introductions,
> tutorials, etc, to MOP, written by other people -- as there
> of course are for lisp, CL, etc -- so if you find one approach
> to learning difficult, perhaps a different author will have
> an approach more suited to one's particular makeup or history
> or top-down vs bottom-up way of thinking, etc.
> 
> *Is* there anything other than the AMOP book?
> 
> Are there books that even have a *chapter* or two
> on the subject?

I can recommend the book "Object-oriented programming - the CLOS 
perspective", edited by Andreas Paepcke. Unfortunately, it is out of print.

His chapter, "User-level language crafting" can be downloaded from his 
website at 
http://www-db.stanford.edu/~paepcke/shared-documents/mopintro.ps and is 
a very good introduction to the basic notions of the CLOS MOP.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: David Douthitt
Subject: Re: Stop thinking in C
Date: 
Message-ID: <n3pq20pgj0vcqisiboh2fv3fbhcdj0s4ab@4ax.com>
On Sun, 8 Feb 2004 17:58:34 +0100, Stefan Scholl <······@no-spoon.de>
wrote:

>On 2004-02-06 12:17:25, Plamen Stamov wrote:
>> David Douthitt wrote:
>>> If you had to finish this sentence: "Newbies often try to think in C;
>>> they make the mistake of ...."

>Iterating over an array. C people use a for-loop with an index from
>0 to n.

My understanding was that originally LISP didn't have a "for loop."
So in LISP I don't think of using loops in that way - I guess I'm safe
then....

>In languages like Ruby or Perl you have other methods to
>work with arrays.

As I've said elsewhere, I program in Ruby almost daily - and I also
used to write in Perl about the same.

I wouldn't use a "for loop" in either language.

David Douthitt (·····@douthitt.net)
UNIX System Administrator
HP-UX, Unixware, Linux
Linux+, LPIC-1