[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: emacs-lisp/cl.el (pushnew): void-variable x
From: |
Miles Bader |
Subject: |
Re: emacs-lisp/cl.el (pushnew): void-variable x |
Date: |
Tue, 12 Sep 2006 14:56:10 +0900 |
Stefan Monnier <address@hidden> writes:
> Honestly, I think using `add-to-list' here makes no sense.
> Since we have the variable as a symbol and we're macro-expanding, we can
> just use `(unless (member ,element ,var) (setq ,var (cons ,element ,var)))
> That'll be a lot more efficient than going through a function call to
> add-to-list, using an aux-var accessed via symbol-value and set and checking
> `append' arg etc...
Yup, and it even looks like cl-macs.el has the machinery in place to do
that, it's just very hard to follow (lots of levels of compiler-macros).
However I think it normally doesn't "take" because the default
comparison function for pushnew is `eql', not eq, so there's no non-cl
way to express the result; that's why it uses member*.
It works now to use: (pushnew a b :test 'eq), which expands at compile
time into the desired: (setq b (if (memq a b) b (cons a b))).
How about adding a new primitive `memql', a variant of memq that uses
eql -- which should be very efficient in C -- and then make the slight
tweak to cl's `member*' expander to produce that in the default case?
Then (pushnew a b) would expand to:
(setq b (if (memql a b) b (cons a b))).
I think this is good behavior because most people probably want
more-or-less memq but don't want to uglify their code with the :test 'eq
grot; memql would be as fast as memq.
The following patche seems to implement this:
orig = address@hidden/emacs--miles--0--patch-27
M lisp/emacs-lisp/cl-macs.el
M lisp/subr.el
* modified files
--- orig/lisp/emacs-lisp/cl-macs.el
+++ mod/lisp/emacs-lisp/cl-macs.el
@@ -2578,21 +2578,7 @@
(cl-const-expr-val (nth 1 keys)))))
(cond ((eq test 'eq) (list 'memq a list))
((eq test 'equal) (list 'member a list))
- ((or (null keys) (eq test 'eql))
- (if (eq (cl-const-expr-p a) t)
- (list (if (floatp-safe (cl-const-expr-val a)) 'member 'memq)
- a list)
- (if (eq (cl-const-expr-p list) t)
- (let ((p (cl-const-expr-val list)) (mb nil) (mq nil))
- (if (not (cdr p))
- (and p (list 'eql a (list 'quote (car p))))
- (while p
- (if (floatp-safe (car p)) (setq mb t)
- (or (integerp (car p)) (symbolp (car p)) (setq mq t)))
- (setq p (cdr p)))
- (if (not mb) (list 'memq a list)
- (if (not mq) (list 'member a list) form))))
- form)))
+ ((or (null keys) (eq test 'eql)) (list 'memql a list))
(t form))))
(define-compiler-macro assoc* (&whole form a list &rest keys)
--- orig/lisp/subr.el
+++ mod/lisp/subr.el
@@ -350,6 +350,15 @@
(setq list (cdr list)))
list)
+(defun memql (elt list)
+ "Like `memq', but compares numbers using `=' instead of `eq'."
+ (if (numberp elt)
+ (progn
+ (while (and list (not (eql elt (car list))))
+ (setq list (cdr list)))
+ list)
+ (memq elt list)))
+
(defmacro with-lexical-binding (&rest body)
"Execute the statements in BODY using lexical binding."
`(let ((internal-interpreter-environment internal-interpreter-environment))
-Miles
--
97% of everything is grunge
- emacs-lisp/cl.el (pushnew): void-variable x, Reiner Steib, 2006/09/11
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Kim F. Storm, 2006/09/11
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Reiner Steib, 2006/09/11
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Richard Stallman, 2006/09/11
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Kim F. Storm, 2006/09/11
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Miles Bader, 2006/09/11
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Stefan Monnier, 2006/09/11
- Re: emacs-lisp/cl.el (pushnew): void-variable x,
Miles Bader <=
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Miles Bader, 2006/09/12
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Kim F. Storm, 2006/09/12
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Stefan Monnier, 2006/09/12
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Richard Stallman, 2006/09/12
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Johan Bockgård, 2006/09/13
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Miles Bader, 2006/09/14
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Kim F. Storm, 2006/09/20
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Miles Bader, 2006/09/20
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Kim F. Storm, 2006/09/21
- Re: emacs-lisp/cl.el (pushnew): void-variable x, Miles Bader, 2006/09/21