Function: oclosure-define

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

Signature

(oclosure-define NAME &optional DOCSTRING &rest SLOTS)

Documentation

Define a new OClosure type.

NAME should be a symbol which is the name of the new type. It can also be of the form (NAME . PROPS) in which case PROPS is a list of additional properties among the following:
  (:predicate PRED): asks to create a predicate function named PRED.
  (:parent TYPE): make TYPE (another OClosure type) be a parent of NAME.
  (:copier COPIER ARGS): asks to create a "copier" (i.e. functional update
    function) named COPIER. It will take an object of type NAME as first
    argument followed by ARGS. ARGS lists the names of the slots that will
    be updated with the value of the corresponding argument.
SLOTS is a list of slot descriptions. Each slot can be a single symbol which is the name of the slot, or it can be of the form (SLOT-NAME . SPROPS) where SLOT-NAME is then the name of the slot and SPROPS is a property list of slot properties. The currently known properties are the following:
  :mutable: A non-nil value mean the slot can be mutated.
  :type: Specifies the type of the values expected to appear in the slot.

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-define (name &optional docstring &rest slots)
  "Define a new OClosure type.
NAME should be a symbol which is the name of the new type.
It can also be of the form (NAME . PROPS) in which case PROPS
is a list of additional properties among the following:
  (:predicate PRED): asks to create a predicate function named PRED.
  (:parent TYPE): make TYPE (another OClosure type) be a parent of NAME.
  (:copier COPIER ARGS): asks to create a \"copier\" (i.e. functional update
    function) named COPIER.  It will take an object of type NAME as first
    argument followed by ARGS.  ARGS lists the names of the slots that will
    be updated with the value of the corresponding argument.
SLOTS is a list of slot descriptions.  Each slot can be a single symbol
which is the name of the slot, or it can be of the form (SLOT-NAME . SPROPS)
where SLOT-NAME is then the name of the slot and SPROPS is a property
list of slot properties.  The currently known properties are the following:
  `:mutable': A non-nil value mean the slot can be mutated.
  `:type': Specifies the type of the values expected to appear in the slot."
  (declare (doc-string 2) (indent 1))
  (unless (or (stringp docstring) (null docstring))
    (push docstring slots)
    (setq docstring nil))
  (let* ((options (when (consp name)
                    (prog1 (copy-sequence (cdr name))
                      (setq name (car name)))))
         (get-opt (lambda (opt &optional all)
                    (let ((val (assq opt options))
                          tmp)
                      (when val (setq options (delq val options)))
                      (if (not all)
                          (cdr val)
                        (when val
                          (setq val (list (cdr val)))
                          (while (setq tmp (assq opt options))
                            (push (cdr tmp) val)
                            (setq options (delq tmp options)))
                          (nreverse val))))))
         (predicate (car (funcall get-opt :predicate)))
         (parent-names (or (funcall get-opt :parent)
                           (funcall get-opt :include)))
         (copiers (funcall get-opt :copier 'all)))
    `(progn
       ,(when options (macroexp-warn-and-return name
                       (format "Ignored options: %S" options)
                       nil))
       (eval-and-compile
         (oclosure--define ',name ,docstring ',parent-names ',slots
                           ,@(when predicate `(:predicate ',predicate))))
       (oclosure--define-functions ,name ,copiers))))