Explain what the contents of L would be after the following call to q2 and why.
(defvar L '(1 2 3 4))
(q2 (cdr L) L)
Sample solution
This one is a bit more complex, as what we're passing as v is the tail of L,
effectively a reference/pointer to the second cell of L
Thus the third data value in L becomes a reference to the second cell in L,
L is now (1 2 [a pointer to the second element] 4)
Question 3 Tail recursion [4 marks]
The C function below uses a loop to calculate and eventually return a final result.
float q3(float x, float y)
{
float tmp = 0;
while (x > y) {
tmp = tmp + (x - y);
x = x/3;
y = y/2;
}
return tmp;
}
Following the logic used by the C function, provide a tail-recursive lisp function
to calculate and return the result, then briefly
explain how your function works and why it is tail recursive.
Sample solution
(defun q3 (x y &optional (tmp 0))
(cond
((< = x y) tmp)
(t (q3 (/ x 3) (/ y 2) (+ tmp (- x y))))))
To do a generalized conversion from the iterative to the tail recursive:
(1) for each local variable in the original we add a new optional parameter to
the tail recursive version, initialized to the same value as in the original,
thus we get the optional tmp=0
(2) for the tail recursive base case, i.e. when not to recurse,
we use the opposite of the continuation condition in the original loop
and return what the original returns after exiting the loop, thus
if x is less than or equal to y we want to return tmp
(3) in the general case for the tail recursion we want to make a recursive call
where the values passed to each parameter mimic the changes made to the
corresponding variable in the original loop, i.e.
in the original x changes to x/3, so in the recursion we pass (/ x 3),
in the original y changes to y/2, so in the recursion we pass (/ y 2),
in the original tmp changes to tmp + (x - y), so in the recursion
we pass (+ tmp (- x y))