Search code examples
listrecursionschemelispracket

Recursively adding to a list using Scheme


I'm brand new to functional programming, and relatively new to programming as a whole. So I'm pretty lost trying to understand the syntax of Scheme. But this is a pretty simple question. I'm trying to create a function that recursively fills and prints a list from numbers x to y. Between recursion and this being a new language for me, I'm quite stuck.

 (define (gen-list x y)

  (if (> start end)

      '()

      (append '() (gen-list ((+ 1 x) y)) ) ))

If I were to enter in (gen-list 1 5) I would expect the result to be 1 2 3 4 5. This is currently giving me an error of "application: not a procedure" when it tries to call itself again. I have gotten around the error, but not been able to print anything remotely like what I'd like to. Any help is appreciated.


Solution

  • You have a couple of errors:

    • The parameters are called x and y, but you refer to them as start and end (I'd suggest to use start and end instead, they make the code easier to understand.)
    • You have more parentheses than needed in the last line. This is very important and an endless source of confusion for beginners. Don't surround all expressions with () unless you want to call a procedure.
    • We recursively build new lists with cons, append is for concatenating existing lists.
    • You're not actually using start, which is the current element in the recursion, to build the new list - you're just appending empty lists.
    • A list is an element consed to another list, or the empty list '(). That's why we return '() in the base case. For example, this is how a two-element list looks like: (cons 1 (cons 2 '())).

    With all said and done, this is the proper way to build our list:

    (define (gen-list start end)
      (if (> start end)
          '()
          (cons start
                (gen-list (+ start 1) end))))
    

    As a final comment: the above procedure already exists in Racket, you don't need to rewrite it. Read about range in the documentation.