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 .