Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #30596 > unrolled thread

A slightly longer mini-oof2.fs example.

Started byJulian Fondren <ayrnieu@gmail.com>
First post2014-05-22 19:29 -0700
Last post2014-05-27 06:19 -0500
Articles 20 on this page of 34 — 11 participants

Back to article view | Back to comp.lang.forth


Contents

  A slightly longer mini-oof2.fs example. Julian Fondren <ayrnieu@gmail.com> - 2014-05-22 19:29 -0700
    Re: A slightly longer mini-oof2.fs example. albert@spenarnc.xs4all.nl (Albert van der Horst) - 2014-05-23 11:22 +0000
      Re: A slightly longer mini-oof2.fs example. Julian Fondren <ayrnieu@gmail.com> - 2014-05-23 09:38 -0700
    Re: A slightly longer mini-oof2.fs example. anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-23 12:11 +0000
      Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-23 10:26 -0500
        Re: A slightly longer mini-oof2.fs example. Bernd Paysan <bernd.paysan@gmx.de> - 2014-05-23 19:59 +0200
          Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-24 04:23 -0500
          Re: A slightly longer mini-oof2.fs example. Hans Bezemer <the.beez.speaks@gmail.com> - 2014-05-24 15:47 +0200
            Re: A slightly longer mini-oof2.fs example. Julian Fondren <ayrnieu@gmail.com> - 2014-05-26 12:46 -0700
          Re: A slightly longer mini-oof2.fs example. anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-24 15:35 +0000
            Re: A slightly longer mini-oof2.fs example. Alexander Skobelev <al.skobelev@gmail.com> - 2014-05-24 20:45 +0400
            Re: A slightly longer mini-oof2.fs example. Bernd Paysan <bernd.paysan@gmx.de> - 2014-05-24 21:46 +0200
              Re: A slightly longer mini-oof2.fs example. anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-25 15:03 +0000
                Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-25 15:16 -0500
                Re: A slightly longer mini-oof2.fs example. Bernd Paysan <bernd.paysan@gmx.de> - 2014-05-26 00:47 +0200
            Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-25 18:55 -0500
              Re: A slightly longer mini-oof2.fs example. albert@spenarnc.xs4all.nl (Albert van der Horst) - 2014-05-26 11:44 +0000
                Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-27 05:25 -0500
                  Re: A slightly longer mini-oof2.fs example. albert@spenarnc.xs4all.nl (Albert van der Horst) - 2014-05-27 11:56 +0000
              Re: A slightly longer mini-oof2.fs example. Julian Fondren <ayrnieu@gmail.com> - 2014-05-26 12:18 -0700
                Re: A slightly longer mini-oof2.fs example. Paul Rubin <no.email@nospam.invalid> - 2014-05-26 12:46 -0700
                  Re: A slightly longer mini-oof2.fs example. Julian Fondren <ayrnieu@gmail.com> - 2014-05-26 13:43 -0700
                Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-27 05:28 -0500
      Re: A slightly longer mini-oof2.fs example. Julian Fondren <ayrnieu@gmail.com> - 2014-05-23 09:39 -0700
        Re: A slightly longer mini-oof2.fs example. mhx@iae.nl - 2014-05-23 10:29 -0700
        Re: A slightly longer mini-oof2.fs example. anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-23 17:16 +0000
    Re: A slightly longer mini-oof2.fs example. andraszsoter@gmail.com - 2014-05-26 10:23 -0700
      Re: A slightly longer mini-oof2.fs example. Mark Wills <markwills1970@gmail.com> - 2014-05-27 02:09 -0700
        Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-27 06:07 -0500
        Re: A slightly longer mini-oof2.fs example. andraszsoter@gmail.com - 2014-05-28 10:17 -0700
      Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-27 05:39 -0500
        Re: A slightly longer mini-oof2.fs example. Mark Wills <markwills1970@gmail.com> - 2014-05-27 04:02 -0700
          Re: A slightly longer mini-oof2.fs example. Mark Wills <markwills1970@gmail.com> - 2014-05-27 04:04 -0700
          Re: A slightly longer mini-oof2.fs example. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-27 06:19 -0500

Page 1 of 2  [1] 2  Next page →


#30596 — A slightly longer mini-oof2.fs example.

FromJulian Fondren <ayrnieu@gmail.com>
Date2014-05-22 19:29 -0700
SubjectA slightly longer mini-oof2.fs example.
Message-ID<70a9649b-29ee-43f8-a1f8-af2581dafab8@googlegroups.com>
Hello clf,

mini-oof2.fs is included in gforth, and is supposedly mini-oof.fs (an object
system in a screen) plus something called a "current object".  If you search
clf, mini-oof2.fs is mentioned a few times in passing and then there's a long
thread where Bernd supports object systems having a "current object" while
others are skeptical of this.  There is also an example of a 'point' class.

Please take a look at this longer example:

\ ------------------------------------------------------------
require mini-oof2.fs

object class
  method :unshift ( x -- )
  method :shift ( -- x )
  method :each ( xt -- )
  method .list ( -- )
  method nil? ( -- f )
end-class nil-class

nil-class class
  field: cdr
  field: car
end-class cons-cell

' true nil-class to nil?
' false cons-cell to nil?
nil-class new constant nil

: cons ( car cdr -- list )
  cons-cell new >o cdr ! car ! o o> ;

[: nil? if o> nil cons >o exit then
   o cons-cell new o> >o cdr ! car ! ;] nil-class to :unshift
[: nil? if nil exit then 
   car @ cdr @  dispose  o> >o ;] nil-class to :shift
[: { xt } o >o begin nil? 0= while car @ xt execute cdr @ o> >o repeat o> ;] nil-class to :each
[: ['] . :each ;] nil-class to .list

\ totally unnecessary -- see below.
nil-class >methods
  dup cell+ swap @
  cell -  \ don't copy 'nil?'
  cons-cell >methods cell+ swap move

: upto ( n -- list )
  nil >o  0 swap -do i :unshift 1 -loop o o> ;

10 upto value a-list
: bump ( -- )  a-list >o [: drop  1 car +! ;] :each .list o> ;
: chop ( -- )  a-list >o :shift . :shift . :shift . o to a-list o> ;
\ ------------------------------------------------------------

Why does this use a nil class?  Because you can't invoke methods on 0.  If
nil is 0, you can't ever say  NIL >o 1 :UNSHIFT o o>  to produce the list (1).

Incidentally, you *can* 'invoke' fields on 0.  You get the offset.
gl-helper.fs in the Android distribution has a use of this in VERTEX-INIT .

Why does this manually copy method XTs from nil-class to cons-cell ?  Because
methods are only copied on class creation, but these methods need to be able to
refer to NIL as well as CONS-CELL .  ... although, come to think of it, they
don't need that: the NIL? IF .. EXIT THEN behaviors should just be NIL-CLASS's
own method definitions.

Why does :EACH have that [: o >o ... o> ;] pattern?  So that it can walk through
the list's cells and then restore the list as the active object.  Otherwise
BUMP would display nothing, because .LIST would always be invoked on NIL

Meanwhile, :SHIFT and :UNSHIFT deliberately replace the active object, so that
you can chain these operations as seen in UPTO and CHOP .

How can BUMP mutate the list?  Because :EACH, originally intended to only
provide the value of CAR to the xt, also happens to leave the cons-cell it's at
as the active object.  The presense of an active object means that :EACH
actually shouldn't provide the value of CAR at all -- it should just let the xt
grab whatever it wants.

What's all this >o o> o stuff again?

: >o ( o -- )  pushes the object at the top of the data stack to the top of the
object stack ;
: o> ( -- )  performs a DROP on the object stack. ;
: o  ( -- o )  copies the top of the object stack to the top of the data stack ;

Other unfactored operations:

: o-dup      ( -- ) ( obj: o -- o o )    o >o ;
: o-replace  ( o2 -- ) ( obj: o1 -- o2 ) o> >o ;
: o>d        ( -- o ) ( obj: o -- )      o o> ;

Methods are applied to the top of the object stack.

What's with these weird names?  :SHIFT :UNSHIFT ?  Why doesn't NIL? also have a
preceeding colon?  Let's not get distracted by the small stuff.

When I CHOP more than a few times I start seeing this weird number?  That's the
address of NIL.

I said A-LIST >O .LIST to gforth and it complained about an Invalid memory
address?  Seems that gforth uses the current object as well, so you should use
the same discipline about the current object that you would use in a
definition, and write: A-LIST >O .LIST O>

--

So what do you think?  My initial reaction to the current object stuff was "why
would you want all that noise?" and "I never missed something like this when
using other object systems."  And in the longer thread that you can search for
(Google only finds four references to mini-oof2.fs in clf) there are complaints
like "I expect that matching the >O and O> operations will be difficult."

But the object no longer needs to be managed on the data stack, and it's easy
to change the current object within a method, or to leave the current object as
part of the environment for an XT.  For all the extra 'noise', the code is
cleaner and is easier to write.  And it's not actually difficult to keep track
of >o and blah; it's a super shallow stack (as far as you ever care) with few
operations, and this is Forth, so managing it does not feel unnatural.

And the 'mini' of mini-oof2 is an advantage.  In the example above, the unnamed
COPY-METHODS ( class1 class2 -- ) was easily written even though it wasn't a
good idea.  If I'd faced some problem like this in SWOOP, I would've sat back,
re-read the documentation, agonized for a bit, and then would've done the right
thing of changing my classes rather than messing with the object system :-)


-- Julian

[toc] | [next] | [standalone]


#30603

Fromalbert@spenarnc.xs4all.nl (Albert van der Horst)
Date2014-05-23 11:22 +0000
Message-ID<537f2f6e$0$3031$e4fe514c@dreader35.news.xs4all.nl>
In reply to#30596
In article <70a9649b-29ee-43f8-a1f8-af2581dafab8@googlegroups.com>,
Julian Fondren  <ayrnieu@gmail.com> wrote:
>Hello clf,
>
>mini-oof2.fs is included in gforth, and is supposedly mini-oof.fs (an object
>system in a screen) plus something called a "current object".  If you search
>clf, mini-oof2.fs is mentioned a few times in passing and then there's a long
>thread where Bernd supports object systems having a "current object" while
>others are skeptical of this.  There is also an example of a 'point' class.
>
>Please take a look at this longer example:

Example of what? Please add one line to a program at the front to
explain what its purpose is. My first guess is your program is for
calculating primes (all my programs are) ,
but I have no idea how it works ;-)

<SNIP>
>
>So what do you think?  My initial reaction to the current object stuff was "why
>would you want all that noise?" and "I never missed something like this when
>using other object systems."  And in the longer thread that you can search for
>(Google only finds four references to mini-oof2.fs in clf) there are complaints
>like "I expect that matching the >O and O> operations will be difficult."

About the current object thing. I made my own objects to implement
manx2 and replace both structs and fields from Marcel Hendrix. I
decided that current object is better over ( object data method ) and
(data object method ) and never looked back. I published the two
screener here a couple of times. Recently it has become a one
screener. A host of applications I did, confirm it, such as ciasdis,
an assembler/disassembler. In particular my implementation of ALLOCATE
that would never have done with objects if my objects required an
extra object id on the stack.

>
>But the object no longer needs to be managed on the data stack, and it's easy
>to change the current object within a method, or to leave the current object as
>part of the environment for an XT.  For all the extra 'noise', the code is
>cleaner and is easier to write.  And it's not actually difficult to keep track
>of >o and blah; it's a super shallow stack (as far as you ever care) with few
>operations, and this is Forth, so managing it does not feel unnatural.

Huh?

>
>And the 'mini' of mini-oof2 is an advantage.  In the example above, the unnamed
>COPY-METHODS ( class1 class2 -- ) was easily written even though it wasn't a
>good idea.  If I'd faced some problem like this in SWOOP, I would've sat back,
>re-read the documentation, agonized for a bit, and then would've done the right
>thing of changing my classes rather than messing with the object system :-)
>
>
>-- Julian

Groetjes Albert
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

[toc] | [prev] | [next] | [standalone]


#30615

FromJulian Fondren <ayrnieu@gmail.com>
Date2014-05-23 09:38 -0700
Message-ID<9e3ce38a-2ea9-4157-8fb2-ac2c7978d7a7@googlegroups.com>
In reply to#30603
On Friday, May 23, 2014 6:22:22 AM UTC-5, Albert van der Horst wrote:
> Example of what? Please add one line to a program at the front to
> explain what its purpose is. My first guess is your program is for
> calculating primes (all my programs are) ,
> but I have no idea how it works ;-)

You've correctly intuited that it calculates primes, though.  Right now it only
counts 1.5 primes.  You just need to add a length method:

[: 0 [: drop  1+ ;] :each ;] nil-class to length

Then, getting the length of a-list and CHOPping it yields a "not a prime / a
prime" alternating pattern: 10 7 4 1

> About the current object thing. I made my own objects to implement
> manx2 and replace both structs and fields from Marcel Hendrix. I
> decided that current object is better over ( object data method ) and
> (data object method ) and never looked back. I published the two
> screener here a couple of times. Recently it has become a one
> screener. A host of applications I did, confirm it, such as ciasdis,
> an assembler/disassembler. In particular my implementation of ALLOCATE
> that would never have done with objects if my objects required an
> extra object id on the stack.

Cool.  A search for 'washing-oo' finds a self-contained example.


-- Julian

[toc] | [prev] | [next] | [standalone]


#30605

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2014-05-23 12:11 +0000
Message-ID<2014May23.141134@mips.complang.tuwien.ac.at>
In reply to#30596
Julian Fondren <ayrnieu@gmail.com> writes:
>Hello clf,
>
>mini-oof2.fs is included in gforth, and is supposedly mini-oof.fs (an object
>system in a screen) plus something called a "current object".  If you search
>clf, mini-oof2.fs is mentioned a few times in passing and then there's a long
>thread where Bernd supports object systems having a "current object" while
>others are skeptical of this.

IIRC the only one sceptical was Andrew Haley.  Most people working on
this have a current object (THIS, SELF or O).  The main discussion was
about how the current object should be set.  Bernd Paysan sets and
restores it explicitly with >O O>, or WITH END-WITH or somesuch,
whereas most others set it implicitly on method call.  As a
consequence, the others put the object that is to become the current
object on the data stack on a method call, while Bernd Paysan makes it
the current object explictly at some earlier point, and then just uses
that for the dynamic dispatch.

This results in the following syntactic differences:

Calling a method FOO for the current object (THIS):

Bernd Paysan: foo
Anton Ertl:   this foo

Callingt a method FOO for a different object BAR

Bernd Paysan:  bar >o foo o>
Anton Ertl:    bar foo   

Bernd Paysan's argument was that he usually calls the method with the
current object and that he changes the current object much less
frequently.  Given your experiment, what do you think?  There are 9
>O, 9 O>, and 5 O in your example, in 8 definitions.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2014: http://www.euroforth.org/ef14/

[toc] | [prev] | [next] | [standalone]


#30614

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2014-05-23 10:26 -0500
Message-ID<zLCdnQlJo9IW9eLOnZ2dnUVZ8tCdnZ2d@supernews.com>
In reply to#30605
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
> Julian Fondren <ayrnieu@gmail.com> writes:
>>Hello clf,
>>
>>mini-oof2.fs is included in gforth, and is supposedly mini-oof.fs
>>(an object system in a screen) plus something called a "current
>>object".  If you search clf, mini-oof2.fs is mentioned a few times
>>in passing and then there's a long thread where Bernd supports
>>object systems having a "current object" while others are skeptical
>>of this.
> 
> IIRC the only one sceptical was Andrew Haley.  Most people working on
> this have a current object (THIS, SELF or O).

Gosh, just me, really?  The only thing I was skeptical about was
having THIS as a hidden argument passed to all routines, even colon
definitions.  I don't think doing that is a good idea: Forth should
pass arguments, including THIS, on the stack.  As far as I'm aware,
most (non-Forth) OOP languages do that.  So, I have no objection to
the idea of a current object, I just think it should be passed in the
normal way.

Andrew.

[toc] | [prev] | [next] | [standalone]


#30620

FromBernd Paysan <bernd.paysan@gmx.de>
Date2014-05-23 19:59 +0200
Message-ID<llo2ag$i0l$1@online.de>
In reply to#30614
Andrew Haley wrote:
> Gosh, just me, really?  The only thing I was skeptical about was
> having THIS as a hidden argument passed to all routines, even colon
> definitions.  I don't think doing that is a good idea: Forth should
> pass arguments, including THIS, on the stack.  As far as I'm aware,
> most (non-Forth) OOP languages do that.  So, I have no objection to
> the idea of a current object, I just think it should be passed in the
> normal way.

"the normal way" is more pragmatic in Forth.  First of all, we don't have 
just *the* stack.  We have a data stack, a floating point stack, and a 
return stack; Gforth has a separate locals stack.  A number of string 
packages offer a string stack, we have a vocabulary stack, there's a 
recognizer stack in Gforth.  Having more than one stack is natural in Forth.

As it quickly turned out with packages like mini-oof.fs, having the object 
on the data stack is too much of an obstacle.  Mini-OOF is barely usable, 
especially for accessing the instance variables.  So you will soon have a 
current object.  Now what?  Use it only for instance variables?  This 
results in inconsistent use: instance variables are relative to the current 
object, methods take it from the stack.  Inconsistent interfaces clutter the 
mind, and therefore should be avoided.

Result: Use a stack (shared with the return stack) for the current object, 
with the top of stack in a user variable or register, passed implicitely to 
other methods.

BTW: Mini-OOF2 has a "plugin system" for how methods and instance variables 
work, so you can make them whatever you want (including explicit object 
passing for methods and implicit for instance variables).  One of the ways 
to plug into that system is to have specific "current objects" for different 
classes.  E.g. the IO vectors in Gforth use that: There's a current output 
object and a current input object.  KEY and EMIT call through that objects, 
they are really just methods.

It wouldn't work if these methods would require a current object on the 
stack.

-- 
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

[toc] | [prev] | [next] | [standalone]


#30639

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2014-05-24 04:23 -0500
Message-ID<_4udnQIXGsmE-B3OnZ2dnUVZ_vednZ2d@supernews.com>
In reply to#30620
Bernd Paysan <bernd.paysan@gmx.de> wrote:
> Andrew Haley wrote:
>> Gosh, just me, really?  The only thing I was skeptical about was
>> having THIS as a hidden argument passed to all routines, even colon
>> definitions.  I don't think doing that is a good idea: Forth should
>> pass arguments, including THIS, on the stack.  As far as I'm aware,
>> most (non-Forth) OOP languages do that.  So, I have no objection to
>> the idea of a current object, I just think it should be passed in the
>> normal way.
> 
> "the normal way" is more pragmatic in Forth.  First of all, we don't
> have just *the* stack.  We have a data stack, a floating point
> stack, and a return stack; Gforth has a separate locals stack.  A
> number of string packages offer a string stack, we have a vocabulary
> stack, there's a recognizer stack in Gforth.  Having more than one
> stack is natural in Forth.
> 
> As it quickly turned out with packages like mini-oof.fs, having the
> object on the data stack is too much of an obstacle.  Mini-OOF is
> barely usable, especially for accessing the instance variables.

OK, why?  Let's assume that you put THIS into a local at the start of
a method, and that instance variables use the local THIS, and that if
you want to call a PRINT method you say THIS PRINT or somesuch.  (I
know that you can't portably tick and COMPILE locals, but let's ignore
that for a moment.)

Python was a real revelation for me: I am used to Smalltalk and Java
style, where "this" (aka "self") is usually implicit, but in Python
you say "self.blah" if you want to access instance variable blah, and
people using Python don't seem to mind having to do that.  AFAIK The
reason they don't mind is that they got used to it, and the advantage
is that you can see easily at the point of use what is an instance
variable.  And also, there is nothing special about "self" in Python:
it's just a local variable, and the name "self" is no more than a
convention.  What you get in return is simplicity and consitency.

> BTW: Mini-OOF2 has a "plugin system" for how methods and instance
> variables work, so you can make them whatever you want (including
> explicit object passing for methods and implicit for instance
> variables).  One of the ways to plug into that system is to have
> specific "current objects" for different classes.  E.g. the IO
> vectors in Gforth use that: There's a current output object and a
> current input object.  KEY and EMIT call through that objects, they
> are really just methods.
> 
> It wouldn't work if these methods would require a current object on
> the stack.

No, it wouldn't, but that's rather obscure.

Andrew.

[toc] | [prev] | [next] | [standalone]


#30640

FromHans Bezemer <the.beez.speaks@gmail.com>
Date2014-05-24 15:47 +0200
Message-ID<5380a2bd$0$2830$e4fe514c@news2.news.xs4all.nl>
In reply to#30620
Bernd Paysan wrote:
> Result: Use a stack (shared with the return stack) for the current object,
> with the top of stack in a user variable or register, passed implicitely
> to other methods.
Agreed. I came to the same conclusion. The only difference is that in FOOS
there is the word "this" which is an alias for "r@". If you can't stand the
return stack being "taken", never use DO..LOOP again, I thought.

Hans Bezemer

[toc] | [prev] | [next] | [standalone]


#30778

FromJulian Fondren <ayrnieu@gmail.com>
Date2014-05-26 12:46 -0700
Message-ID<27c05757-4f87-48ec-b6e6-f932872cc34d@googlegroups.com>
In reply to#30640
On Saturday, May 24, 2014 8:47:19 AM UTC-5, The Beez wrote:
> Bernd Paysan wrote:
> > Result: Use a stack (shared with the return stack) for the current object,
> > with the top of stack in a user variable or register, passed implicitely
> > to other methods.

> Agreed. I came to the same conclusion. The only difference is that in FOOS
> there is the word "this" which is an alias for "r@". If you can't stand the
> return stack being "taken", never use DO..LOOP again, I thought.
> 
> Hans Bezemer

Wow, I hadn't realized that there was any interaction with the return stack.

In mini-oof2.fs:

( output: 0  ) 0 >o 1 >r o . rdrop o>
( output: 0 !) 1 >r 0 >o r@ . o> rdrop
( output: 0  ) 0 >o 1 >r 2 >o o> o . rdrop o>
( output: 3 !) 0 >o 1 >r 2 >o 3 >r o> o . rdrop rdrop o>

: x ( -- ) \ print 0 ten times
  0 >o 10 0 do o . loop o> ;

: x ( -- ) \ break horribly -- which is probably for the best
  10 0 do i >o loop
  10 0 do o>   loop ;

: start 0 >o ;
: stop  o> ;
: invalid-memory-address ( -- )
  start o . stop ;

: continue o 1+ o> >o ;
: x ( -- )  \ output: 1
  0 >o continue o . o> ;

I, uh, look forward to the documentation :-)


-- Julian

[toc] | [prev] | [next] | [standalone]


#30644

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2014-05-24 15:35 +0000
Message-ID<2014May24.173516@mips.complang.tuwien.ac.at>
In reply to#30620
Bernd Paysan <bernd.paysan@gmx.de> writes:
>As it quickly turned out with packages like mini-oof.fs, having the object 
>on the data stack is too much of an obstacle.  Mini-OOF is barely usable, 
>especially for accessing the instance variables.  So you will soon have a 
>current object.  Now what?  Use it only for instance variables?  This 
>results in inconsistent use: instance variables are relative to the current 
>object, methods take it from the stack.  Inconsistent interfaces clutter the 
>mind, and therefore should be avoided.

I did not find that inconsistent when I wrote Gray.  After all,
methods are not instance variables.  E.g., methods are bound
dynamically, instance variables not.  Do you also think that this is
an inconsistency that should be avoided?

One interesting observation in the Java part of my introductory
programming course is that many students write "this.bla" where "bla"
would be sufficient. I did not teach them that, and in what I show
them I use "bla" instead (at least for instance variables).  I guess
they learned it elsewhere and there is someone teaching that style.
Which may be a good idea, it's more consistent with the access to the
instance variables of other objects.

Anyway, the problem with mini-oof.fs is that there is no current
object at all.

Once we have a current object, the question is whether to set it
implicitly on method call (as happens in most OO languages and most
Forth OO packages), or whether to set it explicitly.  Or we might also
do both: set it implicitly on method calls, and also allow explicit
setting.

The actual difference is: When you set it implicitly on method calls,
you pass this object on the stack.  When you don't set it on method
calls, but only explictly, you do not pass the object on the stack,
you only pass it through the current object.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2014: http://www.euroforth.org/ef14/

[toc] | [prev] | [next] | [standalone]


#30648

FromAlexander Skobelev <al.skobelev@gmail.com>
Date2014-05-24 20:45 +0400
Message-ID<m2r43jrupt.fsf@gmail.com>
In reply to#30644
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
> […]
>
> One interesting observation in the Java part of my introductory
> programming course is that many students write "this.bla" where "bla"
> would be sufficient. I did not teach them that, and in what I show
> them I use "bla" instead (at least for instance variables).  I guess
> they learned it elsewhere and there is someone teaching that style.
> Which may be a good idea, it's more consistent with the access to the
> instance variables of other objects.

When I write C++ code I usually use this->bla and in Objective-C it is
_bla. It just a convention to designate instance variables to make the
code more readable. So from this point THIS BLA may be preferable to
BLA. 

[toc] | [prev] | [next] | [standalone]


#30653

FromBernd Paysan <bernd.paysan@gmx.de>
Date2014-05-24 21:46 +0200
Message-ID<llqsu1$ivh$1@online.de>
In reply to#30644
Anton Ertl wrote:

> Bernd Paysan <bernd.paysan@gmx.de> writes:
>>As it quickly turned out with packages like mini-oof.fs, having the object
>>on the data stack is too much of an obstacle.  Mini-OOF is barely usable,
>>especially for accessing the instance variables.  So you will soon have a
>>current object.  Now what?  Use it only for instance variables?  This
>>results in inconsistent use: instance variables are relative to the
>>current
>>object, methods take it from the stack.  Inconsistent interfaces clutter
>>the mind, and therefore should be avoided.
> 
> I did not find that inconsistent when I wrote Gray.  After all,
> methods are not instance variables.  E.g., methods are bound
> dynamically, instance variables not.  Do you also think that this is
> an inconsistency that should be avoided?

No, because that is not an invocation inconsistency - invocation is your 
public interface, how you implement it is a private decision of the 
implementer.

In Forth, all things are first of all *words*.  And then you put them into 
bins like "variable" or "colon definition", usually classified by their 
stack effect.  In mini-oof2, you can have instance variables (they are 
defined with field: or friends, but actually relate to the current object; 
that choice was made because there is a large set of words already there 
with field: and a central place where to hook into to change the behavior), 
you can have methods, and you can factor your definitions into ordinary 
colon definitions, which would be "early bound methods" or non-virtual 
methods in C++.

And when you refactor your code, you can concentrate on the essence of 
refactoring, instead of going through your entire code base.  E.g. let's say 
foo was first an instance variable, holding a cell.  After a while, you 
discover that your object really has two states in which it has two 
different foos, and you now define

: foo ( -- addr ) mystate @ IF  foo1  ELSE  foo2  THEN ;

After a while, you discover furthermore that, well, this distinction is only 
necessary for 20% of your classes, and the other do well with having just 
one foo, so you declare foo as a method, and define that with

' foo1 my-baseclass to foo

or, for those who needs two states

:noname ( -- addr ) mystate @ IF  foo1  ELSE  foo2  THEN ; my-sublass to foo

The invocation never changed, and therefore, you never had to dig through 
your entire code base for all invokations of foo.

This sort of consistency makes maintaining code easy.  The thing you need to 
maintain consistently is the signature of the word (the way it is invoked), 
not the way it is implemented.

> One interesting observation in the Java part of my introductory
> programming course is that many students write "this.bla" where "bla"
> would be sufficient. I did not teach them that, and in what I show
> them I use "bla" instead (at least for instance variables).  I guess
> they learned it elsewhere and there is someone teaching that style.

Yes, probably.

> Which may be a good idea, it's more consistent with the access to the
> instance variables of other objects.

Well, you shouldn't access instance variables of other objects...

> Anyway, the problem with mini-oof.fs is that there is no current
> object at all.
> 
> Once we have a current object, the question is whether to set it
> implicitly on method call (as happens in most OO languages and most
> Forth OO packages), or whether to set it explicitly.  Or we might also
> do both: set it implicitly on method calls, and also allow explicit
> setting.
> 
> The actual difference is: When you set it implicitly on method calls,
> you pass this object on the stack.  When you don't set it on method
> calls, but only explictly, you do not pass the object on the stack,
> you only pass it through the current object.

Yes.  The thing I want to make is a *consistent* minimalistic set of 
operations, which all do *exactly one thing*.  And do that right.  And once 
there is a current object, the only way to manipulate that current object is 
the >o o> stuff, and it's orthogonal to all other operations, i.e. no other 
operation has a hidden side-effect which manipulates the current object.

The good thing for people like you is that the "do one thing right" for 
METHOD is to take a template and produce a method invocation from that 
template (that is to be consistent with +FIELD, which is the central place 
to define instance variables, and it is malleable - it will always add the 
offsets the same way, but what kind of FIELD stuff it implements can 
change).  You can change the template.  And if you like to, you can change 
that template to contain >O and O> around the actual invocation, so the 
variant of mini-oof2 you are using will require a THIS (or O as it is called 
in mini-oof2, as this is more consistent with the >O O> stuff) for invoking 
methods of the same object.  The default method invocation doesn't do this, 
because it is always easier to add things than to take them away.

Perfection is only reached when there's nothing left to take away.  
Consistency is reached when things have the same interface to the outside.
Flexibility is reached when you can change all those things to suit your 
needs.

Mini-oof2 came into life, because I started to experiment with a Forth Meta 
Object Protocol.  The intention is to have something that is so basic that 
nobody can refuse to add the basics.  And that you can extend it the way you 
want.  The basics are there to provide with essential stuff, and that means 
all this essential stuff is then somewhat compatible between different OOP 
systems that base on the same foundation.  Somewhat, because people do have 
incompatible method invocation, and that can't be fixed.  But what can be 
fixed is that these method invocations consist of core components which are 
the same, and the only difference is how to glue them together.

This allows a system implementer to implement a fast and efficient set of 
primitives, which he has the duty to maintain, and leave all the other stuff 
to the OOP package implementers, and there, he doesn't have to maintain 
things.

If you don't like  foo >o bar o>  in mini-oof2, add a dot-parser recognizer 
which will transform

foo.bar   into   foo >o bar o>
foo->bar  into   foo @ >o bar o>

with any number of . and -> in the string (just replace all "." with " >o " 
and all "->" with " @ >o " and count the number of occurances, and then add 
that number of " o>" to the end - and reevaluate). 

That stuff is probably a good idea to do, and improves readability.  It 
works consistently for accessing instance variables and methods from other 
classes.  This is the sort of consistency I'm aiming at.

-- 
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

[toc] | [prev] | [next] | [standalone]


#30693

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2014-05-25 15:03 +0000
Message-ID<2014May25.170321@mips.complang.tuwien.ac.at>
In reply to#30653
Bernd Paysan <bernd.paysan@gmx.de> writes:
>And when you refactor your code, you can concentrate on the essence of 
>refactoring, instead of going through your entire code base.

Given that, as you write, one should only access an instance variable
in its class (and maybe descendent classes), you don't need to go
through the entire code base.  Sure, if I don't control the code base
that would need to be changed, keeping the interface the same is the
way to go, but if I do, it may be better to actually change it
(although keeping the interface the same may be good for the
intermediate step).  Anyway, you also have both options with
objects.fs.

  E.g. let's say 
>foo was first an instance variable, holding a cell.  After a while, you 
>discover that your object really has two states in which it has two 
>different foos, and you now define
>
>: foo ( -- addr ) mystate @ IF  foo1  ELSE  foo2  THEN ;

This works in objects.fs, too; THIS is global, and is not changed when
you call a colon definition.  One may discuss whether this is a
feature, or just an artifact of the implementation; it was not
intended as a feature, but maybe you can convince me that it is one
(better, convince Andrew Haley!-).

>After a while, you discover furthermore that, well, this distinction is only 
>necessary for 20% of your classes, and the other do well with having just 
>one foo, so you declare foo as a method, and define that with
>
>' foo1 my-baseclass to foo
>
>or, for those who needs two states
>
>:noname ( -- addr ) mystate @ IF  foo1  ELSE  foo2  THEN ; my-sublass to foo

In objects.fs I can define

selector foo-s
: foo this foo-s ; \ used global this

\ in my-baseclass
m: foo1 ;m overrides foo-s \ could be made more efficient

\ in some classes
m: ( -- addr ) mystate @ IF  foo1  ELSE  foo2  THEN ;m overrides foo-s

>The invocation never changed, and therefore, you never had to dig through 
>your entire code base for all invokations of foo.
>
>This sort of consistency makes maintaining code easy.  The thing you need to 
>maintain consistently is the signature of the word (the way it is invoked), 
>not the way it is implemented.

As I demonstrated, explicit setting of the current object is not
needed for this.

>> One interesting observation in the Java part of my introductory
>> programming course is that many students write "this.bla" where "bla"
>> would be sufficient. I did not teach them that, and in what I show
>> them I use "bla" instead (at least for instance variables).  I guess
>> they learned it elsewhere and there is someone teaching that style.
>
>Yes, probably.
>
>> Which may be a good idea, it's more consistent with the access to the
>> instance variables of other objects.
>
>Well, you shouldn't access instance variables of other objects...

That's what I thought when I started working with Java.  now I am no
longer convinced of that, at least for Java.

Anyway, back to our discussion: Yes, that was the idea behind the way
instance variables and methods are handled in objects.fs:

Only instance variables of the current object should only be accessed,
so instance variables are only visible in their class, and they always
are accessed through the current objects.

In contrast, methods should be callable everywhere, for arbitrary
objects, so the method selector has a global name, and you pass the
object on which it dispatches explicitly.

As demonstrated, you can emulate the instance variable interface with
colon definitions or methods, so that's no reason to change that.

>Yes.  The thing I want to make is a *consistent* minimalistic set of 
>operations, which all do *exactly one thing*.  And do that right.  And once 
>there is a current object, the only way to manipulate that current object is 
>the >o o> stuff, and it's orthogonal to all other operations, i.e. no other 
>operation has a hidden side-effect which manipulates the current object.
>
>The good thing for people like you is that the "do one thing right" for 
>METHOD is to take a template and produce a method invocation from that 
>template (that is to be consistent with +FIELD, which is the central place 
>to define instance variables, and it is malleable - it will always add the 
>offsets the same way, but what kind of FIELD stuff it implements can 
>change).  You can change the template.  And if you like to, you can change 
>that template to contain >O and O> around the actual invocation, so the 
>variant of mini-oof2 you are using will require a THIS (or O as it is called 
>in mini-oof2, as this is more consistent with the >O O> stuff) for invoking 
>methods of the same object.  The default method invocation doesn't do this, 
>because it is always easier to add things than to take them away.

Now you just need to document it so we can all see the light:-).

The other thing is whether you want to keep it dependent on Gforth
features.

>If you don't like  foo >o bar o>  in mini-oof2, add a dot-parser recognizer 
>which will transform
>
>foo.bar   into   foo >o bar o>
>foo->bar  into   foo @ >o bar o>
>
>with any number of . and -> in the string (just replace all "." with " >o " 
>and all "->" with " @ >o " and count the number of occurances, and then add 
>that number of " o>" to the end - and reevaluate). 

I have been thinking about something like that, too:

Have .BAR take the current object from the TOS, and BAR keep it as it
is (although "." is taken as a prefix in Forth, so we should probably
use something else, maybe ":" or "~"; I'll leave that discussion to
someone else, my names are generally disliked:-).  This could be
implemented in standard Forth by defining two words, or in
sufficiently capable systems with a dot-parser.  So we would have

foo .bar
foo @ .bar

for your examples.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2014: http://www.euroforth.org/ef14/

[toc] | [prev] | [next] | [standalone]


#30709

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2014-05-25 15:16 -0500
Message-ID<fO-dneT_-M4Y0h_OnZ2dnUVZ_u2dnZ2d@supernews.com>
In reply to#30693
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
> This works in objects.fs, too; THIS is global, and is not changed
> when you call a colon definition.  One may discuss whether this is a
> feature, or just an artifact of the implementation; it was not
> intended as a feature, but maybe you can convince me that it is one
> (better, convince Andrew Haley!-).

THIS is thread-local, surely?  A USER variable.

Andrew.

[toc] | [prev] | [next] | [standalone]


#30723

FromBernd Paysan <bernd.paysan@gmx.de>
Date2014-05-26 00:47 +0200
Message-ID<lltrum$vf2$1@online.de>
In reply to#30693
Anton Ertl wrote:

> Bernd Paysan <bernd.paysan@gmx.de> writes:
>>And when you refactor your code, you can concentrate on the essence of
>>refactoring, instead of going through your entire code base.
> 
> Given that, as you write, one should only access an instance variable
> in its class (and maybe descendent classes), you don't need to go
> through the entire code base.

That could be a variable in a base class... used in a lot of places.

> Sure, if I don't control the code base
> that would need to be changed, keeping the interface the same is the
> way to go, but if I do, it may be better to actually change it
> (although keeping the interface the same may be good for the
> intermediate step).  Anyway, you also have both options with
> objects.fs.

Changing an interface in a sufficiently large code base is always a problem, 
even if you control the codebase.

>   E.g. let's say
>>foo was first an instance variable, holding a cell.  After a while, you
>>discover that your object really has two states in which it has two
>>different foos, and you now define
>>
>>: foo ( -- addr ) mystate @ IF  foo1  ELSE  foo2  THEN ;
> 
> This works in objects.fs, too; THIS is global, and is not changed when
> you call a colon definition.  One may discuss whether this is a
> feature, or just an artifact of the implementation; it was not
> intended as a feature, but maybe you can convince me that it is one
> (better, convince Andrew Haley!-).

I think it's just an artefact of the implementation.

>>After a while, you discover furthermore that, well, this distinction is
>>only necessary for 20% of your classes, and the other do well with having
>>just one foo, so you declare foo as a method, and define that with
>>
>>' foo1 my-baseclass to foo
>>
>>or, for those who needs two states
>>
>>:noname ( -- addr ) mystate @ IF  foo1  ELSE  foo2  THEN ; my-sublass to
>>:foo
> 
> In objects.fs I can define
> 
> selector foo-s
> : foo this foo-s ; \ used global this
> 
> \ in my-baseclass
> m: foo1 ;m overrides foo-s \ could be made more efficient
> 
> \ in some classes
> m: ( -- addr ) mystate @ IF  foo1  ELSE  foo2  THEN ;m overrides foo-s

Yes, the global this makes this possible...

>>The invocation never changed, and therefore, you never had to dig through
>>your entire code base for all invokations of foo.
>>
>>This sort of consistency makes maintaining code easy.  The thing you need
>>to maintain consistently is the signature of the word (the way it is
>>invoked), not the way it is implemented.
> 
> As I demonstrated, explicit setting of the current object is not
> needed for this.

You have demonstrated that you can produce a workaround by accidentially 
having a global current object, and that you can therefore create a wrapper 
that supplies the selector with an object on the stack.  In Mini-OOF2, this 
is by design.

>>> Which may be a good idea, it's more consistent with the access to the
>>> instance variables of other objects.
>>
>>Well, you shouldn't access instance variables of other objects...
> 
> That's what I thought when I started working with Java.  now I am no
> longer convinced of that, at least for Java.

I'm not convinced of this rule, either, but at least it should be easier to 
access the own instance variables (that's why having a current object is so 
useful).

> Anyway, back to our discussion: Yes, that was the idea behind the way
> instance variables and methods are handled in objects.fs:
> 
> Only instance variables of the current object should only be accessed,
> so instance variables are only visible in their class, and they always
> are accessed through the current objects.
> 
> In contrast, methods should be callable everywhere, for arbitrary
> objects, so the method selector has a global name, and you pass the
> object on which it dispatches explicitly.
> 
> As demonstrated, you can emulate the instance variable interface with
> colon definitions or methods, so that's no reason to change that.

Mini-OOF2 doesn't handle limited visibility (yet), it will quite likely 
become another thing that you can have when you want it, but not as 
essential feature.

> Now you just need to document it so we can all see the light:-).

Yes.

> The other thing is whether you want to keep it dependent on Gforth
> features.

One of the ideas is that there are a few essential things a system needs to 
provide to implement OOP with good performance, and these things aren't 
portable yet.

>>If you don't like  foo >o bar o>  in mini-oof2, add a dot-parser
>>recognizer which will transform
>>
>>foo.bar   into   foo >o bar o>
>>foo->bar  into   foo @ >o bar o>
>>
>>with any number of . and -> in the string (just replace all "." with " >o
>>" and all "->" with " @ >o " and count the number of occurances, and then
>>add that number of " o>" to the end - and reevaluate).
> 
> I have been thinking about something like that, too:
> 
> Have .BAR take the current object from the TOS, and BAR keep it as it
> is (although "." is taken as a prefix in Forth, so we should probably
> use something else, maybe ":" or "~"; I'll leave that discussion to
> someone else, my names are generally disliked:-).  This could be
> implemented in standard Forth by defining two words, or in
> sufficiently capable systems with a dot-parser.  So we would have
> 
> foo .bar
> foo @ .bar
> 
> for your examples.

Yes, that would work, too, making the parser even easier (does it start with 
a dot?  Is the rest found in the dictionary - use word-recognizer for that)?  
Interpret and compile it wrapped in >o o>.

. is indeed "taken", so there can be conflicts.  The original suggestion 
makes the dot parser way more complicated, but then, foo.bar doesn't 
conflict.

-- 
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

[toc] | [prev] | [next] | [standalone]


#30725

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2014-05-25 18:55 -0500
Message-ID<M92dnR6-YNt9Hx_OnZ2dnUVZ_rqdnZ2d@supernews.com>
In reply to#30644
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
> 
> Once we have a current object, the question is whether to set it
> implicitly on method call (as happens in most OO languages and most
> Forth OO packages), or whether to set it explicitly.

I don't think that Java and C++ really have a current object: "this"
is really just the name given to the first argument that was passed to
a (virtual or non-static) method.  There is the syntactic convenience
that "this" is implicit at the point of call when no receiver is
specified, but "this" is entirely transient: it exists only for the
duration of a method and is only visible in the scope of that method.

Andrew.

[toc] | [prev] | [next] | [standalone]


#30749

Fromalbert@spenarnc.xs4all.nl (Albert van der Horst)
Date2014-05-26 11:44 +0000
Message-ID<5383293b$0$4943$e4fe514c@dreader35.news.xs4all.nl>
In reply to#30725
In article <M92dnR6-YNt9Hx_OnZ2dnUVZ_rqdnZ2d@supernews.com>,
Andrew Haley  <andrew29@littlepinkcloud.invalid> wrote:
>Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
>>
>> Once we have a current object, the question is whether to set it
>> implicitly on method call (as happens in most OO languages and most
>> Forth OO packages), or whether to set it explicitly.
>
>I don't think that Java and C++ really have a current object: "this"
>is really just the name given to the first argument that was passed to
>a (virtual or non-static) method.  There is the syntactic convenience
>that "this" is implicit at the point of call when no receiver is
>specified, but "this" is entirely transient: it exists only for the
>duration of a method and is only visible in the scope of that method.

My take of a current object is apparently totally different.
There is one current object for each class, so a method belonging
to a class automatically uses that object, without any special care.
The current object is changed by executing it.

class APE .. endclass

APE ian     APE jane
ian   \ Ian is on
eat   \ Ian eats
jane \ Jane is on.
eat   \ Jane eats

Moreover an object has no fields. It has data, and getter and setter
methods that are just ordinary methods.
Possibly it has a getter for a pointer to a field, which
amounts to the dreaded global visibility (as if getters and setters
are any different.).

Anton Ertl wants invisibility for some things. Well Forth knows
namespaces, they are called wordlists. This is an orthogonal
concept and can be retrofitted. (In the following CURRENT and
CONTEXT are kept the same throughout).

PREVIOUS  ( order :  FORTH )
NAMESPACE %ape%    %ape% DEFINITIONS ( order :  %ape% FORTH )

class APE .. endclass

FORTH DEFINITIONS  ( order : FORTH %ape% FORTH )
\ There are the only words exported from %ape% into the forth wordlist
'APE ALIAS APE
'eat ALIAS eat

\ There is no need for eat2 to be in %ape%
: eat2    eat eat ... accessing private parts of APE .... ;

PREVIOUS  ( order :  %ape% FORTH )
PREVIOUS  ( order :  FORTH )
\ visible here are : APE eat eat2

Groetjes Albert


>
>Andrew.

Groetjes Albert
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

[toc] | [prev] | [next] | [standalone]


#30826

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2014-05-27 05:25 -0500
Message-ID<y8Wdnfz9Hta29RnOnZ2dnUVZ_uGdnZ2d@supernews.com>
In reply to#30749
Albert van der Horst <albert@spenarnc.xs4all.nl> wrote:
> In article <M92dnR6-YNt9Hx_OnZ2dnUVZ_rqdnZ2d@supernews.com>,
> Andrew Haley  <andrew29@littlepinkcloud.invalid> wrote:
>>Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
>>>
>>> Once we have a current object, the question is whether to set it
>>> implicitly on method call (as happens in most OO languages and most
>>> Forth OO packages), or whether to set it explicitly.
>>
>>I don't think that Java and C++ really have a current object: "this"
>>is really just the name given to the first argument that was passed to
>>a (virtual or non-static) method.  There is the syntactic convenience
>>that "this" is implicit at the point of call when no receiver is
>>specified, but "this" is entirely transient: it exists only for the
>>duration of a method and is only visible in the scope of that method.
> 
> My take of a current object is apparently totally different.
> There is one current object for each class, so a method belonging
> to a class automatically uses that object, without any special care.
> The current object is changed by executing it.
> 
> class APE .. endclass
> 
> APE ian     APE jane
> ian   \ Ian is on
> eat   \ Ian eats
> jane \ Jane is on.
> eat   \ Jane eats

I don't really understand this.  Let's say that you have a word FORMAT
which does some formatting, and internally it uses OOP.  And, you have
a word PRINT to print an object.  Then

(objects called layout and ian)

: formatted-print ( obj)   layout format  print;
ian formatted-print

wouldn't work, would it?

Andrew.

[toc] | [prev] | [next] | [standalone]


#30836

Fromalbert@spenarnc.xs4all.nl (Albert van der Horst)
Date2014-05-27 11:56 +0000
Message-ID<53847d84$0$4720$e4fe514c@dreader36.news.xs4all.nl>
In reply to#30826
In article <y8Wdnfz9Hta29RnOnZ2dnUVZ_uGdnZ2d@supernews.com>,
Andrew Haley  <andrew29@littlepinkcloud.invalid> wrote:
>Albert van der Horst <albert@spenarnc.xs4all.nl> wrote:
>> In article <M92dnR6-YNt9Hx_OnZ2dnUVZ_rqdnZ2d@supernews.com>,
>> Andrew Haley  <andrew29@littlepinkcloud.invalid> wrote:
>>>Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
>>>>
>>>> Once we have a current object, the question is whether to set it
>>>> implicitly on method call (as happens in most OO languages and most
>>>> Forth OO packages), or whether to set it explicitly.
>>>
>>>I don't think that Java and C++ really have a current object: "this"
>>>is really just the name given to the first argument that was passed to
>>>a (virtual or non-static) method.  There is the syntactic convenience
>>>that "this" is implicit at the point of call when no receiver is
>>>specified, but "this" is entirely transient: it exists only for the
>>>duration of a method and is only visible in the scope of that method.
>>
>> My take of a current object is apparently totally different.
>> There is one current object for each class, so a method belonging
>> to a class automatically uses that object, without any special care.
>> The current object is changed by executing it.
>>
>> class APE .. endclass
>>
>> APE ian     APE jane
>> ian   \ Ian is on
>> eat   \ Ian eats
>> jane \ Jane is on.
>> eat   \ Jane eats
>
>I don't really understand this.  Let's say that you have a word FORMAT
>which does some formatting, and internally it uses OOP.  And, you have
>a word PRINT to print an object.  Then
>
>(objects called layout and ian)
>
>: formatted-print ( obj)   layout format  print;
>ian formatted-print
>
>wouldn't work, would it?

Apparently you missed something, or I wasn't clear.
There is a current object for each class.
If I have a `` print '' that prints the current object of class
PAIR, it does so regardless of who else is using OOP.

A small test example :

-------------------------
WANT class
WANT SEE

0 0 class PAIR
M: two @ M;  ,
M: one @ M;  ,
endclass

: print   one . two . ;

4 5 PAIR  jan
1 2 PAIR  piet

WORDS
." Expect 4 5 :"  jan print CR

SEE PAIR
SEE BUILD-PAIR
SEE one
-------------------------

<other output of WORDS snipped>
... SEE ^PAIR two one BUILD-PAIR PAIR print jan piet

Expect 4 5 :4 5

: PAIR CREATE BUILD-PAIR ^PAIR ! DOES> ^PAIR ! ;
: BUILD-PAIR HERE >R , , R> ;
: one ^PAIR @ 8 + @ ;

-------------------------

>
>Andrew.
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

[toc] | [prev] | [next] | [standalone]


#30770

FromJulian Fondren <ayrnieu@gmail.com>
Date2014-05-26 12:18 -0700
Message-ID<a5ebce86-6efb-421e-b885-33f99888975f@googlegroups.com>
In reply to#30725
On Sunday, May 25, 2014 6:55:12 PM UTC-5, Andrew Haley wrote:
> I don't think that Java and C++ really have a current object: "this"
> is really just the name given to the first argument that was passed to
> a (virtual or non-static) method.

You've said this a few times, but always tentatively like this, or with
reference to a language where the passed object is explicitly an argument of
the method, like Python [or Perl or CL].  

If you have a current object, then you can write a non-method that grabs the
current object out of the air:

: .cons ( -- ) 
  ." (" car @ .  cdr @ 0 .r ." ) " ;

: debug ( -- ) 
  cr ." DEBUG: <other debugging information>.  Current class: " o .class ;

And invoke it in the middle of a method or an >o .... o> sequence without
taking any effort to pass anything to it.

If you don't have a current object, then you can't do that.  There's nothing to
grab.  So Java and C++, and certainly the explicit-passing languages, don't
have this feature at all.  objects.fs has it by accident -- if TO-THIS isn't to
be used, then isn't it just an implementation choice to have a VALUE instead of
having methods secretly s" { this }" EVALUATE when defined?

Incidentally, there's no .CLASS in mini-oof2, but when I thought of that as an
example I found that it was easy to graft on:

require mini-oof2.fs

variable classes  \ list of (cdr, class, name)
  align here classes !  0 , object , ' object >name ,

: end-class ( class methods vars "name" -- )  end-class
  align here classes @ , classes !
  lastxt execute ,  lastxt >name , ;

: .classes ( -- )
  classes @ begin dup while
    dup cell+ cell+ @ cr .name
  @ repeat drop ;

: .class ( o -- )
  cell- @ classes @ begin dup while
    2dup cell+ @ = if nip cell+ cell+ @ .name exit then
  @ repeat 2drop ." <unknown> " ;


-- Julian

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.forth


csiph-web