diff options
| author | Stefan Monnier | 2014-04-22 12:22:13 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2014-04-22 12:22:13 -0400 |
| commit | 67c477ae67ae3e83b027fb03c5d11f47fa30566c (patch) | |
| tree | 8956f7cf4fd6753031db1fbec2ec28965d8dacaa | |
| parent | 12b1389c9039dd374951673ca43b1ddf65df400d (diff) | |
| download | emacs-67c477ae67ae3e83b027fb03c5d11f47fa30566c.tar.gz emacs-67c477ae67ae3e83b027fb03c5d11f47fa30566c.zip | |
* lisp/emacs-lisp/byte-run.el (function-put): New function.
(defun-declarations-alist): Use it. Add `pure' and `side-effect-free'.
* lisp/emacs-lisp/cl-macs.el (cl-defstruct, cl-struct-sequence-type)
(cl-struct-slot-info, cl-struct-slot-offset, cl-struct-slot-value):
Use them.
| -rw-r--r-- | etc/NEWS | 9 | ||||
| -rw-r--r-- | lisp/ChangeLog | 20 | ||||
| -rw-r--r-- | lisp/emacs-lisp/byte-run.el | 45 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 17 |
4 files changed, 62 insertions, 29 deletions
| @@ -95,9 +95,14 @@ active region handling. | |||
| 95 | 95 | ||
| 96 | * Lisp Changes in Emacs 24.5 | 96 | * Lisp Changes in Emacs 24.5 |
| 97 | 97 | ||
| 98 | ** New function `function-put' to use instead of `put' for function properties. | ||
| 99 | |||
| 98 | +++ | 100 | +++ |
| 99 | ** You can specify a function's interactive-only property via `declare'. | 101 | ** New properties that can be specified with `declare': |
| 100 | However you specify it, the property affects `describe-function' output. | 102 | *** (interactive-only INSTEAD), tells to use INSTEAD for non-interactive use. |
| 103 | *** (pure VAL), if VAL is non-nil, indicates the function is pure. | ||
| 104 | *** (side-effect-free VAL), if VAL is non-nil, indicates the function does not | ||
| 105 | have side effects. | ||
| 101 | 106 | ||
| 102 | ** You can access the slots of structures using `cl-struct-slot-value'. | 107 | ** You can access the slots of structures using `cl-struct-slot-value'. |
| 103 | 108 | ||
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 06e2732becc..54e1933ecf0 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,7 +1,15 @@ | |||
| 1 | 2014-04-22 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * emacs-lisp/byte-run.el (function-put): New function. | ||
| 4 | (defun-declarations-alist): Use it. Add `pure' and `side-effect-free'. | ||
| 5 | * emacs-lisp/cl-macs.el (cl-defstruct, cl-struct-sequence-type) | ||
| 6 | (cl-struct-slot-info, cl-struct-slot-offset, cl-struct-slot-value): | ||
| 7 | Use them. | ||
| 8 | |||
| 1 | 2014-04-22 Daniel Colascione <dancol@dancol.org> | 9 | 2014-04-22 Daniel Colascione <dancol@dancol.org> |
| 2 | 10 | ||
| 3 | * emacs-lisp/macroexp.el (internal-macroexpand-for-load): Add | 11 | * emacs-lisp/macroexp.el (internal-macroexpand-for-load): |
| 4 | `full-p' parameter; when nil, call `macroexpand' instead of | 12 | Add `full-p' parameter; when nil, call `macroexpand' instead of |
| 5 | `macroexpand-all'. | 13 | `macroexpand-all'. |
| 6 | 14 | ||
| 7 | * emacs-lisp/byte-run.el (eval-when-compile, eval-and-compile): | 15 | * emacs-lisp/byte-run.el (eval-when-compile, eval-and-compile): |
| @@ -102,8 +110,8 @@ | |||
| 102 | (xterm-mouse-tracking-enable-sequence) | 110 | (xterm-mouse-tracking-enable-sequence) |
| 103 | (xterm-mouse-tracking-disable-sequence): New constants. | 111 | (xterm-mouse-tracking-disable-sequence): New constants. |
| 104 | (turn-on-xterm-mouse-tracking-on-terminal) | 112 | (turn-on-xterm-mouse-tracking-on-terminal) |
| 105 | (turn-off-xterm-mouse-tracking-on-terminal): Use | 113 | (turn-off-xterm-mouse-tracking-on-terminal): |
| 106 | tty-mode-set-strings and tty-mode-reset-strings terminal | 114 | Use tty-mode-set-strings and tty-mode-reset-strings terminal |
| 107 | parameters instead of random hooks. | 115 | parameters instead of random hooks. |
| 108 | (turn-on-xterm-mouse-tracking) | 116 | (turn-on-xterm-mouse-tracking) |
| 109 | (turn-off-xterm-mouse-tracking): Delete. | 117 | (turn-off-xterm-mouse-tracking): Delete. |
| @@ -121,8 +129,8 @@ | |||
| 121 | (xterm-turn-off-modify-other-keys) | 129 | (xterm-turn-off-modify-other-keys) |
| 122 | (xterm-remove-modify-other-keys): Delete obsolete functions. | 130 | (xterm-remove-modify-other-keys): Delete obsolete functions. |
| 123 | 131 | ||
| 124 | * term/screen.el: Rewrite to just use the xterm code. Add | 132 | * term/screen.el: Rewrite to just use the xterm code. |
| 125 | copyright notice. Mention tmux. | 133 | Add copyright notice. Mention tmux. |
| 126 | 134 | ||
| 127 | 2014-04-17 Ian D <dunni@gnu.org> (tiny change) | 135 | 2014-04-17 Ian D <dunni@gnu.org> (tiny change) |
| 128 | 136 | ||
diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index be011e2146c..e5f8feb888b 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el | |||
| @@ -84,22 +84,36 @@ The return value of this function is not used." | |||
| 84 | (list 'quote f) (list 'quote new-name) (list 'quote when)))) | 84 | (list 'quote f) (list 'quote new-name) (list 'quote when)))) |
| 85 | (list 'interactive-only | 85 | (list 'interactive-only |
| 86 | #'(lambda (f _args instead) | 86 | #'(lambda (f _args instead) |
| 87 | (list 'put (list 'quote f) ''interactive-only | 87 | (list 'function-put (list 'quote f) |
| 88 | (list 'quote instead)))) | 88 | ''interactive-only (list 'quote instead)))) |
| 89 | ;; FIXME: Merge `pure' and `side-effect-free'. | ||
| 90 | (list 'pure | ||
| 91 | #'(lambda (f _args val) | ||
| 92 | (list 'function-put (list 'quote f) | ||
| 93 | ''pure (list 'quote val))) | ||
| 94 | "If non-nil, the compiler can replace calls with their return value. | ||
| 95 | This may shift errors from run-time to compile-time.") | ||
| 96 | (list 'side-effect-free | ||
| 97 | #'(lambda (f _args val) | ||
| 98 | (list 'function-put (list 'quote f) | ||
| 99 | ''side-effect-free (list 'quote val))) | ||
| 100 | "If non-nil, calls can be ignored if their value is unused. | ||
| 101 | If `error-free', drop calls even if `byte-compile-delete-errors' is nil.") | ||
| 89 | (list 'compiler-macro | 102 | (list 'compiler-macro |
| 90 | #'(lambda (f args compiler-function) | 103 | #'(lambda (f args compiler-function) |
| 91 | `(eval-and-compile | 104 | `(eval-and-compile |
| 92 | (put ',f 'compiler-macro | 105 | (function-put ',f 'compiler-macro |
| 93 | ,(if (eq (car-safe compiler-function) 'lambda) | 106 | ,(if (eq (car-safe compiler-function) 'lambda) |
| 94 | `(lambda ,(append (cadr compiler-function) args) | 107 | `(lambda ,(append (cadr compiler-function) args) |
| 95 | ,@(cddr compiler-function)) | 108 | ,@(cddr compiler-function)) |
| 96 | `#',compiler-function))))) | 109 | `#',compiler-function))))) |
| 97 | (list 'doc-string | 110 | (list 'doc-string |
| 98 | #'(lambda (f _args pos) | 111 | #'(lambda (f _args pos) |
| 99 | (list 'put (list 'quote f) ''doc-string-elt (list 'quote pos)))) | 112 | (list 'function-put (list 'quote f) |
| 113 | ''doc-string-elt (list 'quote pos)))) | ||
| 100 | (list 'indent | 114 | (list 'indent |
| 101 | #'(lambda (f _args val) | 115 | #'(lambda (f _args val) |
| 102 | (list 'put (list 'quote f) | 116 | (list 'function-put (list 'quote f) |
| 103 | ''lisp-indent-function (list 'quote val))))) | 117 | ''lisp-indent-function (list 'quote val))))) |
| 104 | "List associating function properties to their macro expansion. | 118 | "List associating function properties to their macro expansion. |
| 105 | Each element of the list takes the form (PROP FUN) where FUN is | 119 | Each element of the list takes the form (PROP FUN) where FUN is |
| @@ -126,8 +140,17 @@ and should return the code to use to set this property. | |||
| 126 | 140 | ||
| 127 | This is used by `declare'.") | 141 | This is used by `declare'.") |
| 128 | 142 | ||
| 129 | (put 'defmacro 'doc-string-elt 3) | 143 | (defun function-put (f prop value) |
| 130 | (put 'defmacro 'lisp-indent-function 2) | 144 | "Set function F's property PROP to VALUE. |
| 145 | The namespace for PROP is shared with symbols. | ||
| 146 | So far, F can only be a symbol, not a lambda expression." | ||
| 147 | ;; We don't want people to just use `put' because we can't conveniently | ||
| 148 | ;; hook into `put' to remap old properties to new ones. But for now, there's | ||
| 149 | ;; no such remapping, so we just call `put'. | ||
| 150 | (put f prop value)) | ||
| 151 | |||
| 152 | (function-put 'defmacro 'doc-string-elt 3) | ||
| 153 | (function-put 'defmacro 'lisp-indent-function 2) | ||
| 131 | (defalias 'defmacro | 154 | (defalias 'defmacro |
| 132 | (cons | 155 | (cons |
| 133 | 'macro | 156 | 'macro |
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 47a89d0880b..fe064b81e31 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el | |||
| @@ -2589,7 +2589,7 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2589 | (put ',name 'cl-struct-include ',include) | 2589 | (put ',name 'cl-struct-include ',include) |
| 2590 | (put ',name 'cl-struct-print ,print-auto) | 2590 | (put ',name 'cl-struct-print ,print-auto) |
| 2591 | ,@(mapcar (lambda (x) | 2591 | ,@(mapcar (lambda (x) |
| 2592 | `(put ',(car x) 'side-effect-free ',(cdr x))) | 2592 | `(function-put ',(car x) 'side-effect-free ',(cdr x))) |
| 2593 | side-eff)) | 2593 | side-eff)) |
| 2594 | forms) | 2594 | forms) |
| 2595 | `(progn ,@(nreverse (cons `',name forms))))) | 2595 | `(progn ,@(nreverse (cons `',name forms))))) |
| @@ -2598,9 +2598,8 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2598 | "Return the sequence used to build STRUCT-TYPE. | 2598 | "Return the sequence used to build STRUCT-TYPE. |
| 2599 | STRUCT-TYPE is a symbol naming a struct type. Return 'vector or | 2599 | STRUCT-TYPE is a symbol naming a struct type. Return 'vector or |
| 2600 | 'list, or nil if STRUCT-TYPE is not a struct type. " | 2600 | 'list, or nil if STRUCT-TYPE is not a struct type. " |
| 2601 | (declare (side-effect-free t) (pure t)) | ||
| 2601 | (car (get struct-type 'cl-struct-type))) | 2602 | (car (get struct-type 'cl-struct-type))) |
| 2602 | (put 'cl-struct-sequence-type 'side-effect-free t) | ||
| 2603 | (put 'cl-struct-sequence-type 'pure t) | ||
| 2604 | 2603 | ||
| 2605 | (defun cl-struct-slot-info (struct-type) | 2604 | (defun cl-struct-slot-info (struct-type) |
| 2606 | "Return a list of slot names of struct STRUCT-TYPE. | 2605 | "Return a list of slot names of struct STRUCT-TYPE. |
| @@ -2608,9 +2607,8 @@ Each entry is a list (SLOT-NAME . OPTS), where SLOT-NAME is a | |||
| 2608 | slot name symbol and OPTS is a list of slot options given to | 2607 | slot name symbol and OPTS is a list of slot options given to |
| 2609 | `cl-defstruct'. Dummy slots that represent the struct name and | 2608 | `cl-defstruct'. Dummy slots that represent the struct name and |
| 2610 | slots skipped by :initial-offset may appear in the list." | 2609 | slots skipped by :initial-offset may appear in the list." |
| 2610 | (declare (side-effect-free t) (pure t)) | ||
| 2611 | (get struct-type 'cl-struct-slots)) | 2611 | (get struct-type 'cl-struct-slots)) |
| 2612 | (put 'cl-struct-slot-info 'side-effect-free t) | ||
| 2613 | (put 'cl-struct-slot-info 'pure t) | ||
| 2614 | 2612 | ||
| 2615 | (defun cl-struct-slot-offset (struct-type slot-name) | 2613 | (defun cl-struct-slot-offset (struct-type slot-name) |
| 2616 | "Return the offset of slot SLOT-NAME in STRUCT-TYPE. | 2614 | "Return the offset of slot SLOT-NAME in STRUCT-TYPE. |
| @@ -2618,12 +2616,11 @@ The returned zero-based slot index is relative to the start of | |||
| 2618 | the structure data type and is adjusted for any structure name | 2616 | the structure data type and is adjusted for any structure name |
| 2619 | and :initial-offset slots. Signal error if struct STRUCT-TYPE | 2617 | and :initial-offset slots. Signal error if struct STRUCT-TYPE |
| 2620 | does not contain SLOT-NAME." | 2618 | does not contain SLOT-NAME." |
| 2619 | (declare (side-effect-free t) (pure t)) | ||
| 2621 | (or (cl-position slot-name | 2620 | (or (cl-position slot-name |
| 2622 | (cl-struct-slot-info struct-type) | 2621 | (cl-struct-slot-info struct-type) |
| 2623 | :key #'car :test #'eq) | 2622 | :key #'car :test #'eq) |
| 2624 | (error "struct %s has no slot %s" struct-type slot-name))) | 2623 | (error "struct %s has no slot %s" struct-type slot-name))) |
| 2625 | (put 'cl-struct-slot-offset 'side-effect-free t) | ||
| 2626 | (put 'cl-struct-slot-offset 'pure t) | ||
| 2627 | 2624 | ||
| 2628 | (defvar byte-compile-function-environment) | 2625 | (defvar byte-compile-function-environment) |
| 2629 | (defvar byte-compile-macro-environment) | 2626 | (defvar byte-compile-macro-environment) |
| @@ -2913,13 +2910,13 @@ The function's arguments should be treated as immutable. | |||
| 2913 | cl-notevery cl-revappend cl-nreconc gethash)) | 2910 | cl-notevery cl-revappend cl-nreconc gethash)) |
| 2914 | 2911 | ||
| 2915 | ;;; Things that are side-effect-free. | 2912 | ;;; Things that are side-effect-free. |
| 2916 | (mapc (lambda (x) (put x 'side-effect-free t)) | 2913 | (mapc (lambda (x) (function-put x 'side-effect-free t)) |
| 2917 | '(cl-oddp cl-evenp cl-signum last butlast cl-ldiff cl-pairlis cl-gcd | 2914 | '(cl-oddp cl-evenp cl-signum last butlast cl-ldiff cl-pairlis cl-gcd |
| 2918 | cl-lcm cl-isqrt cl-floor cl-ceiling cl-truncate cl-round cl-mod cl-rem | 2915 | cl-lcm cl-isqrt cl-floor cl-ceiling cl-truncate cl-round cl-mod cl-rem |
| 2919 | cl-subseq cl-list-length cl-get cl-getf)) | 2916 | cl-subseq cl-list-length cl-get cl-getf)) |
| 2920 | 2917 | ||
| 2921 | ;;; Things that are side-effect-and-error-free. | 2918 | ;;; Things that are side-effect-and-error-free. |
| 2922 | (mapc (lambda (x) (put x 'side-effect-free 'error-free)) | 2919 | (mapc (lambda (x) (function-put x 'side-effect-free 'error-free)) |
| 2923 | '(eql cl-list* cl-subst cl-acons cl-equalp | 2920 | '(eql cl-list* cl-subst cl-acons cl-equalp |
| 2924 | cl-random-state-p copy-tree cl-sublis)) | 2921 | cl-random-state-p copy-tree cl-sublis)) |
| 2925 | 2922 | ||
| @@ -2942,6 +2939,7 @@ The type name can then be used in `cl-typecase', `cl-check-type', etc." | |||
| 2942 | ;; and a gv-expander "for free". | 2939 | ;; and a gv-expander "for free". |
| 2943 | "Return the value of slot SLOT-NAME in INST of STRUCT-TYPE. | 2940 | "Return the value of slot SLOT-NAME in INST of STRUCT-TYPE. |
| 2944 | STRUCT and SLOT-NAME are symbols. INST is a structure instance." | 2941 | STRUCT and SLOT-NAME are symbols. INST is a structure instance." |
| 2942 | (declare (side-effect-free t)) | ||
| 2945 | (unless (cl-typep inst struct-type) | 2943 | (unless (cl-typep inst struct-type) |
| 2946 | (signal 'wrong-type-argument (list struct-type inst))) | 2944 | (signal 'wrong-type-argument (list struct-type inst))) |
| 2947 | ;; We could use `elt', but since the byte compiler will resolve the | 2945 | ;; We could use `elt', but since the byte compiler will resolve the |
| @@ -2950,7 +2948,6 @@ STRUCT and SLOT-NAME are symbols. INST is a structure instance." | |||
| 2950 | (if (eq (cl-struct-sequence-type struct-type) 'vector) | 2948 | (if (eq (cl-struct-sequence-type struct-type) 'vector) |
| 2951 | (aref inst (cl-struct-slot-offset struct-type slot-name)) | 2949 | (aref inst (cl-struct-slot-offset struct-type slot-name)) |
| 2952 | (nth (cl-struct-slot-offset struct-type slot-name) inst))) | 2950 | (nth (cl-struct-slot-offset struct-type slot-name) inst))) |
| 2953 | (put 'cl-struct-slot-value 'side-effect-free t) | ||
| 2954 | 2951 | ||
| 2955 | (run-hooks 'cl-macs-load-hook) | 2952 | (run-hooks 'cl-macs-load-hook) |
| 2956 | 2953 | ||