I'd like to make an iterator that yields pairs:

(0 1)
(1 1)
(1 2)
(2 2)
(2 3)
(3 3)

I've tried variants of the following:

(iter-defun iter-rectangle-sizes ()
  (let ((rect '(0 1)))
    (while t
      (let ((a (car rect))
            (b (nth 1 rect)))
        (if (> b a)
            (setq rect (list (1+ a) b))
          (setq rect (list a (1+ b))))
        (iter-yield rect)))))

But I'm getting this error that don't understand when I try to create the iterator:

ELISP> (setf rectangles (iter-rectangle-sizes))
 ((cps-state-atom-68 closure #1 nil
                     (setf cps-current-value-40
                               '(0 1)
                             (setf cps-current-state-41 cps-state-let*-67))))
  (cps-state-let*-67 closure #1 nil
                     (setf cps-binding-cps-binding-rect-43-44 cps-current-value-40 cps-current-state-41 cps-state-atom-66))
  (cps-state-atom-66 closure #1 nil
                     (setf cps-current-value-40
                           (prog1 cps-binding-cps-binding-rect-43-44
                             (setf cps-current-state-41 cps-state-let*-65))))
  (cps-state-let*-65 closure #1 nil
                     (setf cps-binding-rect-45 cps-current-value-40 cps-current-state-41 cps-state-atom-47))
  (cps-state-while-46 closure #1 nil
                        (setf cps-current-state-41
                              (if cps-current-value-40 cps-state-atom-64 cps-state-terminal-42))))
  (cps-state-atom-64 closure #1 nil
                     (setf cps-current-value-40
                               (car cps-binding-rect-45)
                             (setf cps-current-state-41 cps-state-let*-63))))
  (cps-state-let*-63 closure #1 nil
                     (setf cps-binding-cps-binding-a-48-50 cps-current-value-40 cps-current-state-41 cps-state-atom-62))
  (cps-state-atom-62 closure #1 nil
                     (setf cps-current-value-40
                               (nth 1 cps-binding-rect-45)
                             (setf cps-current-state-41 cps-state-let*-61))))
  (cps-state-let*-61 closure #1 nil
                     (setf cps-binding-cps-binding-b-49-51 cps-current-value-40 cps-current-state-41 cps-state-atom-60))
  (cps-state-atom-60 closure #1 nil
                     (setf cps-current-value-40
                           (prog1 cps-binding-cps-binding-a-48-50
                             (setf cps-current-state-41 cps-state-let*-59))))
  (cps-state-let*-59 closure #1 nil
                     (setf cps-binding-a-52 cps-current-value-40 cps-current-state-41 cps-state-atom-58))
  (cps-state-atom-58 closure #1 nil
                     (setf cps-current-value-40
                           (prog1 cps-binding-cps-binding-b-49-51
                             (setf cps-current-state-41 cps-state-let*-57))))
  (cps-state-let*-57 closure #1 nil
                     (setf cps-binding-b-53 cps-current-value-40 cps-current-state-41 cps-state-atom-56))
  (cps-state-atom-56 closure #1 nil
                     (setf cps-current-value-40
                                   (> cps-binding-b-53 cps-binding-a-52)
                                   (setq cps-binding-rect-45
                                          (1+ cps-binding-a-52)
                                 (setq cps-binding-rect-45
                                       (list cps-binding-a-52
                                             (1+ cps-binding-b-53))))
                             (setf cps-current-state-41 cps-state-atom-55))))
  (cps-state-atom-55 closure #1 nil
                     (setf cps-current-value-40
                           (prog1 cps-binding-rect-45
                             (setf cps-current-state-41 cps-state-iter-yield-54))))
  (cps-state-iter-yield-54 closure #1 nil
                             (setf cps-current-state-41 cps-state-atom-47)
                             (throw 'cps--yield cps-current-value-40)))
  (cps-state-atom-47 closure #1 nil
                     (setf cps-current-value-40
                           (prog1 t
                             (setf cps-current-state-41 cps-state-while-46))))
  (cps-state-terminal-42 closure #1 nil
                         (signal 'iter-end-of-sequence cps-current-value-40))
  (cps-current-state-41 closure #1 nil
                        (setf cps-current-value-40
                                  '(0 1)
                                (setf cps-current-state-41 cps-state-let*-67))))
 (op value)
  ((eq op :close)
   (setf cps-current-state-41 cps-state-terminal-42 cps-current-value-40 nil))
  ((eq op :next)
   (setf cps-current-value-40 value)
       ((yielded nil))
             (catch 'cps--yield
               (while t
                 (funcall cps-current-state-41)))
           (setf yielded t))
       (unless yielded
         (setf cps-current-state-41 cps-state-terminal-42 cps-current-value-40 nil)))))
   (error "unknown iterator operation %S" op))))

I could leave without generators, but I'm curious about what I'm doing wrong here.

By the way, I'm a beginner with elisp, so don't hesitate to critic iter-rectangle-sizes, even if it's not directly related to the error I'm seeing.


There is no error, the (error "unknown iterator operation %S" op) is part of the closure. Simply type (iter-next rectangles) repeatedly, you will see the expected result. cl-loop also provides a syntax sugar for generators:

(cl-loop repeat 5
         for r iter-by (iter-rectangle-sizes)
         collect r)
;; => ((1 1) (1 2) (2 2) (2 3) (3 3))
  • omg, I spent 30 minutes trying to "fix" this, and I didn't even try to use the iterator... Thanks @xuchunyang! – little-dude May 16 at 16:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.