File: inline.el.html
This package provides the macro define-inline which lets you define
functions by defining their (exhaustive) compiler macro.
The idea is that instead of doing like defsubst and cl-defsubst (i.e. from
the function's definition, guess the best way to inline the function),
we go the other way around: the programmer provides the code that does the
inlining (as a compiler-macro) and from that we derive the definition of the
function itself. The idea originated in an attempt to clean up cl-typep,
whose function definition amounted to (eval (cl--make-type-test EXP TYPE)).
The simplest use is for plain and simple inlinable functions. Rather than:
(defmacro myaccessor (obj)
(macroexp-let2 macroexp-copyable-p obj obj
(if (foop ,obj) (aref (cdr ,obj) 3) (aref ,obj 2))))
Or
(defsubst myaccessor (obj)
(if (foop obj) (aref (cdr obj) 3) (aref obj 2)))
Or
(cl-defsubst myaccessor (obj)
(if (foop obj) (aref (cdr obj) 3) (aref obj 2)))
Youd do
(define-inline myaccessor (obj)
(inline-letevals (obj)
(inline-quote (if (foop ,obj) (aref (cdr ,obj) 3) (aref ,obj 2)))))
Other than verbosity, you get the best of all 3 above without their
respective downsides:
- defmacro: can't be passed to mapcar since it's not a function.
- defsubst: not as efficient, and doesn't work as a gv place.
- cl-defsubst: only works by accident, since it has latent bugs in its
handling of variables and scopes which could bite you at any time.
(e.g. try (cl-defsubst my-test1 (x) (let ((y 5)) (+ x y)))
and then M-: (macroexpand-all '(my-test1 y)) RET)
There is still one downside shared with the defmacro and cl-defsubst
approach: when the function is inlined, the scoping rules (dynamic or
lexical) will be inherited from the call site.
Of course, since define-inline defines a compiler macro, you can also do
call-site optimizations, just like you can with defmacro, but not with
defsubst nor cl-defsubst.
Defined variables (0)
Defined functions (20)
define-inline | (NAME ARGS &rest BODY) |
inline--alwaysconst-p | (EXP) |
inline--alwaysconst-val | (EXP) |
inline--do-leteval | (VAR-EXP &rest BODY) |
inline--do-letlisteval | (LISTVAR &rest BODY) |
inline--do-quote | (EXP) |
inline--dont-leteval | (VAR-EXP &rest BODY) |
inline--dont-letlisteval | (LISTVAR &rest BODY) |
inline--dont-quote | (EXP) |
inline--error | (&rest ARGS) |
inline--getconst-val | (EXP) |
inline--leteval | (VAR-EXP &rest BODY) |
inline--letlisteval | (LIST &rest BODY) |
inline--testconst-p | (EXP) |
inline--warning | (&rest ARGS) |
inline-const-p | (EXP) |
inline-const-val | (EXP) |
inline-error | (FORMAT &rest ARGS) |
inline-letevals | (VARS &rest BODY) |
inline-quote | (EXP) |