Search code examples
lispcommon-lispclos

What's the equivalent of constructors in CLOS?


How would you express the following Java code in Lisp?

class Foo {
    private String s;

    public Foo(String s) {
        this.s = s;
    }
}

class Bar extends Foo {
    public Bar(int i) {
        super(Integer.toString(i));
    }
}

In Lisp, is make-instance or initialize-instance the equivalent of a constructor? If yes, how do you call the super class constructor(s)?


Solution

  • Use CALL-NEXT-METHOD from within a method to call the next one.

    Typically just use the standard method combination facility and write an :BEFORE, :AFTER or :AROUND method for INITIALIZE-INSTANCE.

    One way:

    (defclass foo ()
      ((s :type string :initarg :s)))
    
    (defclass bar (foo) ())
    
    (defmethod initialize-instance :around ((b bar) &key i)
      (call-next-method b :s (princ-to-string i)))
    

    Example:

    CL-USER 17 > (make-instance 'bar :i 10)
    #<BAR 402000B95B>
    
    CL-USER 18 > (describe *)
    
    #<BAR 4130439703> is a BAR
    S      "10"
    

    Note that I've called CALL-NEXT-METHOD without changing the argument it dispatches on. I just changed the &key initarg parameter.