Monday, June 28, 2010

Loop in Racket

FWIW, I like to assert that the familiar "FOR A = 1 TO 10" is actually
not often needed in idiomatic Scheme.  More often, you're processing a
sequence, or you're doing functional programming such that you need to
recurse anyway to avoid mutation, or you need premature exits
sometimes.  One possible exception that comes to mind is if you're
writing a matrix math library, but in that case you might make your own
procedures or syntax for iterating/folding over matrices in different ways.

Anyway, for the benefit of anyone new to syntax extensions, here is a
syntax definition that supports the "for-loop" example (warning: it
doesn't error-check as much as it should, because that would clutter the
example).  You can paste this into DrRacket and use the Macro Stepper to
watch how it expands.


#lang scheme/base

(define-syntax for-loop
  (syntax-rules ()
    ((_ (VAR START END) BODY0 BODY1 ...)
    (let ((end-val END))
      (let loop ((VAR START))
        (if (> VAR end-val)
            (void)
            (begin BODY0 BODY1 ...
                    (loop (add1 VAR)))))))))
           
(for-loop (i 1 10) (print i))
                 
---



It's there:

(for/list ([i (in-range 1 10)]) i)

prints out

'(1 2 3 4 5 6 7 8 9)


All about for loops: http://docs.racket-lang.org/guide/for.html

No comments: