Subject: bug#26073: workaround

From: Paul Pogonyshev <[email-masked]>
Date: Mon, 20 Mar 2017 15:20:58 +0100

> Could you give me some concrete (but simple) example?

Basically, when you define a generator function

    (iter-defun foo ()
      (let ((x (bar 1)))
        (iter-yield x)
        (iter-yield (+ x (bar 2)))))

the resulting iterator must somehow preserve value of `x' after
the first yield-point.  Therefore, the iterator function will
look something like this (simplified):

    (defun foo-iterator ()
      (let* (outer-scope-x
             to-execute
             (step-1 (lambda ()
                       (setf to-execute step-2)
                       (setf outer-scope-x (bar 1))
                       (throw 'yield outer-scope-x)))
             (step-2 (lambda ()
                       (throw 'yield (+ outer-scope-x (bar 2))))))
        (setf to-execute step-1)
        (build-iterator-object ...)))

Here `outer-scope-x' is the rebinding of `x' needed to somehow
send its value from first step closure to the second.

Iteration

    (let ((iter (foo-iterator)))
      (iter-next iter)
      (iter-next iter))

will then look like (omitting all the internal crap):

    (let ((iter (foo-iterator)))
      (call-to-execute iter)   ; here to-execute = step-1
      (call-to-execute iter))  ; here to-execute = step-2

But remember that the caller of `iter-next' knows nothing about
how iterator internally works and has no idea what it really
does and how it achieves the documented behavior (or doesn't,
when there is a bug).

Paul