Monthly Archives: August 2013

SELF — one factory to rule them all

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.

Advertisement
Tagged , , , ,

Pinned constructors — served as promised

Exactly as I wrote previously, I added pinned constructors feature into Skila. Let me show you the syntax:

struct ClassModifier 
  def pinned init(coords NodeCoords)
  do
    ...

The novelty is “pinned” keyword after “def” (“init” is Skila constructor).

Once you add pinned constructor you have to redefine it (or allow compiler to do it for you) in every descendant class. Compare this to regular methods — when you add one you know it will stay in every derived class. It is not true with constructors though, you can have elaborate constructor and it is only good for the class you define it for. So you can think of pinned constructors as an aid for bringing symmetry between methods and constructors.

If you don’t define any constructors compiler will redefine pinned constructors for you with simple field initialization and calling base constructor. Please note that unless parameterless constructor (the default one) is pinned in base class, it won’t be redefined by compiler along with pinned ones.

Tagged ,

9 days as 2 hours

I am in rather bitter mood because I finally did validation of static features in Skila — however instead of 2 hours as I anticipated it took me 9 days. I wish I could say I fainted in the process, but I didn’t — and I feel bad about this.

But no matter how bad the things are there is always a lesson to learn — this experience supports in a way idea expressed by Peter Seibel in his talk “Practical Common Lisp” that the language defines thought.

Here, I was so used to the framework I already had for name resolution that it was obvious I should add a few patches, fix this and that, and I will get working solution. I was absolutely deluded — the right way to achieve solution was a major rework and coming up with completely new name resolver. If I did it right from the beginning I would spent 2-3 days on it with steady progress and no frustration.

Now I need some time to take care of my regular duties, I should be back in 2 weeks.

Tagged ,