3

When developing with Common Lisp, we have three possibilities to define new setf-forms:

  • We can define a function whose name is a list of two symbols, the first one being setf, e.g. (defun (setf some-observable) (…)).

  • We can use the short form of defsetf.

  • We can use the long form of defsetf.

  • We can use define-setf-expander.

I am not sure what is the right or intended use-case for each of these possibilities.

A response to this question could hint at the most generic solution and outline contexts where other solutions are superior.

Michaël Le Barbier
  • 6,103
  • 5
  • 28
  • 57

1 Answers1

5

define-setf-expander is the most general of these. All of setf's functionality is encompassed by it.

Defining a setf function works fine for most accessors. It is also valid to use a generic function, so polymorphism is insufficient to require using something else. Controlling evaluation either for correctness or performance is the main reason to not use a setf function.

For correctness, many forms of destructuring are not possible to do with a setf function (e.g. (setf (values ...) ...)). Similarly I've seen an example that makes functional data structures behave locally like a mutable one by changing (setf (dict-get key some-dict) 2) to assign a new dictionary to some-dict.

For performance, consider the silly case of (incf (nth 10000 list)) which if the nth writer were implemented as a function would require traversing 10k list nodes twice, but in a setf expander can be done with a single traversal.

Jason
  • 1,059
  • 9
  • 13