Anton Ertl's objects.fs's experiment 
Author Message
 Anton Ertl's objects.fs's experiment

Of all the available Forth OO models I've found on the net
so far, I'm beginning to favor Anton Ertl's objects.fs.

Here's a plain vanillia (non optimized, but the purpose was
more to experiment with Anton's syntax/semantics than to get
production quality code) Fifo class.

The only two comments I have up to now on this OO model is that

1)  it doesn't seem possible to invoke a method before it is defined
    -- see my other `FORWARD' thread --, practice wich is very common
    in all (non Forth) OO languages I'm used to.

2)  It seems to me that ;M is *always* followed by either METHOD
    or OVERRIDE. If this is indeed the case, it could be worthwhile
    to define (say) ;METHOD and ;OVERRIDE that would do both at once ?

For the following class to compile, you need, in addition to Anton's
struct.fs and object.fs the following definitions:





OBJECT CLASS

 1 CONSTANT  OVERRUN
 2 CONSTANT  UNDERRUN

 cell% INST-VAR mPutIndex
 cell% INST-VAR mGetIndex
 cell% INST-VAR mSizeMax
 cell% INST-VAR mCurrentSize
 cell% INST-VAR mBuffer
 cell% INST-VAR mFlags             \ only bits 0-1 are currently used

 M: ( -- )  0 mPutIndex !
            0 mGetIndex !
            0 mCurrentSize !
            0 mFlags !                            ;M METHOD clear

 M: ( buffer size -- )
           THIS clear mSizeMax ! mBuffer !        ;M OVERRIDES construct

 \ Adjusts mGetIndex so that the whole fifo becomes available for get.
 \ Used when an overrun occurs to discard all but the last received
 \ bytes (instead of the easier but naive strategy of keeping the oldest)



            THEN                                  ;M METHOD _pinGet


 M: ( b -- )    mFlags OR!                        ;M METHOD _flag!
 M: ( b -- )    INVERT mFlags AND!                ;M METHOD _flag0!

 M: ( -- )      OVERRUN THIS _flag!  
                THIS _pinGet                      ;M METHOD _overrun!
 M: ( -- )      OVERRUN THIS _flag0!              ;M METHOD _overrun0!
 M: ( -- )      UNDERRUN THIS _flag!              ;M METHOD _underrun!
 M: ( -- )      UNDERRUN THIS _flag0!             ;M METHOD _underrun0!

 M: ( -- f )    OVERRUN THIS _flag?               ;M METHOD overrun?
 M: ( -- f )    UNDERRUN THIS _flag?              ;M METHOD underrun?




                1 CHARS mCurrentSize +!
                1 CHARS mPutIndex +!

                    0 mPutIndex !
                THEN                              ;M METHOD _put

 M: ( c -- )    THIS full? IF
                    DROP
                    THIS _overrun!
                ELSE
                    THIS _overrun0!
                    THIS _put
                THEN                              ;M METHOD put

 M: ( -- c )    THIS empty? IF
                    THIS _underrun!
                    -1
                ELSE
                    THIS _underrun0!

                    -1 CHARS mCurrentSize +!
                    1 CHARS  mGetIndex +!

                        0 mGetIndex !
                    THEN
               THEN                               ;M METHOD get
END-CLASS Fifo

DECIMAL
CREATE buffer 256 CHARS ALLOT

buffer 16 Fifo heap-new CONSTANT myFifo

: test-fifo
    myFifo clear
    12 0 DO I myFifo put LOOP

    BEGIN myFifo empty? 0= WHILE
        myFifo get .
    REPEAT
;

: test2-fifo ( n -- )
     myFifo clear

     0 DO I myFifo put LOOP

     BEGIN myFifo empty? 0= WHILE
         myFifo get .
     REPEAT
;

--





Mon, 05 Mar 2001 03:00:00 GMT  
 Anton Ertl's objects.fs's experiment
I know I'm biased, but I don't see how this syntax;


is more Forth like, than Win32Forth's syntax shown here;


Just my thoughts,

Tom Zimmer

Quote:

> Of all the available Forth OO models I've found on the net
> so far, I'm beginning to favor Anton Ertl's objects.fs.

> Here's a plain vanillia (non optimized, but the purpose was
> more to experiment with Anton's syntax/semantics than to get
> production quality code) Fifo class.

> The only two comments I have up to now on this OO model is that

> 1)  it doesn't seem possible to invoke a method before it is defined
>     -- see my other `FORWARD' thread --, practice wich is very common
>     in all (non Forth) OO languages I'm used to.

> 2)  It seems to me that ;M is *always* followed by either METHOD
>     or OVERRIDE. If this is indeed the case, it could be worthwhile
>     to define (say) ;METHOD and ;OVERRIDE that would do both at once ?

> For the following class to compile, you need, in addition to Anton's
> struct.fs and object.fs the following definitions:





> OBJECT CLASS

>  1 CONSTANT  OVERRUN
>  2 CONSTANT  UNDERRUN

>  cell% INST-VAR mPutIndex
>  cell% INST-VAR mGetIndex
>  cell% INST-VAR mSizeMax
>  cell% INST-VAR mCurrentSize
>  cell% INST-VAR mBuffer
>  cell% INST-VAR mFlags             \ only bits 0-1 are currently used

>  M: ( -- )  0 mPutIndex !
>             0 mGetIndex !
>             0 mCurrentSize !
>             0 mFlags !                            ;M METHOD clear

>  M: ( buffer size -- )
>            THIS clear mSizeMax ! mBuffer !        ;M OVERRIDES
> construct

>  \ Adjusts mGetIndex so that the whole fifo becomes available for get.

>  \ Used when an overrun occurs to discard all but the last received
>  \ bytes (instead of the easier but naive strategy of keeping the
> oldest)



>             THEN                                  ;M METHOD _pinGet


>  M: ( b -- )    mFlags OR!                        ;M METHOD _flag!
>  M: ( b -- )    INVERT mFlags AND!                ;M METHOD _flag0!

>  M: ( -- )      OVERRUN THIS _flag!
>                 THIS _pinGet                      ;M METHOD _overrun!
>  M: ( -- )      OVERRUN THIS _flag0!              ;M METHOD _overrun0!

>  M: ( -- )      UNDERRUN THIS _flag!              ;M METHOD _underrun!

>  M: ( -- )      UNDERRUN THIS _flag0!             ;M METHOD
> _underrun0!

>  M: ( -- f )    OVERRUN THIS _flag?               ;M METHOD overrun?
>  M: ( -- f )    UNDERRUN THIS _flag?              ;M METHOD underrun?




>                 1 CHARS mCurrentSize +!
>                 1 CHARS mPutIndex +!

>                     0 mPutIndex !
>                 THEN                              ;M METHOD _put

>  M: ( c -- )    THIS full? IF
>                     DROP
>                     THIS _overrun!
>                 ELSE
>                     THIS _overrun0!
>                     THIS _put
>                 THEN                              ;M METHOD put

>  M: ( -- c )    THIS empty? IF
>                     THIS _underrun!
>                     -1
>                 ELSE
>                     THIS _underrun0!

>                     -1 CHARS mCurrentSize +!
>                     1 CHARS  mGetIndex +!

>                         0 mGetIndex !
>                     THEN
>                THEN                               ;M METHOD get
> END-CLASS Fifo

> DECIMAL
> CREATE buffer 256 CHARS ALLOT

> buffer 16 Fifo heap-new CONSTANT myFifo

> : test-fifo
>     myFifo clear
>     12 0 DO I myFifo put LOOP

>     BEGIN myFifo empty? 0= WHILE
>         myFifo get .
>     REPEAT
> ;

> : test2-fifo ( n -- )
>      myFifo clear

>      0 DO I myFifo put LOOP

>      BEGIN myFifo empty? 0= WHILE
>          myFifo get .
>      REPEAT
> ;

> --






Tue, 06 Mar 2001 03:00:00 GMT  
 Anton Ertl's objects.fs's experiment


Quote:
>I know I'm biased, but I don't see how this syntax;


>is more Forth like, than Win32Forth's syntax shown here;



I'm not sure that I claimed that Anton's OO model was ``More
Forth Like'' than any other model I rejected. This was
not the point anyway.

What I wanted to achieve is to get some feedback from other
Anton's OO model (we should find a name for this!!) users.

Yes, one of its deficienciies that I pointed out seems to be a non
issue in your implementation, and I'd love to see Anton make
a comparable fix for his model. (which might no be trivial)

The main reasons why I favor this model over all the others
I've seen is that:

- it supports interfaces (though, not shown in my examples)
  which I find the best invention since sliced bred ;-)
- it has a reasonably (vtbl based) fast late binding dispatch
- its syntax is not too obscure

Your priorities might be different, but for my way of attacking
problems, the Neon/Mops/OOF/Win32Forth way of (not) doing it
just doesn't cut it.

Quote:
>Just my thoughts,

>Tom Zimmer


>> Of all the available Forth OO models I've found on the net
>> so far, I'm beginning to favor Anton Ertl's objects.fs.

>> Here's a plain vanillia (non optimized, but the purpose was
>> more to experiment with Anton's syntax/semantics than to get
>> production quality code) Fifo class.

--





Wed, 07 Mar 2001 03:00:00 GMT  
 Anton Ertl's objects.fs's experiment

Quote:



> >I know I'm biased, but I don't see how this syntax;


> >is more Forth like, than Win32Forth's syntax shown here;


> I'm not sure that I claimed that Anton's OO model was ``More
> Forth Like'' than any other model I rejected. This was
> not the point anyway.

> What I wanted to achieve is to get some feedback from other
> Anton's OO model (we should find a name for this!!) users.

Is the source in the public domain. If so could you please give me a
URL.

Quote:

> Yes, one of its deficienciies that I pointed out seems to be a non
> issue in your implementation, and I'd love to see Anton make
> a comparable fix for his model. (which might no be trivial)

> The main reasons why I favor this model over all the others
> I've seen is that:

> - it supports interfaces (though, not shown in my examples)
>   which I find the best invention since sliced bred ;-)
> - it has a reasonably (vtbl based) fast late binding dispatch

It is a problem with Neon, the late binding requires a linked list
search but it is a problem that can be overcome with a bit of work (
work I have done, but if there is something better I am willing to
abandon).

- Show quoted text -

Quote:
> - its syntax is not too obscure

> Your priorities might be different, but for my way of attacking
> problems, the Neon/Mops/OOF/Win32Forth way of (not) doing it
> just doesn't cut it.

> >Just my thoughts,

> >Tom Zimmer


> >> Of all the available Forth OO models I've found on the net
> >> so far, I'm beginning to favor Anton Ertl's objects.fs.

> >> Here's a plain vanillia (non optimized, but the purpose was
> >> more to experiment with Anton's syntax/semantics than to get
> >> production quality code) Fifo class.

> --






Thu, 08 Mar 2001 03:00:00 GMT  
 Anton Ertl's objects.fs's experiment


Quote:
> Of all the available Forth OO models I've found on the net
> so far, I'm beginning to favor Anton Ertl's objects.fs.

The URL is http://www.complang.tuwien.ac.at/forth/objects.zip

The name I use for it is just "objects.fs".

Quote:
> Here's a plain vanillia (non optimized, but the purpose was
> more to experiment with Anton's syntax/semantics than to get
> production quality code) Fifo class.

May I use this as additional example in the package?

Quote:
> 1)  it doesn't seem possible to invoke a method before it is defined
>     -- see my other `FORWARD' thread --, practice wich is very common
>     in all (non Forth) OO languages I'm used to.

Well, actually, you can define a selector, then use it before defining
the methods for this selector. Currently you can only do the methods
for a class in one class definition block, but this is going to change
in the next version.

Quote:
> 2)  It seems to me that ;M is *always* followed by either METHOD
>     or OVERRIDE. If this is indeed the case, it could be worthwhile
>     to define (say) ;METHOD and ;OVERRIDE that would do both at once ?

No problem. Just define

: ;OVERRIDES
  POSTPONE ;m overrides ; immediate

Concerning METHOD: I now prefer defining just the selector and
overriding it later, instead of doing both at once with METHOD. This
leads to more readable class definitions: you get all the interface in
one point, without intermixing the implementation (which may be
overridden in subclasses).

- anton
--
M. Anton Ertl                    Some things have to be seen to be believed

http://www.complang.tuwien.ac.at/anton/home.html



Fri, 09 Mar 2001 03:00:00 GMT  
 Anton Ertl's objects.fs's experiment


Quote:

> > What I wanted to achieve is to get some feedback from other
> > Anton's OO model (we should find a name for this!!) users.

I call it objects.fs.

Quote:
> Is the source in the public domain.

Yes.

Quote:
> If so could you please give me a
> URL.

http://www.complang.tuwien.ac.at/forth/objects.zip

- anton
--
M. Anton Ertl                    Some things have to be seen to be believed

http://www.complang.tuwien.ac.at/anton/home.html



Fri, 09 Mar 2001 03:00:00 GMT  
 Anton Ertl's objects.fs's experiment

Quote:

>Is the source in the public domain. If so could you please give me a
>URL.

You'll find everything you'll need at:

<http://www.complang.tuwien.ac.at/forth/objects/objects.html>

I'm using it with PowerMacForth, but it seems it works equally
well using most ANS compliant Forth, including GForth.

--





Fri, 09 Mar 2001 03:00:00 GMT  
 Anton Ertl's objects.fs's experiment
I come to this from a strange angle. I believe object's would be a great
way to deal with drivers in an OS.
For that to work you need fast real time selector resolution. The idea
is to store the objects address where you need to store port numbers
etc. and you automatically get vectored low level types expects reads
write whatever.

I have done the required work on the Neon model so I can comment in same
detail ( I am however doing it from memory as the original version is
now history). The version I attacked was from WIMP FORTH which I believe
was based on Tom Zimmer's work which I believe was based on Neon.

These are the problems I believe neon had and how I overcame them.

1) The method had two code field addresses, one to deal with an object
coming via. the stack, one to deal with an object compiled into the
dictionary.

I changed the dictionary compile words to compile code that put the
object address on the stack, and only had one method code field, the one
that dealt with objects on the stack.

2) The compiler went into special hoopty doos when a word started/ended
in a : ( I have forgotten which). I see from Tom's example above that
this is not the case with his version. I changed this so that methods
dealt with there own problems, the compiler was not involved. It meant
methods were IMMEDIATE words and STATE smart. But it also meant that
methods were standard forth words.

3) Run time selector resolution was really bad, making the original
version unsuitable for it's intended use. I changed the selected to be
an offset in a table, and created a jump table. The jump table was in
initiated at the beginning of the class definition in heap memory, and
copied to dictionary at the end of the class definition. Selectors keep
the same offset from parent to child.

4) I got rid of the [[ ]] syntax. and replaced it with a single word
[stack] . What purpose does it serve not to use the standard compiler to
compile the stack value calculation code.

If you do all this and VALUE can become a class, and TO and +to methods
within that class. This result in a VALUE that is of some use.  TO and
+to can be overridden and whatever tests you desire done.

Remember my original aim, drivers that are simple objects. Well VALUE
can be extended to only accept drivers of a particular class, I called
this class object> , and TO and +to can be modified to abort if you
attempt to install the wrong driver.

The neon model as I now have it doesn't support multiple inheritance,
nor interfaces. But after seeing Antons work I can see how interfaces
could be added.

But I still can't see why you would want to do it, perhaps I haven't
played with objects enough, but they seem like a great way to make a
program unreadable.

Antons work.

I really like the structure stuff, I see only one small issue, when your
tracing down a linked list the link is often within the structure and is
not the base address. To resolve this problem you need to start playing
with the words to determine the offset

\ addr<--
0  field_name  -
\ or using my prefered method
[ 0 new_field_name 0 old_field_name - ] LITERAL +

Really is a minor issue.

I see two problems with the object  model, and I still don't understand
the code in it all it's detail so I could be wrong and welcome
condemnation of my stupidity.

1) The jump tables are built on the heap and left there. This is ok if
you are only going to compile the code and run. Those of us that use
forth  for real time need a model that can generate a runnable binary
image. I think this could be difficult, but I haven't really got my mind
around it so I could be wrong. I definitely need to rewrite it for it to
be of any use to me.

2) The model does not allow objects as instance variables.  don't think
the model supports  calling methods from within methods ( the "this"
value is not saved, when stored).

It that's the case I am sure it could be fixed.

The real difference as I see it, is how the models deal with
transferring the object to the method..

The neon model puts the object after the method, the method looks at how
the object is being presented, compiles appropriate code to get the
object on the stack code to execute the selected method and continues.
If the object is supplied by name, the object is fixed and the neon
model can bind at compile time. If the object comes via a variable,
object> or the [stack]  runtime binding has to occur.  I tend to agree
with Anton it you use jump tables why have immediate and state smart
words so you can bind some cases at compile time. Separating the
compiling of the code to get the object on the stack and the compiling
of the selector would greatly simplify the neon model.

Having said that changing the model removes my neat solution to the
VALUE and TO problem.

I think I will go away and think about it.

Quote:



> >Is the source in the public domain. If so could you please give me a
> >URL.

> You'll find everything you'll need at:

> <http://www.complang.tuwien.ac.at/forth/objects/objects.html>

> I'm using it with PowerMacForth, but it seems it works equally
> well using most ANS compliant Forth, including GForth.

> --






Sun, 11 Mar 2001 03:00:00 GMT  
 Anton Ertl's objects.fs's experiment


Quote:
> I really like the structure stuff, I see only one small issue, when your
> tracing down a linked list the link is often within the structure and is
> not the base address. To resolve this problem you need to start playing
> with the words to determine the offset

> \ addr<--
> 0  field_name  -
> \ or using my prefered method
> [ 0 new_field_name 0 old_field_name - ] LITERAL +

Hmm, if I get you right, you want to inherit from some other class
than (a descendent of) the linked list, but want to use the words
defined for the linked list class. This would require full multiple
inheritance, which is not supported in objects.fs (only interfaces are
supported). The technique you describe is similar to the technique
used for implementing multiple inheritance in C++.

It may be better to program it in a different way anyway; e.g., have
external linked lists that point to the objects (this is more
garbage-collection-friendly, too).

Quote:
> 1) The jump tables are built on the heap and left there. This is ok if
> you are only going to compile the code and run. Those of us that use
> forth  for real time need a model that can generate a runnable binary
> image. I think this could be difficult, but I haven't really got my mind
> around it so I could be wrong. I definitely need to rewrite it for it to
> be of any use to me.

I have already thought about this. It should be pretty easy to move
the method table into ALLOTed space at the end of the class.  I did
not implement it in the current version, because that was intended to
be simple, for the sake of publication. I may do this in the next
version.

Quote:
> 2) The model does not allow objects as instance variables.

The normal (and easy) way is to keep the addresses of other objects in
instance variables; this is more flexible, because you can point to
larger (child) objects, but takes more memory.

But it is also possible that the instance variable contains the object
directly:

\ assume we have a class bar

object class

m: ( foo -- )
  bar fnord init-object ;m
overrides construct

end-class foo

Quote:
>  don't think
> the model supports  calling methods from within methods ( the "this"
> value is not saved, when stored).

You can call methods within methods (it would be pretty pointless,
otherwise). And yes, THIS is saved and restored when entering and
exiting m:...;m methods:

: m: ( -- xt colon-sys; run-time: object -- ) \ objects

    :noname
    POSTPONE this
    POSTPONE >r
    POSTPONE to-this ;

This saves THIS on the return stack.

- anton
--
M. Anton Ertl                    Some things have to be seen to be believed

http://www.complang.tuwien.ac.at/anton/home.html



Sun, 11 Mar 2001 03:00:00 GMT  
 Anton Ertl's objects.fs's experiment

Quote:



> > I really like the structure stuff, I see only one small issue, when
> your
> > tracing down a linked list the link is often within the structure
> and is
> > not the base address. To resolve this problem you need to start
> playing
> > with the words to determine the offset

> > \ addr<--
> > 0  field_name  -
> > \ or using my prefered method
> > [ 0 new_field_name 0 old_field_name - ] LITERAL +

> Hmm, if I get you right, you want to inherit from some other class
> than (a descendent of) the linked list, but want to use the words
> defined for the linked list class. This would require full multiple
> inheritance, which is not supported in objects.fs (only interfaces are

> supported). The technique you describe is similar to the technique
> used for implementing multiple inheritance in C++.

No, nothing as interesting as that,  I was just thinking about your
structures and the possibility ofreplacing what I do.
i.e.
zero
DUP CONSTANT _#offset1 CELL+
DUP CONSTANT _#offset2 CELL+
DROP

Becomes:

struct
    cell% field _offset1+
    cell% field _offset2+
end_struct selector%

- Show quoted text -

Quote:

> It may be better to program it in a different way anyway; e.g., have
> external linked lists that point to the objects (this is more
> garbage-collection-friendly, too).

> > 1) The jump tables are built on the heap and left there. This is ok
> if
> > you are only going to compile the code and run. Those of us that use

> > forth  for real time need a model that can generate a runnable
> binary
> > image. I think this could be difficult, but I haven't really got my
> mind
> > around it so I could be wrong. I definitely need to rewrite it for
> it to
> > be of any use to me.

> I have already thought about this. It should be pretty easy to move
> the method table into ALLOTed space at the end of the class.  I did
> not implement it in the current version, because that was intended to
> be simple, for the sake of publication. I may do this in the next
> version.

Thats good, it gives me the confidence to continue my attempts to
understand it. It took me well over a week to work what was going on
with neon. Yours looks a lot simpler, and I like simple solutions.

Quote:

> > 2) The model does not allow objects as instance variables.

> The normal (and easy) way is to keep the addresses of other objects in

> instance variables; this is more flexible, because you can point to
> larger (child) objects, but takes more memory.

> But it is also possible that the instance variable contains the object

> directly:

What about the initialization of the object, neon has a linked list of
instance objects and recursively constructs and initializes. Going your
way I would have to create the objects in the contractor, and save the
pointers, when you think about it it isn't such a bad idea.

- Show quoted text -

Quote:

> \ assume we have a class bar

> object class

> m: ( foo -- )
>   bar fnord init-object ;m
> overrides construct

> end-class foo

> >  don't think
> > the model supports  calling methods from within methods ( the "this"

> > value is not saved, when stored).

> You can call methods within methods (it would be pretty pointless,
> otherwise). And yes, THIS is saved and restored when entering and
> exiting m:...;m methods:

> : m: ( -- xt colon-sys; run-time: object -- ) \ objects


>     :noname
>     POSTPONE this
>     POSTPONE >r
>     POSTPONE to-this ;

Yes I see it now. My own stupidity.

- Show quoted text -

Quote:

> This saves THIS on the return stack.

> - anton
> --
> M. Anton Ertl                    Some things have to be seen to be
> believed

> seen
> http://www.complang.tuwien.ac.at/anton/home.html



Mon, 12 Mar 2001 03:00:00 GMT  
 Anton Ertl's objects.fs's experiment


Quote:

> > > 2) The model does not allow objects as instance variables.

> > The normal (and easy) way is to keep the addresses of other objects in

> > instance variables; this is more flexible, because you can point to
> > larger (child) objects, but takes more memory.

> > But it is also possible that the instance variable contains the object

> > directly:

> What about the initialization of the object, neon has a linked list of
> instance objects and recursively constructs and initializes. Going your
> way I would have to create the objects in the contractor, and save the
> pointers, [...]

Yes. And for directly embedded objects you have to initialize as shown
below (in he method for CONSTRUCT):

- anton
--
M. Anton Ertl                    Some things have to be seen to be believed

http://www.complang.tuwien.ac.at/anton/home.html



Mon, 12 Mar 2001 03:00:00 GMT  
 
 [ 11 post ] 

 Relevant Pages 

1. Anton Ertl's Gray

2. I can't reach Anton.

3. LOGO-L> Enhanced Ehrenfest's Experiment

4. LOGO-L> Ehrenfest's Experiment - MSWLogo

5. FS/A: Cool rare SMALLTALK stuff, don't miss out, NeXT and BeOS stuff too

6. feild seperators (FS) and atoms: attn GURU's

7. Multiple FS don't work

8. Reparsing an already parsed line onced you've changed the FS

9. Kyocera FS-1750 doesn't print right

10. FS: Used Clipper S'87, 5.01, 5.2 and 5.3

11. Accessing 'non-file' WPS objects

12. linking camera's movement to object's

 

 
Powered by phpBB® Forum Software