Saturday, March 19, 2011

Base class constructors? Oh my!

When a person with quite limited exposure to OO programming (like me) gets such a crazy idea like designing an OO programming language (like Sysel), they shouldn't be surprised when they forget about something important. Like invoking base class constructors.

What happened was that while working on constructing the syntax tree in NNPS I was getting exceptions due to accessing nil reference (equivalent of null pointer dereference in C). The problem boils down to the following: we have two classes A and B, B derived from A. Both have constructors, the constructor for A initializes some reference in A. When a new object of class B was created, only constructor for B was called so the reference was not initialized.

When a new object is created, constructors must be called for its class and all base classes. This is easy if the constructors do not have parameters (in this case it can be done implicitly). If the constructors do have parameters, the programmer must explicitly specify them (since the compiler does not know what they should be).

Different languages solve the problem differently. In C++ (and similar languages) the arguments / call to base class constructor(s) appear to be part of the constructor's signature.
class A {
    public: A(int i, int j) { }
};
class B : public A {
    public: B(int i) : A(i,i+1) { }
};
Others, like PHP, require the programmer to call the base class constructor with a syntax similar to a static method invocation:
class A {
   function __construct(i, j) { }
}
class B extends A {
   function __construct() {
       parent::__construct(i, i+1);
   }
}
The strength of the first approach is that it makes it is syntactically enforcible, i.e.
if you forget about it, the compiler can easily tell. In the second case you can do more
complex processing before calling the parent constructor (than just evaluating an expression),
but it is difficult to tell at compile time whether all code paths contain the constructor
invocation (a problem similar to determining if all code paths in a function end in a return statement).

I still need to decide how to implement this in Sysel. Or I could just make my base class constructors parameter-less for the time being.

2 comments:

  1. What's wrong with D,
    http://www.digitalmars.com/d/
    it's very hard to write new language from scratch!

    ReplyDelete
  2. Creating a programming language from scratch is difficult, but it is also fun. And I like a challenge.

    D has some nice and inspiring features (dos) but also many dont's. D is largely a superset of C, thus it is not a truly high-level and portable language and inherits many of C's deficiencies. D uses templates which is a completely flawed concept. Sysel uses generics instead. Also, does D support RMI? I don't think so.

    ReplyDelete