* bug#25965: 26.0.50; iter-lambda may evaluate certain forms twice
@ 2017-03-04 8:02 Andreas Politz
2017-03-08 21:52 ` Stefan Monnier
0 siblings, 1 reply; 5+ messages in thread
From: Andreas Politz @ 2017-03-04 8:02 UTC (permalink / raw)
To: 25965
Here is an example where the behavior occurs.
#+BEGIN_SRC emacs-lisp
;; -*- lexical-binding: t -*-
(iter-next
(funcall (iter-lambda ()
(let* ((fill-column 10) ;;any special variable will do
(i 0)
(j (setq i (1+ i))))
(iter-yield i)))))
;; => 2
#+END_SRC
But the result should be 1. Looking at the expanded code, we see i
incremented indeed twice.
#+BEGIN_SRC emacs-lisp
;; ....
(setq cps-state-atom--1522
#'(lambda nil
(setq cps-current-value--1513
(let
((fill-column cps-binding-fill-column--1516))
(unwind-protect
(prog1
(setq cps-binding-i--1517
(1+ cps-binding-i--1517))
(setq cps-current-state--1514 cps-state-let*--1521))
(setq cps-binding-fill-column--1516 fill-column))
(prog1
(setq cps-binding-i--1517
(1+ cps-binding-i--1517))
(setq cps-current-state--1514 cps-state-let*--1521))))))
;; ...
#+END_SRC
The unwind-protect form is created in this function.
#+BEGIN_SRC emacs-lisp
(defun cps--make-dynamic-binding-wrapper (dynamic-var static-var)
(cl-assert lexical-binding)
(lambda (form)
`(let ((,dynamic-var ,static-var))
(unwind-protect ; Update the static shadow after evaluation is done
,form
(setf ,static-var ,dynamic-var))
,form)))
#+END_SRC
And it seems to me that the second occurrence of ,form is just an
error.
By the way, why is debugging these generators made so difficult (via the
implementation of cps--gensym) ?
-ap
^ permalink raw reply [flat|nested] 5+ messages in thread
* bug#25965: 26.0.50; iter-lambda may evaluate certain forms twice
2017-03-04 8:02 bug#25965: 26.0.50; iter-lambda may evaluate certain forms twice Andreas Politz
@ 2017-03-08 21:52 ` Stefan Monnier
2017-03-08 22:08 ` Daniel Colascione
0 siblings, 1 reply; 5+ messages in thread
From: Stefan Monnier @ 2017-03-08 21:52 UTC (permalink / raw)
To: Andreas Politz, Daniel Colascione; +Cc: 25965
> The unwind-protect form is created in this function.
>
> #+BEGIN_SRC emacs-lisp
> (defun cps--make-dynamic-binding-wrapper (dynamic-var static-var)
> (cl-assert lexical-binding)
> (lambda (form)
> `(let ((,dynamic-var ,static-var))
> (unwind-protect ; Update the static shadow after evaluation is done
> ,form
> (setf ,static-var ,dynamic-var))
> ,form)))
> #+END_SRC
>
> And it seems to me that the second occurrence of ,form is just an
> error.
Hmm... indeed that looks odd, and maybe just removing the second ,form
is the right fix. Daniel, do you happen to remember what the second
,form above is meant to do?
Stefan
^ permalink raw reply [flat|nested] 5+ messages in thread
* bug#25965: 26.0.50; iter-lambda may evaluate certain forms twice
2017-03-08 21:52 ` Stefan Monnier
@ 2017-03-08 22:08 ` Daniel Colascione
2017-09-21 21:36 ` Gemini Lasswell
0 siblings, 1 reply; 5+ messages in thread
From: Daniel Colascione @ 2017-03-08 22:08 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 25965, Andreas Politz
On Wed, Mar 08 2017, Stefan Monnier wrote:
>> The unwind-protect form is created in this function.
>>
>> #+BEGIN_SRC emacs-lisp
>> (defun cps--make-dynamic-binding-wrapper (dynamic-var static-var)
>> (cl-assert lexical-binding)
>> (lambda (form)
>> `(let ((,dynamic-var ,static-var))
>> (unwind-protect ; Update the static shadow after evaluation is done
>> ,form
>> (setf ,static-var ,dynamic-var))
>> ,form)))
>> #+END_SRC
>>
>> And it seems to me that the second occurrence of ,form is just an
>> error.
>
> Hmm... indeed that looks odd, and maybe just removing the second ,form
> is the right fix. Daniel, do you happen to remember what the second
> ,form above is meant to do?
Embarrass me years later? :-) I think it's safe to remove it. Let's make
sure to add a test too.
^ permalink raw reply [flat|nested] 5+ messages in thread
* bug#25965: 26.0.50; iter-lambda may evaluate certain forms twice
2017-03-08 22:08 ` Daniel Colascione
@ 2017-09-21 21:36 ` Gemini Lasswell
2017-10-05 19:51 ` Gemini Lasswell
0 siblings, 1 reply; 5+ messages in thread
From: Gemini Lasswell @ 2017-09-21 21:36 UTC (permalink / raw)
To: Daniel Colascione; +Cc: 25965, Stefan Monnier, Andreas Politz
[-- Attachment #1: Type: text/plain, Size: 206 bytes --]
tags 25965 patch
quit
Daniel Colascione <dancol@dancol.org> writes:
> I think it's safe to remove it. Let's make
> sure to add a test too.
Here's a patch which removes the second ,form and adds a test:
[-- Attachment #2: 0001-Fix-dynamic-binding-wrapper-in-iter-lambda-bug-25965.patch --]
[-- Type: text/plain, Size: 2116 bytes --]
From 46720f235ff11f64a35b91e74110fd3a8e01be4f Mon Sep 17 00:00:00 2001
From: Gemini Lasswell <gazally@runbox.com>
Date: Wed, 20 Sep 2017 10:17:35 -0700
Subject: [PATCH] Fix dynamic binding wrapper in iter-lambda (bug#25965)
* lisp/emacs-lisp/generator.el (cps--make-dynamic-binding-wrapper):
Remove extra evaluation of form.
* test/lisp/emacs-lisp/generator-tests.el
(cps-iter-lambda-with-dynamic-binding): New test.
---
lisp/emacs-lisp/generator.el | 3 +--
test/lisp/emacs-lisp/generator-tests.el | 10 ++++++++++
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/lisp/emacs-lisp/generator.el b/lisp/emacs-lisp/generator.el
index f3597cc387..3e9885900c 100644
--- a/lisp/emacs-lisp/generator.el
+++ b/lisp/emacs-lisp/generator.el
@@ -142,8 +142,7 @@ cps--make-dynamic-binding-wrapper
`(let ((,dynamic-var ,static-var))
(unwind-protect ; Update the static shadow after evaluation is done
,form
- (setf ,static-var ,dynamic-var))
- ,form)))
+ (setf ,static-var ,dynamic-var)))))
(defmacro cps--with-dynamic-binding (dynamic-var static-var &rest body)
"Evaluate BODY such that generated atomic evaluations run with
diff --git a/test/lisp/emacs-lisp/generator-tests.el b/test/lisp/emacs-lisp/generator-tests.el
index 4cc6c841da..cbb136ae91 100644
--- a/test/lisp/emacs-lisp/generator-tests.el
+++ b/test/lisp/emacs-lisp/generator-tests.el
@@ -282,3 +282,13 @@ cps-test-closed-flag
(ert-deftest cps-test-declarations-preserved ()
(should (equal (documentation 'generator-with-docstring) "Documentation!"))
(should (equal (get 'generator-with-docstring 'lisp-indent-function) 5)))
+
+(ert-deftest cps-iter-lambda-with-dynamic-binding ()
+ "`iter-lambda' with dynamic binding produces correct result (bug#25965)."
+ (should (= 1
+ (iter-next
+ (funcall (iter-lambda ()
+ (let* ((fill-column 10) ;;any special variable will do
+ (i 0)
+ (j (setq i (1+ i))))
+ (iter-yield i))))))))
--
2.14.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* bug#25965: 26.0.50; iter-lambda may evaluate certain forms twice
2017-09-21 21:36 ` Gemini Lasswell
@ 2017-10-05 19:51 ` Gemini Lasswell
0 siblings, 0 replies; 5+ messages in thread
From: Gemini Lasswell @ 2017-10-05 19:51 UTC (permalink / raw)
To: Daniel Colascione; +Cc: 25965-done, Stefan Monnier, Andreas Politz
Pushed to emacs-26.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-10-05 19:51 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-03-04 8:02 bug#25965: 26.0.50; iter-lambda may evaluate certain forms twice Andreas Politz
2017-03-08 21:52 ` Stefan Monnier
2017-03-08 22:08 ` Daniel Colascione
2017-09-21 21:36 ` Gemini Lasswell
2017-10-05 19:51 ` Gemini Lasswell
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.