Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #16299 > unrolled thread
| Started by | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| First post | 2012-10-15 16:40 +0000 |
| Last post | 2012-10-16 17:25 -0400 |
| Articles | 18 — 4 participants |
Back to article view | Back to comp.lang.forth
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
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2012-10-15 16:40 +0000 |
| Subject | EuroForth 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]
| From | Mark Wills <forthfreak@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2012-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2012-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]
| From | Bernd Paysan <bernd.paysan@gmx.de> |
|---|---|
| Date | 2012-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Bernd Paysan <bernd.paysan@gmx.de> |
|---|---|
| Date | 2012-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]
| From | Bernd Paysan <bernd.paysan@gmx.de> |
|---|---|
| Date | 2012-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2012-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2012-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]
| From | Bernd Paysan <bernd.paysan@gmx.de> |
|---|---|
| Date | 2012-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2012-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2012-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]
| From | Bernd Paysan <bernd.paysan@gmx.de> |
|---|---|
| Date | 2012-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2012-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