Speaking of setf-like macros, there's something that bothers me about Common Lisp's define-modify-macro
: most of its uses are very predictable. Alexandria, for example, contains at least five of them: minf
, maxf
, appendf
, removef
, and deletef
. Except for argument order, all five are identical macroifications of standard functions. From their names, you can predict not only their meanings but their whole implementations.
This is not a good sign. Rather than trying to define a modify macro for each function, wouldn't it be better to just have one modify macro which takes a function as a parameter?
(defmacro modify (fn place &rest args &environment e)
(expand-setf (v r w) place e
`(let ((,v (,fn ,r ,@args)))
,w)))
So instead of (define-modify-macro foof (args ...) foo)
and (foof place args ...)
, you'd write (modify foo place args ...)
. This could make most modify macros unnecessary, although it would need a shorter name, perhaps even one as short as !
. However, its usefulness depends heavily on having functions available with the right argument order. If you have to fiddle with the function to fix its argument order, modify
loses its brevity, and you might as well write out the setf
.
Indeed, why not +f, -f, *f, /f, modf, remf, bit-and-f, bit-ior-f, bit-xor-f, ashf, like C? Andf and orf are common in other languages (orf is often used in Perl to set a default). There is no end to these things: wherever you have a function of type A -> B -> A (possibly with more arguments), a define-modify-macro is lurking around the corner.
ReplyDelete