Если вы вызываете list-length
на каждом шаге рекурсии, вы будете каждый раз проходить оба списка целиком, что дает вашей функции zipper
квадратичную сложность по времени относительно суммы размеров ваших списков:
(zipper '(1 2 3) '(4 5 6))
=> (list-length (1 2 3))
=> (list-length (2 3))
=> (list-length (3))
=> (list-length ())
=> (list-length (4 5 6))
=> (list-length (4 5))
=> (list-length (5))
=> (list-length ())
(zipper '(2 3) '(5 6))
=> (list-length (2 3))
...
=> (list-length (5 6))
...
...
Это неэффективно и не нужно здесь.Поскольку вы уже посещаете оба списка, вы можете напрямую проверить, является ли какой-либо из них пустым, используя null
или endp
, что занимает постоянное время.Вы возвращаете NIL, как только один из списков пуст, что, кстати, является поведением по умолчанию mapcar
.Также обратите внимание, что mapcar
может работать с несколькими списками одновременно, например:
(mapcar #'+ '(1 2) '(5 8))
=> (6 10)
Если вам известна функция, которая принимает (как минимум) два аргумента и возвращает список, тогда вы могли бы mapcar
, которые функционируют над вашими списками и имеют список списков.