super, self, and sideways & durable vs. template

Peter Michaux petermichaux at gmail.com
Sun Jun 12 13:00:36 PDT 2011


Something I try to do when designing constructors is to ensure the
constructed objects will be durable. That is, if some code modifies or
breaks parts of the constructed object's exposed interface, the other
parts of the exposed interface should continue working the same as
before. Part of what I use for this is what I term "sideways" calls
because I don't know any better. I don't know if there is a proper
name for this type of call but it is different than super and self
calls. Using sideways calls allows subclasses to still override
interface methods but doesn't allow subclasses to change the behavior
of non-overridden interface methods.

If anyone knows a name for this kind of call I'd be interested to know
it and if there are class-based languages that have support for this
type of call. It can be done by using very obscure method names,
perhaps involving the class name as a namespacing technique, but this
is not as elegant as what JavaScript, Scheme, etc allow as shown in
the example below.

The following example shows that m3 in makeB is brittle because it
uses a self call but that m4 is durable because it uses a sideways
call. How would one make a durable m4 with the class syntax while
still allowing m4 to be overridden in subclasses that choose to over
ride it.

My primary reason for asking here is I'm curious if there is any
allowance for sideways calls in the proposed class syntax. By that I
mean using the prototype parts of the proposed syntax rather than the
closure based parts of the syntax (since the syntax can do both.)

Thanks,
Peter

------------

function makeA() {
    return {
        m1: function() {return 'm1 in A';},
        m2: function() {return 'm2 in A';},
        m3: function() {return 'm3 in A';}
    };
}

function makeB() {
    var self = makeA();
    var superM1 = self.m1;

    var m1 = self.m1 = function() {
        return superM1(); // calling up the inheritance chain
                          // (durable)
    };
    var m2 = self.m2 = function() {
        return 'm2 in B';
    };
    self.m3 = function() {
        return self.m2(); // calling down the inheritance chain
                          // (template pattern & brittle)
    };
    self.m4 = function() {
        return m2(); // calling sideways in the inheritance chain
                     // (durable)
    };
    return self;
}

// The makeC constructor breaks the m3 method even though it doesn't
override the m3 method.
//
function makeC() {
    var self = makeB();

    self.m2 = function() {
        throw new Error('aaaaaahhhh');
    };

    return self;
}


More information about the es-discuss mailing list