elisp: Setting Generalized Variables

 
 11.15.1 The ‘setf’ Macro
 ------------------------
 
 The ‘setf’ macro is the most basic way to operate on generalized
 variables.  The ‘setf’ form is like ‘setq’, except that it accepts
 arbitrary place forms on the left side rather than just symbols.  For
 example, ‘(setf (car a) b)’ sets the car of ‘a’ to ‘b’, doing the same
 operation as ‘(setcar a b)’, but without having to remember two separate
 functions for setting and accessing every type of place.
 
  -- Macro: setf [place form]...
      This macro evaluates FORM and stores it in PLACE, which must be a
      valid generalized variable form.  If there are several PLACE and
      FORM pairs, the assignments are done sequentially just as with
      ‘setq’.  ‘setf’ returns the value of the last FORM.
 
    The following Lisp forms will work as generalized variables, and so
 may appear in the PLACE argument of ‘setf’:
 
    • A symbol naming a variable.  In other words, ‘(setf x y)’ is
      exactly equivalent to ‘(setq x y)’, and ‘setq’ itself is strictly
      speaking redundant given that ‘setf’ exists.  Many programmers
      continue to prefer ‘setq’ for setting simple variables, though,
      purely for stylistic or historical reasons.  The macro ‘(setf x y)’
      actually expands to ‘(setq x y)’, so there is no performance
      penalty for using it in compiled code.
 
    • A call to any of the following standard Lisp functions:
 
           aref      cddr      symbol-function
           car       elt       symbol-plist
           caar      get       symbol-value
           cadr      gethash
           cdr       nth
           cdar      nthcdr
 
    • A call to any of the following Emacs-specific functions:
 
           alist-get                     process-get
           frame-parameter               process-sentinel
           terminal-parameter            window-buffer
           keymap-parent                 window-display-table
           match-data                    window-dedicated-p
           overlay-get                   window-hscroll
           overlay-start                 window-parameter
           overlay-end                   window-point
           process-buffer                window-start
           process-filter                default-value
 
 ‘setf’ signals an error if you pass a PLACE form that it does not know
 how to handle.
 
    Note that for ‘nthcdr’, the list argument of the function must itself
 be a valid PLACE form.  For example, ‘(setf (nthcdr 0 foo) 7)’ will set
 ‘foo’ itself to 7.
 
DONTPRINTYET     The macros ‘push’ (SeeList Variables) and ‘pop’ (*noteList
DONTPRINTYET     The macros ‘push’ (SeeList Variables) and ‘pop’ (SeeList

 Elements) can manipulate generalized variables, not just lists.  ‘(pop
 PLACE)’ removes and returns the first element of the list stored in
 PLACE.  It is analogous to ‘(prog1 (car PLACE) (setf PLACE (cdr
 PLACE)))’, except that it takes care to evaluate all subforms only once.
 ‘(push X PLACE)’ inserts X at the front of the list stored in PLACE.  It
 is analogous to ‘(setf PLACE (cons X PLACE))’, except for evaluation of
 the subforms.  Note that ‘push’ and ‘pop’ on an ‘nthcdr’ place can be
 used to insert or delete at any position in a list.
 
    The ‘cl-lib’ library defines various extensions for generalized
 variables, including additional ‘setf’ places.  See(cl)Generalized
 Variables.