Scheme: Defining Familiar Iteration Forms

This page provides Scheme definitions for some iteration forms familiar from other languages.

Requirements

We use the following to implement the forms:

(define-syntax define-simple-syntax
  (syntax-rules ()
    ((_ (name arg ...) body ...)
     (define-syntax name (syntax-rules () ((name arg ...) (begin body ...)))))))

While

See Java, C, C++, Python, etc.

;;; (while condition body ...)
;;;
(define-simple-syntax (while condition body ...)
  (letrec ((loop (lambda () (if condition (begin body ... (loop)))))) (loop)))

In case you're wondering: the implementation is tail-recursive which Scheme recognizes, thus it won't overflow the stack.

For

See Java, C, C++, etc.

;;; (for ((v1 a1) ...) condition step body ...)
;;;
;;;    initialize vi's to ai's, in order
;;;    check condition, execute body, execute step, repeat
;;;  
(define-simple-syntax (for ((v1 a1) ...) condition step body ...)
  (let* ((v1 a1) ...) (while condition body ... step)))

; Example: long way to add up 1 to 100
;   Uses some of the definitions from "Defining Common Operations on Variables"
(define sum 0)
(for ((i 1)) (<= i 100) (++ i) (+= sum i))

Python's for

Iterate through a list, setting a variable to each element successively.

;;; (for e in list body ...)
;;;
;;;    Iterate through list, executing body with e set to current element.
;;;
(define-syntax for
  (syntax-rules (in)
    ((for elt in list body ...)
     (for-each (lambda (elt) body ...) list))))

; Example: displays 123
(for e in '(1 2 3) (display e))