Learning Lisp. Can't seem to get a value from one function and use it within another

StackOverflow https://stackoverflow.com/questions/14232433

  •  14-01-2022
  •  | 
  •  

Вопрос

I'm trying to find the maximum number within a list, then do something with it:

(defun maxList (l)
    (if (= (length l) 1)
            (first l)
        (if (> (first l) (maxList (rest l)))
            (first l)
            (maxList (rest l))
        );if
    );if
);defun


(defun try-let (l)
    (let (a (maxList l))
    (print a)
    );let
);defun

However it prints null, yet maxList works. What am I doing wrong ?

Это было полезно?

Решение

You're missing a pair of parentheses:

(let ((a (maxList l)))

This is because let takes a list of bindings as in

(let ((a 1) (b 2) (c 'foo))
  expr)

so in this case you have to pass a one-element list containing the binding (a (maxList l))

Другие советы

(defun maxList (l)
  (if (= (length l) 1)

Calling LENGTH is not a good idea. It traverses the whole list.

      (first l)
    (if (> (first l) (maxList (rest l)))
        (first l)
      (maxList (rest l)))))

Above calls MAXLIST twice. Maybe here a LET is useful? How about the function MAX?

If you compile your function, a Common Lisp system will complain.

CL-USER 35 > (defun try-let (l)
               (let (a (maxList l))
                 (print a)))
TRY-LET

CL-USER 36 > (compile 'try-let)
;;;*** Warning in TRY-LET: MAXLIST is bound but not referenced

This shows that the Lisp compiler thinks MAXLIST is a variable. Something is wrong. Next look up the syntax of LET.

See Special Operator LET, LET*

let ({var | (var [init-form])}*) declaration* form* => result*

Which says that it is a list of variables or a list of (variable initform). So you can see that you have missed to make it a list. You have just written one binding.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top