Search code examples
ooplanguage-featuresdowncast

Which languages allow to change identity of an object (not cast)?


In this post, a brave wants (in C++) to downcast a object of type Base to a Derived type. Assuming that the Derived type has no more attributes than Base, it can make sense if you're jealous of the extra methods that the Derived class provides.

Are there programming languages that allow such a thing?


Solution

  • Actually, this is something that is done without problem in Common Lisp, and in other Lisp dialects where CLOS (Common Lis Object System) was ported. You use the change-class generic function for that.

    CLOS works with multiple dispatch methods, so a method is not tied to a class or object, it's just a function that is chosen in a group of similar functions WRT to the types (or identities) of its arguments. When using change-class, you can give arguments as if you were creating a new instance, and data already stored in the object will remain. Here is a little session that shows how it works:

    CL-USER> (defclass base ()
           ((name :initarg :name)))
    #<STANDARD-CLASS BASE>
    CL-USER> (defclass derived (base)
           ((age :initarg :age :initform 0)))
    #<STANDARD-CLASS DERIVED>
    CL-USER> (defvar foo (make-instance 'base :name "John Doe"))
    FOO
    CL-USER> (change-class foo 'derived :age 27)
    #<DERIVED {100338F2D1}>
    CL-USER> (with-slots (name age) foo
           (list name age))
    ("John Doe" 27)
    CL-USER> (defvar bar (make-instance 'base :name "Baby Joe"))
    BAR
    CL-USER> (change-class bar 'derived)
    #<DERIVED {10036CF6E1}>
    CL-USER> (with-slots (name age) bar
           (list name age))
    ("Baby Joe" 0)
    CL-USER> 
    

    If this default behaviour is not enough, you may define a method on update-instance-for-different-class.

    So yeah, there are programming languages that allow such a thing!