Make it possible for the last expression in the body of a generator to

return any number of values.  They will be collected and used as the
repeat-forever result of calling the generator again.

Note: there's an exception for using no values -- instead of returning
no values forever, use void, since no values can be more surprising, and
it can happen when someone uses something like

  (generator (yield 1) (yield 2) (yield 3))

since the result of `yield' is (values).  (This will change in a
following commit, but even then it will be popular since people will
usually invoke the generator with no arguments which leads to the zero
values.  Could be solved if you use (g (void)) -- but that's awkward, I
think.)

svn: r17978
This commit is contained in:
Eli Barzilay 2010-02-05 03:21:59 +00:00
parent 5c54f3a5ac
commit 18c8e41fac

View File

@ -56,10 +56,18 @@
(shift-at yield-tag k (set! cont k) value)) (shift-at yield-tag k (set! cont k) value))
(reset-at yield-tag (reset-at yield-tag
(parameterize ([current-yielder yielder]) (parameterize ([current-yielder yielder])
(let ([retval (begin body0 body ...)]) (call-with-values
;; normal return: (lambda () (begin body0 body ...))
(set! cont (lambda () retval)) ;; only a normal return gets here
retval)))) (case-lambda
;; Note: in this case, the generator was invoked with no
;; arguments, so returning no values is more symmetric. But
;; this is a common case, and probably people would expect a
;; void result more than no values.
[() (set! cont void)]
[(r) (set! cont (lambda () r))]
[rs (set! cont (lambda () (apply values rs)))]))
(cont))))
(define (generator) (cont)) (define (generator) (cont))
generator)) generator))