Skip to content

Instantly share code, notes, and snippets.

@ijp
Created November 20, 2011 22:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ijp/1381091 to your computer and use it in GitHub Desktop.
Save ijp/1381091 to your computer and use it in GitHub Desktop.
#!r6rs
;; Really simple generators using delimited continuations
(library (toys simple-generators)
(export make-generator
up-from
list->generator)
(import (rnrs)
(spells delimited-control))
(define (make-generator proc)
(define (next dummy)
;; dummy necessary for spells version of shift/reset
(reset
(begin
;; call procedure with a 'yield' procedure as its argument
(proc (lambda (value)
(shift k
(begin
;; save continuation of call to 'yield' and
;; make that the next function
(set! next k)
value))))
;; When the generator 'runs out' this symbol is returned, an
;; exception as in python or a special object like
;; (eof-object) would work equally well.
;;
;; This could be improved by mutating a 'finished?' variable,
;; so that any actions after the final call to yield only get
;; performed once.
'end-of-generator)))
(lambda ()
(next 'dummy)))
(define (list->generator list)
;; Turns lists into thunks that produce those values one at a time
(make-generator
(lambda (yield)
(for-each yield list))))
(define (up-from n)
;; Simple example of an infinite generator
(make-generator
(lambda (yield)
(let loop ((n n))
(yield n)
(loop (+ n 1))))))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment