Q:

I don't know what this function should do

I have here a function that I need to modify so that I would avoid the double recursive call of (f (car l)) . First of all I can't figure it out what it shows..
If I pass (f '((3 4) 5 6)) it shows me CAR: 3 is not a list
Can anybody help me understand and then modify it?
(DEFUN F (L)
   (COND
      ((NULL L) 0)
      ((> (f (car l)) 2) (+ (car l) (f (cdr l))))
      (T (f (CAR L)))
))

A:

You can figure out what this function should accept as input by looking at what it does with the input, and what it returns by looking at what each case returns.  There are three cases:
Case 1
((NULL L) 0)

In this case, L can be nil, and 0, which is a number, is returned.
Case 2
((> (f (car l)) 2) (+ (car l) (f (cdr l))))

In this case, we call both car and cdr on l, so l had better be a cons.   We also compare (f (car l)) with 2, so f must return a number, at least for whatever type (car l) is.  Since we're calling + with (car l), (car l) must be a number.  So f must return a number when given a number.    Now, we're also calling + with (f (cdr l)), so whatever type (cdr l) has, f had better return a number for it, too.
Case 3
(T (f (CAR L)))

This doesn't put many constraints on us.  This just says that if we didn't have either of the first two cases, then we return (f (car l)).  Since checking the second case didn't fail, and because we're calling (car l), l still has to be a cons in this case.
So what is f?
Well, it's still not immediately clear what f is, but we can write it as a piecewise function, and maybe that will help.  It take a list, which is either the empty list or a cons that has a first and a rest.
f []   = 0
f x:xs = if (f x) > 2
         then x + (f xs)
         else (f x)

To modify it so that you only call (f (car l)) is easy enough, although since we know that the input needs to be a list, I'm going to use first and rest to suggest that, rather than car and cdr.
(defun f (list)
    (if (endp list)
        0
        (let ((tmp (f (first list))))
          (if (> tmp 2)
              (+ (first list) 
                 (f (rest list)))
              tmp))))

Let's try to walk through some possible inputs and try to cover the different code branches. What sort of input could we call this with?  Well, we can call it with ():
CL-USER> (f '())
0

That takes care of the first then branch.  Now what if we want to hit the second?  Then we need to pass something that's not the empty list, so it looks like (? . ??).  Now the first thing that has to happen is a recursive call to(f (first list)).  The only way that this is going to work is if(first list)is also a list that we can pass tofand get a value back. Then(first list)` must have either been the empty list or another suitable list.  So we can call:
CL-USER> (f '(() a b c))
0

In general, we can call f with () and with any list such that (first (first (first ... (first list)))) is ().  Can we call it with anything else?  It doesn't appear so. So now we know what the acceptable inputs to f are:
input ::= ()
        | (input . anything)

and the output will always be 0.

