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 like defmacro, but has several advantages. See Info node (elisp)Defining Functions for more details.

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 like `defmacro', but has several advantages.
See Info node `(elisp)Defining Functions' for more details."
  ;; FIXME: How can this work with CL arglists?
  (declare (indent defun) (debug defun) (doc-string 3))
  (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)))
        (bodyexp (macroexp-progn body)))
    ;; 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 (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)))
       :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))))))))