diff options
| author | Stefan Monnier | 2024-03-11 16:12:26 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2024-04-18 15:28:36 -0400 |
| commit | 126be02077520a943252d0d219bb7677466d0168 (patch) | |
| tree | f762237714f11b303c708f93f09a8dc72426bb2a /doc/lispref/functions.texi | |
| parent | 7842af6095db4384898725fb4a14ebaa11379a34 (diff) | |
| download | emacs-scratch/interpreted-function.tar.gz emacs-scratch/interpreted-function.zip | |
Use a dedicated type to represent interpreted-function valuesscratch/interpreted-function
Change `function` so that when evaluating #'(lambda ...)
we return an object of type `interpreted-function` rather than
a list starting with one of `lambda` or `closure`.
The new type reuses the existing PVEC_CLOSURE (nee PVEC_COMPILED)
tag and tries to align the corresponding elements:
- the arglist, the docstring, and the interactive-form go in the
same slots as for byte-code functions.
- the body of the function goes in the slot used for the bytecode string.
- the lexical context goes in the slot used for the constants of
bytecoded functions.
The first point above means that `help-function-arglist`,
`documentation`, and `interactive-form`s don't need to
distinguish interpreted and bytecode functions any more.
Main benefits of the change:
- We can now reliably distinguish a list from a function value.
- `cl-defmethod` can dispatch on `interactive-function` and `closure`.
Dispatch on `function` also works now for interpreted functions but still
won't work for functions represented as lists or as symbols, of course.
- Function values are now self-evaluating. That was alrready the case
when byte-compiled, but not when interpreted since
(eval '(closure ...)) signals a void-function error.
That also avoids false-positive warnings about "don't quote your lambdas"
when doing things like `(mapcar ',func ...)`.
* src/eval.c (Fmake_interpreted_closure): New function.
(Ffunction): Use it and change calling convention of
`Vinternal_make_interpreted_closure_function`.
(FUNCTIONP, Fcommandp, eval_sub, funcall_general, funcall_lambda)
(Ffunc_arity, lambda_arity): Simplify.
(funcall_lambda): Adjust to new representation.
(syms_of_eval): `defsubr` the new function. Remove definition of `Qclosure`.
* lisp/emacs-lisp/cconv.el (cconv-make-interpreted-closure):
Change calling convention and use `make-interpreted-closure`.
* src/data.c (Fcl_type_of): Distinguish `byte-code-function`s from
`interpreted-function`s.
(Fclosurep, finterpreted_function_p): New functions.
(Fbyte_code_function_p): Don't be confused by `interpreted-function`s.
(Finteractive_form, Fcommand_modes): Simplify.
(syms_of_data): Define new type symbols and `defsubr` the two
new functions.
* lisp/emacs-lisp/cl-print.el (cl-print-object) <interpreted-function>:
New method.
* lisp/emacs-lisp/oclosure.el (oclosure): Refine the parent
to be `closure`.
(oclosure--fix-type, oclosure-type): Simplify.
(oclosure--copy, oclosure--get, oclosure--set): Adjust to
new representation.
* src/callint.c (Fcall_interactively): Adjust to new representation.
* src/lread.c (bytecode_from_rev_list):
* lisp/simple.el (function-documentation):
* lisp/help.el (help-function-arglist): Remove the old `closure` case
and adjust the byte-code case so it handles `interpreted-function`s.
* lisp/emacs-lisp/cl-preloaded.el (closure): New type.
(byte-code-function): Add it as a parent.
(interpreted-function): Adjust parent (the type itself was already
added earlier by accident).
* lisp/emacs-lisp/bytecomp.el (byte-compile--reify-function): Adjust to
new representation.
(byte-compile): Use `interpreted-function-p`.
* lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand): Adjust to
new representation.
(side-effect-free-fns): Add `interpreted-function-p` and `closurep`.
* src/profiler.c (trace_hash, ffunction_equal): Simplify.
* lisp/profiler.el (profiler-function-equal): Simplify.
* lisp/emacs-lisp/nadvice.el (advice--interactive-form-1):
Use `interpreted-function-p`; adjust to new representation; and take
advantage of the fact that function values are now self-evaluating.
* lisp/emacs-lisp/lisp-mode.el (closure):
Remove `lisp-indent-function` property.
* lisp/emacs-lisp/disass.el (disassemble-internal): Adjust to
new representation.
* lisp/emacs-lisp/edebug.el (edebug--strip-instrumentation):
Use `interpreted-function-p`.
* lisp/emacs-lisp/comp-common.el (comp-known-type-specifiers):
Add `closurep` and `interpreted-function-p`.
* test/lisp/help-fns-tests.el (help-fns-test-lisp-defun): Adjust to
more precise type info in `describe-function`.
* test/lisp/erc/resources/erc-d/erc-d-tests.el (erc-d--render-entries):
Use `interpreted-function-p`.
* test/lisp/emacs-lisp/macroexp-resources/vk.el (vk-f4, vk-f5):
Don't hardcode function values.
* doc/lispref/functions.texi (Anonymous Functions): Don't suggest that
function values are lists. Reword "self-quoting" to reflect the
fact that #' doesn't return the exact same object. Update examples
with the new shape of the return value.
* doc/lispref/variables.texi (Lexical Binding):
* doc/lispref/lists.texi (Rearrangement):
* doc/lispref/control.texi (Handling Errors): Update examples to reflect
new representation of function values.
Diffstat (limited to 'doc/lispref/functions.texi')
| -rw-r--r-- | doc/lispref/functions.texi | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index ff635fc54b2..c57de08460f 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi | |||
| @@ -130,7 +130,7 @@ it also encloses an environment of lexical variable bindings. | |||
| 130 | 130 | ||
| 131 | @item byte-code function | 131 | @item byte-code function |
| 132 | A function that has been compiled by the byte compiler. | 132 | A function that has been compiled by the byte compiler. |
| 133 | @xref{Byte-Code Type}. | 133 | @xref{Closure Type}. |
| 134 | 134 | ||
| 135 | @item autoload object | 135 | @item autoload object |
| 136 | @cindex autoload object | 136 | @cindex autoload object |
| @@ -227,6 +227,16 @@ Compilation}), or natively-compiled (@pxref{Native Compilation}), or | |||
| 227 | a function loaded from a dynamic module (@pxref{Dynamic Modules}). | 227 | a function loaded from a dynamic module (@pxref{Dynamic Modules}). |
| 228 | @end defun | 228 | @end defun |
| 229 | 229 | ||
| 230 | @defun interpreted-function-p object | ||
| 231 | This function returns @code{t} if @var{object} is an interpreted function. | ||
| 232 | @end defun | ||
| 233 | |||
| 234 | @defun closurep object | ||
| 235 | This function returns @code{t} if @var{object} is a closure, which is | ||
| 236 | a particular kind of function object. Currently closures are used | ||
| 237 | for all byte-code functions and all interpreted functions. | ||
| 238 | @end defun | ||
| 239 | |||
| 230 | @defun subr-arity subr | 240 | @defun subr-arity subr |
| 231 | This works like @code{func-arity}, but only for built-in functions and | 241 | This works like @code{func-arity}, but only for built-in functions and |
| 232 | without symbol indirection. It signals an error for non-built-in | 242 | without symbol indirection. It signals an error for non-built-in |
| @@ -1136,8 +1146,7 @@ Functions}). @xref{describe-symbols example}, for a realistic example | |||
| 1136 | of this. | 1146 | of this. |
| 1137 | 1147 | ||
| 1138 | When defining a lambda expression that is to be used as an anonymous | 1148 | When defining a lambda expression that is to be used as an anonymous |
| 1139 | function, you can in principle use any method to construct the list. | 1149 | function, you should use the @code{lambda} macro, or the |
| 1140 | But typically you should use the @code{lambda} macro, or the | ||
| 1141 | @code{function} special form, or the @code{#'} read syntax: | 1150 | @code{function} special form, or the @code{#'} read syntax: |
| 1142 | 1151 | ||
| 1143 | @defmac lambda args [doc] [interactive] body@dots{} | 1152 | @defmac lambda args [doc] [interactive] body@dots{} |
| @@ -1145,17 +1154,18 @@ This macro returns an anonymous function with argument list | |||
| 1145 | @var{args}, documentation string @var{doc} (if any), interactive spec | 1154 | @var{args}, documentation string @var{doc} (if any), interactive spec |
| 1146 | @var{interactive} (if any), and body forms given by @var{body}. | 1155 | @var{interactive} (if any), and body forms given by @var{body}. |
| 1147 | 1156 | ||
| 1148 | Under dynamic binding, this macro effectively makes @code{lambda} | 1157 | For example, this macro makes @code{lambda} forms almost self-quoting: |
| 1149 | forms self-quoting: evaluating a form whose @sc{car} is @code{lambda} | 1158 | evaluating a form whose @sc{car} is @code{lambda} yields a value that is |
| 1150 | yields the form itself: | 1159 | almost like the form itself: |
| 1151 | 1160 | ||
| 1152 | @example | 1161 | @example |
| 1153 | (lambda (x) (* x x)) | 1162 | (lambda (x) (* x x)) |
| 1154 | @result{} (lambda (x) (* x x)) | 1163 | @result{} #f(lambda (x) :dynbind (* x x)) |
| 1155 | @end example | 1164 | @end example |
| 1156 | 1165 | ||
| 1157 | Note that when evaluating under lexical binding the result is a | 1166 | When evaluating under lexical binding the result is a similar |
| 1158 | closure object (@pxref{Closures}). | 1167 | closure object, where the @code{:dynbind} marker is replaced by the |
| 1168 | captured variables (@pxref{Closures}). | ||
| 1159 | 1169 | ||
| 1160 | The @code{lambda} form has one other effect: it tells the Emacs | 1170 | The @code{lambda} form has one other effect: it tells the Emacs |
| 1161 | evaluator and byte-compiler that its argument is a function, by using | 1171 | evaluator and byte-compiler that its argument is a function, by using |
| @@ -1164,8 +1174,8 @@ evaluator and byte-compiler that its argument is a function, by using | |||
| 1164 | 1174 | ||
| 1165 | @defspec function function-object | 1175 | @defspec function function-object |
| 1166 | @cindex function quoting | 1176 | @cindex function quoting |
| 1167 | This special form returns @var{function-object} without evaluating it. | 1177 | This special form returns the function value of the @var{function-object}. |
| 1168 | In this, it is similar to @code{quote} (@pxref{Quoting}). But unlike | 1178 | In many ways, it is similar to @code{quote} (@pxref{Quoting}). But unlike |
| 1169 | @code{quote}, it also serves as a note to the Emacs evaluator and | 1179 | @code{quote}, it also serves as a note to the Emacs evaluator and |
| 1170 | byte-compiler that @var{function-object} is intended to be used as a | 1180 | byte-compiler that @var{function-object} is intended to be used as a |
| 1171 | function. Assuming @var{function-object} is a valid lambda | 1181 | function. Assuming @var{function-object} is a valid lambda |
| @@ -1495,7 +1505,7 @@ distinguish between a function cell that is void and one set to | |||
| 1495 | @group | 1505 | @group |
| 1496 | (defun bar (n) (+ n 2)) | 1506 | (defun bar (n) (+ n 2)) |
| 1497 | (symbol-function 'bar) | 1507 | (symbol-function 'bar) |
| 1498 | @result{} (lambda (n) (+ n 2)) | 1508 | @result{} #f(lambda (n) [t] (+ n 2)) |
| 1499 | @end group | 1509 | @end group |
| 1500 | @group | 1510 | @group |
| 1501 | (fset 'baz 'bar) | 1511 | (fset 'baz 'bar) |
| @@ -1608,7 +1618,7 @@ argument list and body forms as the remaining elements: | |||
| 1608 | @example | 1618 | @example |
| 1609 | ;; @r{lexical binding is enabled.} | 1619 | ;; @r{lexical binding is enabled.} |
| 1610 | (lambda (x) (* x x)) | 1620 | (lambda (x) (* x x)) |
| 1611 | @result{} (closure (t) (x) (* x x)) | 1621 | @result{} #f(lambda (x) [t] (* x x)) |
| 1612 | @end example | 1622 | @end example |
| 1613 | 1623 | ||
| 1614 | @noindent | 1624 | @noindent |