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

 ;;;Python-like generators in Scheme
 ;;;Michele Simionato ( May 2005
 ;;;Adapted from
 ;;;Assumes you have the "match" module and "define-macro" enabled

 ;; in many schemes this is already defined
 (define-macro (let/cc k . body) 
   `(call/cc (lambda (,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) (list routine 'suspended)
      (() (if (eq? status 'dead)
	      (error 'dead-generator)
	      (let/ continuation-and-value
		(let/cc exit
		   (let/ yield
		      (lambda (value)
			(let/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!")
		(display "SORRY, I'M OUT"))))

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

 ;; 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