You are looking at historical revision 1620 of this page. It may differ significantly from its current revision.
;;;Python-like generators in Scheme ;;; ;;;Michele Simionato (michele.simionato@gmail.com) May 2005 ;;;Adapted from http://c2.com/cgi/wiki?SchemeCoroutineExample ;;;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) (match-lambda* (() (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)) 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