Lisp - Structure Options



LISP provides multiple options while creating a structure using defstruct to control the structure's behavior and characteristics. In this chapter, we're discussing various options available to customize structures to tailor our needs.

:constructor

constructor function is used to create instance of a structure. Using :constructor option, we can control the generation and behavior of a constructor. We can choose a different name, provide arguments which a constructor to accept and so on.

Example - Define Constructor with arguments

main.lisp

; define a structure point with constructor name as make-point 
; accepting two arguments
(defstruct (point (:constructor make-point (x y))) x y)

; create a point instance
(setq point1 (make-point 10 20))

; get and print the value of x and y
(print(point-x point1))
(print(point-y point1))

Output

When you execute the code, it returns the following result −

10
20

:predicate

predicate function is used to check if a structure is of given type. Using :predicate option, we can define a custom name for the predicate function.

Example - Define Predicate with arguments

main.lisp

; define a structure point with predicate function
(defstruct (point (:predicate pointp)))

; create a point instance
(setq point1 (make-point))

; check if point1 is instance of point struture
(print(pointp point1))

Output

When you execute the code, it returns the following result −

T

:copier

copier function is used to create a copy of structure. Using :copier option, we can define a custom name for the copier function.

Example - Define Copier with arguments

main.lisp

; define a structure point with copier function
(defstruct (point (:copier copy-point)))

; create a point instance
(setq point1 (make-point))

; create a copy of point1
(setq point2 (copy-point point1))

; check if point2 is instance of point struture
(print(point-p point2))

Output

When you execute the code, it returns the following result −

T

:print-function

print function is used to print a structure. Using :print-function option, we can define a custom printer function for the structure.

Example - Define print-function

main.lisp

(defstruct (point (:constructor make-point (x y) :print-function print-point))
   x y)

(defun print-point (p)
   (format t "#POINT (~a, ~a)" (point-x p) (point-y p)))

; create a point instance
(setq point1 (make-point 10 20))

; print point 1
(print-point point1)	

Output

When you execute the code, it returns the following result −

#POINT (10, 20)

:include

include option allows to inherit slots of another struture.

Example - Inheritance using include option

main.lisp

; define a structure shape
(defstruct shape color)

; define a structure circle with slots of shape
(defstruct (circle (:include shape)) radius)	

; create and assign a structure to circle
( setq circle1 (make-circle :radius 10
   :color "red"))

; print circle structure
(write circle1)

Output

When you execute the code, it returns the following result −

#S(CIRCLE :COLOR "red" :RADIUS 10)

:type

type option allows to specify underlying data type of the structure, for example, vector.

Example - Setting Type

main.lisp

; define a point of type vector
(defstruct (point (:type vector)) x y)

; create a point instance
(setq point1 (make-point))

; print type of point
(write (type-of point1))

Output

When you execute the code, it returns the following result −

(SIMPLE-VECTOR 2)

These options provides developers a fine-grained control on how a LISP struture is created and used.

Advertisements