/
принимает в качестве аргументов одно или несколько чисел, но в вашем коде вы передаете ему список - очевидно, это не будет работать.Функция apply
здесь ваш друг - (apply #'foo a b (list c d e))
эквивалентно (foo a b c d e)
.Обратите внимание, что аргументы apply
между используемой функцией и окончательным списком являются необязательными, поэтому (apply #'/ '(20 2 5))
эквивалентно (/ 20 2 5)
.
Также ваша попытка удаления нулей не будет работать.dolist
оценивает его тело для каждого элемента в списке аргументов elements
, но вы фактически ничего не делаете для изменения содержимого elements
(результат оценки тела dolist
не переназначается источникуэлемент, как вы ожидаете).
Функции remove-if
(и его разрушительный аналог, delete-if
) - это то, что вы ищете.Ниже показано, как его использовать (для этого требуется множество необязательных аргументов, о которых вам не нужно беспокоиться для этой цели).
(defun divtest (elements)
(apply #'/ (remove-if #'zerop elements)))
Также обратите внимание, что это не будет работать правильно, если elements
список имеет ноль в качестве первого элемента (при условии, что я понимаю, для чего предназначена функция).Таким образом, вы можете вместо этого захотеть что-то вроде
(defun divtest (elements)
(apply #'/ (first elements) (remove-if #'zerop (rest elements))))
См. Hyperspec для более подробной информации.