Tail Recursion Understanding - recursion

I was wondering if anyone could walk me through tail recursion. I have this procedure I made in Racket and I would like a simple explanation on what steps I should take to utilize what I have in the form of tail recursion.
The code in Racket is as follows,
;SQUARE LIST FUNCTION
(define (square-list lst)
(cond
[(empty? lst) 0]
[else (map (lambda (i)
(* i i)) lst)]))
OR better defined as.
(define (square-list lst)
(for-each (lambda (i)
(printf "Iteration: ~a\n" (* i i)))lst))
So I really just want to know:
How should I approach changing this procedure into a tail-recursive procedure?

Both your examples are tail call optimized in the sense that, an interpreter can look at it and see that in the first case the cond is always executed as the last expression of this function call. This means that it does not keep stack. In your second example it can tell that the for-each statement will always be executed last.
For didactic purposes, have a look at the function below:
(define (square-list ls)
(if (empty? ls)
'()
(let ((first-square (* (car ls) (car ls))))
(cons first-square (square-list (cdr ls)))))
In this function you will calculate the square of the first element. Then the result of the square of the entire list is this square, cons'd to the front of a recursive call to the function to do the same for the rest of the list.
The point is that in this case, the interpreter has to remember the first-square value, then calculate the rest of the squares and finally create a list out of them. The remembering part is what makes a function non-tail recursive.
So it basically boils down to help your interpreter remember as little as possible by building up your output and passing the intermediate resulsts consecutive calls to the function. So how can we do this? Simple, you pass your squared values into the recursive call and make sure the recursive call is the last statement in your function body.
(define (square-list ls squares)
(if (empty? ls)
squares
(let ((first-square (* (car ls) (car ls))))
(square-list (cdr ls) (cons first-square squares)))
What we do here is create the output (list of squares) in the call of the function. This means that every recursive call gets a list of already squared values. So in the body we simply take a value of the "unsquared" list and cons the value to the list of squared values.
So calling this function is as simple as:
(square-list '(1 2 3) '())
In each iteration we will take the first value from the input list, square it and cons it to the output list.
(Note: this will produce the reverse squared list)
Example in REPL
Welcome to DrRacket, version 5.3.6 [3m].
Language: racket; memory limit: 128 MB.
> (define (square-list ls squares)
(if (empty? ls)
squares
(let ((first-square (* (car ls) (car ls))))
(square-list (cdr ls) (cons first-square squares)))))
> (square-list '(1 2 3) '())
'(9 4 1)
>

Related

Determine if a list of numbers forms an arithmetic sequence, using higher-order functions, lambda

How can I define a function that determines if a list of numbers is an arithmetic sequence, using lambda, and only either of the higher-order-functions filter, map, or foldr (but not build-list)?
I was thinking of forming a list of all the consecutive differences and then checking if they are all equal, but that would involve the build-list function.
Another approach I thought of was to use foldr, but I'm not sure how I can calculate the common differences between each consecutive term.
If you're allowed to use the srfi/1 version of map (which allows uneven input lists, unlike the racket/base version), then it's really easy:
(require srfi/1)
(define (arithmetic-sequence? lst)
(apply = (map - lst (cdr lst))))
If you're only able to use racket/list functions, then you'd have to do some list trimming:
(define (arithmetic-sequence? lst)
(apply = (map - (drop-right lst 1) (cdr lst))))
foldr can be called with more than one argument lists. For instance, you can call it with the input list, and its cdr. Then in the combining function you'd find the difference and compare it to
(- (cadr xs) (car xs))
which you'd calculate in advance.
Unfortunately, both lists must be of the same length, so instead of plain (cdr xs) you'd have to use e.g.
;; (append (cdr xs) (list #f))
(foldr cons (list #f) (cdr xs))
and modify the combining function accordingly:
(lambda (a b r)
(and (or ....
(= (- b a) the-diff))
r))
(r standing for "recursive result").

Matrix Transpose Common Lisp

Well, i've been told to make a Matrix Transpose function in common lisp. I'm a beginner, so i don't know so much of it.
My Matrix is a list of lists, and i can't use apply, mapcar or similar to solve it, just CONS, CAR and CDR. If not, my solution would be this (I put this solution so someone can use it):
(DEFUN transpose (List)
(apply #'mapcar #'list List)
)
But I can't use anything of the above.
The function has to be recursive, no loops or similar.
So, the question is, how could this be done?
This is how far i've gone, but it gets me an overflow error. I don't really know how to do it (i could have done it in C++ or Java, but i'm asked to do it in Lisp...)
(DEFUN transpose (Matrix)
(COND ((NULL Matrix) NIL
)
(T (CONS (CAR(CAR Matrix))(transpose (CONS (CAR(CDR Matrix)) (CDR Matrix))))
)
)
)
Any help would be thanked!
Here is a simple solution that does not use iteration or high-order functions.
(defun cars (matrix)
"Return a list with all the cars of the lists in matrix"
(if (null matrix)
nil
(cons (car (car matrix)) (cars (cdr matrix)))))
(defun cdrs (matrix)
"Return a list with all the cdrs of the lists in matrix"
(if (null matrix)
nil
(cons (cdr (car matrix)) (cdrs (cdr matrix)))))
(defun transpose (matrix)
"Transpose matrix"
(cond ((null matrix) nil)
((null (car matrix)) nil)
(t (cons (cars matrix) (transpose (cdrs matrix))))))
The function transpose uses two auxiliary functions: cars returns a list with all the first elements of the lists representing the matrix, while cdrs returns a list with all the remaining parts of the lists representing the matrix, so we can use the recursion.
cars works by applying recursively car to all the elements of the lists (that are lists), and returns a list obtained by “consing” them; cdrs works in the same way, this time applying cdr instead of car.

How can I add an object to each element of a list in LISP?

I'm trying to write a function that adds an element to each element of a given powerset. No matter what it always evaluates (null pset) as true. I can't understand why.
Here's what I have so far:
(defun addxtopowerset(x pset)
(cond
((null pset) (list x '())) ; If the powerset is null, display x and NIL.
;;First display a list combining x and the first item of pset. Then display the first item of pset itself. Then recursively call the function passing the rest of pset as a parameter.
(T (list 'x (car pset))(list (car pset))
(addxtopowersetch x (cdr pset)))))
First, note that in the terminal case you should return an empty list, since is in the recursion that all the elements of the powerset are processed, and we should assume that a powerset is always a list of list, each of them representing a set (in fact, the powerset of an empty set contains at least one element, the empty set itself).
So, since a powerset is a non-empty list, the task of adding a new element to the powerset can be solved by adding to the result, for each list of the powerset, both the list and a copy of the list with the element added.
In both cases, “add” means: get something and return a new-something, and use the value returned, otherwise, as Rainer Joswig note, “the result go straight into the digital nirvana”. In other words, in the recursive case your function must add the two values, the list and the new list with the element added, to the result of the recursive call. So, here is the function:
(defun addxtopowerset(x pset)
(if (null pset)
nil
(append (list (car pset) (cons x (car pset)))
(addxtopowerset x (cdr pset)))))
Finally, here a couple of alternative ways of defining the function, the first one with the high order function mapcan:
(defun addxtopowerset(x pset)
(mapcan (lambda(y) (list y (cons x y))) pset))
and the second one with a loop:
(defun addxtopowerset(x pset)
(loop for y in pset append (list y (cons x y))))

The mechanism of anonymous function to call itself in Scheme?

I'm reading The Little Schemer and feel confused about the following code:
((lambda (len)
(lambda (l)
(cond
((null? l) 0)
(else
(+ 1 (len (cdr l)))))))
eternity)
(define eternity
(lambda (x)
(eternity x)))
The code is to determine the empty list, otherwise it never stops.
Why is the "len" not recursion?
Although it can be dangerous to apply textual substitution to Lisp forms (since there are dangers of multiple evaluation, etc.), in this case it may help to look at this form and see how it fits together:
((lambda (len)
(lambda (l)
...))
eternity)
is an application, i.e., a function call. The function getting called takes one argument, called len, and returns another function that takes a single argument l. The function getting called is called with eternity. When the call completes, the result is this function:
(lambda (l)
(cond
((null? l) 0)
(else (+ 1 (eternity (cdr l))))))
Now, this function takes a list l and if it's empty, returns 0. Otherwise, it computes (cdr l) (the rest of the list), and calls eternity with that value. When that returns, 1 is added to the result, and that's the return value of the whole function. The problem, of course, is that eternity
(define eternity
(lambda (x)
(eternity x)))
which could also be written as
(define (eternity x)
(eternity x))
simply takes an argument x, and then calls eternity with x. That's an infinite loop. In the above, I wrote "When that returns", but in fact, (eternity (cdr l)) never returns. So,
((lambda (len)
(lambda (l)
(cond
((null? l) 0)
(else (+ 1 (len (cdr l)))))))
eternity)
is a function call that returns a function (lambda (l) …) that returns 0 if called with an empty list, and goes into an infinite loop with a non-empty list.
From a program analysis side of things, it's worth noting that there are other values for which this won't go into an infinite loop. For instance, if you call it with a string, then (cdr l) will be an error.
Like you say, this is a definition of a length function as a partial function where it only completes for the empty list. But this hasn't gotten to the y-combinator part yet, it isn't an example of an anonymous function calling itself.
l is a list of atoms, it is the argument to the function returned when (lambda (len) ...) is evaluated.
len is a function passed into the outer lambda as an argument.
The outer expression creates a lambda with eternity passed in as its argument. The outer lambda returns a function created by evaluating the inner lambda, the returned function is the thing that takes eternity as an argument.
If the code is passed an empty list (meaning wrap the whole first part followed by a '() in another set of parens) then it will evaluate to 0, of course. len never gets evaluated.
If the code is passed a nonempty lat then it will try to evaluate the len argument and you get an infinite recursion.

Flatten a list two ways: (i) using MAPCAN and (ii) using LOOP

My professor has given us a refresher assignment in clisp. One exercise is to achieve the same thing in three ways: Return a flattened list of all positive integers in a given list.
Now, there's only one way I really like doing this, using cons and recursion, but he wants me to do this using mapcan and a loop (I suspect lisp is not his first choice of language because this style of coding feels extremely resistant to the nature of lisp). I'm having a hard time working out how one would do this using a loop...I need to first start a list, I suppose?
I apologize for vague language as I'm not really sure how to TALK about using a functional language to write procedurally. Following is my first attempt.
(defun posint-loop (l)
(loop for i in l
do (if (listp i)
(posint-loop i)
(if (integerp i)
(if (> i 0)
(append i) ; this doesn't work because there's nothing to
; start appending to!
nil)
nil))))
In order to establish a new lexical binding, use let or the with keyword of loop. In order to extend an existing list, you might want to use push; if you need the original order, you can nreverse the new list finally.
Another way would be to use the when and collect keywords of loop.
Another hint: mapcan implicitly creates a new list.
Mapcan applies a function to each element of a list, expecting the function to return a list, and then concatenates those resulting lists together. To apply it to this problem, you just need to process each element of the toplevel list. If the element is a list, then you need to process it recursively. If it's not, then you either need to return an empty list (which will add no elements to the final result) or a list of just that element (which will add just that element to the final result):
(defun flatten2 (list)
(mapcan (lambda (x)
(cond
((listp x) (flatten2 x))
((and (integerp x) (plusp x)) (list x))
(t '())))
list))
(flatten2 '((a 1 -4) (3 5 c) 42 0))
;=> (1 3 5 42)
With loop, you can do just about the same thing with the recognition that (mapcan f list) is functionally equivalent to (loop for x in list nconc (funcall f x)). With that in mind, we have:
(defun flatten3 (list)
(loop for x in list
nconc (cond
((listp x) (flatten3 x))
((and (integerp x) (plusp x)) (list x))
(t '()))))

Resources