* lisp/subr.el (apply-partially): Use a non-nil static environment.
authorStefan Monnier <monnier@iro.umontreal.ca>
Wed, 30 Mar 2011 18:40:00 +0000 (14:40 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Wed, 30 Mar 2011 18:40:00 +0000 (14:40 -0400)
(--dolist-tail--, --dotimes-limit--): Don't declare dynamically bound.
(dolist): Use a more efficient form for lexical-binding.
(dotimes): Use a cleaner semantics for lexical-binding.
* lisp/emacs-lisp/edebug.el (edebug-eval-top-level-form):
Use eval-sexp-add-defvars.

lisp/ChangeLog
lisp/emacs-lisp/edebug.el
lisp/subr.el
src/lread.c

index c1e1215..b517c48 100644 (file)
@@ -1,3 +1,13 @@
+2011-03-30  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * subr.el (apply-partially): Use a non-nil static environment.
+       (--dolist-tail--, --dotimes-limit--): Don't declare dynamically bound.
+       (dolist): Use a more efficient form for lexical-binding.
+       (dotimes): Use a cleaner semantics for lexical-binding.
+
+       * emacs-lisp/edebug.el (edebug-eval-top-level-form):
+       Use eval-sexp-add-defvars.
+
 2011-03-30  Juanma Barranquero  <lekktu@gmail.com>
 
        * makefile.w32-in (COMPILE_FIRST): Remove pcase.
index dfc2684..8135b5c 100644 (file)
@@ -566,7 +566,8 @@ already is one.)"
    ;; but this causes problems while edebugging edebug.
    (let ((edebug-all-forms t)
         (edebug-all-defs t))
-     (edebug-read-top-level-form))))
+     (eval-sexp-add-defvars
+      (edebug-read-top-level-form)))))
 
 
 (defun edebug-read-top-level-form ()
index c5fedae..205828b 100644 (file)
@@ -124,7 +124,7 @@ ARGS is a list of the first N arguments to pass to FUN.
 The result is a new function which does the same as FUN, except that
 the first N arguments are fixed at the values with which this function
 was called."
-  `(closure () (&rest args)
+  `(closure (t) (&rest args)
             (apply ',fun ,@(mapcar (lambda (arg) `',arg) args) args)))
 
 (if (null (featurep 'cl))
@@ -174,8 +174,6 @@ value of last one, or nil if there are none.
   ;; If we reload subr.el after having loaded CL, be careful not to
   ;; overwrite CL's extended definition of `dolist', `dotimes',
   ;; `declare', `push' and `pop'.
-(defvar --dolist-tail-- nil
-  "Temporary variable used in `dolist' expansion.")
 
 (defmacro dolist (spec &rest body)
   "Loop over a list.
@@ -189,19 +187,27 @@ Then evaluate RESULT to get return value, default nil.
   ;; use dolist.
   ;; FIXME: This cost disappears in byte-compiled lexical-binding files.
   (let ((temp '--dolist-tail--))
-    `(let ((,temp ,(nth 1 spec))
-          ,(car spec))
-       (while ,temp
-         ;; FIXME: In lexical-binding code, a `let' inside the loop might
-         ;; turn out to be faster than the an outside `let' this `setq'.
-        (setq ,(car spec) (car ,temp))
-        ,@body
-        (setq ,temp (cdr ,temp)))
-       ,@(if (cdr (cdr spec))
-            `((setq ,(car spec) nil) ,@(cdr (cdr spec)))))))
-
-(defvar --dotimes-limit-- nil
-  "Temporary variable used in `dotimes' expansion.")
+    ;; This is not a reliable test, but it does not matter because both
+    ;; semantics are acceptable, tho one is slightly faster with dynamic
+    ;; scoping and the other is slightly faster (and has cleaner semantics)
+    ;; with lexical scoping.
+    (if lexical-binding
+        `(let ((,temp ,(nth 1 spec)))
+           (while ,temp
+             (let ((,(car spec) (car ,temp)))
+               ,@body
+               (setq ,temp (cdr ,temp))))
+           ,@(if (cdr (cdr spec))
+                 ;; FIXME: This let often leads to "unused var" warnings.
+                 `((let ((,(car spec) nil)) ,@(cdr (cdr spec))))))
+      `(let ((,temp ,(nth 1 spec))
+             ,(car spec))
+         (while ,temp
+           (setq ,(car spec) (car ,temp))
+           ,@body
+           (setq ,temp (cdr ,temp)))
+         ,@(if (cdr (cdr spec))
+               `((setq ,(car spec) nil) ,@(cdr (cdr spec))))))))
 
 (defmacro dotimes (spec &rest body)
   "Loop a certain number of times.
@@ -214,15 +220,30 @@ the return value (nil if RESULT is omitted).
   ;; It would be cleaner to create an uninterned symbol,
   ;; but that uses a lot more space when many functions in many files
   ;; use dotimes.
+  ;; FIXME: This cost disappears in byte-compiled lexical-binding files.
   (let ((temp '--dotimes-limit--)
        (start 0)
        (end (nth 1 spec)))
-    `(let ((,temp ,end)
-          (,(car spec) ,start))
-       (while (< ,(car spec) ,temp)
-        ,@body
-        (setq ,(car spec) (1+ ,(car spec))))
-       ,@(cdr (cdr spec)))))
+    ;; This is not a reliable test, but it does not matter because both
+    ;; semantics are acceptable, tho one is slightly faster with dynamic
+    ;; scoping and the other has cleaner semantics.
+    (if lexical-binding
+        (let ((counter '--dotimes-counter--))
+          `(let ((,temp ,end)
+                 (,counter ,start))
+             (while (< ,counter ,temp)
+               (let ((,(car spec) ,counter))
+                 ,@body)
+               (setq ,counter (1+ ,counter)))
+             ,@(if (cddr spec)
+                   ;; FIXME: This let often leads to "unused var" warnings.
+                   `((let ((,(car spec) ,counter)) ,@(cddr spec))))))
+      `(let ((,temp ,end)
+             (,(car spec) ,start))
+         (while (< ,(car spec) ,temp)
+           ,@body
+           (setq ,(car spec) (1+ ,(car spec))))
+         ,@(cdr (cdr spec))))))
 
 (defmacro declare (&rest specs)
   "Do not evaluate any arguments and return nil.
index 7a8d7cf..2418353 100644 (file)
@@ -1889,6 +1889,7 @@ which is the input stream for reading characters.
 This function does not move point.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object printflag, Lisp_Object read_function)
 {
+  /* FIXME: Do the eval-sexp-add-defvars danse!  */
   int count = SPECPDL_INDEX ();
   Lisp_Object tem, cbuf;