In Scheme, you can't have mutliple things going on in one branch of an
if form. The syntax for
if is
(if predicate expression [alternate])
So Scheme is expecting to return an expression if the predicate is true, instead it finds this:
((write (f iter))
(newline)
(loopf N (+ iter 1) f))
Now, this has the form
(item1 item2 item3)
In Lisp, the rule is that when we see something like that, we evaluate
item2, and
item3, and then apply item1 to them. This means that item1 should be a function. But in our case
item1 is
(write (f iter)) which is definitely
not a function. Scheme panics and throws up all over the output!
Luckily, there is a way to specify a sequence of actions as an
if branch expression:
the begin special form.
begin will evaluate your list items in sequence, and return the result of evaluating the last item as the value of the expression, satisfying the
if form.
(define (loopf N iter f)
(if (not (= iter N))
(begin
(write (f iter))
(newline)
(loopf N (+ iter 1) f))))
(loopf 10 0 (lambda (x) (* x x)))
Now stylistically, you can write functional programs without loops by utilizing maps and folds.
For example, let's assume you have a function
range
(define (range a b)
(cond
((< a b) (cons a (range (+ a 1) b)))
((> a b) (cons a (range (- a 1) b)))
((= a b) (cons a '()))))
So that the expression
(range 1 5) yields
(1 2 3 4 5), you could implement the above loop as follows:
(map (lambda (x) (begin (write (square x)) (newline) x)) (range 0 9))
The result of evaluating this expression is the list
(0 1 2 3 4 5 6 7 8 9) and it has the
side effect of printing the squares of those values on the screen, separated by newlines.
The reason the above expression evaluates to the list of numbers from 0 to 9 is that
begin evaluates to the value of the last expression in its list, which is
x, the input to the function that we map over the range.
For each item in the original list,
map will apply the function to that item, and put the result of the function in a new list.
I hope that made sense and I wasn't just rambling. Have fun with Scheme! SICP is a masterpiece. :D