From 18c8e41fac201d84a308b42f57f2dc5cc5107e2d Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 5 Feb 2010 03:21:59 +0000 Subject: [PATCH] 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 --- collects/scheme/generator.ss | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/collects/scheme/generator.ss b/collects/scheme/generator.ss index a8be9c3fae..81b9bb8961 100644 --- a/collects/scheme/generator.ss +++ b/collects/scheme/generator.ss @@ -56,10 +56,18 @@ (shift-at yield-tag k (set! cont k) value)) (reset-at yield-tag (parameterize ([current-yielder yielder]) - (let ([retval (begin body0 body ...)]) - ;; normal return: - (set! cont (lambda () retval)) - retval)))) + (call-with-values + (lambda () (begin body0 body ...)) + ;; only a normal return gets here + (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)) generator))