0

I'm supposed to write a recursive function that applies another function to a set of consecutive integers and returns a list. If start is > than stop, I'm just supposed to return an empty set.

Here's what I've got. I'm not sure this is the best solution to the problem, but...

(define (myfunction start stop fn)
  (if (<= start stop)
      (cons (fn start)(myfunction (+ start 1) stop fn)))
 )

(define (foo val1) ; just to demonstrate myfunction
  (* val1 2))

When I try to use it in the scheme interpreter, I get this:

(myfunction 0 5 foo)
(0 2 4 6 8 10 . #<void>)

What can I do to get rid of the void thing? I'm a bit confused.

1 Answers1

3

Consider what happens if you do:

> (list (if #f 'then-value))
;=> (#<void>)

Your function has an if without an "else" part.

(define (myfunction start stop fn)
  (if (<= start stop)
      (cons (fn start)
            (myfunction (+ start 1) stop fn))
      ; missing something here
 ))

What should the list be when it's not the case that (<= start stop)? I'd guess that a reasonable default would be the empty list, so that when (myfunction (+ start 1) stop fn) is finally called with values of start and stop such that start is greater than stop, you get the empty list, so that (cons (fn start) (myfunction ...)) has an empty list as its second argument:

(define (myfunction start stop fn)
  (if (<= start stop)
      (cons (fn start)
            (myfunction (+ start 1) stop fn))
      '()))

(myfunction 0 5 (lambda (x) (* x 2)))
;=> (0 2 4 6 8 10)

For more about why the output was (<elements> . #<void>) (i.e., why it's got the dot at the end), have a look at this answer (disclaimer: it's my answer) to Recursive range in Lisp adds a period?.

Community
  • 1
  • 1
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353