defstruct

Mit dem Macro defstruct definiert man Strukturen. Strukturen sind spezielle Klassen (siehe Klasse). Das Macro erwartet drei Argumente: ein Symbol als Namen der Struktur, eine Liste von Symbolen, diese legen die Instanzvariablen der Struktur fest und schließlich ein Prädikat über diesen Instanzvariablen.

Das Prädikat drückt eine Invariante aus. Das bedeutet, für alle Instanzen der Struktur muss das Prädikat angewendet auf die Werte der Instanzvariablen einen Wert ungleich nil ergeben.

Beispielsweise definiert der folgende Ausdruck eine Struktur mit dem Namen complex. Diese hat zwei Instanzvariablen, für die nur Zahlenwerte erlaubt sind.

> (defstruct complex (real imaginary) (and (number? real) (number? imaginary)))

Nachdem die Struktur definiert wurde, können neue Instanzen mit new erzeugt werden.
 
> (setq c (new complex 1.2 3.1))

Die Werte der Instanzvariablen ermittelt man mit slot-valueq (oder dessen Synonym .).

> (. c real)
1.2

> (. c imaginary)
3.1

Das Macro erzeugt eine Zwischenform, die zunächst mit defclass eine Klasse definiert (Strukturen sind, wie oben erwähnt, spezielle Klassen) und dann mit defmethod einen passenden Konstruktor für diese Klasse:

(defmacro defstruct args
  (quasi-quote
    (progn
      (defclass (unquote (first args)) nil)
      (defmethod initialize
        (unquote
          (cons
            (list (quote this) (first args))
            (second args)))
        (unquote (third args))
        (progn
          (unquote
            (cons
              progn
              (map-with
                (lambda (slot) (list .= (quote this) slot slot))
                (second args))))
          (freeze this))))))