[racket] Can't `yield' multiple values when `in-generator' is returned from a function?

From: Greg Hendershott (greghendershott at gmail.com)
Date: Fri Sep 14 08:20:22 EDT 2012

tl'dr: I can `yield' multiple values when an `in-generator' sequence
is used directly in a comprehension, but not when it is returned from
a function. I'm stumped.


Let's try using the `in-generator' sequence directly in a comprehension:

;; Yield 1 value, directly using `in-generator`
(for/list ([x (in-generator (for ([i (in-range 4)])
                              (yield i)))])
  x)
;; => '(0 1 2 3)

;; Yield 2 values, directly using `in-generator`
(for/list ([(x y) (in-generator (for ([i (in-range 4)])
                                  (yield i 0)))])
  (cons x y))
;; => '((0 . 0) (1 . 0) (2 . 0) (3 . 0))

Great!

Next, let's try using the `in-generator' sequence as returned from a
function. As best I can understand from the docs, this should work. It
does for the case of yield-ing 1 value -- but not 2 values:

;; Yield 1 value, using `in-generator' returned from a function:
(define (in-gen-1)
  (in-generator (for ([i (in-range 4)])
                  (yield i))))
(for/list ([x (in-gen-1)])
  x)
;; => '(0 1 2 3)

;; Yield 2 values, using `in-generator' returned from a function:
(define (in-gen-2)
  (in-generator (for ([i (in-range 4)])
                                  (yield i 0))))
(for/list ([(x y) (in-gen-2)])
  (cons x y))
;; ==> EXCEPTION:
; .../private/for.rkt:1046:17: arity mismatch;
;  the expected number of arguments does not match the given number
;   expected: 1
;   given: 2
;   arguments...:
;    0
;    0

Why?

Posted on the users mailing list.