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


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

EuroForth 2012 proceedings

Started byanton@mips.complang.tuwien.ac.at (Anton Ertl)
First post2012-10-15 16:40 +0000
Last post2012-10-16 17:25 -0400
Articles 18 — 4 participants

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


Contents

  EuroForth 2012 proceedings anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2012-10-15 16:40 +0000
    Re: EuroForth 2012 proceedings Mark Wills <forthfreak@gmail.com> - 2012-10-16 01:38 -0700
    Re: EuroForth 2012 proceedings Doug Hoffman <glidedog@gmail.com> - 2012-10-16 07:47 -0400
      Re: EuroForth 2012 proceedings anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2012-10-16 16:20 +0000
        Re: EuroForth 2012 proceedings Bernd Paysan <bernd.paysan@gmx.de> - 2012-10-16 20:13 +0200
          Re: EuroForth 2012 proceedings Doug Hoffman <glidedog@gmail.com> - 2012-10-16 17:22 -0400
            Re: EuroForth 2012 proceedings Bernd Paysan <bernd.paysan@gmx.de> - 2012-10-17 01:29 +0200
              Re: EuroForth 2012 proceedings Bernd Paysan <bernd.paysan@gmx.de> - 2012-10-17 01:49 +0200
                Re: EuroForth 2012 proceedings Doug Hoffman <glidedog@gmail.com> - 2012-10-17 06:29 -0400
                Re: EuroForth 2012 proceedings Doug Hoffman <glidedog@gmail.com> - 2012-10-19 10:16 -0400
              Re: EuroForth 2012 proceedings anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2012-10-17 14:15 +0000
                Re: EuroForth 2012 proceedings Bernd Paysan <bernd.paysan@gmx.de> - 2012-10-17 17:14 +0200
                Re: EuroForth 2012 proceedings Doug Hoffman <glidedog@gmail.com> - 2012-10-19 09:57 -0400
                  Re: EuroForth 2012 proceedings Doug Hoffman <glidedog@gmail.com> - 2012-10-24 08:50 -0400
          Re: EuroForth 2012 proceedings anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2012-10-17 13:29 +0000
            Re: EuroForth 2012 proceedings Bernd Paysan <bernd.paysan@gmx.de> - 2012-10-17 17:31 +0200
        Re: EuroForth 2012 proceedings Doug Hoffman <glidedog@gmail.com> - 2012-10-16 17:20 -0400
          Re: EuroForth 2012 proceedings Doug Hoffman <glidedog@gmail.com> - 2012-10-16 17:25 -0400

#16299 — EuroForth 2012 proceedings

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2012-10-15 16:40 +0000
SubjectEuroForth 2012 proceedings
Message-ID<2012Oct15.184019@mips.complang.tuwien.ac.at>
The EuroForth 2012 proceedings and the individual papers and/or
presentation slides are now available on

http://www.complang.tuwien.ac.at/anton/euroforth/ef12/papers/

and BibTeX entries for these papers and slides are also available
<http://www.complang.tuwien.ac.at/anton/euroforth/ef12/papers/euroforth2012.bib>.

The papers page is also linked from the EuroForth 2012 page
<http://www.complang.tuwien.ac.at/anton/euroforth/ef12/>, which is
linked from the EuroForth page <http://www.euroforth.org/> (or
<http://www.complang.tuwien.ac.at/anton/euroforth/>).

The authors and titles of the papers are:

Refereed Papers

    * Andrew Read: The N.I.G.E. Machine: an FPGA based micro-computer
      system for prototyping experimental scientic hardware

Non-Refereed Papers

    * Dirk Bruehl: Forth for Education -- 4E4th and 4E4th IDE
    * Stephen Pelc: Notation Matters
    * Bill Stoddart, Campbell Ritchie, Steve Dunne: Forth Semantics
      for Compiler Verification
    * Willi Stricker: Connection of a Forth Target with a Forth Host
    * Ian van Breda: Building an LR parser using Forth
    * Ian van Breda: Some comments on the proposed Forth Standard
    * M. Anton Ertl: Methods in objects2: Duck Typing and Performance 

Presentation Slides

    * Bernd Paysan: net2o: Transport Layer -- Implemented
    * Bernd Paysan: Recognizers

- 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 2012: http://www.euroforth.org/ef12/

[toc] | [next] | [standalone]


#16335

FromMark Wills <forthfreak@gmail.com>
Date2012-10-16 01:38 -0700
Message-ID<abb8cf7d-c618-4ebb-a901-ff72128f2217@c17g2000yqe.googlegroups.com>
In reply to#16299
On Oct 15, 5:41 pm, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:
> The EuroForth 2012 proceedings and the individual papers and/or
> presentation slides are now available on
>
> http://www.complang.tuwien.ac.at/anton/euroforth/ef12/papers/
>
> and BibTeX entries for these papers and slides are also available
> <http://www.complang.tuwien.ac.at/anton/euroforth/ef12/papers/eurofort...>.
>
> The papers page is also linked from the EuroForth 2012 page
> <http://www.complang.tuwien.ac.at/anton/euroforth/ef12/>, which is
> linked from the EuroForth page <http://www.euroforth.org/> (or
> <http://www.complang.tuwien.ac.at/anton/euroforth/>).
>
> The authors and titles of the papers are:
>
> Refereed Papers
>
>     * Andrew Read: The N.I.G.E. Machine: an FPGA based micro-computer
>       system for prototyping experimental scientic hardware
>
> Non-Refereed Papers
>
>     * Dirk Bruehl: Forth for Education -- 4E4th and 4E4th IDE
>     * Stephen Pelc: Notation Matters
>     * Bill Stoddart, Campbell Ritchie, Steve Dunne: Forth Semantics
>       for Compiler Verification
>     * Willi Stricker: Connection of a Forth Target with a Forth Host
>     * Ian van Breda: Building an LR parser using Forth
>     * Ian van Breda: Some comments on the proposed Forth Standard
>     * M. Anton Ertl: Methods in objects2: Duck Typing and Performance
>
> Presentation Slides
>
>     * Bernd Paysan: net2o: Transport Layer -- Implemented
>     * Bernd Paysan: Recognizers
>
> - 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 2012:http://www.euroforth.org/ef12/

Thank you. I enjoyed Stephen's paper, and I particularly enjoyed Ian
Van Breva's paper on proposals for the latest standard, in particular
with reference to vocabularies, and with reference to
Try...Catch...Finally.

I'm not alone! Simply brilliant.

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


#16343

FromDoug Hoffman <glidedog@gmail.com>
Date2012-10-16 07:47 -0400
Message-ID<507d495f$0$289$14726298@news.sunsite.dk>
In reply to#16299
On 10/15/12 12:40 PM, Anton Ertl wrote:
> The EuroForth 2012 proceedings and the individual papers and/or
> presentation slides are now available

Thank you.

I found your paper on Duck Typing to be well done and pertinent.

It is encouraging to see Duck Typing explored in this manner.  I 
personally believe that Duck Typing for a Forth objects extension holds 
advantages (I've discussed them before and won't repeat them now).

A few initial observations/questions:

In Figure 1: it appears that the dispatch tables for every class defined 
contains an xt cell for every message defined.  There are four classes: 
object, A, A1, and B.  There are two messages: foo and bar.  So there 
are a total of 4 x 2 = 8 cells total used for the method xts:

Figure 1: (abbreviated)
       object  A    A1   B

foo     xt    xt   xt   xt
bar     xt    xt   xt   xt

But the code for the classes show that there are just 4 methods used not 
counting the not-understood xts:

object class
:: foo ." foo-A" ;; \ first method
end-class A

A class
\ foo is inherited from class A \ second method
:: bar ." bar-A1" ;; \ third method
end-class A1

object class
:: foo ." foo-B" ;; \ fourth method
end-class B


So couldn't the number of cells used be reduced to four?:

Figure 1':
       object  A    A1   B

foo           xt   xt   xt
bar                xt


I believe I understand that the other xts are intended to be used for 
two purposes:
1) Provide a "message not understood" development debugging mechanism.
2) Allow for a possible default method in the case of a not understood 
message.

But 1) could be done by maintaining a count of methods for each class 
and checking that count during method execution.  This check is 
analogous to an array check and would only be done during development. 
Removing the check for production code would restore the run time 
dispatch speed.

The need for 2) I think was questioned by several people.  Maybe it's a 
good thing.  I don't know.  Perhaps it could be optional?

Regardless, Figure1': represents one dispatch table sixe reduction 
technique that Vitek and Horspool call table trimming.  I use it in FMS. 
  But perhaps I don't fully understand the implications for the overall 
dispatch scheme used in objects2 and this trimming may not work there. 
Also, I am assuming that all message names have global scope, which 
seems like the best way to go, IMO.


Regarding sparse dispatch tables, it seems that with the "unhashed 
general selector" scheme that you present in the paper (which is 
essentially the scheme used in the dispatch table version of FMS) it can 
be important to pay attention to the number of different message names 
used and also the order of class definitions with those names.  To 
illustrate with an extreme example:  This only applies to a table 
trimming scheme as I show in Figure 1': above.  If one first defines a 
class X using 100 message names then a table with 100 cells (100 xts) is 
needed for X.  If one then defines a class Y that uses only one message 
name, but it is a different name from any of the 100 in class X, then Y 
will have 101 dispatch table cells with the first 100 cells empty.  Had 
class Y been defined first it would have had only 1 cell, and class X 
defined second would have had 101 cells.  A savings of 101 cells simply 
by changing the order of class definition.

Btw, there is a fairly simple way to "compress" the 100 empty cells in 
class Y, had Y been defined after X, but I won't get into that now.

Also, and I believe this is important but often overlooked, message 
names in OOP are simple generic verbs and can (should be) re-used as 
often as practicable.  This "best practice" will minimize the number of 
message names and pay off in fewer names to remember and significantly 
smaller dispatch table sizes.  I have seen message names used like PUT 
and PUT$ when PUT would have sufficed for both.


In section 8 of your paper you mention that FMS "seems to be based on a 
compressed table".  This is true, only for the dispatch table version, 
and uses a scheme like I mentioned for compressing the 100 empty cells 
in class Y above.  But the latest FMS dispatch table package in FLAG is 
a Multiple Inheritance(MI) OOP package.  Because of this, extra 
information must be carried in the tables.  Any size/speed comparisons 
to this version should also have MI capability for an apples-to-apples 
analysis.  The MI capability necessarily leads to somewhat larger tables 
(hence the use of compression) and somewhat slower late binding speed 
due to the extra information that must be retrieved.  This size and 
speed trade-off may or may not be important to the user.

I should also mention that a linked list approach with multiple "bins" 
for the linked lists can provide a surprisingly efficient late binding 
mechanism for both size and speed.  The linked list version of FMS uses 
a scheme with several important improvements over that used by McKewan 
and others.


Again, a very good paper.  It has provided some new and useful insight 
to me.  Hopefully we can continue to converge on the best ideas for 
Forth OOP, like Duck Typing, and how best to implement them.

-Doug


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


#16347

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2012-10-16 16:20 +0000
Message-ID<2012Oct16.182021@mips.complang.tuwien.ac.at>
In reply to#16343
Doug Hoffman <glidedog@gmail.com> writes:
>So couldn't the number of cells used be reduced to four?:
>
>Figure 1':
>       object  A    A1   B
>
>foo           xt   xt   xt
>bar                xt
>
>
>I believe I understand that the other xts are intended to be used for 
>two purposes:
>1) Provide a "message not understood" development debugging mechanism.
>2) Allow for a possible default method in the case of a not understood 
>message.
>
>But 1) could be done by maintaining a count of methods for each class 
>and checking that count during method execution.

Purpose 2) could also be done with such a check and a small additional
change.

>This check is 
>analogous to an array check and would only be done during development. 
>Removing the check for production code would restore the run time 
>dispatch speed.

Of course, for purpose 2) you must not remove the check.

>  But perhaps I don't fully understand the implications for the overall 
>dispatch scheme used in objects2 and this trimming may not work there.

Not as it is currently designed, but it could be designed differently
(without class selectors, or maybe with class selectors growing in one
direction and unhashed general selectors growing in the other
direction).

>Regarding sparse dispatch tables, it seems that with the "unhashed 
>general selector" scheme that you present in the paper (which is 
>essentially the scheme used in the dispatch table version of FMS) it can 
>be important to pay attention to the number of different message names 
>used and also the order of class definitions with those names.  To 
>illustrate with an extreme example:  This only applies to a table 
>trimming scheme as I show in Figure 1': above.  If one first defines a 
>class X using 100 message names then a table with 100 cells (100 xts) is 
>needed for X.  If one then defines a class Y that uses only one message 
>name, but it is a different name from any of the 100 in class X, then Y 
>will have 101 dispatch table cells with the first 100 cells empty.  Had 
>class Y been defined first it would have had only 1 cell, and class X 
>defined second would have had 101 cells.  A savings of 101 cells simply 
>by changing the order of class definition.

No, that does not play a role in objects2.  You just specify how many
unhashed selectors you want, and all other selectors are then hashed.
So you might specify 101 unhashed selectors, than you need 202 cells
in your example, or 200, then you need 400 cells.  Or 20, then you
need 40 cells for unhashed selectors, and 256 cells or 512 cells for
hashed selectors (so hashed selectors are a bad idea for that such
not-so-sparsely populated matrices).

>Also, and I believe this is important but often overlooked, message 
>names in OOP are simple generic verbs and can (should be) re-used as 
>often as practicable.  This "best practice" will minimize the number of 
>message names and pay off in fewer names to remember and significantly 
>smaller dispatch table sizes.  I have seen message names used like PUT 
>and PUT$ when PUT would have sufficed for both.

If they do conceptually similar things, and have compatible
interfaces, then yes, they should have the same name.  If not, then
they should have different names.  If you want to save space, use
class selectors, hashed selectors, or, to get the effect you are
thinking of, make one selector an alias of the other one.

>In section 8 of your paper you mention that FMS "seems to be based on a 
>compressed table".  This is true, only for the dispatch table version, 
>and uses a scheme like I mentioned for compressing the 100 empty cells 
>in class Y above.  But the latest FMS dispatch table package in FLAG is 
>a Multiple Inheritance(MI) OOP package.  Because of this, extra 
>information must be carried in the tables.  Any size/speed comparisons 
>to this version should also have MI capability for an apples-to-apples 
>analysis.  The MI capability necessarily leads to somewhat larger tables 
>(hence the use of compression) and somewhat slower late binding speed 
>due to the extra information that must be retrieved.  This size and 
>speed trade-off may or may not be important to the user.

IIRC I looked at the FMS from FLAG, but did not understand it enough
to do any size comparisons, and did not try to do speed comparisons.

- 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 2012: http://www.euroforth.org/ef12/

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


#16349

FromBernd Paysan <bernd.paysan@gmx.de>
Date2012-10-16 20:13 +0200
Message-ID<2268724.XZ4vdR9vIK@sunwukong.fritz.box>
In reply to#16347
Anton Ertl wrote:

> Doug Hoffman <glidedog@gmail.com> writes:
>>The MI capability necessarily leads to somewhat larger
>>tables (hence the use of compression) and somewhat slower late binding
>>speed
>>due to the extra information that must be retrieved.  This size and
>>speed trade-off may or may not be important to the user.
> 
> IIRC I looked at the FMS from FLAG, but did not understand it enough
> to do any size comparisons, and did not try to do speed comparisons.

Concerning the idea of using a meta object protocol to implement Forth 
OOPs, it would be quite a good idea to put the actual invocation part 
into at least a well-enough separated section of the file - if not a 
file of its own.

For MI, you AFAIK need two things: The actual xt of the method, and the 
offset to adjust the object pointer when you call the method.  When I 
would implement that, I probably would create delegate methods that do 
the offset adjustment and call the inherited methods using early binding 
(you inherit one particular class, so the binding is known at compile 
time) - this could compile to an add %reg,#offset and a jump; not really 
expensive. Leave the dispatch table mechanism as is.

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

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


#16365

FromDoug Hoffman <glidedog@gmail.com>
Date2012-10-16 17:22 -0400
Message-ID<507dd029$0$290$14726298@news.sunsite.dk>
In reply to#16349
On 10/16/12 2:13 PM, Bernd Paysan wrote:

> For MI, you AFAIK need two things: The actual xt of the method, and the
> offset to adjust the object pointer when you call the method.

Yes.  The tricky part can be when you are multiply inheriting from 
classes that themselves are multiply inherited.  It's an interesting 
problem to solve.

-Doug

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


#16369

FromBernd Paysan <bernd.paysan@gmx.de>
Date2012-10-17 01:29 +0200
Message-ID<2589967.XU4GPribo4@sunwukong.fritz.box>
In reply to#16365
Doug Hoffman wrote:

> On 10/16/12 2:13 PM, Bernd Paysan wrote:
> 
>> For MI, you AFAIK need two things: The actual xt of the method, and
>> the offset to adjust the object pointer when you call the method.
> 
> Yes.  The tricky part can be when you are multiply inheriting from
> classes that themselves are multiply inherited.  It's an interesting
> problem to solve.

The solution, as I tried to explain, is to convert each inheritance into 
wrapper methods that work as if the class was created through single 
inheritance.  That way you only pay the cost of adjusting the offset 
pointer when it's not the primary inheritance, and everything looks like 
SI from the outside.

Then inheriting that as a MI is again a piece of cake, though you might 
want to optimize, i.e. combine all the pointer adjustments into one 
single add.  But that's not that difficult.

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

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


#16370

FromBernd Paysan <bernd.paysan@gmx.de>
Date2012-10-17 01:49 +0200
Message-ID<1490196.IifiXLFvxu@sunwukong.fritz.box>
In reply to#16369
Bernd Paysan wrote:
> Then inheriting that as a MI is again a piece of cake, though you
> might want to optimize, i.e. combine all the pointer adjustments into
> one single add.  But that's not that difficult.

The interesting part of multiple inheritance is usually when you like to 
combine classes with common ancestors. E.g.

object class point
   var x
   var y
   :: draw  x @ y @ draw-point ;
class;

point class circle
   var r
   :: draw  x @ y @ r @ draw-circle ;
class;

point class rectangle
   point p2
   :: draw x @ y @ p2 x @ p2 y @ draw-rectangle ;
class;

rectangle class rounded-rectangle
   inherit circle
...

Now you have two times the x y from the original class...

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

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


#16382

FromDoug Hoffman <glidedog@gmail.com>
Date2012-10-17 06:29 -0400
Message-ID<507e8871$0$292$14726298@news.sunsite.dk>
In reply to#16370
On 10/16/12 7:49 PM, Bernd Paysan wrote:

> The interesting part of multiple inheritance is usually when you like to
> combine classes with common ancestors. E.g.
>
> object class point
>     var x
>     var y
>     :: draw  x @ y @ draw-point ;
> class;
>
> point class circle
>     var r
>     :: draw  x @ y @ r @ draw-circle ;
> class;
>
> point class rectangle
>     point p2
>     :: draw x @ y @ p2 x @ p2 y @ draw-rectangle ;
> class;
>
> rectangle class rounded-rectangle
>     inherit circle
> ...
>
> Now you have two times the x y from the original class...
>

: draw-rectangle { x1 y1 x2 y2 -- }
   ." draw-rectangle at x1= " x1 . ." y1= " y1 .
   ." x2= " x2 . ." y2= " y2 . ;

:class point
   var x
   var y
   :m @: ( -- x y ) x @ y @ ;m
   :m draw: self @: draw-point ;m
;class

:class circle super{ point }
   var r
   :m draw: x @ y @ r @ draw-circle ;m
;class

:class rectangle super{ point }
   point p2
   :m draw: super @:  p2 @: draw-rectangle ;m
\  :m draw: x @ y @ .. p2.x @ .. p2.y @
\     draw-rectangle ;m  \ alternative
;class

:class rounded-rectangle super{ rectangle circle }
   :m draw: cr super draw:
      cr ." with corners of radius = " r @ .
      cr ." with unused x,y = " super> circle @: swap . .
      ;m
   :m init: 10 x ! 20 y ! 30 .. p2.x ! 40 .. p2.y !
       5 r ! ;m
;class

rounded-rectangle rr
rr draw:
draw-rectangle at x1= 10 y1= 20 x2= 30 y2= 40
with corners of radius = 5
with unused x,y = 0 0

The above is one way to do it in FMS.
The rules for resolving ambiguity must be clear. The FMS object system 
will first search the base class (the new class being defined) for 
methods and ivars.  If not found then the search will proceed to the 
first superclass, the first class in the SUPER{...} list read 
left-to-right.  The search will continue if necessary to the 
superclasses of each and then on to the next superclass to the right and 
its superclasses and so on.  As soon as the method or ivar is found then 
the searching stops.

The phrase " super> circle @: " explicitly directs the @: message to the 
circle superclass.

-Doug

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


#16492

FromDoug Hoffman <glidedog@gmail.com>
Date2012-10-19 10:16 -0400
Message-ID<508160b7$0$290$14726298@news.sunsite.dk>
In reply to#16370
On 10/16/12 7:49 PM, Bernd Paysan wrote:
> Bernd Paysan wrote:
>> Then inheriting that as a MI is again a piece of cake, though you
>> might want to optimize, i.e. combine all the pointer adjustments into
>> one single add.  But that's not that difficult.
>
> The interesting part of multiple inheritance is usually when you like to
> combine classes with common ancestors. E.g.

There is a Lua multiple inheritance example in lua-users.org that fails 
to run (gives an error) due to ambiguity.  Makes me think that the MI 
design is inadequate:

http://lua-users.org/wiki/MultipleInheritanceClasses

myCombinedAccount:deposit(2.00)  <-† Error, deposit is nil

The same example will run in FMS without error or further qualification. 
  Again, MI hierarchy rules should be (can be) defined that avoid these 
issues.

-Doug

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


#16388

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2012-10-17 14:15 +0000
Message-ID<2012Oct17.161512@mips.complang.tuwien.ac.at>
In reply to#16369
Bernd Paysan <bernd.paysan@gmx.de> writes:
>Doug Hoffman wrote:
>
>> On 10/16/12 2:13 PM, Bernd Paysan wrote:
>> 
>>> For MI, you AFAIK need two things: The actual xt of the method, and
>>> the offset to adjust the object pointer when you call the method.
>> 
>> Yes.  The tricky part can be when you are multiply inheriting from
>> classes that themselves are multiply inherited.  It's an interesting
>> problem to solve.
>
>The solution, as I tried to explain, is to convert each inheritance into 
>wrapper methods that work as if the class was created through single 
>inheritance.  That way you only pay the cost of adjusting the offset 
>pointer when it's not the primary inheritance, and everything looks like 
>SI from the outside.

That's the C++ solution IIRC.  If you are interested in implementing
multiple inheritance, read Roland Ducournau' papers, which discuss
several ways to implement it.

However, I wonder is if we need MI.  Maybe already things like
objects2, objects.fs, and bernd-OOF are too big and too general, and
most needs are satisfied with something like mini-oof, but with
THIS/SELF.

- 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 2012: http://www.euroforth.org/ef12/

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


#16390

FromBernd Paysan <bernd.paysan@gmx.de>
Date2012-10-17 17:14 +0200
Message-ID<1576975.ojDzJkpY6L@sunwukong.fritz.box>
In reply to#16388
Anton Ertl wrote:
> However, I wonder is if we need MI.  Maybe already things like
> objects2, objects.fs, and bernd-OOF are too big and too general, and
> most needs are satisfied with something like mini-oof, but with
> THIS/SELF.

I don't really need MI, but the point we figured out is that different 
people have vastly different needs.  The Forth-like solution is to 
provide a way to extend the system so that these needs can be fulfilled 
if necessary.

C++'s approach to MI implementation is one which you can do as add-on, 
i.e. the base system (which could be something like Mini-OOF with 
this/self, and a small meta-object protocol) doesn't need to take this 
possibility into account.

There are a number of constructs, which are somewhat related to MI, but 
all differ substantially.  IMHO, MI is not flexible enough - you inherit 
one particular class, and that's it.  My MINOS objects delegate 
different work into different objects they point to, allowing much more 
flexibility.  ATM, I'm often using explicit references to all these 
objects, but I also define delegating methods, like a key method to a 
widget goes right to the key method of the embedded action object - this 
is manually doing what C++'s MI does, but more flexible.

It doesn't hurt us if we provide the means to deal with these things.  
You don't need to load these extensions if you don't need them.

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

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


#16491

FromDoug Hoffman <glidedog@gmail.com>
Date2012-10-19 09:57 -0400
Message-ID<50815c3c$0$284$14726298@news.sunsite.dk>
In reply to#16388
On 10/17/12 10:15 AM, Anton Ertl wrote:

> However, I wonder is if we need MI.

Regardless of the answer, we already have it (and have had for some time):
http://soton.mpeforth.com/flag/fms/index.html
Granted it isn't intended for embedded use, but it wasn't written for that.

> Maybe already things like
> objects2, objects.fs, and bernd-OOF are too big and too general, and
> most needs are satisfied with something like mini-oof, but with
> THIS/SELF.

I'll assume you're not serious.  Even if you solve the instance variable 
namespace problem with mini-oof, one still has the message naming order 
constraint that is unacceptable, in my opinion.  There are better ways.

-Doug

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


#16647

FromDoug Hoffman <glidedog@gmail.com>
Date2012-10-24 08:50 -0400
Message-ID<5087e402$0$292$14726298@news.sunsite.dk>
In reply to#16491
On 10/19/12 9:57 AM, Doug Hoffman wrote:

> Even if you solve the instance variable
> namespace problem with mini-oof, one still has the message naming order
> constraint that is unacceptable, in my opinion.  There are better ways.

Having said that I suppose I should provide something.
So here is one better way, IMO.  The late bound dispatch speed is 
identical to a mini-oof with self/this ( @ over @ + @ ex-meth ).

- a little over 40 lines of code
- real duck typing, no message order constraint
- private namespace for instance variables
- uses self instead of stack juggling
- messages to self are late bound
- ?isSel does the work of determining if a word has been
   defined as a selector
- extra capabilities, if desired, are easily added:
    - instantiate objects in the heap
    - implicit object initialization
    - early binding
    - public/private methods
    - methodless ivar accessing
    - message-not-understood error checks
    - etc.

[undefined] cell  [if] 1 cells constant cell [then]
get-current value dflt-cur
0 value self
0 value ^cls
: dfa  ( cls -- a) cell+ ;
: sfa  ( cls -- a) [ 2 cells ] literal + ;
: wida ( cls -- a) [ 3 cells ] literal + ;
4 cells constant clsSz
0 value hptr
0 value hptrSz
: initHtbl ( n --) cells dup allocate throw to hptr to hptrSz
   hptr hptrSz erase ;
: HtblSz ( -- cells) hptrSz cell / ;
: rszHtbl ( n --) cells dup hptr swap resize throw to hptr to hptrSz ;
: ^helem ( idx -- a) cells hptr + ;
: Stbl ( -- a) ^cls sfa @ @ ;
: StblSz ( -- cells) Stbl @ cell / ;
: toDtbl ( n idx --) cells ^cls @ + ! ;
: buildDtbl HtblSz 1 do i ^helem @ dup 0= if i StblSz 1+ < if drop
   i cells Stbl + @ then then i toDtbl loop hptrSz cell - 0 toDtbl ;
create object clsSz allot  here 0 , object !  cell object dfa !
   variable meta 0 meta !  meta object sfa !
: cls>wlorder ( cls -- wn..w1 n)  >r get-order get-order
   begin  r@ wida @ swap 1+ r> sfa @ >r r@ object = until r> drop 
set-order ;
: <super ( name-- wn..w1 n) here dup >r to ^cls clsSz allot ' >body dup
   r@ clsSz move r@ sfa ! wordlist r@ wida ! r> cls>wlorder StblSz 1+ 
initHtbl ;
: ex-meth ( ^obj xt -- ) self >r swap to self execute r> to self ;
0 value selIdx  here constant seltag
: ?isSel ( name -- in a t | in pfa f) >in @ bl word find if >body dup
   if dup cell+ @ seltag = else 0 then else 0 then ;
: sel ( name --) create selIdx cell+ dup to selIdx , seltag ,
   does> ( ^obj addr) @ ( ^obj selIdx) over @ + @ ex-meth ;
: gs ( -- sel) ?isSel if nip else drop >in ! sel here 2 cells - then @ ;
: :m ( name -- idx xt) gs cell / :noname ;
: ;m ( idx xt --) postpone ; swap  begin HtblSz 1- over < while HtblSz 1+
   rszHtbl 0 HtblSz 1- ^helem ! repeat ^helem ! ; immediate
: super ( name --) ' >body @ Stbl + @ compile, ; immediate
: (ivar) ( offset name --) ^cls wida @ set-current create immediate ,
   dflt-cur set-current does> ( --a) @ postpone literal postpone self 
postpone + ;
: bytes ( n name --) ^cls dfa dup @ (ivar) +! ;
: >dict ( ...cls -- o) dup dfa @ align here swap allot swap @ over ! ;
: ;class ( wn..w1 n --) set-order align here ^cls !  hptrSz allot
   buildDtbl  hptr free throw  dflt-cur  set-current ;

\ example use
create var <super object
   cell bytes data
  :m get ( -- n )  data @ ;m
  :m print self get . ;m
  :m put ( n -- )  data ! ;m
;class

var >dict constant x
35 x put
x print  \ => 35

create var' <super var
  :m get data @ 1+ ;m
;class

var' >dict constant x'
40 x' put
x' print  \ => 41

\ example of message name and ivar name reuse
create bvar <super object
   1 bytes data
  :m print data c@ . ;m
;class

bvar >dict constant b
b print  \ => xx
x print  \ => 35
data  \ => error, undefined word

0 [if]
dispatch table sizes:
object  0 cells
var     3 cells total, 0 of 3 empty
var'    3 cells total, 0 of 3 empty
bvar    2 cells total, 1 of 2 empty
[then]

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


#16385

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2012-10-17 13:29 +0000
Message-ID<2012Oct17.152956@mips.complang.tuwien.ac.at>
In reply to#16349
Bernd Paysan <bernd.paysan@gmx.de> writes:
>Concerning the idea of using a meta object protocol to implement Forth 
>OOPs, it would be quite a good idea to put the actual invocation part 
>into at least a well-enough separated section of the file - if not a 
>file of its own.

Given that VFX compiles the unhashed method dispatch of objects2 into

MOV EDX, 0 [EBX]
CALL [EDX+<u-offset>]

it seems to me that Forth is the meta-object protocol as far as method
dispatch is concerned.

- 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 2012: http://www.euroforth.org/ef12/

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


#16391

FromBernd Paysan <bernd.paysan@gmx.de>
Date2012-10-17 17:31 +0200
Message-ID<2150021.JlsZ2jzo4u@sunwukong.fritz.box>
In reply to#16385
Anton Ertl wrote:

> Bernd Paysan <bernd.paysan@gmx.de> writes:
>>Concerning the idea of using a meta object protocol to implement Forth
>>OOPs, it would be quite a good idea to put the actual invocation part
>>into at least a well-enough separated section of the file - if not a
>>file of its own.
> 
> Given that VFX compiles the unhashed method dispatch of objects2 into
> 
> MOV EDX, 0 [EBX]
> CALL [EDX+<u-offset>]
> 
> it seems to me that Forth is the meta-object protocol as far as method
> dispatch is concerned.

That's not the point.  The point is rather that you separate the actual 
method dispatch from the syntax of your OOP extension, including *how* 
it is done.  System implementer A choses that unhashed method dispatch 
is the way to go, and system implementer B has a customer with 10k 
classes (with on average 10 methods) and 1000 different methods, and 
therefore decides that the method array is way too sparse, and some 
compression is absolutely necessary.

Both of them can actually use Forth to implement the method dispatch; 
that's not the issue.  The issue is that by separating both parts and 
having a well-defined interface, you can improve the maintenance and 
interoperability of the 10+ different OOP packages we still have in 
active use.

The functionality of a meta object protocol are things like

* create a new method ( "name" -- xt-m ) and reserve space for it in the 
vtables
* implement a method ( xt xt-m class -- )
* bind a method ( xt-m class -- xt )
* set the way how to obtain the object when calling a method (may be 
self, may be top of stack, may be an object pointer)

The actual calling of a method is just invoking the xt-m (append to 
dictionary with COMPILE, or EXECUTE it).  And have that interface in a 
class, so that you can modify it.

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

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


#16364

FromDoug Hoffman <glidedog@gmail.com>
Date2012-10-16 17:20 -0400
Message-ID<507dcf8c$0$290$14726298@news.sunsite.dk>
In reply to#16347
On 10/16/12 12:20 PM, Anton Ertl wrote:
> Doug Hoffman <glidedog@gmail.com> writes:

> IIRC I looked at the FMS from FLAG, but did not understand it enough
> to do any size comparisons, and did not try to do speed comparisons.

If I get a chance I may put together a demo version that uses this kind 
of compression with single inheritance.  This one would be suitable for 
comparison testing.  I'll try for decent documentation as well.

-Doug

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


#16366

FromDoug Hoffman <glidedog@gmail.com>
Date2012-10-16 17:25 -0400
Message-ID<507dd0b2$0$290$14726298@news.sunsite.dk>
In reply to#16364
Oops.  Bad quote.  Should have been:

On 10/16/12 12:20 PM, Anton Ertl wrote:

 > IIRC I looked at the FMS from FLAG, but did not understand it enough
 > to do any size comparisons, and did not try to do speed comparisons.

If I get a chance I may put together a demo version that uses this kind 
of compression with single inheritance.  This one would be suitable for 
comparison testing.  I'll try for decent documentation as well.

-Doug

[toc] | [prev] | [standalone]


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


csiph-web