Recursively adding to a list using Scheme - list

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.

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.

One of the problems with the 'obvious' answer to this question is that it doesn't really work very well. Consider this:
(define (gen-list start end)
(if (> start end)
'()
(cons start
(gen-list (+ start 1) end))))
Well, if start is much less than end there are going to be a huge number of recursive calls on the stack, because this is a properly recursive function: the recursive call to gen-list is a real call and has to return before the call to cons (which is a tail call) can happen.
The way to deal with this is to turn patterns which look like (cons x (<recursive-call> ...)) into patterns which look like (<tail-call> ... (cons x ...)): you need a function with an extra argument, an accumulator. This means that the calls which were previously recursive are now tail calls and everything is therefore good: the process is now iterative.
The problem with this is that lists come out backwards (you need to think about why this is, but it's obvious after a bit of thought). So you then need to reverse the result. Fortunately reversing a list is also an iterative process, so that's OK.
But in this case, well, you can just count backwards! So a simple-minded approach looks like this, using a locally-defined auxiliary function (this can be defined as a top-level function, but why bother?):
(define (gen-list low high)
(define (gla i result)
(if (< i low)
result
(gla (- i 1) (cons i result))))
(gla high '()))
You can see this is counting backwards: the initial call to gla starts with high & then constructs the list backwards. So, now:
> (gen-list 1 3)
'(1 2 3)
As we want.
This is such a common pattern in Scheme that there is a special construct for it: named let. So we can rewrite the above more idiomatically as:
(define (gen-list low high)
(let gla ([i high] [result '()])
(if (< i low)
result
(gla (- i 1) (cons i result)))))
This is exactly the same as the previous answer: it just moves the initial call to the top and combines it with the local definition of gla. This is probably the idiomatic Scheme way to do something like this (although people who write more Scheme than me might differ: I'm really a CL person and have inevitably poor taste).
This is where the story should end, but I can't resist adding the following. In the bad old days of comp.lang.lisp, people used to ask obvious homework questions and since there was no karma system one approach was to give an answer which solved the problem ... while being absurdly opaque.
So first of all we can turn gla into a function which gets passed a continuation to call rather than knowing it must call itself:
(define (gen-list low high)
(let ([gla (λ (cont i result)
(if (< i low)
result
(cont cont (- i 1) (cons i result))))])
(gla gla high '())))
And then, of course we can turn (let ([x y]) ...) into ((λ (x) ...) y):
(define (gen-list low high)
((λ (gla)
(gla gla high '()))
(λ (cont i result)
(if (< i low)
result
(cont cont (- i 1) (cons i result))))))
And that's a nice, pure answer ... which no student would ever come up with.
An alternative approach which is even more malicious is just to explicitly use the Y combinator, of course.

Just adding tail call recursive version
(define (gen-list start end (acc '()) #:step (step 1))
(cond ((> start end) (reverse acc))
(else (gen-list (+ start step) end (cons start acc)))))
Personally I love cond because you have all the conditions then below each other (or an else) - this is the style of The little Schemer a very good book for learning recursive thinking.

You need more than just the (> start end) base case, you also need a (= start end) base case in which you return (list start)

Related

Iterative filtering odd numbers in list

Here is a task I have to solve: Write an iterative function, that receives a list with numbers and creates a new list, which only consists of the even numbers from the received list.
I even found a few posts with similar questions and solutions, but I couldn't use them as help, because in these solution they were using the "car" and "cdr" commands, which we haven't had in our schedule yet. How can do this? I would start like this:
(define filter-odds
(lambda(x)
(if (odd? x)
...)
Terrible oversight: no one has mentioned How To Design Programs, here. This kind of program is right smack in the middle of HtDP's path. Specifically, this is a totally straightforward application of the List template from section 9.3, "Programming with Lists." Perhaps your class is already using HtDP?
Well, in the absence of car ⁄ cdr accessors, your only other choice is using reduce from SRFI1:
(define filter-odds
(lambda (lst)
(reduce-right
(lambda (e ; list's element
acc) ; accumulated results from the right
(if (odd? e)
.... ; combine e and the results-so-far
.... )) ; ignore e
'()
lst )))
But, right reduce most likely won't be iterative. Left reduce usually is. It will build the result in reverse order though, but you can reverse a list iteratively in another pass, using the same approach, without filtering at all (i.e. using the test procedure which always succeeds).
With the first ⁄ rest accessors available though, all you need to do is to write down the implementation for reduce yourself, then fuse it into the definitions above:
(define reduce
(lambda (f acc ls)
(if (null? ls)
acc
(reduce f (f acc (first ls)) .....))))
In other words, just follow the above code skeleton and add replace the call to f with some checks for odd? or something, to get the filter-odd?-reversed; then figure out the f to use so as to define the reverse-list function.

Building a list with loops

We just covered loops today in class and I've got a few things I need to do. Put simply, I have to build a list using loops instead of recursion. I seem to be at a stumbling block here. For this example, we need to do a simple countdown. The function takes an argument and then returns a list of all the positive integers less than or equal to the initial argument. (countdown 5) => (5 4 3 2 1)
I'm having a hard time getting loops for whatever reason. The ones we talked about was Loop, Do, Dotimes, and Dolist. I've tried this with a couple loops and always end up with a similar result.
(defun countdown (num)
(cond ((= num 0) nil)
(T (let* ((list nil))
(loop
(if (= num 0) (return list)
(setf list (cons list num)))
(setf num (- num 1)))))))
My output shows up like this:
(((((NIL . 5) . 4) . 3) . 2) .1)
update: I've solved the issue. Apparently I needed to reverse the order in the cons, so num comes before list. Does anyone care to explain this? I thought you put the list first and then what you put second would be added to the end of it. At least, that's how I've been using it so far without issue.
Reverse the arguments to cons (and why)
You wrote in an answer (that, since it asks for more information, perhaps should have been a comment):
I've solved the issue. Apparently I needed to reverse the order in the
cons, so num comes before list. Does anyone care to explain this? I
thought you put the list first and then what you put second would be
added to the end of it. At least, that's how I've been using it so far
without issue.
The function is documented in the HyperSpec clearly: Function CONS. The examples in the documentation show, e.g.,
(cons 1 (cons 2 (cons 3 (cons 4 nil)))) => (1 2 3 4)
(cons 'a (cons 'b (cons 'c '()))) => (A B C)
(cons 'a '(b c d)) => (A B C D)
and even the note
If object-2 is a list, cons can be thought of as producing a new list which is like it but has object-1 prepended.
It may help to read through 14.1.2 Conses as Lists, as well, which includes:
A list is a chain of conses in which the car of each cons is an element of the list, and the cdr of each cons is either the next link in the chain or a terminating atom.
Concerning loop
Many of the answers here are pointing out to you that the loop form includes a special iteration language. That's true, but it can also be used in the way that you're using it. That way is called a simple loop:
6.1.1.1.1 Simple Loop
A simple loop form is one that has a body containing only compound
forms. Each form is evaluated in turn from left to right. When the
last form has been evaluated, then the first form is evaluated again,
and so on, in a never-ending cycle. A simple loop form establishes an
implicit block named nil. The execution of a simple loop can be
terminated by explicitly transfering control to the implicit block
(using return or return-from) or to some exit point outside of the
block (e.g., using throw, go, or return-from).
Simple loops probably aren't as common as loops using the nicer features that loop provides, but if you just covered this in class, you might not be there yet. The other answers do provide some good examples, though.
If you speaking about common lisp loop, your countdown may look like this:
(defun countdown (from-number)
(loop :for x :from from-number :downto 1 :collect x))
CL-USER> (countdown 10)
(10 9 8 7 6 5 4 3 2 1)
Using loop, which has its own "special-purpose language" that does not really look like Lisp:
(defun countdown (n)
(loop
for i from n downto 1
collect i))
Or using do:
(defun countdown (n)
(do ((i 1 (1+ i))
(res nil (cons i res)))
((> i n) res)))
See here, especially chapters 7 and 22.

Clojure - Recursive up function

Hi I'm kind of new to clojure and I'm trying to write a function called up that removes a pair of parentheses from each top level element of a list. If the top level element is not a list, then it is added as well. For example,
>(up '((1 2) (3 4)))
(1 2 3 4)
>(up '(x (y) z))
(x y z)
Right now, I'm having a problem with the function ending too soon if I'm trying to remove one pair of parentheses. I want to do this recursively and without the help of other functions if possible. What I have at the moment:
(defn up [lst]
(if (empty? lst)
()
(if (list? (first lst))
(up (first lst))
(cons (first lst) (up (rest lst))))))
I know that the problem is that I am cons-ing an empty list with the last element of a nested list which ends my function, but I can't figure out how else to do it.
Diego's comment seems to indicate there were other answers here, but I don't see them now, so here goes...
Your function ends too soon because, when it hits an item that is itself a list, it recursively calls up on that item and ignores the rest of the items in the original list. (up (first lst))
The minimal change to your code would be to, instead, recursively call up on the concatenation of that first list item and the rest of the list. (up (concat (first lst) (rest lst)))
Even better would be to use the existing core function flatten instead of up.
On a side note, you would generally want to achieve recursion using recur instead of calling up directly, in order to avoid a stack overflow for large input lists.

Scheme list counting function

I'm trying to write a Scheme function that counts all the items in a list, but unlike the length function that is available would count inner lists also so countAll '(a (a b)) would return 3 and not 2.
the first check is for an empty list, the second is supposed to check if the head of the list is currently a list itself, it should then add the length of THAT list to the total and call the next recursive call, if it isn't, it should simply skip to the third part which will add one to the total and call the function recursively.
I'm getting syntactical errors and I'm unsure about my approach. Am I going about this the right way? Are there better/Easier ways to do this?
(define countAll
(lambda (list)
(if (null? list)
0
((if (list? (car list)
(+ length (car list)
(countAll (cdr list))))))
(+ 1
(countAll (cdr list))))))
(+ 1
(countAll(cdr list)
)))))
You've made a mess of your parentheses. I would strongly advise rewriting this using cond, as in
(cond
((null? lst) 0)
((list? (car lst)) (???))
(else (???)))
This will make it easier to see what you are doing and much less likely that you mess up your parentheses. Nested ifs really are something to avoid except in the simplest of circumstances.
Your approach is nearly right, but you've missed something. You have made a big assumption about what happens when (list? (car lst)) evaluates to true. Can you think what it is? If you think about it hard enough, you'll realise that you cannot use the length function here.
The solution to this kind of problem follows a well-known structure, a recipe if you wish, for traversing a list of lists. This looks like homework, so I'll help you with the general idea and you go ahead filling-in the blanks:
(define (countAll lst)
(cond ((null? lst) ; if the list is empty.
<???>) ; then it doesn't have any elements
((not (list? (car lst))) ; if the first element in the list is not a list
(<???> (countAll <???>))) ; add one and advance the recursion over the `cdr`
(else ; otherwise
(+ (countAll <???>) ; add the result of the recursion over the `car`
(countAll <???>))))) ; with the result of the recursion over the `cdr`
If you need more help understanding how to structure a solution to this kind of problems dealing with lists of lists, I'd recommend you take a look at either The Little Schemer or How to Design Programs, both books will teach you how to grok recursive processes in general.
if you want to count elements of nested list you can use the deep recursion function as some people answer here. or what I do is use racket function (flatten) to make the nested list flat then use recursion on level 1 list as in the following code
(define (howMany ls)
(if (null? ls)
0
(+ 1 (howMany (cdr ( flatten ls )))))) ; flat the nested list and deal with it as a level 1 list.

Racket - output content of a list

I have defined a list (in Racket/Scheme):
(define myList (cons 'data1 (cons 'data2 (cons 'data3 (cons 'data4 empty)))))
or
(list 'data1 'data2 'data3 'data4)
And I want to write a function that cycles through the list and outputs all values of the list.
(define (outputListData list)
(cond
[(null? list) list]
[else (getListData)]))
With what function can I cycle through the content of the list? I know one can use first & rest to get list data, but I guess that's not the right way here.
BTW: Is there a good, compact racket reference like php.net? I find the official Racket docs very confusing ...
You can use a for loop. Example:
(for ([x (list 1 2 3)])
(printf "~s -> ~s\n" x (* x x)))
There are more functional ways to do this, of course, but this way works too. You'll probably want to look at a textbook like How To Design Programs to do the recursive approach. See: http://www.ccs.neu.edu/home/matthias/HtDP2e/
dyoo's solution is nice and succinct in a Scheme like Racket that has useful iteration routines built in. Just FYI, though, your 'outputListData' is not far from being the standard recursive way to do this. You just need to change a couple of lines:
(define (outputListData list)
(cond
[(null? list) #f] ; actually doesn't really matter what we return
[else (printf "~s\n" (first list)) ; display the first item ...
(outputListData (rest list))])) ; and start over with the rest
Since this is an "imperative" kind of procedure that isn't designed to return a value, it doesn't really matter what we do with an empty list so long as we stop recurring (to avoid an infinite loop). If the list isn't empty, we output the first element and start over recursively with the rest of the list.
BTW, here's another way you could write something almost identical if you just needed a "for" loop in the middle of some other function:
(let loop ((l (list 'foo 'bar 'baz 'quux))) ; or put whatever input you need
(cond ((null? l) #f)
(else
(printf "~s\n" (first l))
(loop (rest l)))))
One way to think about this "named let" is that it defines a temporary function called loop, which works just like outputListData above. Scheme has the nice property that it won't grow the stack for "tail calls" like these, so you can always write what would be an "iterative" for or while loop in this recursive style.
I highly recommend The Little Schemer by Friedman and Felleisen for a quick intro to this style of function writing! I found it through Douglas Crockford's page here.
Edit as per comments: Use for-each
(for-each display myList)
Try this:
(void (map display myList))
Breaking it down:
(void x) causes x to be ignored instead of returned to the REPL/parent expression as a value.
(map function lst): For a list '(a1 a2 ... an) returns the list '((function a1) (function a2) ... (function an)).
So we use map to display all the items, but since we only care about the side-effect and not the return value, we call void on the returned list.
Official docs:
void
map
I think the solution that is the easiest to understand it to come up with a so called "list-eater" function. This is the way my university introduced recursion and lists in Racket. Also most books on Racket (i.e. "How To Design Programs" or "Realm Of Racket") explain it this way. This is the code:
(define my-list (list 'data1 'data2 'data3 'data4))
(define (print-list a-list-of-data)
(when (not (empty? a-list-of-data))
(print (first a-list-of-data))
(print-list (rest a-list-of-data))))
If you call the function with the example list my-list, you will get the following output:
(print-list my-list)
'data1'data2'data3'data4
The function does the following: As long as the given list is not empty, it grabs the first element of that list and passes it to the function print. Then, it tells itself to do the exact same thing with the rest of the list. (It calls itself on the rest of the list.) This second part is what they call recursion.
However, you can shorten that by using a function called map:
(define (print-list a-list-of-data)
(map print a-list-of-data))
This basically says that you want the function print to be called on each element of the given list. The output is exactly the same.
Hope it helped!