gnu.org (original) (raw)
12.17.2 Defining new setf
forms
This section describes how to define new forms that setf
can operate on.
Macro: gv-define-simple-setter name setter &optional fix-return ¶
This macro enables you to easily define setf
methods for simple cases. name is the name of a function, macro, or special form. You can use this macro whenever name has a directly corresponding setter function that updates it, e.g.,(gv-define-simple-setter car setcar)
.
This macro translates a call of the form
(setf (name args…) value)
into
Such a setf
call is documented to return value. This is no problem with, e.g., car
and setcar
, becausesetcar
returns the value that it set. If your setterfunction does not return value, use a non-nil
value for the fix-return argument of gv-define-simple-setter
. This expands into something equivalent to
(let ((temp value)) (setter args… temp) temp)
so ensuring that it returns the correct result.
Macro: gv-define-setter name arglist &rest body ¶
This macro allows for more complex setf
expansions than the previous form. You may need to use this form, for example, if there is no simple setter function to call, or if there is one but it requires different arguments to the place form.
This macro expands the form(setf (name args…) value)
by first binding the setf
argument forms(value args…)
according to arglist, and then executing body. body should return a Lisp form that does the assignment, and finally returns the value that was set. An example of using this macro is:
(gv-define-setter caar (val x) `(setcar (car ,x) ,val))
Macro: gv-define-expander name handler ¶
For more control over the expansion, the gv-define-expander
macro can be used. For instance, a settable substring
could be implemented this way:
(gv-define-expander substring
(lambda (do place from &optional to)
(gv-letplace (getter setter) place
(macroexp-let2* (from to)
(funcall do (substring ,getter ,from ,to) (lambda (v) (macroexp-let2* (v)
(progn
,(funcall setter `(cl--set-substring
,getter ,from ,to ,v))
,v))))))))
Macro: gv-letplace (getter setter) place &rest body ¶
The macro gv-letplace
can be useful in defining macros that perform similarly to setf
; for example, the incf
macro of Common Lisp could be implemented this way:
(defmacro incf (place &optional n) (gv-letplace (getter setter) place (macroexp-let2* ((v (or n 1))) (funcall setter `(+ ,v ,getter)))))
getter will be bound to a copyable expression that returns the value of place. setter will be bound to a function that takes an expression v and returns a new expression that setsplace to v. body should return a Emacs Lisp expression manipulating place via getter and setter.
Consult the source file gv.el for more details.
Function: make-obsolete-generalized-variable obsolete-name current-name when ¶
This function makes the byte compiler warn that the generalized variable obsolete-name is obsolete. If current-name is a symbol, then the warning message says to use current-nameinstead of obsolete-name. If current-name is a string, this is the message. when should be a string indicating when the variable was first made obsolete (usually a version number string).
Common Lisp note: Common Lisp defines another way to specify the
setf
behavior of a function, namelysetf
functions, whose names are lists(setf name)
rather than symbols. For example,(defun (setf foo) …)
defines the function that is used whensetf
is applied tofoo
. Emacs does not support this. It is a compile-time error to usesetf
on a form that has not already had an appropriate expansion defined. In Common Lisp, this is not an error since the function(setffunc)
might be defined later.