#lang shplait macro 'generator $yield_id: $body': 'make_generator(fun($yield_id): // binds in `body` (fun (vd): // dummy argument $body))' fun make_generator(proc): def mutable yield: // <- assigned on each demand fun (x): #void def mutable go: // <- assigned to generator's state // initial state is the body function, // which needs a way to call yield: proc(fun (v): yield(v)) // represent a generator as this function: fun (): // generator's escape to yield jumps here: let_cc escape: // install `yield` for this time: yield := (fun (v): // save generator's continuation: let_cc k: go := k // escape with yielded value: escape(v)) // run generator until yield: go(#void) // ---------------------------------------- fun make_numbers(start_n): generator yield: // <- binds for use below block: fun numbers(n): begin: yield(n) // <- yield a value numbers(n + 1) numbers(start_n) def g = make_numbers(0) g() // => 0 g() // => 1 g() // => 2 // ...