86 lines
2.1 KiB
Markdown
86 lines
2.1 KiB
Markdown
# awesome-coroutine-generators
|
|
|
|
Welcome. Did you ever feel limited by the strict dogma of srfi-158 generators? Me neither. I just read Mark's thoughts about srfi-158 and thought I would implement them properly. This library is multi-way incompatible with srfi-158.
|
|
|
|
They allow you to write coroutine generators without having to deal with any nitty gritty details:
|
|
|
|
``` scheme
|
|
(import (awesome-coroutine-generators base))
|
|
(define simple-gen
|
|
(simple-generator
|
|
(let loop ((a 0))
|
|
(when (< a 100)
|
|
(yield a)
|
|
(loop (+ a 1))))
|
|
"Happy end!"))
|
|
|
|
;; We can now call a and it will yield the values 0 to 99.
|
|
(simple-gen) ;; => 0
|
|
(simple-gen) ;; => 1
|
|
...
|
|
(simple-gen) ;; => 99
|
|
(simple-gen) ;; => #<<generator-end> list-of-returned-values ("Happy end!")>
|
|
|
|
;; This looks very much like the coroutine-generators of srfi-158, but wait, there is more:
|
|
|
|
(define g
|
|
(generator (a b)
|
|
(let loop ((a a) (b b))
|
|
(yield a)
|
|
(loop b (+ a b)))))
|
|
|
|
;; prime the generator (if we use 1 1 it will generate the common fibonacci sequence)
|
|
(g 2 1)
|
|
;; Now it yields lucas numbers.
|
|
(g) ; => 2
|
|
(g) ; => 1
|
|
(g) ; => 3
|
|
|
|
;;
|
|
;; We can also pass values INTO the generator
|
|
|
|
(define g
|
|
(generator ()
|
|
(let loop ((start (yield)))
|
|
(when (>= start 0)
|
|
(yield start)
|
|
(loop (- start 1))))))
|
|
|
|
;; First, prime the generator. This is done to reach the point where it accepts
|
|
;; input:
|
|
(g)
|
|
;; Then we pass start into it:
|
|
(g 2)
|
|
(g) ; => 2
|
|
(g) ; => 1
|
|
(g) ; => 0
|
|
(g) ; <genertor-end>
|
|
|
|
;; We can also pass control over to another generator
|
|
|
|
(define generate-3-values
|
|
(generator ()
|
|
(let ((next (yield 1)))
|
|
(yield next)
|
|
(yield 'the-end))))
|
|
|
|
(define g
|
|
(generator (g2)
|
|
(yield-from g2)
|
|
(yield "banana")))
|
|
|
|
(g generate-3-values)
|
|
(g) ;; => 1
|
|
(g 55) ; => 55
|
|
(g) ; => 'the-end
|
|
(g) ; => "banana"
|
|
|
|
|
|
```
|
|
# Details
|
|
If you want to check whether the yield returned a value, wrap it in (maybe-none (yield val)) and test it with none?.
|
|
|
|
|
|
# Licence
|
|
Public domain, or CC0. Whichever work best in your jurisdiction. If you build something from this, i'd be delighted to be mentioned by name.
|
|
|