Struct Embedding in Lisp

;; Lisp supports composition of types through multiple inheritance
;; and mixins, which can be used to achieve similar functionality
;; to struct embedding in Go.

;; Define a base class
(defclass base ()
  ((num :initarg :num :accessor num)))

(defmethod describe-base ((b base))
  (format nil "base with num=~a" (num b)))

;; Define a container class that inherits from base
(defclass container (base)
  ((str :initarg :str :accessor str)))

;; Main function equivalent
(defun main ()
  ;; Create an instance of container
  (let ((co (make-instance 'container :num 1 :str "some name")))
    ;; We can access the base's fields directly on co
    (format t "co={num: ~a, str: ~a}~%" (num co) (str co))

    ;; We can also access the base's fields using the class name
    (format t "also num: ~a~%" (slot-value co 'num))

    ;; Since container inherits from base, the methods of
    ;; base are also available to container instances
    (format t "describe: ~a~%" (describe-base co))

    ;; In Lisp, we don't need to explicitly define interfaces.
    ;; Any object that responds to the 'describe-base' method
    ;; can be considered a 'describer'.
    (format t "describer: ~a~%" (describe-base co))))

;; Run the main function
(main)

This Lisp code demonstrates concepts similar to struct embedding in Go:

  1. We define a base class with a num slot and a describe-base method.

  2. We then define a container class that inherits from base. This is similar to embedding in Go.

  3. In the main function, we create an instance of container and demonstrate how we can access the inherited num slot and the describe-base method.

  4. Lisp’s object system (CLOS) provides multiple inheritance, which can be used to achieve composition similar to Go’s struct embedding.

  5. Lisp doesn’t have explicit interfaces. Instead, any object that responds to a particular method can be considered to implement that “interface”.

To run this program, save it to a file (e.g., struct-embedding.lisp) and load it into your Lisp environment. The output should be:

co={num: 1, str: some name}
also num: 1
describe: base with num=1
describer: base with num=1

This example shows how Lisp’s object-oriented features can be used to achieve functionality similar to Go’s struct embedding, demonstrating the flexibility and power of Lisp’s object system.