Yeah, that works. I came up with a similar scheme where if the value that's
passed to the generator is an exception, it will raise it. Your scheme is a
little simpler, but for completeness I listed mine below too. One thing I'm
still a little unhappy with is that whoever uses it, needs to remember to
use ((yield)) (or in my version (yield*)). I'm trying to build a discrete
event simulator where generators are used as processes. My idea was to use
exceptions as a way to interrupt processes (actually it's not really my
idea; this is how simpy
<https://simpy.readthedocs.io/en/latest/topical_guides/process_interaction.html#interrupting-another-process>
does it).
While this scheme works, it silently breaks if a user accidentally calls
(yield) instead of ((yield)). It might not be a big deal, but in an ideal
world I'd only allow the 'correct' way.

===
(define-syntax-rule (yield* . vals)
  (call-with-values (thunk (yield . vals))
                    (case-lambda
                      [() (void)]
                      [(v) (if (exn? v)
                               (raise v)
                               v)]
                      [vs vs])))

(define mygenerator2 (generator ()
                                (with-handlers ([exn? (lambda (e) (yield*
42))])
                                  (yield* 1)
                                  (yield* 2)
                                  (yield* 3))))
===
> (mygenerator)
1
> (mygenerator (exn:fail "Welp" (current-continuation-marks)))
42



On Tue, Feb 19, 2019 at 10:36 PM Jon Zeppieri <[email protected]> wrote:

>
>
> On Tue, Feb 19, 2019 at 9:57 PM Kees-Jochem Wehrmeijer <[email protected]>
> wrote:
>
>> Basically when I call the function throw. So e.g.
>>
>> (define mygenerator (generator ()
>>                                (with-handlers ([exn:fail? (lambda (e)
>> 42)])
>>                                  (yield 1)
>>                                  (yield 2)
>>                                  (yield 3))))
>>
>> > (mygenerator)
>> 1
>> > (throw mygenerator)
>> 42
>>
>>
> The most straightforward thing would be to pass the generator a thunk that
> either raises or does not, e.g,
>
> #lang racket/base
>
> (require racket/generator)
>
> (define mygenerator
>   (generator (thunk)
>              (with-handlers ([exn:fail? (lambda (e) 42)])
>                (thunk)
>                ((yield 1))
>                ((yield 2))
>                ((yield 3)))))
>
> ===
> > (mygenerator void)
> 1
> > (mygenerator (λ () (raise (exn:fail "wah"))))
> 42
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to