[comp.lang.forth] ... and zen there were objects.

rob@idacom.uucp (Rob Chapman) (08/07/90)

 I did a paper about 3 years ago on adding structure defining words to
 Forth much in the way of the C struct{} (Roch'87).  I designed the language
 for this extension with a few prototypes and a lot of gut feel about how I
 would like to use the words.  Following Forth ideals, I desired to keep it
 simple (in implementation and in definition) as well as extendable.
 
 I implemented it twice and used it with a group of programmers to build a
 user interface toolkit.  Then I thought about if for 3 years.

 I was going to include it in botForth if I could make it simple enough yet
 very powerful.  A co-Forther, Andrew Scott, suggested that it would be nice
 to have a zen version of structures.  This inspired the desire to seek a
 simple way.  That night I prototyped a very simple set of words.  It seemed
 to be what I was looking for.  Only two words were needed.  But it still
 didn't seem powerful enough.

 Suddenly I had an impulse to replace all occurances of the word structure
 with the word object and all the occurances of access with method.  All of
 a sudden the code seemed to grow in ability.  Before, I had used the structure
 words to define memory templates.  Now, I could define more than just memory
 objects, they could be more abstract like a window or a file etc.

 What follows is an edited version of what I presented at one of our weekly
 FUG (Forth Users Group) gatherings.  I still consider it raw code but it is
 amusing what can be done with 2 level defining words and by forming a
 link list of compilers.  Interestingly the link listing allows a method to
 inherit objects.

 At the bottom, I've included a glossary of some words from botForth.

( ==== Excerpt from FUG Aug 2 1990 ==== )

			  Objects in botForth
			      Rob Chapman

  Object Oriented Programming (OOP) employs the notion of objects and
  methods as a programming abstraction.  By defining the two words OBJECT
  and METHOD, we can explore this programming paradigm.
  
  OBJECT is used to create objects which have three properties:
     1. INSTANCE - creates a memory space for an object.
     2. ELEMENT  - used to define the memory elements of an object.
     3. CAST     - provide a context for determining which method to use.

  METHOD is used to define a method of dealing with an object.  In OOP,
  like English, one word may be used in many different contexts.  This means
  that the word OPEN could be a method to open windows and files; + could be a
  method to operate on floating point or complex numbers or as many objects as
  defined.  In fact, it might be possible to create a smaller set of words to
  work with, for programming, by applying OOP to the whole dictionary (imagine
  a one screen WORDS).  

( ==== Object internals ==== )
  0 VARIABLE object  ( points to current object )

: +BYTES  ( n -- )  object @ +! ;
: #BYTES  ( -- n )  object @ @ ;

( ==== Properties of Objects ==== )
: CAST  ( object -- )  object ! ;
: INSTANCE ( object -- )  <BUILDS IMMEDIATE  DUP ,  @ ALLOT
   DOES>  ( inst -- a )  @+  \ LITERAL  CAST ;
: ELEMENT  ( object -- )  <BUILDS IMMEDIATE  DUP ,  @ +BYTES
   DOES>  ( a \ element -- a+ )  @  DUP CAST  @ \ LITERAL ' + ?COMPILE ;

( ==== Object Builder ==== )
  NO VARIABLE in-object  ( flags whether an object is being built )

: OBJECT  ( -- )  YES in-object !
   <BUILDS IMMEDIATE  HERE 0 , CAST
   DOES>  ( object -- )  compile @
    IF  CAST
    ELSE  in-object @  IF  ELEMENT  ELSE  INSTANCE  THEN ENDIF ;
: END-OBJECT  ( -- )  NO in-object ! ;

( ==== Method Builder ==== )
: METHOD  ( default \ method -- )  <BUILDS IMMEDIATE  object @ ,  ,  ,
   DOES>  ( handle -- )  @+ SWAP  object @ =
    IF  @ ?COMPILE  ELSE  4 + @ EXECUTE  ENDIF ;


( ===== Object definitions ===== )

( ==== No method error message ==== )
: NO-METHOD  ( -- )
   ." Sorry, method not defined for current object. " ERROR ;

( ==== Memory Objects ==== )
  OBJECT BYTE>
    1 +BYTES

    ' NO-METHOD  ' C@  METHOD  GET
    ' NO-METHOD  ' C!  METHOD  PUT
    ' NO-METHOD  ' C+! METHOD +PUT
  END-OBJECT

  OBJECT WORD>
    BYTE> >UPPER	( motorola-ish )
    BYTE> >LOWER

    ' GET  ' @  METHOD  GET
    ' PUT  ' !  METHOD  PUT
    ' +PUT ' +! METHOD +PUT
  END-OBJECT

( ==== Mathematical objects ==== )
  OBJECT INTEGER>
    2 +BYTES

    ' NO-METHOD  ' +  METHOD  ADD
    ' NO-METHOD  ' -  METHOD  SUB
    ' NO-METHOD  ' *  METHOD  MUL
    ' NO-METHOD  ' /  METHOD  DIV
  END-OBJECT

  OBJECT FLOAT>
    INTEGER> >MANTISSA
    INTEGER> >EXPONENT

    ' ADD        ' F+    METHOD  ADD
    ' SUB        ' F-    METHOD  SUB
    ' MUL        ' F*    METHOD  MUL
    ' DIV        ' F/    METHOD  DIV
    ' NO-METHOD  ' FSIN  METHOD  SIN
  END-OBJECT

( ==== Environmental Objects ==== )
  OBJECT TIME-STAMP>
    6 +BYTES

    ' ADD  ' TSTAMP_ADD  METHOD  ADD
    ' SUB  ' TSTAMP_SUB  METHOD  SUB
  END-OBJECT

  OBJECT WINDOW>
    BYTE> >COL
    BYTE> >ROW

    ' NO-METHOD  ' OPEN_WINDOW  METHOD  OPEN
  END-OBJECT

  OBJECT FILE>
    ...

    ' OPEN  ' OPEN-FILE  METHOD OPEN
  END-OBJECT

( ==== Excerpt from botForth Glossary: 32-bit figForth interface ==== )
: compile  ( -- a )  STATE ;
: COMPILE  ( cfa -- )  , ;
: ?COMPILE  ( cfa -- )  compile @  IF  COMPILE  ELSE  EXECUTE  ENDIF ;
: \  ( -- )  [COMPILE] [COMPILE] ; IMMEDIATE
: '  ( -- cfa )  \ '  ' CFA CFA ?COMPILE ; IMMEDIATE
: @+  ( a -- n \ a+ )  DUP @  SWAP 4 + ;

 Note to the casual user of [COMPILE] (or \):
   I prefer to use  \  to force a compile on the next word.  But I find it
   clearer to do the equivelant using  '  and  EXECUTE.  For instance:
   I prefer  \ LITERAL  but to explain what that phrase means, its becomes
   clear when written as  ' LITERAL EXECUTE.

dwp@willett.pgh.pa.us (Doug Philips) (08/10/90)

In <1990Aug7.081509.2315@idacom.uucp>, rob@idacom.uucp (Rob Chapman) writes:

I was going to reply to your message specificly, but decided that it
would rather make a good jumping off point for something that I've just
recently put my finger on.  I don't intend this to discourage you, or anyone
else, from making posts of the quality that you made.  I have not
read all of the existing Forth literature, but I would be surprised if
what I have to say has not been said before.

What I think is wrong with Object Oriented Extensions to Forth:

All the OOEF's I have seen so far involve active objects or messages
or both.  By active I mean that the words are IMMEDIATE words.

I have a couple of problems with active obects and messages.

Take for example Pountain's system as described in his book.  Objects
are active.  That means that all objects must have names.  In order to
create arrays of objects, one must create special active arrays.  From
this it seems to follow that one must create special active versions of
other things that involve objects.  It also means that you cannot have
anonymous objects.  That is in part what annoys me most.  You cannot
write a word which will "return" (i.e. leave on the top of the stack)
an object.  I think you could probably cobble something up if you
restricted the word to always return objects of the same type.  Hardly
a liveable restriction in my book.

Active message names are not much better.  You cannot have a word which
returns a message.  That is a somewhat esoteric thing to do in most
OO systems, but it does allow for message names to be passed as 
parameters to other messages, esp. to the message 'RespondsTo' which
will tell you if the object can respond to the given message.

I also dislike the necessity of doing message sends from the "inside
out":
	PushArg PushArg Object Message

I say "inside out" because in traditional OO systems, say SmallTalk, the
syntax is:
	Object Message Arg Arg ...

so the "inside out" syntax is neither "prefix" nor "post fix" but inside out.
	
The SmallTalk syntax works nicely for both nesting and cascading.  Since
Forth is post-fix, I think that the syntax should be:
	PushArg PushArg Message Object

That looks ok, but it does not do anything.  In order to do something you
would have to add a special word.  I would pick SEND, as in:
	10 20 MoveTo MyRectangle SEND

the nice thing about having an explicit send is that you can replace
MoveTo and/or MyRectangle with arbitrary Forth code and still have it
work.

This is not stuff that I've thought hard about for a long time, nor have I
implemented and played with to get at its practicality.  I would appreciate
feedback.  I would also like to hear defenses for the active systems.
Perhaps I have overlooked or misunderstood something.


-Doug

---
Preferred: ( dwp@willett.pgh.pa.us  OR  ...!{sei,pitt}!willett!dwp )
Daily: ...!{uunet,nfsun}!willett!dwp  [last resort: dwp@vega.fac.cs.cmu.edu]

tsaari@tukki.jyu.fi (Antero Taivalsaari) (08/15/90)

In message <1498.UUL1.3#5129@willett.pgh.pa.us> (Doug Philips) writes:

>What I think is wrong with Object Oriented Extensions to Forth:
>
>All the OOEF's I have seen so far involve active objects or messages
>or both.  By active I mean that the words are IMMEDIATE words.
>
>Take for example Pountain's system as described in his book. ...

My personal opinion is that Pountain's book - although it is
rather well written - is not that good in the object-oriented sense. 
However, his earlier paper in JFAR (vol 3, nr 3, 1986, p.51-73) 
introduces much more elegant object-oriented extensions to Forth. 
In these extensions, the syntax for message sending is:

	PushArg PushArg Object \ message

The word '\' is a special message operator that simply takes 
an address from the top of stack and considers it as the receiver 
of the message. By using this solution, the receiver object and
the message need not have any syntactic relationship to each other.
It is very easy to pass objects around in the system, since 
they can be referred to by simple addresses.

By using this kind of solution, you can easily have anonymous objects;
also, you can easily write words that return objects on the top of the
stack (both of these are, indeed, VERY fundamental operations in 
object-oriented programming).

I have been programming with these kind of OOP extensions to
Forth about three years now, heavily extending and modifying 
Pountain's original code and I am quite convinced that this is the 
right way to do message passing in Forth. However, if a more postfix 
solution is desired, an alternative syntax could also be (as you suggest):

	PushArg PushArg " message" Object SEND

Again, 'SEND' is a special word that simply takes an address
from the top of stack and considers it as the receiver of the message.
'Message' is a string whose address will also be passed to the 
message operator 'SEND'. In Pountain's JFAR code, this kind of 
solution is used internally by the system; however, in his code
message strings are first hashed to integers to improve the efficiency 
of late binding.

Regards,

Antero Taivalsaari
University of Jyvaskyla, Finland
tsaari@jyu.fi

DN5@psuvm.psu.edu (08/15/90)

In article <1498.UUL1.3#5129@willett.pgh.pa.us>, dwp@willett.pgh.pa.us (Doug
>What I think is wrong with Object Oriented Extensions to Forth:

  [Deleted text]

>That looks ok, but it does not do anything.  In order to do something you
>would have to add a special word.  I would pick SEND, as in:
>        10 20 MoveTo MyRectangle SEND
>
>the nice thing about having an explicit send is that you can replace
>MoveTo and/or MyRectangle with arbitrary Forth code and still have it
>work.

My comments:

I don't like this syntax, because it means that I would have to
do something special if I had a function which returned an object
(i.e., I had an anonymous object on the top of the stack).  The
syntax which I came up with when I was experimenting with objects
in forth is similar:

    10 20 MyRectangle ~ MoveTo

Using the Mac keyboard, I had access to all sorts of funky symbols,
but I liked the tilda best, because it is obvious, unused, and also
on most other keyboards of other systems.

Basically ~ was an immediate word which took the next word as a
string, and hashed it to a method reference, and compiled a call
to the object dereferencer with that as a parameter.  In the future
I would replace all calls which could be figured out at compile
time to a direct call to word involved.

Unfortunately, I never got any further than creating the syntax,
because somebody offered me actual cash to work on something else.
Hopefully in the fall I can go back to work on this, so I can have
a better development environment than Pascal or C. :-)  :-)

()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
D. Jay Newman                !  All syllogisms have three parts,
dn5@psuvm.psu.edu            !  therefore this is not a syllogism.
CBEL--Teaching and Learning Technologies Group

bouma@cs.purdue.EDU (William J. Bouma) (08/16/90)

In article <1498.UUL1.3#5129@willett.pgh.pa.us> dwp@willett.pgh.pa.us (Doug Philips) writes:
>I also dislike the necessity of doing message sends from the "inside
>out":
>	PushArg PushArg Object Message
>
>I say "inside out" because in traditional OO systems, say SmallTalk, the
>syntax is:
>	Object Message Arg Arg ...
>
>so the "inside out" syntax is neither "prefix" nor "post fix" but inside out.


    Well, you asked for feedback. I would say you are being needlessly
    picky here. Since when has anyone who advocates forth cared what any
    'traditional' language looks like. I would say the syntax with the
    message at the end is really the most forth-like. The function usually
    comes at the end in forth. The message is basically just an indirect
    function call.

	
>The SmallTalk syntax works nicely for both nesting and cascading.  Since
>Forth is post-fix, I think that the syntax should be:
>	PushArg PushArg Message Object


    Dissagree. I would call this syntax "inside out".
 

>That looks ok, but it does not do anything.  In order to do something you
>would have to add a special word.  I would pick SEND, as in:
>	10 20 MoveTo MyRectangle SEND


    SEND is a good word. But it should only be necessary if there is a
    message sitting on the stack. ie "normal" generic function call should
    go like this:
			PushArg PushArg Object Message

    But the same thing could be accomplished by:

			PushArg PushArg Object ' Message SEND

    Thus you can have messages returned on the stack and you can tell at
    a glance whether that is in fact what a line of code will do.
-- 
Bill <bouma@cs.purdue.edu>      Just ask the Axis   He knows everything

dwp@willett.pgh.pa.us (Doug Philips) (08/16/90)

In <1990Aug15.071510.3363@tukki.jyu.fi>, tsaari@tukki.jyu.fi (Antero Taivalsaari) writes:
> However, his [Pountain's] earlier paper in JFAR (vol 3, nr 3, 1986, p.51-73) 
> introduces much more elegant object-oriented extensions to Forth. 
> In these extensions, the syntax for message sending is:
> 
> 	PushArg PushArg Object \ message
> 
> It is very easy to pass objects around in the system, since 
> they can be referred to by simple addresses.
> 
> By using this kind of solution, you can easily have anonymous objects;
> also, you can easily write words that return objects on the top of the
> stack (both of these are, indeed, VERY fundamental operations in 
> object-oriented programming).

Agreed.  I think that is better than what he had in the book.  I still
don't like the prefix nature of '\ message' though.

> right way to do message passing in Forth. However, if a more postfix 
> solution is desired, an alternative syntax could also be (as you suggest):
> 
> 	PushArg PushArg " message" Object SEND
> 
> Again, 'SEND' is a special word that simply takes an address
> from the top of stack and considers it as the receiver of the message.
> 'Message' is a string whose address will also be passed to the 
> message operator 'SEND'. In Pountain's JFAR code, this kind of 
> solution is used internally by the system; however, in his code
> message strings are first hashed to integers to improve the efficiency 
> of late binding.

Yes, the issue of method lookup is an efficiency stickler.  Given the
SEND form above it would be easy to add all kinds of tricks to speed up
method lookup and still preserve the correct semantics.  (dictionaries,
method caches, hashed method structures, hybrids, etc.)

-Doug

---
Preferred: ( dwp@willett.pgh.pa.us  OR  ...!{sei,pitt}!willett!dwp )
Daily: ...!{uunet,nfsun}!willett!dwp  [last resort: dwp@vega.fac.cs.cmu.edu]

dwp@willett.pgh.pa.us (Doug Philips) (08/16/90)

In <90227.092721DN5@psuvm.psu.edu>, DN5@psuvm.psu.edu writes:
> In article <1498.UUL1.3#5129@willett.pgh.pa.us>, dwp@willett.pgh.pa.us (Doug
> >        10 20 MoveTo MyRectangle SEND
> >
> >the nice thing about having an explicit send is that you can replace
> >MoveTo and/or MyRectangle with arbitrary Forth code and still have it
> >work.
> 
> My comments:
> 
> I don't like this syntax, because it means that I would have to
> do something special if I had a function which returned an object
> (i.e., I had an anonymous object on the top of the stack).

Now I'm really confused.  When I said 'you can replace MyRectangle with
arbitrary Forth code' that is precisely what I meant (anonymous objects).
I think we agree here despite what we are saying.  ;-)

> (i.e., I had an anonymous object on the top of the stack).  The
> syntax which I came up with when I was experimenting with objects
> in forth is similar:
> 
>     10 20 MyRectangle ~ MoveTo
> 
> Basically ~ was an immediate word which took the next word as a
> string, and hashed it to a method reference, and compiled a call
> to the object dereferencer with that as a parameter.  In the future
> I would replace all calls which could be figured out at compile
> time to a direct call to word involved.

Whether the message name itself is IMMEDIATE or whether there is a special
prefix which is IMMEDIATE, message names are still active and I still object
to them.

-Doug

---
Preferred: ( dwp@willett.pgh.pa.us  OR  ...!{sei,pitt}!willett!dwp )
Daily: ...!{uunet,nfsun}!willett!dwp  [last resort: dwp@vega.fac.cs.cmu.edu]

dwp@willett.pgh.pa.us (Doug Philips) (08/16/90)

In <11376@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:

>     'traditional' language looks like. I would say the syntax with the
>     message at the end is really the most forth-like. The function usually
>     comes at the end in forth. The message is basically just an indirect
>     function call.

I must disagree here.  Your view is still the traditional NON OO view
of functions with arguments.  OO says just the opposite.  OO says that it
is the object which is interesting/important.  The message is a thing which
is passed to the object and which the object examines and does with as it
sees fit.  The message is just another parameter of sorts.  Your style
re-asserts the functional style in which the object is a parameter to the
function.  Not a common view of OO systems as I understand them.

There is one other point you made which I think is independant of the
"inside-outness" issue.    Constant message names versus "anonymous"
message names.  That is, message names known at compile time versus
message names found on the stack at run time.  That strikes me as a
purely efficiency consideration.  I don't yet think I know if it is
possible to encompass both with one simple and powerful purely postfix
(my defitition of postfix) syntax.

-Doug

---
Preferred: ( dwp@willett.pgh.pa.us  OR  ...!{sei,pitt}!willett!dwp )
Daily: ...!{uunet,nfsun}!willett!dwp  [last resort: dwp@vega.fac.cs.cmu.edu]

peter@ficc.ferranti.com (Peter da Silva) (08/17/90)

In article <11376@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:
>     I would say the syntax with the
>     message at the end is really the most forth-like.

Personally, I prefer "Arg Arg Message Object", too. Where "Object" executes
(look up (possibly) message) (push self) (jump). But that's because I like
Xlisp... either way seems reasonable.

> >	PushArg PushArg Message Object

>     Dissagree. I would call this syntax "inside out".

Why?

> >That looks ok, but it does not do anything.  In order to do something you
> >would have to add a special word.  I would pick SEND, as in:
> >	10 20 MoveTo MyRectangle SEND

Why? Do you really want to pepper your code with SENDs?

>     But the same thing could be accomplished by:
 
> 			PushArg PushArg Object ' Message SEND

Or "Arg Arg Message 'Object SEND"

(also, I like the idea of making the outer interpreter more powerful, so
 you can say 'name and get a symbol table entry. Then make "characters" just
 be a name. Then you get a SUPER-STOIC... (anyone remember STOIC))
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com (currently not working)
peter@hackercorp.com

bouma@cs.purdue.EDU (William J. Bouma) (08/18/90)

In article <1533.UUL1.3#5129@willett.pgh.pa.us> dwp@willett.pgh.pa.us (Doug Philips) writes:
>In <11376@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:
>
>>     'traditional' language looks like. I would say the syntax with the
>>     message at the end is really the most forth-like. The function usually
>>     comes at the end in forth. The message is basically just an indirect
>>     function call.
>
>I must disagree here.  Your view is still the traditional NON OO view
>of functions with arguments.  OO says just the opposite.  OO says that it
>is the object which is interesting/important.  The message is a thing which
>is passed to the object and which the object examines and does with as it
>sees fit.  The message is just another parameter of sorts.  Your style
>re-asserts the functional style in which the object is a parameter to the
>function.  Not a common view of OO systems as I understand them.

   So wich of us is being more traditional? 8^)
   
   However some OO pusher wants to look at things the fact of the
   implementation remains! The message is basically just an indirect
   function call. I'll assume we agree on this. Then, getting back to
   tradition, what is the traditional forth way of doing things? I would
   say it is to take the easy way, the simplest is the best. So think of
   implementing such a beast. The way I propose, the message can be a
   normal forth word that simply does the indirection given the object
   on the stack. The object can be just some data address plus a tag to
   identify its "class". Your way can be implemented pretty much the same
   way (SEE BELOW), but then why bother to hide the implementation at the
   cost of lost efficiency? There would be an even greater loss of effic-
   iency if it was implemented the way you describe its functionality.
   Consider: A message has to be either a word that
   pushes some ID onto the stack, or a string. Both are awkward. Then an
   object instance has to be a word with run time behavior of reading the
   message off the stack, pushing its data address on the stack, and 
   finally executing the identified function. But an object instance
   is really a piece of data and thus you should be able to store it in
   a variable plus you need to access the data address. You NEED "SEND" ...
>
>There is one other point you made which I think is independant of the
>"inside-outness" issue.    Constant message names versus "anonymous"
>message names.  That is, message names known at compile time versus
>message names found on the stack at run time.  That strikes me as a
>purely efficiency consideration.  I don't yet think I know if it is
>possible to encompass both with one simple and powerful purely postfix
>(my defitition of postfix) syntax.
>
   Let's review:

   Your way: ... message object SEND
     My way: ... object message       ( : SEND execute ; )

   I hope what I have said above makes it clear that this is indeed a
   matter of efficiency. (At the very least my way requires one less "swap"
   or "push".) Also that these issues are not in the slightest "independent".
   Suppose your way was implemented my way. Then you would have to type:

   ... ' message object SEND      ( : SEND swap execute ; )

   What does this gain you? A feeling that you are doing it the OO way.
   My way fits in easily with the way forth is already setup. It is 
   cleaner, faster, and doesn't try to hide the implementation. So even
   if you believe "message object" is in some way more postfix than
   "object message", forth traditionally trashes postfixedness for the 
   sake of clarity (typing less) and simplicity. 
-- 
Bill <bouma@cs.purdue.edu>      Just ask the Axis   He knows everything

bouma@cs.purdue.EDU (William J. Bouma) (08/18/90)

In article <EI95UT3@ggpc2.ferranti.com> peter@ficc.ferranti.com (Peter da Silva) writes:
>In article <11376@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:
>>     But the same thing could be accomplished by:
> 
>> 			PushArg PushArg Object ' Message SEND
>
>Or "Arg Arg Message 'Object SEND"


How?


-- 
Bill <bouma@cs.purdue.edu>      Just ask the Axis   He knows everything

carroll@udel.edu (Mark Carroll <MC>) (08/20/90)

In article <11406@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:
>In article <1533.UUL1.3#5129@willett.pgh.pa.us> dwp@willett.pgh.pa.us (Doug Philips) writes:
>>In <11376@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:
>>
>>>     'traditional' language looks like. I would say the syntax with the
>>>     message at the end is really the most forth-like. The function usually
>>>     comes at the end in forth. The message is basically just an indirect
>>>     function call.
>>
>>I must disagree here.  Your view is still the traditional NON OO view
>>of functions with arguments.  OO says just the opposite.  OO says that it
>>is the object which is interesting/important.  The message is a thing which
>>is passed to the object and which the object examines and does with as it
>>sees fit.  The message is just another parameter of sorts.  Your style
>>re-asserts the functional style in which the object is a parameter to the
>>function.  Not a common view of OO systems as I understand them.
>
>   So wich of us is being more traditional? 8^)
>   
>   However some OO pusher wants to look at things the fact of the
>   implementation remains! The message is basically just an indirect
>   function call. I'll assume we agree on this. 

I've got to disagree here. It's true that on the implementation level,
a "message pass" is a special kind of indirect function call. But if
you think of it as being "just an indirect function call", then you've
missed the entire point of object-oriented programming. If your
programming style asserts the traditional functional style, considering
methods to be nothing but functions, then you're going to end up seeing
no benefit from the use of an object-oriented system. 

Object-orientation represents a very different way of approaching a
problem. The benefits of object-oriented programming don't come from
indirect function calls - those have been around for ages, and they aren't
really that big a deal. The benefits comes from the difference in programming
style. And that object-oriented programming style derives from the difference
in approach. In an object-oriented programs, OBJECTS are active, FUNCTIONS
are passive. An object-oriented automaton has a passive processor and an
active store. Active objects are the entire point of object-orientation.


>Then, getting back to
>   tradition, what is the traditional forth way of doing things? I would
>   say it is to take the easy way, the simplest is the best. So think of
>   implementing such a beast. The way I propose, the message can be a
>   normal forth word that simply does the indirection given the object
>   on the stack. The object can be just some data address plus a tag to
>   identify its "class". 

In traditional Forth, the active entity comes last. In a normal
Forth program, the active entity is the word (function), so the name
of the word (the function name) comes last. In an object-oriented Forth 
program, the active entity is the OBJECT. So the name of the object should
come last.


	<MC>
--
|Mark Craig Carroll: <MC>  |"We the people want it straight for a change;
|Soon-to-be Grad Student at| cos we the people are getting tired of your games;
|University of Delaware    | If you insult us with cheap propaganda; 
|carroll@udel.edu          | We'll elect a precedent to a state of mind" -Fish

bouma@cs.purdue.EDU (William J. Bouma) (08/21/90)

In article <27883@nigel.ee.udel.edu> carroll@udel.edu (Mark Carroll <MC>) writes:
>In article <11406@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:
>>   
>>   However some OO pusher wants to look at things the fact of the
>>   implementation remains! The message is basically just an indirect
>>   function call. I'll assume we agree on this. 
>
>I've got to disagree here. It's true that on the implementation level,
>a "message pass" is a special kind of indirect function call. But if

  So we do agree then! First you disagree with the fact and then you
  say that it is true. Please try to be less wishy-washy.

>you think of it as being "just an indirect function call", then you've
>missed the entire point of object-oriented programming.

  Oh, so what you really dissagree with is my honesty. The OO abstraction
  is very useful for handling certain problems, but let's not confuse it
  with what is really goin on.

>Object-orientation represents a very different way of approaching a
>problem. The benefits of object-oriented programming don't come from
>indirect function calls - those have been around for ages, and they aren't
>really that big a deal. The benefits comes from the difference in programming
>style. And that object-oriented programming style derives from the difference
>in approach. In an object-oriented programs, OBJECTS are active, FUNCTIONS
>are passive. An object-oriented automaton has a passive processor and an
>active store. Active objects are the entire point of object-orientation.
  
  Object oriented programming relies upon basically three computational
  constructs:

  1. Automatic association between code and a type (class) of object. This
     is where the indirect function call comes in. If this is nothing new,
     then OOP is just another way to look at something old. Actually
     OO has innovation here for making it automatic. The association and
     bookeeping is done by the system rather than explicitly by the user.

  2. Multiple inheritance. A new class can include several other classes and
     inherit data components and values from them.

  3. Flexible inheritance of behavior. A class can inherit code from the
     classes upon which it is built. It also has capability to modify or
     override that behavior.

  I don't see how you can divorce the benefits of OOP from the indirect
  function call as you have done? That is the biggest part of what makes
  an OO language work (1 and 3).

>In traditional Forth, the active entity comes last. In a normal
>Forth program, the active entity is the word (function), so the name
>of the word (the function name) comes last. In an object-oriented Forth 
>program, the active entity is the OBJECT. So the name of the object should
>come last.

  Not really. The forth abstraction is that every word is active.
  Even though it isn't implemented that way, even constants can be thought
  of as active. For instance a number's action is to push itself onto the
  stack. The only requirement forth puts on order is that when a word needs
  something to be on the stack, it must be there.
-- 
Bill <bouma@cs.purdue.edu>      Just ask the Axis   He knows everything

dwp@willett.pgh.pa.us (Doug Philips) (08/21/90)

In <11418@medusa.cs.purdue.edu>, bouma@cs.purdue.EDU (William J. Bouma) writes:
> >In article <11406@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:
> >>   
> >>   However some OO pusher wants to look at things the fact of the
> >>   implementation remains! The message is basically just an indirect
> >>   function call. I'll assume we agree on this. 
> >
> >I've got to disagree here. It's true that on the implementation level,
> >a "message pass" is a special kind of indirect function call. But if
> 
>   So we do agree then! First you disagree with the fact and then you
>   say that it is true. Please try to be less wishy-washy.

And you can stop being so cut-and-dried.  He can disagree without having
to disagree totally.  (Ok, if you were kidding, I'm just kidding, if not,
I'm not).

> >you think of it as being "just an indirect function call", then you've
> >missed the entire point of object-oriented programming.
> 
>   Oh, so what you really dissagree with is my honesty. The OO abstraction
>   is very useful for handling certain problems, but let's not confuse it
>   with what is really goin on.

And just what is really going on?  The "Indirect function call" abstraction
is very useful for handling certain problems...  :-)  Your definition of
"what is really goin on" is no more or less arbitrary, capricous or correct
that the one you are refuting.  Levels of abstraction are not useless
because they hide other levels of abstraction, quite the contrary.  There
are (at least) two problems with focusing on "what is really goin on".

    First, there is no objective way to decide "what is really going on."
    You pick that by using a level of abstraction apropriate to the task at
    hand.

    Second, you tie your thinking to a level of "how" and not "what".

Yes, perhaps, OOP is "like" a kind of indirection function call.  BUT, it
doesn't have to be.  It "could be" just a big switch statement (which is
not a function call of any kind).  The point is the effect, not the
mechanism.  Once you determine that all OOP is "really" is is indirect
function calls, you *have* missed the point.  CM and Wil Baden both have
indicated Forth is a language for letting you specify "the what," instead
of "the how."  I would like to strive to reach that level of usage and
understanding.  I don't think it can be done in the way you are suggesting,
which I see as focusing on "the how."

>   1. Automatic association between code and a type (class) of object. This
>      is where the indirect function call comes in. If this is nothing new,
>      then OOP is just another way to look at something old. Actually
>      OO has innovation here for making it automatic. The association and
>      bookeeping is done by the system rather than explicitly by the user.

Here you go again with that assumption about an implementation.  Yes, it
can be done that way, but that is not the only way.

>   2. Multiple inheritance. A new class can include several other classes and
>      inherit data components and values from them.

This is a topic that is far from agreed upon.  I don't care to dispute it
here since it isn't related to the topic at hand.  Single inheritance
is sufficient.  If you want to require MI, I won't argue the point.

> [ 3.  Inheret, add or over-ride behaviour of parent class(es).]
> 
>   I don't see how you can divorce the benefits of OOP from the indirect
>   function call as you have done? That is the biggest part of what makes
>   an OO language work (1 and 3).

OOP does not specify the mechanism buy which it works.  I don't see how you
can focus on such a low level detail and still reap the benefits of OOP.

> >In traditional Forth, the active entity comes last. In a normal
> >Forth program, the active entity is the word (function), so the name
> >of the word (the function name) comes last. In an object-oriented Forth 
> >program, the active entity is the OBJECT. So the name of the object should
> >come last.
> 
>   Not really. The forth abstraction is that every word is active.
>   Even though it isn't implemented that way, even constants can be thought
>   of as active. For instance a number's action is to push itself onto the
>   stack. The only requirement forth puts on order is that when a word needs
>   something to be on the stack, it must be there.

Lets not equivocate here.

	Words can be active because they "do something", even if that
	something is only to push a number onto the parameter stack.  This
	is your sense of active.

	Words can be active in that they consume data from the parameter
	stack, do something useful, and may even put results back onto the
	stack.  This is the sense that I and the text you quote mean.

Your definition (the first) of active is vacuously true when you consider
that every word is active by virtue of causing the interpreter or compiler
to "do something", such as executing or compiling it.

Getting back to the original point...

Look at it from an esthetic point of view (now I'm really in trouble!):

		Arg Arg Arg Object Message

			vs.

		Arg Arg Arg Message Object

Assume that Message and Object are only one Forth word each.  Which form
scans most understandibly?  In the first form the Object gets in the way of
connecting the arguements to their Message.  In the second form the arguments
are more closely related to the Message.  In the first form you have a
mixture of post-fix style (push arguments then do actions) and prefix style
(procedure name [Object] followed by argument [Message]).  In the second
form all arguments are pushed and the action on them invoked.

How do the forms support cascading?  Cascading is where one message
returns an object which is the destination for the next message.  In
SmallTalk it looks like, say:
	MyRect moveToX: 3 Y: 4 Draw: Green
which means:  Send MyRect the message moveToXY with parameters 3,4.
moveToXY returns the object to which the message was sent.  That object
is then send the message Draw with parameter Green.

		Green 3 4 MyRect moveToXY Draw

			vs.

		Green Draw 3 4 moveToXY MyRect SEND SEND


Which of those scans more easily?  I think that it is harder in the
first example to group the message names and their arguments.  In the
second example message names are parameters too, so they are naturally
and automatically grouped with "their" parameters.

Consider even with just one message send what happens if their is
non-trivial code to generate the arguments and the objec reference.  That
also makes it hard to see which words are associated as parameters to the
message and which are words that construct the object reference.

Consider another case.  You have a linked list object which keeps a list
of objects.  You want to invoke a message for each object in the list.
How to do it?  The obvious way is to have a word which pushes the
message and its arguments onto the stack.  The linked list object
can then walk its list, EXECUTE the word, push the current object and
do a SEND.  In your mechanism that won't work because the object has
to be on the stack already in order to put the message after it.  That
means the word you pass to the linked list method must play all kinds
of ugly stack games to work right.  My experience with Forth so far says
that ugly stack games indicate bad factoring.

-Doug

---
Preferred: ( dwp@willett.pgh.pa.us  OR  ...!{sei,pitt}!willett!dwp )
Daily: ...!{uunet,nfsun}!willett!dwp  [last resort: dwp@vega.fac.cs.cmu.edu]

carroll@udel.edu (Mark Carroll <MC>) (08/21/90)

In article <11418@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:
]In article <27883@nigel.ee.udel.edu> carroll@udel.edu (Mark Carroll <MC>) writes:
]]In article <11406@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:
]]]   
]]]   However some OO pusher wants to look at things the fact of the
]]]   implementation remains! The message is basically just an indirect
]]]   function call. I'll assume we agree on this. 
]]
]]I've got to disagree here. It's true that on the implementation level,
]]a "message pass" is a special kind of indirect function call. But if
]
]  So we do agree then! First you disagree with the fact and then you
]  say that it is true. Please try to be less wishy-washy.
]

I'm simultaneously agreeing and disagreeing. Implementationally, a
message pass is nothing more than an indirected function call. But, to
say that object-oriented programming is nothing more than programming
with indirected function calls misses the point. Object-oriented
programming represents a different approach, and to trivialize it into
indirect function calls loses the real point of object-oriented
programming. Indirect function calls are just a tool that make a new
approach possible - they're not the entirety of the new approach.

]]you think of it as being "just an indirect function call", then you've
]]missed the entire point of object-oriented programming.
]
]  Oh, so what you really dissagree with is my honesty. The OO abstraction
]  is very useful for handling certain problems, but let's not confuse it
]  with what is really goin on.
]

There's an important point to be found is this disagreement: What do
we mean by "What is really going on?" It's an important question. To
me, what is really going on when we add object-orientation to Forth is
that we're adding a new computational model to the system. If that's
what's really going on, that the language constructs should be
designed to match that new model. To you (I think), what is really going
on is that we're adding an indirect functional call construct to Forth,
and you'd like to see the language constructs reflect that reality. I
don't really think that the two of us will ever agree on what we want
from an object extension.

]]Object-orientation represents a very different way of approaching a
]]problem. The benefits of object-oriented programming don't come from
]]indirect function calls - those have been around for ages, and they aren't
]]really that big a deal. The benefits comes from the difference in programming
]]style. And that object-oriented programming style derives from the difference
]]in approach. In an object-oriented programs, OBJECTS are active, FUNCTIONS
]]are passive. An object-oriented automaton has a passive processor and an
]]active store. Active objects are the entire point of object-orientation.
]  

I completely disagree with what comes next. You describe what
Object-orientation is in terms of the underlying implementation of it
on a VN machine. I don't think that an OO system can be properly described
in terms of a VN machine. The VN is equally powerful, (so an OO can be
implemented on a VN, and a VN can be implemented on an OO), but the
models are different.

]  Object oriented programming relies upon basically three computational
]  constructs:
]
]  1. Automatic association between code and a type (class) of object. This
]     is where the indirect function call comes in. If this is nothing new,
]     then OOP is just another way to look at something old. Actually
]     OO has innovation here for making it automatic. The association and
]     bookeeping is done by the system rather than explicitly by the user.
]

Object-orientation doesn't necessarily have anything to do with
classes!  Classes are not necessary in an object-oriented language.
(Self!) In fact, I believe that the best way to add oo to forth is
without classes. Forth believes in the minimal approach - and the minimal
approach to object-orientation is prototypes with delegation, not classes
with inheritance.

]  2. Multiple inheritance. A new class can include several other classes and
]     inherit data components and values from them.
]

Multiple inheritance is not necessary for Object-orientation. Smalltalk -
the first of the real object-oriented languages didn't include multiple
inheritance. And most of the time, multiple inheritance is not necessary.

]  3. Flexible inheritance of behavior. A class can inherit code from the
]     classes upon which it is built. It also has capability to modify or
]     override that behavior.
]

Again, trash the classes. The real key ability is the ability of an object
to divert a message pass to another object.

]  I don't see how you can divorce the benefits of OOP from the indirect
]  function call as you have done? That is the biggest part of what makes
]  an OO language work (1 and 3).
]

The benefits of object-oriented programming come from active objects.
Indirect function calls are just implementation level details that make
active objects possible.

]]In traditional Forth, the active entity comes last. In a normal
]]Forth program, the active entity is the word (function), so the name
]]of the word (the function name) comes last. In an object-oriented Forth 
]]program, the active entity is the OBJECT. So the name of the object should
]]come last.
]
]  Not really. The forth abstraction is that every word is active.
]  Even though it isn't implemented that way, even constants can be thought
]  of as active. For instance a number's action is to push itself onto the
]  stack. The only requirement forth puts on order is that when a word needs
]  something to be on the stack, it must be there.

In a way, you're right here. But in another way, any statement in Forth
contains certain "goal" words, where some portion of the sequence of words
preceding are just setting up for the goal, and the goal word is the really
important part of the sequence. The goal word is, in some way, the most
active part of the expression. And that goal always comes last. I still
think that for a proper implementation of object-orientation in Forth,
active objects should be the most active part of the expression.

]-- 
]Bill <bouma@cs.purdue.edu>      Just ask the Axis   He knows everything

	<MC>
--
|Mark Craig Carroll: <MC>  |"We the people want it straight for a change;
|Soon-to-be Grad Student at| cos we the people are getting tired of your games;
|University of Delaware    | If you insult us with cheap propaganda; 
|carroll@udel.edu          | We'll elect a precedent to a state of mind" -Fish

bouma@cs.purdue.EDU (William J. Bouma) (08/22/90)

In article <28039@nigel.ee.udel.edu> carroll@udel.edu (Mark Carroll <MC>) writes:
>There's an important point to be found is this disagreement: What do
>we mean by "What is really going on?" It's an important question. To
>me, what is really going on when we add object-orientation to Forth is
>that we're adding a new computational model to the system. If that's
>what's really going on, that the language constructs should be
>designed to match that new model. To you (I think), what is really going
>on is that we're adding an indirect functional call construct to Forth,
>and you'd like to see the language constructs reflect that reality. I
>don't really think that the two of us will ever agree on what we want
>from an object extension.

  On the contrary, I think our disagreement is actually very small. We are
  just approaching this from different directions, different backgrounds.
  What I want to do is add some interesting low-level features to the
  language in the best, most implementable way. Then let the user decide
  how to use and view them. Of course I have in mind the OO view in building
  the features inititialy, but if the programmer chooses to view them a
  different way, fine.
  But you want to decide what things should look like at the top level, and
  then impose that view on the language at whatever the implementation cost.
  I have just been saying that this does not coincide with the way forth
  has traditionally been done. The way I see it forth has tried to be fast,
  simple, and flexible always at the cost of what it looks like at the top.

>I completely disagree with what comes next. You describe what
>Object-orientation is in terms of the underlying implementation of it
>on a VN machine. I don't think that an OO system can be properly described
>in terms of a VN machine. The VN is equally powerful, (so an OO can be
>implemented on a VN, and a VN can be implemented on an OO), but the
>models are different.

  Again, I fail to see what you disagree with? Perhaps it is because you
  are being too vague. What we have been talking about all along here IS
  the implementation, (specifically a FORTH implementation)! I have 
  described my implementation in some detail, and made a reasonable case
  for it.  I would be very interested to hear what you believe and OO forth
  should look like? If you can tell me how it can be cleanly implemented, I
  would be even more interested.

  You go on to object to my use of the term "class". Call it what you will,
  you will need to have something of the same functionality. If not, how
  does it work? Just what is an "object", anyway?

>]  I don't see how you can divorce the benefits of OOP from the indirect
>]  function call as you have done? That is the biggest part of what makes
>]  an OO language work (1 and 3).
>
>The benefits of object-oriented programming come from active objects.
>Indirect function calls are just implementation level details that make
>active objects possible.

  Ah, now we are getting somewhere!
-- 
Bill <bouma@cs.purdue.edu>      Just ask the Axis   He knows everything

bouma@cs.purdue.EDU (William J. Bouma) (08/22/90)

In article <1567.UUL1.3#5129@willett.pgh.pa.us> dwp@willett.pgh.pa.us (Doug Philips) writes:
>
>And just what is really going on?  The "Indirect function call" abstraction
>is very useful for handling certain problems...  :-)  Your definition of
> ...
>    First, there is no objective way to decide "what is really going on."
>    You pick that by using a level of abstraction apropriate to the task at
>    hand.

  Yes, and I picked a level of abstraction appropriate to what I was
  talking about, namely, implementing OO in forth. The person I was
  replying to was trying to pull me to some higher level, saying that
  I shouldn't look at OO that way as OO is really something much more
  than that. Fine if it is, but that has nothing to do with what I was
  talking about. Contemplating OO on some high level of abstraction is
  not going to get it implemented. It seems like people think I have
  something against OO just because I stoop to the level of implementation!
  
>mechanism.  Once you determine that all OOP is "really" is is indirect
>function calls, you *have* missed the point.  CM and Wil Baden both have

  If you think of it as something more than that when you are trying
  to implement it you have really missed the point.

>Here you go again with that assumption about an implementation.  Yes, it
>can be done that way, but that is not the only way.

   As far as I know indirect function call is the only way. Please tell me
   some other way. I really would love to talk something solid here rather
   than this silly bickering over word semantics. It is easy to see that
   writing if-then statements on the fly isn't going to work. I consider
   indirect jump equivalent to indirect function call, don't you?

>>   I don't see how you can divorce the benefits of OOP from the indirect
>>   function call as you have done? That is the biggest part of what makes
>>   an OO language work (1 and 3).
>
>OOP does not specify the mechanism buy which it works.  I don't see how you
>can focus on such a low level detail and still reap the benefits of OOP.

   But if I am to write an OO language, I MUST specify the mechanism by
   which it works! If I do not focus on such a low level detail, I will not
   have any OO to reap the benefits from!

>Consider another case.  You have a linked list object which keeps a list
>of objects.  You want to invoke a message for each object in the list.
>How to do it?  The obvious way is to have a word which pushes the
>message and its arguments onto the stack.  The linked list object
>can then walk its list, EXECUTE the word, push the current object and
>do a SEND.  In your mechanism that won't work because the object has
>to be on the stack already in order to put the message after it.  That
>means the word you pass to the linked list method must play all kinds
>of ugly stack games to work right.  My experience with Forth so far says
>that ugly stack games indicate bad factoring.

   You consider a single SWAP an ugly stack game? You should not be
   programming in forth.
-- 
Bill <bouma@cs.purdue.edu>      Just ask the Axis   He knows everything

dwp@willett.pgh.pa.us (Doug Philips) (08/23/90)

In <11423@medusa.cs.purdue.edu>, bouma@cs.purdue.EDU (William J. Bouma) writes:
> In article <28039@nigel.ee.udel.edu> carroll@udel.edu (Mark Carroll <MC>) writes:
>   On the contrary, I think our disagreement is actually very small. We are
>   just approaching this from different directions, different backgrounds.
>   What I want to do is add some interesting low-level features to the
>   language in the best, most implementable way. Then let the user decide
>   how to use and view them. Of course I have in mind the OO view in building
>   the features inititialy, but if the programmer chooses to view them a
>   different way, fine.

Aha!  This is quite different than wanting to OO (right) from the start.
Now that some of the secret agendas are on the table we can perhaps make
progress.

>   But you want to decide what things should look like at the top level, and
>   then impose that view on the language at whatever the implementation cost.
>   I have just been saying that this does not coincide with the way forth
>   has traditionally been done. The way I see it forth has tried to be fast,
>   simple, and flexible always at the cost of what it looks like at the top.

My impression has always been that Forth is supposed to GROW into the
language with which you describe your solution.  This is the first time I
can remember hearing a Forth programmer advocating that the solution be
bent towards Forth instead of the other way around.

> >The benefits of object-oriented programming come from active objects.
> >Indirect function calls are just implementation level details that make
> >active objects possible.
> 
>   Ah, now we are getting somewhere!

Indeed, see below.

In <11425@medusa.cs.purdue.edu>, bouma@cs.purdue.EDU (William J. Bouma) writes:
[ Quoted quotes: "> >" are now mine -dwp]
>   Yes, and I picked a level of abstraction appropriate to what I was
>   talking about, namely, implementing OO in forth. The person I was
>   replying to was trying to pull me to some higher level, saying that
>   I shouldn't look at OO that way as OO is really something much more
>   than that. Fine if it is, but that has nothing to do with what I was
>   talking about. Contemplating OO on some high level of abstraction is
>   not going to get it implemented. It seems like people think I have
>   something against OO just because I stoop to the level of implementation!

No, the objection is that you are letting the implementation pollute the
abstraction.  Would you just as readily claim that the best way to implement
stacks was with arrays, and therefore make stacks *look* like arrays, or
even put arrayish things into them?  I hope not.

> > mechanism.  Once you determine that all OOP is "really" is is indirect
> > function calls, you *have* missed the point.  CM and Wil Baden both have
>   If you think of it as something more than that when you are trying
>   to implement it you have really missed the point.

How you implement it should not pollute how you use it!  Were you to
write a symbol table ADT, would you let the underlying lookup mechanism
show through (i.e. AVL trees, hash tables, B-tree, etc?).  Again, I hope
not.  "What" the ADT is should not be affected by "how" it happens to
be implemented in some particular instance.

>    As far as I know indirect function call is the only way. Please tell me
>    some other way. I really would love to talk something solid here rather
>    than this silly bickering over word semantics. It is easy to see that
>    writing if-then statements on the fly isn't going to work. I consider
>    indirect jump equivalent to indirect function call, don't you?
[I consider indirect jump equivalent, for the sake of the current
discussion.].  Actually, I fail to see how you can avoid a chain of if-then
statements.  If you have active messages and passive objects, as you have
been advocating, then message names are words that must be known globally.
That implies that the set of message names understood by a class of objects
is not necessarily going to be contiguous.  That means you are going to
have to search for the method that implements the message.  You could
easily have something like this:  (Rough, off the cuff, proof-of-concept
sketch follows:)

\ Ignore multiple/single inheretance for clarity of example.
\   for every method described here, SELF is a word that puts the receiver
\   of the message onto the stack.
\ Instance variables can be declared after the CLASS and before the
\   first METHOD, but that doesn't affect what we're doing here.
CLASS Foo
METHOD m1 ( code for method m1. )
METHOD m2 ( ... )
METHOD m3 ( ... )
ENDCLASS

The above code can compile into a series of if-then tests, much like
Wavrik's recently posted IF( )IF might.  The SEND method (in my scheme)
pops the object, arranges for it to be the result of SELF, which leaves
the message name on the top of stack.  It then jumps to the if-then
code above (based on information gotten from the object).  The code
then figures out which method to invoke, if it finds one, it executes
it and returns.  If the code falls through to ENDCLASS, ENDCLASS could
arrange for a search of the super-classes dictionary, or whatever.
You have the above Forth code compile all the methods and then generate
a vector of indirect addresses.  That table would still have to be searched.
You might even flatten the table so that it includes the addresses of the
superclass(es) methods that aren't eliminated or over-ridden.  You *might*
even keep a table per message and look up object types in it.  Of course
every class (object type) isn't going to implement every message, so you'll
have to provide large tables or search compacted ones.  If you allow the
classes to dynamicly change the methods for their messages that may effect
the way you choose to implement SENDs.  None of these alternatives should
affect the way you *use* OOP in Forth.  Nor should you pick a OOP Forth
extension that forces you to use one of those implementation strategies.
This is also why the X3J14 TC will *not* prescribe how a dictionary is
to be implemented.  It just doesn't matter.  If you need to hack your
particular implementation for dictionaries for some reason, you can.
Doing -FIND or EXECUTE or whatever can all be done, efficiently, by
whatever kind of dictionary implementation you have, without you *having*
to know what that implementation is.

>    But if I am to write an OO language, I MUST specify the mechanism by
>    which it works! If I do not focus on such a low level detail, I will not
>    have any OO to reap the benefits from!

*How* you implement it is obviously constrained by *what* you implement.
*What* you implement should not be constrained by *How* you think it should
be implemented on machine X at point in time Y.  You *may* decide that you
cannot implement the full ADT because it would be just too expensive to be
used.  I have not seen anything like that kind of argument or analysis
here.  What you seem to be saying is:  I can only imagine that OOF is
implemented by using indirect function calls.  Therefore, there is no
reason to hide that fact from the OOF extensions.

>    You consider a single SWAP an ugly stack game? You should not be
>    programming in forth.

No, I think inconsistency is ugly.  In order to do delayed sends you
are going to have to play stack manipulation games.  In your scheme
you write delayed sends differently because you have no choice.  In
my scheme, delayed sends are easily accomplished by controlling when
SEND is executed.  I claim that my way is more consistent, is simpler,
and is still in the spirit of Forth.  I consider having to do
SWAP EXECUTE ugly.  It is gratuitous stack manipulation.  I think that
gratuitous stack manipulation is ugly.  I also think it indicates that
the factoring involved is not as good as it could be.

Look, you can probably use method-active OOF and get away with it for
a majority of your OOF needs.  Personally I think it is flawed.  I would
rather have a *real* OOF.  Even if you only notice the difference 5% or
10% of the time.  If we (the royal we) are to take up Mikael Patel's
challange to build a good OOF and then start to build a library of objects
on top of it, I would really like to see that that effort is not hamhocked
by an ill-chosen OOF base.  In reality, I don't know that any of this
matters.  I will not write a line of object or message active OOF.  I will
first do it right.  I may be the only person to think this way.  Perhaps
the beauty of Forth is that that doesn't matter.

-Doug

---
Preferred: ( dwp@willett.pgh.pa.us  OR  ...!{sei,pitt}!willett!dwp )
Daily: ...!{uunet,nfsun}!willett!dwp  [last resort: dwp@vega.fac.cs.cmu.edu]

bouma@cs.purdue.EDU (William J. Bouma) (08/24/90)

In article <1569.UUL1.3#5129@willett.pgh.pa.us> dwp@willett.pgh.pa.us (Doug Philips) writes:
>
>here.  What you seem to be saying is:  I can only imagine that OOF is
>implemented by using indirect function calls.  Therefore, there is no
>reason to hide that fact from the OOF extensions.

   Not at the expense of efficiency and simplicity. In a language that
   doesn't try to be consistently post/pre fix, why do you insist that
   the syntax for OO be perfectly postfix? I just don't think the order
   of message-object is that big a deal. So use whichever way costs less
   in the implementation. I am able to read the OO abstraction into either
   syntax, just as I can read word definition into either
   : zzy ... ;   or   { ... } "zzy" define         .
 
>No, I think inconsistency is ugly.  In order to do delayed sends you

   What inconsistency?

>are going to have to play stack manipulation games.  In your scheme
>you write delayed sends differently because you have no choice.  In

   No, you have no choice!

>my scheme, delayed sends are easily accomplished by controlling when
>SEND is executed.  I claim that my way is more consistent, is simpler,

   Same thing with my scheme.

>and is still in the spirit of Forth.  I consider having to do
>SWAP EXECUTE ugly.  It is gratuitous stack manipulation.  I think that
>gratuitous stack manipulation is ugly.  I also think it indicates that
>the factoring involved is not as good as it could be.

   You can claim all you want, but you haven't shown anything! You give
   me a single example where my method would need to swap and yours wouldn't
   and then claim my method is "not as good". I can turn around and give
   you an example where yours would need to swap and mine wouldn't. That
   proves nothing! Are you trying to say that forth should have no "swap"?

   The discussion thus far:

   I give the best implementation I can think of and show how the
   object-message syntax matches that implementation more cleanly than
   the message-object syntax. 

   People object to me letting the implementation reflect in the syntax as
   it somehow offends their OO ideals.

   I claim that in forth the implementation has always been reflected in
   the syntax, so that is not a very strong objection. (eg. It is obvious
   from the syntax that there is a stack hiding back there somewhere.)

   People claim I don't understand forth or OO.

   Oh, you really got me there! Ohh. Ohhh.  8^)

   Now here is some vague claim that my implementation is "not as good" as
   some other one that hasn't even been specified! My implementation is
   inconsistent? I have yet to see "your way". I challenge you to give an
   implementation that fits your chosen syntax and fits as cleanly with forth
   as the one I gave for my syntax. If you could do that, I would probably
   prefer your syntax too. ... naaaaaah!
-- 
Bill <bouma@cs.purdue.edu>      Just ask the Axis   He knows everything

dwp@willett.pgh.pa.us (Doug Philips) (08/24/90)

In <11444@medusa.cs.purdue.edu>, bouma@cs.purdue.EDU (William J. Bouma) writes:
> In article <1569.UUL1.3#5129@willett.pgh.pa.us> dwp@willett.pgh.pa.us (Doug Philips) writes:

> >here.  What you seem to be saying is:  I can only imagine that OOF is
> >implemented by using indirect function calls.  Therefore, there is no
> >reason to hide that fact from the OOF extensions.
> 
>    Not at the expense of efficiency and simplicity. In a language that
>    doesn't try to be consistently post/pre fix, why do you insist that
>    the syntax for OO be perfectly postfix? I just don't think the order
>    of message-object is that big a deal. So use whichever way costs less
>    in the implementation. I am able to read the OO abstraction into either
>    syntax, just as I can read word definition into either
>    : zzy ... ;   or   { ... } "zzy" define         .

To paraphrase your reply:  "Well, Forth isn't consistent anyway, so there
is no need to worry about muddling the pot any more.  Just hack whatever
is easiest."  The point is that in OOP, objects are active and messages
are "parameters".  Parameters go first.  Even CONSTANT has the constant
value on the stack, rather than parsing it as " CONSTANT 24 Lines/Page".
OOP is not all that simplisitic in its implementation.  It is a powerfully
simple idea, but it takes *some* machinery to make it work.  See my
reply to Patel:  "What are you trying to get by adding OOP to Forth" etc...

> >No, I think inconsistency is ugly.  In order to do delayed sends you
> 
>    What inconsistency?

	( Your scheme: )	10 20 MyRectangle MoveTo
					( vs. )
				10 20 ' MoveTo ( done in a separate word )
					MyRectangle
					SWAP EXECUTE

	( delayed sends are not written the same in your message-active
	  version.  You even quoted me 'In order to do delayed sends' )

	( In my scheme: )	10 20 MoveTo MyRectangle SEND
					(vs.)
				10 20 MoveTo ( done in a separate word )
					MyRectangle SEND

	( see, the message and its arguments are constructed in exactly
	  the same way.  Just *add* object and SEND.  Easy, simple,
	  consistent.)

> >are going to have to play stack manipulation games.  In your scheme
> >you write delayed sends differently because you have no choice.  In
> 
>    No, you have no choice!

Huh?  You have no choice in that you MUST write delayed messages sends
differently.  It follows directly from the fact that message-names are
active.

>    Same thing with my scheme.

No, you're scheme requires gratuitous stack mungling and writing sends
differently depending on whether they are delayed or not, see above.
Also see below.

>    You can claim all you want, but you haven't shown anything! You give
>    me a single example where my method would need to swap and yours wouldn't
>    and then claim my method is "not as good". I can turn around and give
>    you an example where yours would need to swap and mine wouldn't.

Accuse me of not showing then do it yourself.  My method (as I have shown
you above) never requires a swap.  The order is ALWAYS:
	<parameters> <message-name> <object> SEND.
Until you get to the SEND, nothing happens.  You can write arbitrary Forth
code to compute any and all of the components and the complex cases don't
have to do anything special just because they are complex.  The code to
compute the message and its parameters doesn't change depending on whether
you are doing a delayed send or not.  You can write a word that pushes
parameters and a message name onto the stack.  Other code can then merely
push an object and SEND.  No stack machinations.  Works even for cascaded
messages:
	<params-2> <message-2> <params-1> <message-1> Object SEND SEND
which sends <message-1> with parameters <params-1> to Object.
That message leaves an object on the stack.  That object (which may even
be Object) is then sent <message-2> with parameters <params-2>.  In your
scheme:
	<params-2> <params-1> Object <message-1> <message-2>
My scheme allows you to push the messages and their parameters onto the
stack from separate words (or arbitrary code) without having to worry
about any existing messages already on the stack.  You cannot do that in
your scheme.  You have to arrange to quote the message names so that
they don't fire before the object is put onto the stack.  You also have
to arrange that the messages put on later know how many other messages
are already on the stack so that they can put their parameters underneath.
The parameters stay in place, but the Ticked message names must be shuffled
so that they stay on top of the stack.  Therefore you have to know how
many message names are on the stack to get the parameters (and the object
when it comes to that part) far enough underneath.

> Are you trying to say that forth should have no "swap"?

Hardly.  What I am saying is that everything I've read, and my esthetic
sensibilities, both say that gratiutous stack manipulations are indicitive
of poor factoring... items on the stack are not ordered the way that they
should be.  Cascading example above is just the kind of thing I'm refering
to here.  In order for one word to work properly it should not have to
know what other words have (read:  To push one message and its parameters
onto the stack shouldn't require knowing how many other messages are
already on the stack ahead of you).

>    I give the best implementation I can think of and show how the
>    object-message syntax matches that implementation more cleanly than
>    the message-object syntax. 

Of course it does, you set it up that way in the first place.

>    People object to me letting the implementation reflect in the syntax as
>    it somehow offends their OO ideals.

You have yet to say what your OO ideals are.  You have failed to indicate
you have any.  You have indicated that you are more interested in adding
indirect function calling to Forth with the hopes that it might work out
to be useful for OOF.

>    I claim that in forth the implementation has always been reflected in
>    the syntax, so that is not a very strong objection. (eg. It is obvious
>    from the syntax that there is a stack hiding back there somewhere.)

Oh, and I objected to there being a stack?  Where?  I suppose all your
data types are just:  : ARRAY STACK ;   : QUEUE STACK ;   : LIST STACK ;
: TREE STACK ;   Ohh, you really got yourself there! :-)

>    Now here is some vague claim that my implementation is "not as good" as
>    some other one that hasn't even been specified! My implementation is
>    inconsistent? I have yet to see "your way". I challenge you to give an
>    implementation that fits your chosen syntax and fits as cleanly with forth
>    as the one I gave for my syntax. If you could do that, I would probably
>    prefer your syntax too. ... naaaaaah!

The inconsistency of your implementation depends only your implementation.
I don't have to provide any alternatives in order to show that.

Of course you wouldn't, you didn't invent it! :-).
Besides, you haven't shown your implementation (I assume your copping one
of the ones posted on the net).  What I have done is shown you rough-sketches
and proofs-of-concept.  I will hardly go to the bother of implementing them
before I'm sure their sound.  Do you always do your coding without thinking
through your design? :-).  In actuality, I would like to have an implementation
that does just what I describe.  I think it is possible.  I think your
way is possible too.  I think my way is better.  I have seen nothing to
indicate an implementation difficulty.  I have already sketched several ways
to do it.  

If you may recall I started this whole thread because of the short comings
I saw in the existing active object and active message OOFS.  I never
claimed to have implemented a better way.  If I had implemented a better
way I would have posted it.  My point was to *indicate* that there is a
better way.  I have shown above that while your scheme may work most of the
time, there are cases that it botches:  Cascades interacting with delayed
message sends.  How many cracks do I have to find in a bridge before I
won't use it?  One, if it is serious enough, even if it is in a corner.  You
keep asserting that yours is the only efficient way to do OOP in Forth.  I
grant that you have an efficient mechanism, but withhold granting that it
is OOP.  You say that I claim you don't understand what OOP is, and yet you
can only reply by merely saying that you do in fact understand.  You claim
that Message-Object and Object-Message can be scanned just as easily.  I
claim that that is only true in the simplest of cases.  Cascading again
belies that claim:

		10 20 30 40 Object message-1 message-2

Which parameters belong to which message.  Where is the dividing line?

		10 20 30 message-1 30 Message-2 Object SEND SEND

Now where is the dividing line?  If you can't get something that simple
right, there is no way I'm going to trust you'll get something tricky
right.

-Doug

---
Preferred: ( dwp@willett.pgh.pa.us  OR  ...!{sei,pitt}!willett!dwp )
Daily: ...!{uunet,nfsun}!willett!dwp  [last resort: dwp@vega.fac.cs.cmu.edu]

bouma@cs.purdue.EDU (William J. Bouma) (08/25/90)

In article <1594.UUL1.3#5129@willett.pgh.pa.us> dwp@willett.pgh.pa.us (Doug Philips) writes:
>In <11444@medusa.cs.purdue.edu>, bouma@cs.purdue.EDU (William J. Bouma) writes:
>> In article <1569.UUL1.3#5129@willett.pgh.pa.us> dwp@willett.pgh.pa.us (Doug Philips) writes:

   When it starts like that, it can only get better! 8^)

>> >No, I think inconsistency is ugly.  In order to do delayed sends you
>> 
>>    What inconsistency?
>
>	( Your scheme: )	10 20 MyRectangle MoveTo
>					( vs. )
>				10 20 ' MoveTo ( done in a separate word )
>					MyRectangle
>					SWAP EXECUTE

   No, you seem to be trying to make my chosen syntax fit yours! Try:

         		        10 20 MyRectangle Moveto ( done in sep word )
					SEND

>	( delayed sends are not written the same in your message-active
>	  version.  You even quoted me 'In order to do delayed sends' )
>
>	( In my scheme: )	10 20 MoveTo MyRectangle SEND
>					(vs.)
>				10 20 MoveTo ( done in a separate word )
>					MyRectangle SEND
>
>	( see, the message and its arguments are constructed in exactly
>	  the same way.  Just *add* object and SEND.  Easy, simple,
>	  consistent.)

   If you consistently follow your syntax it is consistent. If you
   consistently follow my syntax it is consistent. You argument here is
   completely invalid.

>> >are going to have to play stack manipulation games.  In your scheme
>> >you write delayed sends differently because you have no choice.  In
>> 
>>    No, you have no choice!
>
>Huh?  You have no choice in that you MUST write delayed messages sends
>differently.  It follows directly from the fact that message-names are
>active.

   Uh, you lost me here? First let me say that my reply above came from a
   missunderstanding of what you wrote. I though you meant that I write 
   delayed sends differently from the way YOU write them. 8^) I really don't
   understand what you mean? Differently than what? I can always write my
   OO lines like this:

       Arg Arg ... Object Message SEND

   If message is a literal, it must be quoted. That seems appropriate and
   there is nothing inconsistent about it. In fact I could argue that your
   method is flawed in that it treats literal and not literal messages the
   same way. But that would be as stupid as the argument you are making. I
   see nothing wrong with doing it either way.
 
>>    Same thing with my scheme.
>
>No, you're scheme requires gratuitous stack mungling and writing sends
>differently depending on whether they are delayed or not, see above.
>Also see below.

   My scheme does not require "gratuitous stack mungling".

>>    You can claim all you want, but you haven't shown anything! You give
>>    me a single example where my method would need to swap and yours wouldn't
>>    and then claim my method is "not as good". I can turn around and give
>>    you an example where yours would need to swap and mine wouldn't.
>
>Accuse me of not showing then do it yourself.  My method (as I have shown
>you above) never requires a swap.  The order is ALWAYS:
>	<parameters> <message-name> <object> SEND.

   Well, it just seems pretty obvious. You claim that my syntax is
   flawed because you can have some code compute a message, THEN push an
   object on the stack and call SEND. Under those circumstamces, I would
   have to call SWAP before the SEND. So, what if I reverse this on you.
   I have some code that returns an object, THEN I push a message on the
   stack and call SEND. Under that circumstance, your method would need
   to SWAP! An example? Suppose I want to send a list of message to
   a group of objects possibly computed on the fly. Isn't that essentially
   the inverse of the example you gave? 

>	<params-2> <message-2> <params-1> <message-1> Object SEND SEND
>which sends <message-1> with parameters <params-1> to Object.
>That message leaves an object on the stack.  That object (which may even
>be Object) is then sent <message-2> with parameters <params-2>.  In your
>scheme:
>	<params-2> <params-1> Object <message-1> <message-2>

   Or:
	<params-2> <params-1> Object <message-1> SEND <message-2> SEND

   Now you are talking some sense.
   You know, both of these look like a real mess when you put it this
   way! It seems your syntax is better if you know what messages you
   want to send, but the objects are not prespecified. Mine is better
   if you have the objects, but the messages are variable. Although I
   think you are making much bigger a deal of this than there is, you
   way does appeal to me here. Interesting, though, that forth generally
   takes the form of my syntax. What a mess it should be!
 
>to here.  In order for one word to work properly it should not have to
>know what other words have (read:  To push one message and its parameters
>onto the stack shouldn't require knowing how many other messages are
>already on the stack ahead of you).

   I am not convinced that it does. Do words in forth need to know how
   many other words went before them?

>>    I give the best implementation I can think of and show how the
>>    object-message syntax matches that implementation more cleanly than
>>    the message-object syntax. 
>
>Of course it does, you set it up that way in the first place.

   Am I talking to a brick wall? I chose the best implementation I could
   think of. That implementation just happens to fit a particular syntax
   which happens to be different than your ideal. I wish I, or someone
   could devise an implementation that fits your syntax as cleanly. Then
   perhaps we could stop arguing.

>>    I claim that in forth the implementation has always been reflected in
>>    the syntax, so that is not a very strong objection. (eg. It is obvious
>>    from the syntax that there is a stack hiding back there somewhere.)
>
>Oh, and I objected to there being a stack?  Where?  I suppose all your
>data types are just:  : ARRAY STACK ;   : QUEUE STACK ;   : LIST STACK ;
>: TREE STACK ;   Ohh, you really got yourself there! :-)

   Huh? What are you blabbering about? I have no idea what you are reading
   in to what I wrote there?
 
>>    Now here is some vague claim that my implementation is "not as good" as
>>    some other one that hasn't even been specified! My implementation is
>>    inconsistent? I have yet to see "your way". I challenge you to give an
>>    implementation that fits your chosen syntax and fits as cleanly with forth
>>    as the one I gave for my syntax. If you could do that, I would probably
>>    prefer your syntax too. ... naaaaaah!
>
>The inconsistency of your implementation depends only your implementation.
>I don't have to provide any alternatives in order to show that.

   You have yet to say anything about implementation. All you have talked
   about is syntax. When I say "implementation" I mean the code behind
   the concept. How are objects and messages actually implemented in code
   to provide the behavior you prescribe to them. Apparently you have a
   different definition!

   In my original message I made a case that the object at the end syntax
   had problems in its IMPLEMENTATION. That syntax would not be as clean or
   simple as the message at the end syntax in its implementation in forth.
   I am still waiting for someone to show me I am wrong here!

   You have argued that the message at end syntax will cause the programmer
   stack manipulation grief. You are correct that that would be a valid
   reason to scratch that syntax in favor of the object at end. But that
   would be DESPITE the implementation. As stated above, I think your 
   arguments are basically flawed and that either syntax will cause grief
   depending on what you are trying to do.

>Besides, you haven't shown your implementation (I assume your copping one
>of the ones posted on the net).  What I have done is shown you rough-sketches

   You presume too much!

>through your design? :-).  In actuality, I would like to have an implementation
>that does just what I describe.  I think it is possible.  I think your
>way is possible too.  I think my way is better.  I have seen nothing to
>indicate an implementation difficulty.  I have already sketched several ways
>to do it.  

   Lost me here again. You THINK it is possible, and yet you KNOW several
   ways to do it? I must have missed your post on how to do it.
 
>can only reply by merely saying that you do in fact understand.  You claim
>that Message-Object and Object-Message can be scanned just as easily.  I
>claim that that is only true in the simplest of cases.  Cascading again
>belies that claim:
>
>		10 20 30 40 Object message-1 message-2
>
>Which parameters belong to which message.  Where is the dividing line?
>
>		10 20 30 message-1 30 Message-2 Object SEND SEND

   You are being very silly here! Of course this is simple to understand
   because you have chosen numbers as the arguments, messages have the word
   "message" in them and objects say "object"! 8^) Try going the other
   extreme and see if you can parse it either way:

                a b c d e f g SEND SEND

    Let's try a real (contrived 8^) example:

                dog fly frog  net shelf obtain-from  catch-in

                dog fly frog catch-in  net obtain-from shelf SEND SEND

    Again, doesn't it depend on what you are doing?
-- 
Bill <bouma@cs.purdue.edu>      Just ask the Axis   He knows everything

dwp@willett.pgh.pa.us (Doug Philips) (08/29/90)

[Lines with an odd number of >'s are William J. Bouma.]
[Lines with an even number of >'s are Doug Philips.]

In <11455@medusa.cs.purdue.edu>, bouma@cs.purdue.EDU (William J. Bouma) writes:
>    No, you seem to be trying to make my chosen syntax fit yours! Try:
> 
>          		        10 20 MyRectangle Moveto ( done in sep word )
> 					SEND

Sorry, the message/parameters pushing is the part to be put into a separate
word, if you change the problem of course the solution will change.
BTW: you can't have it both ways.  You were advocating an active message
name system.  Of course it gets simpler if you abandon that, that is one of
my points.

>    If you consistently follow your syntax it is consistent. If you
>    consistently follow my syntax it is consistent. You argument here is
>    completely invalid.

That claim is based on the fact you changed your position and went from
active message names to passive message names.  My point is still that the
code which pushes messages and their arguments is written exactly the same
way whether it is in a separate word or not.

>    If message is a literal, it must be quoted. That seems appropriate and
>    there is nothing inconsistent about it. In fact I could argue that your
>    method is flawed in that it treats literal and not literal messages the
>    same way. But that would be as stupid as the argument you are making. I
>    see nothing wrong with doing it either way.

You've missed the point.  "My way" allows arbitrary code to compute message
"names".  Your way has "active" message names.  That means you must quote
them if you want to delay the message invocation.  In my method computing the
message name and sending the message are separate steps.  In my method one
doesn't have to "write/construct" messages differently depending on when they
will be sent.

>    to SWAP! An example? Suppose I want to send a list of message to
>    a group of objects possibly computed on the fly. Isn't that essentially
>    the inverse of the example you gave? 

How do you get this "list of messages" onto the stack?  Are you assuming
that those messages have no parameters?  If the messages have parameters
you must push those, then push the object, then push the message and send it.
Its hard to talk in generalities about this specific case.  Without knowing
HOW you "store" your message list, it is hard for me to give a more concrete
example of HOW we differ here.  If your message list is a simple list of
parameterless message ID's, then there is little difference in the mechanics
of how our schemes work.  If the messages have paramters your scheme is more
complicated.

> 	<params-2> <params-1> Object <message-1> SEND <message-2> SEND
> 
>    Now you are talking some sense.
>    You know, both of these look like a real mess when you put it this
>    way! It seems your syntax is better if you know what messages you
>    want to send, but the objects are not prespecified. Mine is better
>    if you have the objects, but the messages are variable. Although I
>    think you are making much bigger a deal of this than there is, you
>    way does appeal to me here. Interesting, though, that forth generally
>    takes the form of my syntax. What a mess it should be!

I still disagree here.  You have to manipulate the stack to get the objects
in-between the parameters and the messages (which is why I called the
message-last form "inside out" in my initial posting).  Making your scheme
into passive message names (i.e.  requiring an explicit SEND) does not
alter the fact that you have to wiggle the object down the stack to its
"proper" place.

> >to here.  In order for one word to work properly it should not have to
> >know what other words have (read:  To push one message and its parameters
> >onto the stack shouldn't require knowing how many other messages are
> >already on the stack ahead of you).
> 
>    I am not convinced that it does.

Well, I can't say why you aren't convinced, but I'll try re-phrasing it
this way:  Your scheme requires that objects be on the stack between message
parameters and the message id's.  That means that cascading requires that
you push parameters onto the stack below the object.  In order to do that
you need to know how deep to go to find the object, i.e. you need to know
how many pending messages are already on the stack.  As for your question:

>                                     Do words in forth need to know how
>    many other words went before them?

They aren't supposed to, as I understand Forth.  Words that use parameters
on the stack aren't supposed to care how they got there.  In your scheme
words that want to push "delayed" sends MUST know how many other messages
there are pending on the stack in order to work properly.  I consider my
method to be cleaner and more Forth-like.

>    Am I talking to a brick wall? I chose the best implementation I could
>    think of. That implementation just happens to fit a particular syntax
>    which happens to be different than your ideal. I wish I, or someone
>    could devise an implementation that fits your syntax as cleanly. Then
>    perhaps we could stop arguing.

We aren't arguing implementation.  We are arguing design.  You built your
design around an implementation (or so it seems from your arguments).  I
built my design based on principles of how Forth words should be factored.

>    Huh? What are you blabbering about? I have no idea what you are reading
>    in to what I wrote there?
>    You have yet to say anything about implementation. All you have talked
>    about is syntax. When I say "implementation" I mean the code behind
>    the concept. How are objects and messages actually implemented in code
>    to provide the behavior you prescribe to them. Apparently you have a
>    different definition!

I guess I was being too subtle.  You have still not responded to my questions
about design.  As far as I can tell, you insist that the implementation drive
the design.  If you would decide that the best way to implement a tree were
with an array, I would expect to see array operations available for your
tree objects.  How you use something is not the same as how you implement it.

>    In my original message I made a case that the object at the end syntax
>    had problems in its IMPLEMENTATION. That syntax would not be as clean or
>    simple as the message at the end syntax in its implementation in forth.
>    I am still waiting for someone to show me I am wrong here!

I have shown you that in the case of cascaded messages.  My method has
suggested (and finally in this message stated directly) that the composing
and the sending of a message should be distinct steps.  What you have been
advocating, until now, is active messages (which requires them to be last,
of course).  You seem to have backed off to just a message-last position
with an explicit SEND.  I suppose that means I'm making some progress in
convincing you of the uncleanliness of message-last form.  You see, there
is another issue that has been here too, which is ease of implementation
versus ease of use.  I claim that if one designs without a specific
implementation in mind at the start that one is more likely to achieve both
ease of use and ease of implementation.  Your method and mine are similar
in ease-of-use if one is doing very simple things.  If one is doing more
complicated things then using your system is more complicated than using
mine.

>    You have argued that the message at end syntax will cause the programmer
>    stack manipulation grief. You are correct that that would be a valid
>    reason to scratch that syntax in favor of the object at end. But that
>    would be DESPITE the implementation. As stated above, I think your 
>    arguments are basically flawed and that either syntax will cause grief
>    depending on what you are trying to do.

Well, you railed at me in an earlier posting for 'claiming without
showing,' now you are doing the same thing.  You see, I have never wanted
to discuss particular implementation details and have avoided doing so as
much as I could.  I was arguing against active objects and active messages
from a users point of view, not from an implementor's point of view.  I
guess I didn't make that clear enough.  In any event, I ask you to SHOW me
how my way will cause grief.  I am certainly willing to discuss
implementation after we can agree on what it is we should be implementing.
See next reponse.

>    Lost me here again. You THINK it is possible, and yet you KNOW several
>    ways to do it? I must have missed your post on how to do it.

I was unclear.  I think it is possible in Forth.  I know it is possible
in other languages, because its been done.  The techniques should apply
without undue difficulty.  In fact I would be hesitant to insist on any
one of them over the others since there are, in fact, efficiency
trade-offs.

> >
> >		10 20 30 40 Object message-1 message-2
> >
> >Which parameters belong to which message.  Where is the dividing line?
> >
> >		10 20 30 message-1 30 Message-2 Object SEND SEND
> 
>    You are being very silly here! Of course this is simple to understand
>    because you have chosen numbers as the arguments, messages have the word
>    "message" in them and objects say "object"! 8^)

I specifically chose enlightening names for two reasons:  Its good programming
style, and it highlights how even with good names your scheme makes unclear
which of the numbers/arguments goes with which of the messages.  In my scheme
messages and arguments are grouped together, and it is thus easy to tell
which parameters go with which messages.

>    extreme and see if you can parse it either way:
> 
>                 a b c d e f g SEND SEND

I won't try to argue that you can't write opaque and incomprehensible code
in Forth.

>     Let's try a real (contrived 8^) example:
> 
>                 dog fly frog  net shelf obtain-from  catch-in
> 
>                 dog fly frog catch-in  net obtain-from shelf SEND SEND
> 
>     Again, doesn't it depend on what you are doing?

Precisely the point!  Again, your method and mine are of similiar
comprehensibility and ease-of-use for simple things.  My method lets you do
compilicated things in an easier way.  No programming method will prevent
you from writing obscure and incomprehensible code.  The question shoule
be:   How easily/comprehensibly can you write easy AND complicated things?

-Doug

---
Preferred: ( dwp@willett.pgh.pa.us  OR  ...!{sei,pitt}!willett!dwp )
Daily: ...!{uunet,nfsun}!willett!dwp  [last resort: dwp@vega.fac.cs.cmu.edu]

peter@ficc.ferranti.com (Peter da Silva) (08/29/90)

Whether you use an explicit SEND or not, the point comes up as to whether
an object or a message should be passive (on the stack) or active (or at
the top of the stack). I would like to suggest that the thing on the top
of the stack be something that is not going to undergo further manipulation.
That is, it should be a verb rather than a noun.

	1 17 4 5  4 array SEND  total SEND

		Push 4 numbers on the stack. Send the message ARRAY
		to the object 4. Send the message TOTAL to the resulting
		object.

	total  1 17 4 5  array 4 SEND SEND

		Push the message TOTAL on the stack. Push 4 numbers
		and the message ARRAY. Send this to the object 4. Do
		another send to send the (previously pushed) TOTAL
		to the resulting object.

But why should you have to have this message sitting down there on
the stack somewhere?

	1 17 4 5  array 4 SEND  total swap SEND

So why not have the message final anyway? And when are you going to
want to manipulate a message?
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com

bouma@cs.purdue.EDU (William J. Bouma) (08/30/90)

    This is garbage! I have changed nothing! Message NAMES are active.
    This does not mean a message cannot be left on the stack. How can I
    make something so obvious more clear? In forth you can leave a word
    on the stack and "execute" it. Well, the names of forth words are
    active! In my system messages ARE just normal forth words. That is
    why it is so practical to implement.
    
  
 >>    way does appeal to me here. Interesting, though, that forth generally
 >>    takes the form of my syntax. What a mess it should be!
 >
 >I still disagree here.  You have to manipulate the stack to get the objects
 >in-between the parameters and the messages (which is why I called the
 
 
    Your whole argument is based that the objects are unknown, computed on
    the fly. On top of that, you aren't quite sure what other arguments are
    to be included with the messages you are going to send! How often is this
    going to happen? To convice me, you will need to give something more
    specific than just the vague generalities so far! You seem convinced this
    sort of thing will be happening all the time.
 
 
 >>    I am not convinced that it does.
 >
 >Well, I can't say why you aren't convinced, but I'll try re-phrasing it
 >this way:  Your scheme requires that objects be on the stack between message
 >parameters and the message id's.  That means that cascading requires that
 >you push parameters onto the stack below the object.  In order to do that
 >you need to know how deep to go to find the object, i.e. you need to know
 >how many pending messages are already on the stack.  As for your question:
 >
 >>                                     Do words in forth need to know how
 >>    many other words went before them?
 >
 >They aren't supposed to, as I understand Forth.  Words that use parameters
 >on the stack aren't supposed to care how they got there.  In your scheme
 >words that want to push "delayed" sends MUST know how many other messages
 >there are pending on the stack in order to work properly.  I consider my
 
 
     Why? Why do you think that the OO message has to care how its other
     arguments got there?  Again, how is this situation different from the
     way forth does everything already?
     
 
 >I have shown you that in the case of cascaded messages.  My method has
 >suggested (and finally in this message stated directly) that the composing
 >and the sending of a message should be distinct steps.  What you have been
 >advocating, until now, is active messages (which requires them to be last,
 >of course).  You seem to have backed off to just a message-last position
 >with an explicit SEND.  I suppose that means I'm making some progress in
 >convincing you of the uncleanliness of message-last form.  You see, there
 
 
     Progress, I would call it digress! I still advocate the active messages.
     Why? 1. I see nothing better about the other way. 2. I have to type
     less "SEND"'s. 3. I can see how easy it is to implement. This is the
     same position I have had since day one. But what has this to do with
     our current discussion? I thought we had dealt with this issue 5 or 6
     messages ago. You mistakenly think I have changed my position.
 
 
 >is another issue that has been here too, which is ease of implementation
 >versus ease of use.  I claim that if one designs without a specific
 
 
     I wonder why I didn't think of that! 8^)
     It seems a lot of what I wrote has been missunderstood.
 
 
 >>     Again, doesn't it depend on what you are doing?
 >
 >Precisely the point!  Again, your method and mine are of similiar
 >comprehensibility and ease-of-use for simple things.  My method lets you do
 >compilicated things in an easier way.  No programming method will prevent
 >you from writing obscure and incomprehensible code.  The question shoule
 >be:   How easily/comprehensibly can you write easy AND complicated things?
 
 
     The answer to that question remains to be seen. (for both syntax's)
-- 
Bill <bouma@cs.purdue.edu>      Just ask the Axis   He knows everything

rob@idacom.uucp (Rob Chapman) (08/31/90)

To add to the discussion on oo syntax (sorry Doug, I pressed the wrong button):

 One may make this interesting if we allow active objects and active methods.
 These objects and methods may do different things depending on the context.
 ie.
  	File-Menu

 The object File-Menu could activate itself when executed and display an
 apropriate popup menu.  If it was already active, it would deativate
 itself.

 If the object was a counter, it would count in the set direction by the
 specified increments until it reached a terminal count.  To initialize a
 counter, its handle (provided by ' Key-counter) is passed to a polymorphic
 method:

    #up 1 0 infinite#  ' KeyCounter INITIALIZE  ( count keystrokes forever )
   or
    ' COUNT-UP  ' KeyCounter BIND  1 0 infinite#  ' KeyCounter INITIALIZE

 Every time KeyCounter is executed, it counts.  If the object is dynamicly
 bound, it may be turned off and back on by binding it to new actions.

    ' KeyCounter  ' STOP  BIND
  or
    ' KeyCounter STOP
 
 Getting back to your views on syntax, this could be achieved by binding
 different actions to the objects and methods.

    ' TIC  ' KeyCounter  BIND
 
 Now we no longer to ' KeyCounter, its action is to put its handle on the
 stack.  We could do the same for the methods,

    ' TIC  ' COUNT-UP  BIND

 and now we have the syntax:

   KeyCounter COUNT-UP  SEND

 by different BINDings, all syntax forms in your discussion may be achieved:

   KeyCounter COUNT-UP
   COUNT-UP KeyCounter
   fill in your choice:

 The key issue here, is Forth is a meta-language (amongst other things).  It
 is used to create languages to abstract solutions into the computer domain.
 Once one understands the problem, the solution is intuitive (assuming the
 converse: if a solution is not known, the problem is not understood).
 Forth allows quick protyping of ones initial understandings of a problem
 which allow progression towards a solution.

 Addressing your discussion with this perspective, Forth is the appropriate
 language to prototype oo syntax.  By adopting an extensible set of oo
 tools, we can adapt the syntax to different situations.  If ANS Forth had
 an oo wordset, it could probably consist of the word BIND !  

 Hysterically speaking this in not unlike the defur stuff with a little more
 edge.

 And for some ramblings on implementations, we tie this into the
 separated heads stuff.

     ______________________
    | header | body vector |
     ----------------------
		     |_________
			       |
			       V__________________________________________
			       | body of some definition or headless code |
			        ------------------------------------------
 
 In a subroutine-threaded Forth, the body vector would be a jump
 instruction.  This would allow late binding by compiling calls to the
 location of the body vector in the header.  Early binding is done by
 compiling calls to the code pointed to by the body vector, which is bound to
 the header at time of compilation.

 DEFER IS, really just a late binding mechanism.

 Anybody want to start a discussion on funtional programming?  In the Forth
 dimension of course {:^{)-]--[.

Rob

peter@ficc.ferranti.com (Peter da Silva) (09/05/90)

It's simple:

	Ask yourself: "What does an object return?"

Since that's what's going to be frequently on the stack, it should be
obvious that:

	arg arg arg that-thing the-other-thing

is the way to go. Guess what... objects rarely return messages. They
usually return other objects.

Think about it.
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com

dwp@willett.pgh.pa.us (Doug Philips) (09/07/90)

In <AFJ5HQE@xds13.ferranti.com>, peter@ficc.ferranti.com (Peter da Silva) writes:
> Whether you use an explicit SEND or not, the point comes up as to whether
> an object or a message should be passive (on the stack) or active (or at
> the top of the stack). I would like to suggest that the thing on the top
> of the stack be something that is not going to undergo further manipulation.
> That is, it should be a verb rather than a noun.

I think I see a point of potential confusion here.  In cascading one is
not sending multiple messages "to the same object".  One is sending
successive messages to the objects which are returned by the preceeding
message(s).   I think I was unclear about pointing that out.

-Doug

---
Preferred: ( dwp@willett.pgh.pa.us  OR  ...!{sei,pitt}!willett!dwp )
Daily: ...!{uunet,nfsun}!willett!dwp  [last resort: dwp@vega.fac.cs.cmu.edu]

dwp@willett.pgh.pa.us (Doug Philips) (09/07/90)

In <11485@medusa.cs.purdue.edu>, bouma@cs.purdue.EDU (William J. Bouma) writes:

>     Your whole argument is based that the objects are unknown, computed on
>     the fly. On top of that, you aren't quite sure what other arguments are
>     to be included with the messages you are going to send! How often is this
>     going to happen? To convice me, you will need to give something more
>     specific than just the vague generalities so far! You seem convinced this
>     sort of thing will be happening all the time.

Consider the ubiquitous list of graphical objects.  The "list" is itself
an object.  Consider the following example

	' SomeWord Map-Over List-Specifier SEND

where:	 SomeWord is a word which pushes a message (arguments first, then
	     message "key".
	 Map-Over is the message which takes one argument, an
	     execution-token.  Map-Over asks a list object to iterate over
	     its list and for each object, in turn:
		     first execute Map-Over's argument which is supposed to
			 cause a message and its arguments to be put onto the
			 stack.
		     push the object under consideration on the stack.
		     execute SEND.
	List-Specifier is arbitrary Forth code that leaves a list object
	    on the top of the stack.

In case that explanation isn't clear:  Send the message generated by
a call to SomeWord to each object in the list specified by the arbitrary
Forth code "List-Specifier".  Map-Over itself could be a constant, or
a string, or any other arbitrary Forth code.  How the message id is
generated is not important to this example.

>      our current discussion? I thought we had dealt with this issue 5 or 6
>      messages ago. You mistakenly think I have changed my position.

You changed your style in your last set of examples.  At first you had
active message names, but your latest round of examples showed quoted
message names without the quoting mechanism.  Perhaps that was an
unintentional change in style.


It has become abundantly clear that I am unable to get through to you.
There is no arbiter for the definition of OOP.  I hold that OOP, to be
meaningful, involves a shift in the way one looks at programming.  It is
not "merely" indirect function calling.  I cannot prove that any more than
I can prove that short word definitions are more the style and philosophy
of Forth than long word definitions are.

-Doug

-Doug

---
Preferred: ( dwp@willett.pgh.pa.us  OR  ...!{sei,pitt}!willett!dwp )
Daily: ...!{uunet,nfsun}!willett!dwp  [last resort: dwp@vega.fac.cs.cmu.edu]

dwp@willett.pgh.pa.us (Doug Philips) (09/07/90)

In <R1P54B@xds13.ferranti.com>, peter@ficc.ferranti.com (Peter da Silva) writes:
> It's simple:
> 
> 	Ask yourself: "What does an object return?"
> 
> Since that's what's going to be frequently on the stack, it should be
> obvious that:
> 
> 	arg arg arg that-thing the-other-thing
> 
> is the way to go. Guess what... objects rarely return messages. They
> usually return other objects.
> 
> Think about it.

That has been my point all along.  That is what makes cascading
possible.  If objects are "active" in the sense of being named
words then how does code that returns an object cause it to become
active?  My whole point (and I'm not sure what you are saying
is in total disagreement) has been that the following are all
separate and distinct operations:
	pushing message arguments and messages
	selecting the object which is to recieve the message
	sending the message

Having active message names muddles all three of those steps.
Having active objects muddles the last two and contorts cascading
and other anonymous object handling (like lists of objects).

-Doug

-Doug

---
Preferred: ( dwp@willett.pgh.pa.us  OR  ...!{sei,pitt}!willett!dwp )
Daily: ...!{uunet,nfsun}!willett!dwp  [last resort: dwp@vega.fac.cs.cmu.edu]

dwp@willett.pgh.pa.us (Doug Philips) (09/07/90)

In <1990Aug30.193356.26274@idacom.uucp>, rob@idacom.uucp (Rob Chapman) writes:

>  One may make this interesting if we allow active objects and active methods.
>  These objects and methods may do different things depending on the context.
>  ie.
>   	File-Menu
> 
>  The object File-Menu could activate itself when executed and display an
>  apropriate popup menu.  If it was already active, it would deativate
>  itself.

I think that that may be an interesting variant on object-active OOF, but I
don't see how it avoids having to name every object, which is my primary
objection to object-active OOF.  This is a separate issue from the details
you go into below, however.

>     #up 1 0 infinite#  ' KeyCounter INITIALIZE  ( count keystrokes forever )
>    or
>     ' COUNT-UP  ' KeyCounter BIND  1 0 infinite#  ' KeyCounter INITIALIZE

I much prefer the latter scheme, with the exception for making the object
_name_ active.  (implied by needing to quote) and having message names
last.  (What you are doing is good, but I disagree with how you say it).

>  Getting back to your views on syntax, this could be achieved by binding
>  different actions to the objects and methods.

I was at first intrigued by this, but it seems to violate the encapsulation
ideas of OOP.  Objects should have their actions "bound" by the code and
data structures that define the object.  I'm not sure what it means to have
a "rebind" message, but it doesn't seem right to call it OOP.

>  The key issue here, is Forth is a meta-language (amongst other things).  It
>  is used to create languages to abstract solutions into the computer domain.
>  Once one understands the problem, the solution is intuitive (assuming the
>  converse: if a solution is not known, the problem is not understood).
>  Forth allows quick protyping of ones initial understandings of a problem
>  which allow progression towards a solution.

I agree with all of that.

>  Addressing your discussion with this perspective, Forth is the appropriate
>  language to prototype oo syntax.  By adopting an extensible set of oo
>  tools, we can adapt the syntax to different situations.  If ANS Forth had
>  an oo wordset, it could probably consist of the word BIND !  

I think your BIND could be used to implement an OOF, but I don't think it
_is_ an OOF.

>  Hysterically speaking this in not unlike the defur stuff with a little more
>  edge.

Exactly.  As Bouma has pointed out, DEFER ( indirect function call ) is
often how OOF is implemented, but implementation isn't interface.  (i.e.
one uses stack objects in the same manner regardless of whether they are
implemented as arrays or linked lists or ....  )

-Doug

-Doug

---
Preferred: ( dwp@willett.pgh.pa.us  OR  ...!{sei,pitt}!willett!dwp )
Daily: ...!{uunet,nfsun}!willett!dwp  [last resort: dwp@vega.fac.cs.cmu.edu]

peter@ficc.ferranti.com (Peter da Silva) (09/10/90)

In article <1681.UUL1.3#5129@willett.pgh.pa.us> dwp@willett.pgh.pa.us (Doug Philips) writes:
> 	pushing message arguments and messages
> 	selecting the object which is to recieve the message
> 	sending the message

> Having active message names muddles all three of those steps.

	No, just the first. And only if you push messages which is
	pretty much only if you want an "apply" operation. Pushing
	messages is a damn rare case, and when you do it you can use
	a word that returns any message it's passed (like ' does
	in normal Forth).

> Having active objects muddles the last two and contorts cascading
> and other anonymous object handling (like lists of objects).

	Since message arguments are likely to be objects as well,
	it muddles all three.
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com

bouma@cs.purdue.EDU (William J. Bouma) (09/12/90)

In article <1680.UUL1.3#5129@willett.pgh.pa.us> dwp@willett.pgh.pa.us (Doug Philips) writes:
>
>	' SomeWord Map-Over List-Specifier SEND
>
>where:	 SomeWord is a word which pushes a message (arguments first, then
>	     message "key".
>	 Map-Over is the message which takes one argument, an
>	     execution-token.  Map-Over asks a list object to iterate over
>	     its list and for each object, in turn:
>		     first execute Map-Over's argument which is supposed to
>			 cause a message and its arguments to be put onto the
>			 stack.
>		     push the object under consideration on the stack.
>		     execute SEND.
>	List-Specifier is arbitrary Forth code that leaves a list object
>	    on the top of the stack.


   This is the same example given before!

   It is a SINGLE example, and it requires only a SINGLE swap (each iteration)
   to make it work with the message at the end. If you consider that a big
   deal, fine, then you have shown one instance where message at the end is
   not as nice as object at the end. Again (dejavu) I do not, and I do not
   see how anyone who uses forth could make such a big deal out of a single
   swap!

   Now, suppose I did consider that swap to be intollerable. It is still only
   one example, and does not prove that there is anything fundamentally wrong
   the message at the end syntax!

> bouma writes:
>>      our current discussion? I thought we had dealt with this issue 5 or 6
>>      messages ago. You mistakenly think I have changed my position.
>
>You changed your style in your last set of examples.  At first you had
>active message names, but your latest round of examples showed quoted
>message names without the quoting mechanism.  Perhaps that was an
>unintentional change in style.

   I am getting tired of repeating myself. I have NOT changed anything!
   The quoting mechanism is ' !!!!!!!!!!!!!!!!!!!!!! How can I emphasize
   this anymore? Messages are forth words! EXECUTE == SEND !!!! It is 
   annoying me that you cannot see this. Please take a few minutes and
   think about it. Haven't you ever used EXECUTE?
 
>It has become abundantly clear that I am unable to get through to you.

   You haven't made a case. Thus far you have simply made an opinion.
   An opinion proves nothing. From the start you have been stating that
   there is something wrong with a OO forth having the message at the end.
   If you want me to agree with you on this, you will need to show me. I
   do not have to accept this just because you say so!

>There is no arbiter for the definition of OOP.  I hold that OOP, to be
>meaningful, involves a shift in the way one looks at programming.  It is
>not "merely" indirect function calling.  I cannot prove that any more than

   And I hold that the syntax of something and the way one thinks about it
   are separate things. I have no problem thinking of the object doing the
   work (ie. your OOP model) even with the message at the end. Since that is
   the simplest way to implement it in forth, do it that way.
-- 
Bill <bouma@cs.purdue.edu>      Just ask the Axis   He knows everything

dwp@willett.pgh.pa.us (Doug Philips) (09/12/90)

In <7US58MD@xds1.ferranti.com>, peter@ficc.ferranti.com (Peter da Silva) writes:
> In article <1681.UUL1.3#5129@willett.pgh.pa.us> dwp@willett.pgh.pa.us (Doug Philips) writes:
> > 	pushing message arguments and messages
> > 	selecting the object which is to recieve the message
> > 	sending the message
> 
> > Having active message names muddles all three of those steps.
> 
> 	No, just the first. And only if you push messages which is
> 	pretty much only if you want an "apply" operation. Pushing
> 	messages is a damn rare case, and when you do it you can use
> 	a word that returns any message it's passed (like ' does
> 	in normal Forth).

Hmm... Active message names definitely muddles the first *and* third.
Or rather, merges them.  It muddles the second if you are doing an
apply.  How rare that is isn't really the issue, though I think it
is (and should be) much less rare than you think.

-Doug
---
Preferred:  dwp@willett.pgh.pa.us    Daily:  {uunet,nfsun}!willett!dwp

dwp@willett.pgh.pa.us (Doug Philips) (09/19/90)

In <11656@medusa.cs.purdue.edu>, bouma@cs.purdue.EDU (William J. Bouma) writes:
> In article <1680.UUL1.3#5129@willett.pgh.pa.us> dwp@willett.pgh.pa.us (Doug Philips) writes:

>    Now, suppose I did consider that swap to be intollerable. It is still only
>    one example, and does not prove that there is anything fundamentally wrong
>    the message at the end syntax!

Yow!  My intention was never to be as rigourous as that.  Mitch Bradley's
analogy of "buy" versus "build" and my reply to that sums up my intention.

>    And I hold that the syntax of something and the way one thinks about it
>    are separate things. I have no problem thinking of the object doing the
>    work (ie. your OOP model) even with the message at the end. Since that is
>    the simplest way to implement it in forth, do it that way.

That is a curious thing to say.  Everything I've read about Forth says just
the opposite.  Learning Forth involves seeing and doing programming a
different way.  There are those who say (essentially) that Forth's power
derives from its syntax.  Its syntax forces you to program differently.
The result is that you are supposed to think differently about programming
because of that.  Do you agree or disagree?

-Doug
---
Preferred:  dwp@willett.pgh.pa.us    Daily:  {uunet,nfsun}!willett!dwp