File: gv.el.html

This is a re-implementation of the setf machinery using a different underlying approach from the one used earlier in CL, which was based on define-setf-expander. define-setf-expander makes every "place-expander" return a 5-tuple
  (VARS VALUES STORES GETTER SETTER)
where STORES is a list with a single variable (Common-Lisp allows multiple variables for use with multiple-return-values, but this is rarely used and not applicable to Elisp). It basically says that GETTER is an expression that returns the place's value, and (lambda STORES SETTER) is an expression that assigns the value(s) passed to that function to the place, and that you need to wrap the whole thing within a `(let* ,(zip VARS VALUES) ...).

Instead, we use here a higher-order approach: instead of a 5-tuple, a place-expander returns a function. If you think about types, the old approach returns things of type
   {vars: List Var, values: List Exp,
    stores: List Var, getter: Exp, setter: Exp}
whereas the new approach returns a function of type
   (do: ((getter: Exp, setter: ((store: Exp) -> Exp)) -> Exp)) -> Exp.
You can get the new function from the old 5-tuple with something like:
   (lambda (do)
      (let* ,(zip VARS VALUES)
         (funcall do GETTER (lambda ,STORES ,SETTER))))
You cant easily do the reverse, because this new approach is more expressive than the old one, so we can't provide a backward-compatible get-setf-method.

While it may seem intimidating for people not used to higher-order functions, you will quickly see that its use (especially with the gv-letplace macro) is actually much easier and more elegant than the old approach which is clunky and often leads to unreadable code.

Food for thought: the syntax of places does not actually conflict with the pcase patterns. The cons gv works just like a `(,a . ,b) pcase pattern, and actually the logand gv is even closer since it should arguably fail when trying to set a value outside of the mask. Generally, places are used for destructors (gethash, aref, car, ...) whereas pcase patterns are used for constructors (backquote, constants, vectors, ...).

Defined variables (0)

Defined functions (19)

decf(PLACE &optional DELTA)
gv--defsetter(NAME SETTER DO ARGS &optional VARS)
gv--defun-declaration(SYMBOL NAME ARGS HANDLER &optional FIX)
gv--expander-defun-declaration(&rest ARGS)
gv--setter-defun-declaration(&rest ARGS)
gv-define-expander(NAME HANDLER)
gv-define-setter(NAME ARGLIST &rest BODY)
gv-define-simple-setter(NAME SETTER &optional FIX-RETURN)
gv-delay-error(PLACE)
gv-deref(REF)
gv-get(PLACE DO)
gv-letplace((GETTER SETTER) PLACE &rest BODY)
gv-ref(PLACE)
gv-setter(NAME)
gv-synthetic-place(GETTER SETTER)
gv-synthetic-place--anon-cmacro(_ GETTER SETTER)
incf(PLACE &optional DELTA)
make-obsolete-generalized-variable(OBSOLETE-NAME CURRENT-NAME WHEN)
setf(PLACE VAL PLACE VAL ...)

Defined faces (0)