all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* oref* and with-slots* macros
@ 2018-05-26 10:26 Adam Porter
  0 siblings, 0 replies; only message in thread
From: Adam Porter @ 2018-05-26 10:26 UTC (permalink / raw)
  To: emacs-devel

Hi,

I came up with these EIEIO-related macros a while back to help the
clarity of some code I was writing.  They seem generally useful enough
that I think it would be good to add them to Emacs itself, rather than
distributing them in a package on ELPA or MELPA.

+ `oref*' accesses slots of nested EIEIO objects.  For example, instead of:

        (oref (oref room :connection) :connect-time)

    You can write:

        (oref* room :connection :connect-time)

+ `with-slots*' allows access to nested EIEIO objects' slots.  For
  example, instead of:

        (with-slots (id session) room
          (with-slots (user) session
            user))

    You can write:

        (with-slots* (((id session) room)
                      ((user) session))
                     user)

    This is also possible using `pcase-let*` with its "eieio" type, but
    `with-slots*' is a bit simpler when only accessing object slots.

The source for these macros is below.  If the Emacs devs agree that
these should be added, I'll be happy to submit a patch with whatever
changes are desired.

Thanks,
Adam Porter

#+BEGIN_SRC elisp
(defmacro oref* (&rest slots)
  "Access SLOTS of nested EIEIO objects.
The first of SLOTS should be an object, while the rest should be
slot symbols.  Accessing each slot should return an object for
which the next slot is valid, except for the last slot, which may
return any value."
  (cl-labels ((rec (slots)
                   `(oref ,(if (and (consp (cdr slots))
                                    (cddr slots))
                               (rec (cdr slots))
                             (cadr slots))
                          ,(car slots))))
    (rec (nreverse slots))))

(defmacro with-slots* (slots-objects &rest body)
  "Access slots of nested objects, evaluating BODY.
Creates nested `with-slots' forms, so each slot is a generalized
variable.  For example:

\(with-slots* (((id session) room)
              ((user) session))
             user)

Is transformed to:

\(with-slots (id session) room
  (with-slots (user) session
    user))"
  (declare (indent defun))
  (cl-loop for (slots object) in (nreverse slots-objects)
           do (setq body `((with-slots ,slots ,object ,@body)))
           finally return (car body)))
#+END_SRC



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2018-05-26 10:26 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-05-26 10:26 oref* and with-slots* macros Adam Porter

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.