Structs in Lisp

Our chosen language is Lisp. The code example demonstrates how to use structs to group data together. Here’s the full translation:

Go’s structs are typed collections of fields. They’re useful for grouping data together to form records.

(defstruct person
  name
  age)

new-person constructs a new person struct with the given name.

(defun new-person (name)
  (let ((p (make-person :name name)))
    (setf (person-age p) 42)
    p))

This function safely returns a pointer to a local variable. It will only be cleaned up by the garbage collector when there are no active references to it.

(defun main ()
  ;; This syntax creates a new struct.
  (format t "~a~%" (make-person :name "Bob" :age 20))
  ;; You can name the fields when initializing a struct.
  (format t "~a~%" (make-person :name "Alice" :age 30))
  ;; Omitted fields will be zero-valued.
  (format t "~a~%" (make-person :name "Fred"))
  ;; An & prefix yields a pointer to the struct.
  (format t "~a~%" (copy-struct (make-person :name "Ann" :age 40)))
  ;; It’s idiomatic to encapsulate new struct creation in constructor functions.
  (format t "~a~%" (new-person "Jon"))

  ;; Access struct fields with a dot.
  (let ((s (make-person :name "Sean" :age 50)))
    (format t "~a~%" (person-name s))
    ;; You can also use dots with struct pointers.
    (let ((sp s))
      (format t "~a~%" (person-age sp))
      ;; Structs are mutable.
      (setf (person-age sp) 51)
      (format t "~a~%" (person-age sp))))

  ;; If a struct type is only used for a single value, we don’t have to give it a name.
  (let ((dog (make-struct :name "Rex" :is-good t)))
    (format t "~a~%" dog)))

To run the program, execute the main function.

(main)

This will output:

#S(PERSON :NAME "Bob" :AGE 20)
#S(PERSON :NAME "Alice" :AGE 30)
#S(PERSON :NAME "Fred" :AGE 0)
#S(PERSON :NAME "Ann" :AGE 40)
#S(PERSON :NAME "Jon" :AGE 42)
Sean
50
51
#S((:NAME "Rex" :IS-GOOD T))

Now that we can run and build basic Lisp programs, let’s learn more about the language.