Hi,
I just wanted to announce that I have started a small tool which helps you in doing some OOP in Nimrod. Currently the support for OOP in Nimrod is a little bit rudimentary compared to other languages. For new projects this is OK, because Nimrod offers you other design possibilities, but if you need to port some old code to Nimrod, it happens that you get stuck. Nimrod strength is its flexibility and this tool tries to show how you can use Nimrods macros to mimic OOP like in other languages. The source is at https://github.com/AdrianV/nimrod-tools Here is a small example how to use it
import oopHelper
declClass TBase:
var
data: int
proc Foo(self: TBase): int = return self.data
declClass TSecond, TBase:
var
d2: int
proc Foo(self: TSecond): int {.override.} = return Inherited(self).Foo(self) + self.d2
var
o2 = TSecond.newInstance()
o : TBase = o2
o.data = 10
echo o.Foo()
o2.d2 = 12
echo o.Foo()
echo o.getClassName
currently it supports virtual procs, access to the inherited proc (!), some RTTI like the className. More to come.
I've written something similar https://github.com/fowlmouth/nimlibs/blob/master/macros/classlib.nim
Where mine differs:
Adrian: I'm curious why you need all the special TCustomObject stuff. When I wrote the earlier version I talk about above, I believe I only stored the type names as a table of PNimrodNodes, I only needed it to connect class names "Animal" to the name of the type (IdentNode !"PAnimal")
because I am building a VMT in the class object. Each instance has a pointer to its corresponding class object, which holds the VMT, the class name, a pointer to the base class and later other information for serialization and unserialization. To ensure that the class pointer exists I need a (virtual) common base class = TCustomObject which points to a TClassOfTCustomObject. I could have done it without, but there is also some fallback code (a empty initialization, if none is defined) - and it was easier to do ;-)
I will adopt your idea with adding the self if not defined or rewriting it, if wrong defined
changed to automatically add self. now virtual methods have to be declared as method, normal procs can be added to. used term rewriting to use a custom of because the base class is pure the above example gets now:
import oopHelper
declClass TBase:
var
data: int
method Foo(): int = return self.data
proc initialize() = self.data = 10
declClass TSecond, TBase:
var
d2: int
method Foo(): int {.override.} = return Inherited(self).Foo(self) + self.d2
proc initialize() = self.d2 = 12
var
o2 = TSecond.newInstance()
o : TBase = o2
echo o.Foo()
echo o.getClassName
echo o of TSecond
benchmarks shows, that virtual methods via VMT are much faster than the normal methods.
benchmarks shows, that virtual methods via VMT are much faster than the normal methods.
Hey, I haven't optimized normal methods yet ... And benchmarks on x86 are unfair anyway as they have excellent prediction for indirect calls ;-)
I guess you will inline the of operation, which would be easy to do. This could really bring a big boost as long as the hierarchy isn't too deep. For deep hierarchies like in existing class libraries a VMT has its advantages because performance doesn't depend on the level of class (in good and bad). My main intent was to make it easier to port existing code and to have the possibility to call the inherited method.
And its not my fault that most of my work is done on x86 ;-)
anyway Nimrod rocks, because you have the freedom to do almost anything the way you like !