scheme – Implementing a for loop in racket

scheme – Implementing a for loop in racket

First off for in #lang racket is purely for side effects. Usually you would want the other variants like for/map and for/fold that ends up producing a value.

Racket is a descendant of Scheme and all looping in it is just syntactic sugar for a recursive function being applied. As an example the do loop:

(do ((vec (make-vector 5))
     (i 0 (+ i 1)))
    ((= i 5) vec)
  (vector-set! vec i i))                  
; ==>  #(0 1 2 3 4)

In reality the language doesnt have do as a primitive. Instead the implementation usually have a macro that makes it into this (or something similar):

(let loop ((vec (make-vector 5)) (i 0))
  (if (= i 5)
      vec
      (begin
        (vector-set! vec i i)
        (loop vec (+ i 1)))))

This is of course just sugar for this:

((letrec ((loop (lambda (vec i)  
                    (if (= i 5)
                        vec
                        (begin
                          (vector-set! vec i i)
                          (loop vec (+ i 1)))))))
   loop)
 (make-vector 5) (i 0))

And of course letrec is also sugar… It goes down to just using lambda at some level.

Here is an example. The function squares produces a list of the first n square numbers. To produce that list, it loops over the number 0, …, n-1 using an index i.

 (define (squares n)
    (define (loop i)
      (if (= i n)
          ()
          (cons (* i i) (loop (+ i 1)))))
    (loop 0))

 (squares 10)

scheme – Implementing a for loop in racket

Leave a Reply

Your email address will not be published.