Dynamic inheritance?

Consider class C that inherits from class B in a (statically) typed language. I would like to extend, at runtime, an instance of type B to type C:

    B b = new B();
    Assert(b is B);
    b.Method(); // invokes B.Method() 

    extend b to C();  // partial constructor for C
    Assert(b is B);
    Assert(b is C);
    b.Method(); // invokes C.Method() override 

Is there any reason why this should not be allowed in terms of type safety? If not, what is it called and is there any language out there that supports this?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Yes, no, call me maybe

Some forms of dynamic inheritance are statically type safe; two systems I know of:

  • Cecil by Chambers et al. Safety is achieved by predicating the extension. Cecil is fairly general purpose.
  • I copied Cecil in the version of Superglue that supported live programming. Since Superglue is a declarative language, extensions can be guarded by conditions that are sometimes false.

In general, dynamic inheritance that involves imperative mutation is not statically type checkable.

From absence predicates (row variables) to crazy field types

The work on statically modelling object-oriented programming practices using row-variables (eg. the ML-ART work by Didier Rémy) did touch on direct object extension -- usually presented as a functional update returning a new object, rather than mutation of an existing object as in your example, but that's an orthogonal issue.

The right intuitions are given in (undated but apparently quite old) slides by neelk, Row Polymorphism, in particular the "Mixins" slide number 13. Note the use of "absence predicate" to restrict, when you extend your object foo with an additional method "bar", the type of foo to the type of objects that *do not* already have a method "bar" (which is different from the type of objects that do not expose a method "bar", as they may have hidden it by subtyping/abstraction).

This can be extended to an infinite amount of complexity. In Didier Rémy's 1998 paper "From Classes to Objects via Subtyping", there are 6 different qualifiers for method labels (and variance-annotated versions of some of them), to express things as "I may have exposed a method of name 'bar' in the past, and in this case it was of type T, type of which my other methods only relied covariantly, so you may dynamically extend me with a new method 'bar' of any larger type".