Function: oclosure-lambda

oclosure-lambda is a macro defined in oclosure.el.gz.

Signature

(oclosure-lambda TYPE-AND-SLOTS ARGS &rest BODY)

Documentation

Define anonymous OClosure function.

TYPE-AND-SLOTS should be of the form (TYPE . SLOTS) where TYPE is an OClosure type name (defined by oclosure-define) and SLOTS is a let-style list of bindings for the various slots of TYPE. ARGS and BODY are the same as for lambda.

View in manual

Probably introduced at or before Emacs version 29.1.

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/oclosure.el.gz
(defmacro oclosure-lambda (type-and-slots args &rest body)
  "Define anonymous OClosure function.
TYPE-AND-SLOTS should be of the form (TYPE . SLOTS)
where TYPE is an OClosure type name (defined by `oclosure-define')
and SLOTS is a let-style list of bindings for the various slots of TYPE.
ARGS and BODY are the same as for `lambda'."
  (declare (indent 2) (debug ((sexp &rest (sexp form)) sexp def-body)))
  ;; FIXME: Should `oclosure-define' distinguish "optional" from
  ;; "mandatory" slots, and/or provide default values for slots missing
  ;; from `fields'?
  (pcase-let*
      ((`(,type . ,fields) type-and-slots)
       (class (or (cl--find-class type)
                  (error "Unknown class: %S" type)))
       (slots (oclosure--class-slots class))
       (mutables '())
       (slotbinds (mapcar (lambda (slot)
                            (let ((name (cl--slot-descriptor-name slot)))
                              (when (oclosure--slot-mutable-p slot)
                                (push name mutables))
                              (list name)))
                          slots))
       (tempbinds (mapcar
                   (lambda (field)
                     (let* ((name (car field))
                            (bind (assq name slotbinds)))
                       (cond
                        ;; FIXME: Should we also warn about missing slots?
                        ((not bind)
                         (error "Unknown slot: %S" name))
                        ((cdr bind)
                         (error "Duplicate slot: %S" name))
                        (t
                         (let ((temp (gensym "temp")))
                           (setcdr bind (list temp))
                           (cons temp (cdr field)))))))
                   fields)))
    ;; FIXME: Optimize temps away when they're provided in the right order?
    `(let ,tempbinds
       (oclosure--lambda ',type ,slotbinds ,mutables ,args ,@body))))