Сначала стандартное форматирование:
(defun breadth (list y)
(setf l y)
(mapcar #'(lambda (element)
(when (listp element)
(when (> (breadth element (length element)) l)
(setf l (breadth element (length element))))))
list)
l)
(defun max-breadth (list)
(breadth list (length list)))
Ваша проблема - (setf l y)
, которая должна дать вам предупреждение о том, что l
не определено. Setf
не следует использовать для несвязанных переменных. Используйте let
для создания лексической области видимости:
(defun breadth (list y)
(let ((l y))
(mapcar #'(lambda (element)
(when (listp element)
(when (> (breadth element (length element)) l)
(setf l (breadth element (length element))))))
list)
l))
Тогда вместо двух вложенных when
используйте один и and
:
(when (and (listp element)
(> (breadth element (length element)) 1))
(setf l (breadth element (length element))))
Я считаю dolist
более кратким здесь:
(dolist (element list)
(when (and (listp element)
(> (breadth element (length element)) l))
(setf l (breadth element (length element)))))
Параметр y
всегда является длиной параметра list
, поэтому этот вызов можно упростить. Вам также не нужно псевдоним y
:
(defun breadth (list &aux (y (length list)))
(dolist (element list)
(when (and (listp element)
(> (breadth element) y))
(setf y (breadth element))))
y)
Вы можете исключить двойной рекурсивный вызов через let
, но мы можем использовать max
здесь:
(defun breadth (list &aux (y (length list)))
(dolist (element list)
(when (listp element)
(setf y (max y (breadth element)))))
y)
Вы также можете использовать reduce
для этого:
(defun breadth (l)
(if (listp l)
(reduce #'max l
:key #'breadth
:initial-value (length l))
0))