Simple loops in Scheme

October 10, 2009
by Lee Spector (lspector)

After that post on memoization, which used very fancy features of Scheme, I thought I’d post some answers to questions I’ve received on much less fancy stuff, for creating iterative (non-recursive) loops in Scheme. Here’s about the simplest kind of iterative loop:

(for ((x (in-range 3 12)))
 (printf "~A\n" x))

The thing after the variable name can be anything that produces a sequence or list, so this also works:

(for ((x '(fee fi fo fum)))
 (printf "~A\n" x))

Those loops just execute their bodies for “side effects,” but there are related procedures that will return a result of all of the looping, like:

(for/list ((x (in-range 3 12)))
 (* x 2))

This returns a list of whatever was returned from each time through the body of the loop.

“for” and friends can also loop over more than one variable at a time and do some other somewhat fancy things. The “do” procedure is sort of the most powerful variant of all of these, making it easy (among other things) to leave the loop whenever a condition is met, instead of keeping going through as many times as indicated at the beginning. Because of its generality the syntax is also a little confusing at first, but here’s a fairly simple example:

(do ((car1-position 0 (+ car1-position 5))
     (car2-position 100 (- car2-position 4)))
  ((> car1-position car2-position)
   (printf "Crash detected, Car1: ~A, Car2: ~A\n"
           car1-position car2-position)
   (abs (- car1-position car2-position)))
  (printf "Cruising along, Car1: ~A, Car2: ~A\n"
          car1-position car2-position))

Other procedures that loop in some sense, and that are worth checking out, are “map” and the various versions of “fold”.

-Lee



Leave a Reply

You must be logged in to post a comment.