I started Scheme, I'm reading SICP. Finally!
While experimenting with Scheme I came across an error that I cannot explain.

Here's the code:
(define square (lambda (x)
                 (* x x)))

(define (loopf N iter f)
  (if (not (= iter N))
      ((write (f iter))
       (newline)
       (loopf N (+ iter 1) f))))

(loopf 10 0 square)
loopf is supposed to execute procedure f, N times, similar to a C for loop.
Here's the output I get:
$ ./scheme ../scripts/loopf.scm
0
1
4
9
16
25
36
49
64
81
Error: (../scripts/fib.scm : 10) illegal function
Errors encountered reading ../scripts/loopf.scm
My question: Why do I get an error at the end of my loop?
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
5 days later
Hey thanks for the info. You kinda lost me with "map" and I don't know what "cons" does, but the first part of your answer made so much sense.

I reimplemented a loop; except this time in a setting that makes a bit more sense:
This function returns f(a) + f(a+1) + f(a+2) + ... + f(b)
(define (sumf f a b)
  (if (> a b)
      0
      (+
       (f a)
       (sumf f (+ a 1) b))))