[racket] generator performance
On Tue, Sep 18, 2012 at 12:59 PM, John Clements
<clements at brinckerhoff.org> wrote:
>
> On Sep 18, 2012, at 5:28 AM, Matthew Flatt wrote:
>
>> Meanwhile, it might be interesting to try implementing a `generator'
>> form that rewrites its body to implement `yield's that are
>> syntactically apparent (after local-expansion), leaving parameter and
>> continuations to handle the general case.
>
> +1! +1!
>
> I'm sure this idea flitted through about twenty minds yesterday.
>
> John
I've re-read this paragraph at intervals today. What could it mean for
"a yield to be syntactically apparent"?
All I can come up with so far is the following rough idea:
;; Here's a simplest-case generator, as a let loop:
(define foo
(generator
()
(let loop ([i 5])
(cond [(not (zero? i))
(yield i)
(loop (sub1 i))]))))
(foo) ;5
(foo) ;4
(foo) ;3
;; This macro distills the key pieces:
(define-syntax-rule (make-gen id init more? next)
(generator
()
(let loop ([id init])
(cond [more?
(yield id)
(loop next)]))))
;; Letting you define the same thing like this:
(define foo2 (make-gen i 5 (not (zero? i)) (sub1 i)))
(foo2) ;5
(foo2) ;4
(foo2) ;3
;; Given those same key pieces, the generator could instead be defined
;; as this equivalent simple producer procedure:
(define-syntax-rule (fake-gen id init more? next)
(let ([id init])
(lambda ()
(cond [more?
(begin0 id
(set! id next))]
[else (void)]))))
;; Which does yield (no pun intended) the same results:
(define foo3 (fake-gen i 5 (not (zero? i)) (sub1 i)))
(foo3) ;5
(foo3) ;4
(foo3) ;3
Is that even in the same ballpark as what flitted through the twenty minds?