Brand new to Nim, trying out parametric type with hierarchy, got stung with an indentation error for the last two lines that I can't figure out why
type
floatingPoint = float | float64 | float32
Parent1 = ref object
Parent2 = ref Parent1
Parent3 = ref Parent1
Child1[T: FloatingPoint] = ref Parent1
nOutNodes: uint
outputNodes: seq[seq[T]]
Remedy appreciated
Thanks
Child1[T: FloatingPoint] = ref Parent1
It means that Child1 is just a reference to Parent1, so no additional fields allowed after such a declaration. I assume you intended to write something like this
type
floatingPoint = float | float64 | float32
Parent1Obj = object of RootObj # Parent object should be non-final
Parent1 = ref Parent1Obj
Parent2 = ref Parent1
Parent3 = ref Parent1
Child1[T: floatingPoint] = ref object of Parent1Obj # Child1 is a reference to object inherited from Parent1Obj
nOutNodes: uint
outputNodes: seq[seq[T]]
Many thanks! Looks like I didn't read the manual properly, I ended up thinking that ref Parent was how inheritance works. Just for confirmation:
type
# This is equivalent to a struct
Object1 = object
# This is a reference type to the "struct" Object1
Object2 = ref Object1
# This is a class
Class1 = ref object of RootObj
# This is a child class of Class1
Class2 = ref object of Class1
# This is a reference type to Class1
Class3 = ref Class1
Something else I have noticed is that this compiles:
type
Class4 = object of RootObj
Class5 = object of Class4
I guess that this is also inheritance - does that mean that the first set of classes are reference classes and this set are value classes complete with inheritance - similar to C++ classes which are value types in contrast to D classes which are reference types?
The corollary I guess is that below are reference classes that are not garbage collected while those marked with ptr are:
type
Class6 = ptr object of RootObj
Class7 = ptr object of Class6
If we extend this logic to the "struct"-like types that below are both reference struct-like types but the ref type is garbage collected while the ptr type is not:
type
Object3 = ref object
Object4 = ptr object
If so that is an awesome amount of flexibility.
Yes, object is a value, ptr object is a non-garbage-collected pointer to an object, ref object is a garbage-collected pointer to an object, object of ... is the way to inherit, to be combined with any of the previous, and after any of that a list of fields may go.
RootObj is not smth special and built-in, it's defined in system.nim (like many other things, read that module for better understanding) as type RootObj* {.inheritable.} = object, a predefined root for inheritance hierarhies, but you can create separate hierarchies (your own roots) the same way, marking your object type as {.inheriatable.}.
Class3 = ref Class1 - values of this type will be double references: references to referenced (Class1) subtype of empty objects (RootObj).
Nitpicking but just use the SomeReal typeclass instead of this line:
floatingPoint = float | float64 | float32
By the way, I don't really understand your need but you can usually go very far in Nim with just generics and overloading without to implement class-like types.
If you need runtime polymorphism, don't forget to look into object variants and methods (which are dispatched at runtime instead of compile-time).
@LeuGim - thanks for the clarification
@mratsim I didn't know about SomeReal thanks for pointing that out.
By the way, I don't really understand your need but you can usually go very far in Nim with just generics and overloading without to implement class-like types.
If you need runtime polymorphism, don't forget to look into object variants and methods (which are dispatched at runtime instead of compile-time).
I did look at object variants which are very interesting. In the end I think I'll probably end up writing using compile time parametric polymorphism with generics - but at the moment, I'm kind of feeling my way around the language to see what I can do with it. I'm now getting round to playing with generics. My experience of meta-programming comes mostly from D, Julia and even less C++, I have read type parameters, templates, and macros section in the manual and it certainly looks very flexible - I'll definitely have questions about it later.
Many thanks