comparison lisp/cl-macs.el @ 5566:4654c01af32b

Improve the implementation, documentation of #'labels, #'flet. lisp/ChangeLog addition: 2011-09-07 Aidan Kehoe <kehoea@parhasard.net> * bytecomp.el: * bytecomp.el (for-effect): Move this earlier in the file, it's referenced in byte-compile-initial-macro-environment. * bytecomp.el (byte-compile-initial-macro-environment): In the byte-compile-macro-environment definition for #'labels, put off the compiling the lambda bodies until the point where the rest of the form is being compiled, allowing the lambda bodies to access appropriate values for byte-compile-bound-variables, and reducing excessive warning about free variables. Add a byte-compile-macro-environment definition for #'flet. This modifies byte-compile-function-environment appropriately, and warns about bindings of functions that have macro definitions in the current environment, about functions that have byte codes, and about functions that have byte-compile methods (which may not do what the user wants at runtime). * bytecomp.el (byte-compile-funcall): If FUNCTION is constant, call #'byte-compile-callargs-warn if that's appropriate, giving warnings about problems with calling functions bound with #'labels. * cl-macs.el: * cl-macs.el (flet): Mention the main difference from Common Lisp, that the bindings are dynamic, not lexical. Counsel the use of #'labels, not #'flet, for this and other reasons. Explain the limited single use case for #'flet. Cross-reference to bytecomp.el in a comment. * cl-macs.el (labels): Go into detail on which functions may be called from where. Explain how to access the function definition of a label within FORM. Add a comment cross-referencing to bytecomp.el. man/ChangeLog addition: 2011-09-07 Aidan Kehoe <kehoea@parhasard.net> * cl.texi (Function Bindings): Move #'labels first, describe it in more detail, explaining that it is to be preferred over #'flet, and explaining why. Explain that dynamic bindings with #'flet will also not work when functions are accessed through their bytecodes.
author Aidan Kehoe <kehoea@parhasard.net>
date Wed, 07 Sep 2011 16:26:45 +0100
parents 855b667dea13
children 3bc58dc9d688
comparison
equal deleted inserted replaced
5565:48a3d3281b48 5566:4654c01af32b
1712 (list 'let '((cl-progv-save nil)) 1712 (list 'let '((cl-progv-save nil))
1713 (list 'unwind-protect 1713 (list 'unwind-protect
1714 (list* 'progn (list 'cl-progv-before symbols values) body) 1714 (list* 'progn (list 'cl-progv-before symbols values) body)
1715 '(cl-progv-after)))) 1715 '(cl-progv-after))))
1716 1716
1717 ;;; This should really have some way to shadow 'byte-compile properties, etc. 1717 ;;;###autoload
1718 ;;;###autoload 1718 (defmacro flet (functions &rest form)
1719 (defmacro flet (bindings &rest body)
1720 "Make temporary function definitions. 1719 "Make temporary function definitions.
1720
1721 This is an analogue of `let' that operates on the function cell of FUNC 1721 This is an analogue of `let' that operates on the function cell of FUNC
1722 rather than its value cell. The FORMs are evaluated with the specified 1722 rather than its value cell. The FORMs are evaluated with the specified
1723 function definitions in place, then the definitions are undone (the FUNCs 1723 function definitions in place, then the definitions are undone (the FUNCs go
1724 go back to their previous definitions, or lack thereof). 1724 back to their previous definitions, or lack thereof). This is in
1725 1725 contravention of Common Lisp, where `flet' makes a lexical, not a dynamic,
1726 arguments: (((FUNC ARGLIST &body BODY) &rest FUNCTIONS) &body FORM)" 1726 function binding.
1727 (list* 'letf* 1727
1728 (mapcar 1728 Normally you should use `labels', not `flet'; `labels' does not have the
1729 #'(lambda (x) 1729 problems caused by dynamic scope, is less expensive when byte-compiled, and
1730 (if (or (and (fboundp (car x)) 1730 allows lexical shadowing of functions with byte-codes and byte-compile
1731 (eq (car-safe (symbol-function (car x))) 'macro)) 1731 methods, where `flet' will fail. The byte-compiler will warn when this
1732 (cdr (assq (car x) byte-compile-macro-environment))) 1732 happens.
1733 (error "Use `labels', not `flet', to rebind macro names")) 1733
1734 (let ((func (list 'function* 1734 If you need to shadow some existing function at run time, and that function
1735 (list 'lambda (cadr x) 1735 has no associated byte code or compiler macro, then `flet' is appropriate.
1736 (list* 'block (car x) (cddr x)))))) 1736
1737 (if (and (cl-compiling-file) 1737 arguments: (((FUNCTION ARGLIST &body BODY) &rest FUNCTIONS) &body FORM)"
1738 (boundp 'byte-compile-function-environment)) 1738 ;; XEmacs; leave warnings, errors and modifications of
1739 (push (cons (car x) (eval func)) 1739 ;; byte-compile-function-environment to the byte compiler. See
1740 byte-compile-function-environment)) 1740 ;; byte-compile-initial-macro-environment in bytecomp.el.
1741 (list (list 'symbol-function (list 'quote (car x))) func))) 1741 (list*
1742 bindings) 1742 'letf*
1743 body)) 1743 (mapcar
1744 (function*
1745 (lambda ((function . definition))
1746 `((symbol-function ',function)
1747 ,(cons 'lambda (cdr (cl-transform-lambda definition function))))))
1748 functions) form))
1744 1749
1745 ;;;###autoload 1750 ;;;###autoload
1746 (defmacro labels (bindings &rest body) 1751 (defmacro labels (bindings &rest body)
1747 "Make temporary func bindings. 1752 "Make temporary function bindings.
1753
1748 This is like `flet', except the bindings are lexical instead of dynamic. 1754 This is like `flet', except the bindings are lexical instead of dynamic.
1749 Unlike `flet', this macro is fully compliant with the Common Lisp standard. 1755 Unlike `flet', this macro is compliant with the Common Lisp standard with
1750 1756 regard to the scope and extent of the function bindings.
1751 arguments: (((FUNC ARGLIST &body BODY) &rest FUNCTIONS) &body FORM)" 1757
1758 Each function may be called from within FORM, from within the BODY of the
1759 function itself (that is, recursively), and from any other function bodies
1760 in FUNCTIONS.
1761
1762 Within FORM, to access the function definition of a bound function (for
1763 example, to pass it as a FUNCTION argument to `map'), quote its symbol name
1764 using `function'.
1765
1766 arguments: (((FUNCTION ARGLIST &body BODY) &rest FUNCTIONS) &body FORM)"
1767 ;; XEmacs; the byte-compiler has a much better implementation of `labels'
1768 ;; in `byte-compile-initial-macro-environment' that is used in compiled
1769 ;; code.
1752 (let ((vars nil) (sets nil) 1770 (let ((vars nil) (sets nil)
1753 (byte-compile-macro-environment byte-compile-macro-environment)) 1771 (byte-compile-macro-environment byte-compile-macro-environment))
1754 (while bindings 1772 (while bindings
1755 (let ((var (gensym))) 1773 (let ((var (gensym)))
1756 (push var vars) 1774 (push var vars)
1762 'cl-labels-args)) 1780 'cl-labels-args))
1763 byte-compile-macro-environment))) 1781 byte-compile-macro-environment)))
1764 (cl-macroexpand-all (list* 'lexical-let vars (cons (cons 'setq sets) body)) 1782 (cl-macroexpand-all (list* 'lexical-let vars (cons (cons 'setq sets) body))
1765 byte-compile-macro-environment))) 1783 byte-compile-macro-environment)))
1766 1784
1767 ;; The following ought to have a better definition for use with newer
1768 ;; byte compilers.
1769 ;;;###autoload 1785 ;;;###autoload
1770 (defmacro* macrolet ((&rest macros) &body form) 1786 (defmacro* macrolet ((&rest macros) &body form)
1771 "Make temporary macro definitions. 1787 "Make temporary macro definitions.
1772 This is like `flet', but for macros instead of functions." 1788 This is like `flet', but for macros instead of functions."
1773 (cl-macroexpand-all (cons 'progn form) 1789 (cl-macroexpand-all (cons 'progn form)