Take the 2-minute tour ×

I'm trying to understand how to pass functions as arguments in scheme but I'm having a lot of trouble understanding tutorials. Here's what I'm trying to do:

(define (addone n)
(+ n 1))
(define (for-n start stop fn)
(if (< start stop)
    (cons (fn start) (for-n (+ start 1) stop fn))))

Basically I just want a function that returns the values of fn for start, start+1, ... start+stop in a list.

Expected output of (for-n 1 5 (addone 0)) would thus be (1 2 3 4 5). I think I'm really missing some very basic concepts here because I don't seem to even be calling the function in the interpreter correctly and I'm not grasping how to tell scheme to interpret fn as a function rather than just a regular parameter.

I figured it out (though through sheer trial and error) and I'm not sure what I did but at least it works!

 (define (function x)
(define (for-n start stop fn)
  (if (> start stop)
share|improve this question
Do you have a problem of just asking questions and leaving them undiscussed ..... The respondents put their valuable time to answer your question and leaving them like this , undiscussed or unaccepted...... is it justified ? –  PHI Jul 17 '13 at 4:46
add comment

2 Answers

The function invocation (addone 0) is equal to the value 1. If you want to pass the function addone itself (as opposed to 1), don't wrap it in parentheses at all. (for-n 1 5 addone) passes the addone function to for-n. If you wrap parentheses around it, Scheme will call addone and pass the result.

share|improve this answer
add comment

Some feedback, for you to know what was wrong with your first version:

  • The base case for a recursion that builds a list usually usually returns '() and not (list)
  • As you've already discovered, the condition for the base case was wrong: the recursion ends when (> start stop) and not when (< start stop) as initially stated
  • It's not necessary to define an addone procedure, at least in some Scheme interpreters there already exists a procedure called add1
  • Finally, when invoking a procedure that receives another procedure, just pass along the function, no need to apply it first - that will return a value and not a function as intended. What I mean to say is that this is wrong: (for-n 1 5 (addone 0)) and this is correct: (for-n 1 5 addone). When you write (addone 0) the function gets applied and returns the value 1, and what you intended to pass was addone, the procedure itself.

With all the above suggestions in place, this is how a correct procedure should look:

(define (for-n start stop fn)
  (if (> start stop)
      (cons (fn start) (for-n (add1 start) stop fn))))

Call it like this:

(for-n 1 5 add1)
> '(2 3 4 5 6)
share|improve this answer
add comment

Your Answer


