Function: define-inline

define-inline is an autoloaded macro defined in inline.el.gz.

Signature

(define-inline NAME ARGS &rest BODY)

Documentation

Define an inline function NAME with arguments ARGS and body in BODY.

This is halfway between defmacro and defun. BODY is used as a blueprint both for the body of the function and for the body of the compiler-macro used to generate the code inlined at each call site. See Info node (elisp)Inline Functions for more details.

A (noinline t) in the `declare form prevents the definition of the compiler macro. This is for the rare case in which you want to use this macro to define a function that should not be inlined.

View in manual

Probably introduced at or before Emacs version 25.1.

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/inline.el.gz
;; (defmacro inline-if (testfun testexp then else)
;;   (declare (indent 2) (debug (sexp symbolp form form)))
;;   (macroexp-let2 macroexp-copyable-p testsym testexp
;;     `(if (inline-const-p ,testexp)
;;          (if (,testfun (inline-const-val ,testexp)) ,then ,else)
;;        (inline-quote (if (,testfun ,testexp) ,(list '\, then)
;;                         ,(list '\, else))))))

;;;###autoload
(defmacro define-inline (name args &rest body)
  "Define an inline function NAME with arguments ARGS and body in BODY.
This is halfway between `defmacro' and `defun'.  BODY is used as a blueprint
both for the body of the function and for the body of the compiler-macro
used to generate the code inlined at each call site.
See Info node `(elisp)Inline Functions for more details.

A (noinline t) in the `declare' form prevents the definition of the
compiler macro.  This is for the rare case in which you want to use this
macro to define a function that should not be inlined."
  ;; FIXME: How can this work with CL arglists?
  (declare (indent defun) (debug defun) (doc-string 3)
           (autoload-macro expand)) ; expand to the defun on autoload gen
  (let* ((doc (if (stringp (car-safe body)) (list (pop body))))
         (declares (if (eq (car-safe (car-safe body)) 'declare) (pop body)))
         (cm-name (intern (format "%s--inliner" name)))
         (noinline-decl (assq 'noinline declares))
         (inline (not (cadr noinline-decl)))
         (bodyexp (macroexp-progn body)))
    (when noinline-decl
      (setq declares (delq noinline-decl declares)))
    ;; If the function is autoloaded then when we load the .el file, the
    ;; `compiler-macro' property is already set (from loaddefs.el) and might
    ;; hence be called during the macroexpand-all calls below (if the function
    ;; is recursive).
    ;; So we disable any pre-loaded compiler-macro setting to avoid this.
    (function-put name 'compiler-macro nil)
    `(progn
       (defun ,name ,args
         ,@doc
         (declare ,@(when inline `((compiler-macro ,cm-name)))
                  ,@(cdr declares))
         ,(macroexpand-all bodyexp
                           `((inline-quote . inline--dont-quote)
                             ;; (inline-\` . inline--dont-quote)
                             (inline--leteval . inline--dont-leteval)
                             (inline--letlisteval . inline--dont-letlisteval)
                             (inline-const-p . inline--alwaysconst-p)
                             (inline-const-val . inline--alwaysconst-val)
                             (inline-error . inline--error)
                             ,@macroexpand-all-environment)))
       ,@(when inline
           `(:autoload-end
             (eval-and-compile
               (defun ,cm-name ,(cons 'inline--form args)
                 (ignore inline--form)  ;In case it's not used!
                 (catch 'inline--just-use
                   ,(macroexpand-all
                     bodyexp
                     `((inline-quote . inline--do-quote)
                       ;; (inline-\` . inline--do-quote)
                       (inline--leteval . inline--do-leteval)
                       (inline--letlisteval
                        . inline--do-letlisteval)
                       (inline-const-p . inline--testconst-p)
                       (inline-const-val . inline--getconst-val)
                       (inline-error . inline--warning)
                       ,@macroexpand-all-environment))))))))))