You are looking at historical revision 7230 of this page. It may differ significantly from its current revision.

;;;Python-like generators in Scheme
 ;;;Michele Simionato ( May 2005
 ;;;Adapted from

 (define-macro (store/cc! name . body)
   (let ((k (gensym)))
      (lambda (,k) (set! ,name ,k) ,@body))))

 ; to spare parenthesis, real schemers will hate this one ;)
 (define-macro (let/ name value . args) 
   `(match-let ((,name ,value)) ,@args))

 ;; the core implementation
 (define (generator routine)
   (let/ (current status exit next) (list routine 'suspended #f #f)
      (() (if (eq? status 'dead)
	      (error 'dead-generator)
	      (let/ continuation-and-value
		(store/cc! exit
		   (let/ yield
		      (lambda (value)
			(store/cc! next
			   (exit (cons next value))))
		      (current yield) ; exits from here,
		      ;; except after the last yield
		      (set! status 'dead)
		      (error 'dead-generator)))
		(if (pair? continuation-and-value)
		    (begin (set! current (car continuation-and-value))
			   (cdr continuation-and-value))
      (('status?) status)
      (('dead?) (eq? status 'dead))
      (('alive?) (not (eq? status 'dead)))
      (('kill!) (set! status 'dead)))))

 ;; an example
 (define test
   (generator (lambda (yield)
		(yield "HELLO!")
		(yield "WORLD!"))))

 (test 'status?) ; suspended
 (test 'dead?) ; #f
 (test 'alive?) ; #t
 (test) ; "HELLO!"
 (test) ; "WORLD!"
 (test) ; Error: dead-generator
 (test 'status?) ; dead
 (test 'dead?) ; #t

 ;; another example:

 (define (list->iterator list)
   (generator (lambda (yield)
		(for-each yield list))))

 (define (iterator-empty? iterator)
   (iterator 'dead?))

 (define my-iterator
   (list->iterator (list 1 2 3)))

 (my-iterator) ; 1
 (my-iterator) ; 2
 (my-iterator) ; 3
 (iterator-empty? my-iterator) ; #f