0
votes

I have that Lisp function:

(defun F(l)
      (cond
        ((atom l) -1)
        ((>(F(car l))0)(+(car l)(F(car l))(F(cdr l))))
        (t(F(cdr l)))
      )
)

and I want to prevent double invocation of recursive function (F (car l)) in the second line of cond using a lambda function.

I tried that:

(defun F(l)
  ((LAMBDA (ff)
         (cond
             ((atom l) -1)
             ((> ff 0)(+(car l) ff (F(cdr l))))
             (t(F(cdr l)))
         )
    ) (F (car l)))
)

but I get error :

CAR: 1 is not a list

at call (F '(1 2 3 4)).

Also I'm not sure if that correctly avoids double recursive call.

1
Any particular reason you do not want to use let? - sds
It would be nice if you could format your code in a more traditional Lisp style (indentation, spaces, and paren placement) - sds
@sds I could use let too, but I'm more familiar with lambda, I'm not sure how to solve that with let. - Raul1998

1 Answers

4
votes

The reason you are getting this error is that you are calling (car l) always, even when l is, in fact, not a list.

To avoid this, only do that when needed:

(defun F(l)
  (if (atom l) -1
      (let* ((l1 (car l))
             (f1 (F l1))
             (f2 (F (cdr l))))
        (if (plusp f1)
            (+ l1 f1 f2)
            f2))))