I needed to define a set of classes in Forth, where certain method names may repeat in different classes.
The final solution should work on a simple J1B processor in FPGA, with Swapforth. Therefore it should be as simple as possible.
Because Swapftorth includes mini-oof.fs, I tried to use that library, but it does not handle non-unique method names correctly.
The code below shows the problem in Gforth, but in Swapforth it works the same way. The only difference is that in Gforth I had to use "new" instead of "anew":
require mini-oof.fs
object class
method y
method x
end-class wc1
:noname drop ." method x in wc1" ; wc1 defines x
:noname drop ." method y in wc1" ; wc1 defines y
object class
method x
method y
end-class wc2
:noname drop ." method x in wc2" ; wc2 defines x
:noname drop ." method y in wc2" ; wc2 defines y
wc1 new constant xx1
wc2 new constant xx2
If I load the above code to the Gforth, and then try to call the x and y methods of objects xx1 and xx2, I get the following results:
xx1 x method y in wc1 ok
xx1 y method x in wc1 ok
xx2 y method y in wc2 ok
xx2 x method x in wc2 ok
It appears, that the definition of methods "x" and "y" for class "wc2" has affected their definition for class "wc1". It seems, that after definition of class wc2, mini-oof simply translates the "x" to the first method in any class, and "y" to the second method in any class.
To verify that hypothesis, I have added the third class:
object class
method m1
method m2
end-class wc3
:noname drop ." method m1 in wc3" ; wc2 defines m1
:noname drop ." method m2 in wc3" ; wc2 defines m2
wc3 new constant xx3
Indeed, the tests below show, that x, y, m1, m2 are simply translated to the method numbers:
xx3 x method m1 in wc2 ok
xx3 y method m2 in wc2 ok
xx3 m1 method m1 in wc2 ok
xx1 m1 method y in wc1 ok
Is there another simple Forth library that supports classes with non-unique method names?
There are too many OOP implementations to test them all in swapforth and point you some specific variant.
In general, there are only two options:
Hence, in case of early binding you need to specify a class in some way along with a method (in a place of the method call).
So, if you want to use a grammar like the following:
xx1 dup >r x r> y
xx2 dup >r y r> x
— the only options is late binding. Is it acceptable?
In the case of late binding a method will be resolved in run-time. Implementation can be based on the standard wordlists (search occurs among the methods of the corresponding class only), or even on the own hash-tables.
In case of early binding either parsing words or lexeme resolvers mechanism (recognizers) should be used. A usage example could look like the following:
a) ^ is an immediate parsing word:
xx1 dup >r ^ wc1#x r> ^ wc1#y
xx2 dup >r ^ wc2#y r> ^ wc2#x
b) . is a possible syntax for qualification of the methods:
xx1 dup >r wc1.x r> wc1.y
xx2 dup >r wc2.y r> wc2.x
So, unqualified method call can be used inside a class definition only. Outside the class definition the methods should be always qualified.
In other typed languages a method is qualified via variable identifier (since the variable type is known in advance). In Forth it should work without variables at all.
In absent of "wordlist" or resolvers API — they can be easy implemented along with outer interpreter loop.
A possible alternative to a library like mini-oof.fs is to take advantage of the Forth internal features for handle complexity, namely the ability to distribute the sourcecode over different files. File “gui.fs” is equal to the class gui, while file “physics.fs” stores all the physics. In each file, variables and methods are defined in the normal Forth syntax, that means with:
variable x
variable y
: getx
: gety
The concept was described as “Ascetic Programming” in a talk at a meeting of the Silicon Valley Forth Interest Group (SVIG): “Samuel A. Falvo II: Follow Up to OO Extensions Considered Harmful, Forth Day November 2010 Meeting Notes"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With