It is preliminary step of enhanced generics we know from C# and I hope all things finally clicked in for implementing this feature. Consider such code:
public class ClassModifier : TreeNode
{
public bool IsAbstract { get; private set; }
public bool IsVirtual { get; private set; }
public bool IsStatic { get; private set; }
private ClassModifier(NodeCoords coords)
: base(coords)
{
}
public static ClassModifier Abstract(NodeCoords coords)
{
return new ClassModifier(coords)
{ IsAbstract = true };
}
...
and
public class MethodModifier : TreeNode
{
public bool IsAbstract { get; private set; }
public bool IsVirtual { get; private set; }
public bool IsStatic { get; private set; }
public bool IsNew { get; private set; }
public bool IsOverride { get; private set; }
private MethodModifier(NodeCoords coords)
: base(coords)
{
}
public static MethodModifier Abstract(NodeCoords coords)
{
return new MethodModifier(coords)
{ IsAbstract = true };
}
...
Factory methods as usual, nothing special except the code is highly redundant. In PHP it can be expressed nicely because it has static constructor with late binding — it works like static polymorphism. It can be shortened in C# too, but with ugly twists.
However Skila is meant to be expressive and compiled language.
So I came up with idea of pinned constructor for the beginning. Once added to any class such constructor has to be overridden in every descendant class (or automatically upgraded). Secondly special keyword to express static polymorphism is needed — “SELF
” sounds just right. With those two enhancements the code becomes much shorter (it is not Skila yet):
public class ClassModifier : TreeNode
{
public bool IsAbstract { get; protected set; }
public bool IsVirtual { get; protected set; }
public bool IsStatic { get; protected set; }
protected pinned ClassModifier(NodeCoords coords)
: base(coords)
{
}
public static SELF Abstract(NodeCoords coords)
{
return new SELF(coords)
{ IsAbstract = true };
}
...
public class MethodModifier : ClassModifier
{
public bool IsNew { get; private set; }
public bool IsOverride { get; private set; }
...
}
Thanks to pinned constructor it is safe to write “new SELF(coords)
” — every class has to support such call. And because “SELF
” works as implicit generics when I call “MethodModifier.Abstract()
” I will get “MethodModifier
”, not “ClassModifier
” despite the fact the method is static and it is defined in “ClassModifier
” class.