Another promise fulfilled — having pinned constructors in hand I could add “SELF
” which behaves like implicit generics. Or you can think of it as virtual static feature.
Probably the best way to present it is using factory pattern:
struct Foo // constructor def pinned init() Foo do return self // "this" in C++ family end def static Create() SELF do return new SELF(); end end struct Bar : Foo def pinned init() Bar do return self end end
The “SELF
” which interests us sits in “Create
” method. When you call it as “Foo.Create
” you will get instance of “Foo
”, but when you call it as “Bar.Create
” you will get “Bar
” object. Please note that such call does not cause an error:
var obj Bar = Bar.Create();
The above snippet would be erroneous if “Create
” was defined differently, namely:
... def static Create() Foo do return new SELF(); end
forcing you to write:
var obj Foo = Bar.Create(); // Bar is created nevertheless
But since it was defined with result type as “SELF
”, the actual result type changes from call to call and compiler knows about it.
To summarize — “self
” is a polymorphic reference to an object, “SELF
” is a polymorphic reference to a type. You can create new instances using “SELF
” as long as the used constructor is marked as pinned.