Есть рекурсивный способ:
(nil defmethod len () 0) ('cons defmethod len () (1 + ((this rest) len)))
В таких простых задачах невыгодно использовать рекурсию, так как результатом будет чрезмерное использование памяти стека для возврата из функций. Используем переменную.
(nil defmethod len () (nil let ((i this) (l (0 copy))) (nil while (nil consp i) (nil parallel (nil setq i (i rest)) (l += 1))) l))
Списки могут быть не линейными а зацикленными. В таких условиях программа чтобы не зациклится должна контролировать возможность циклов. Сложность алгоритма станет O(n²).
(nil defmethod len () (nil let ((last this) (lastnext (this rest)) (l (0 copy)) (flagcycled false)) (nil while (nil and (nil consp last) (nil not flagcycled)) (nil parallel (nil if (lastnext find this last) (nil setq flagcycled true) (nil setq last lastnext lastnext (lastnext rest))) (l += 1))) l)) (nil defmethod find (first last) (nil let ((flagfound false)) (nil while (nil and (nil not (nil eq first last)) (nil not flagfound)) (nil if (nil eq this first) (nil setq flagfound true) (nil setq first (first rest)))) (nil if (nil not flagfound) (nil if (nil eq this first) (nil setq flagfound true))) flagfound))
Использование сложных алгоритмов сложностью O(n²) это запретная зона для программистов. Такие ситуации стараются избегать. Зацикленный список это по сути граф (мат.). У графов нет понятия длина, но есть количество элементов. У графов никто не подсчитывает элементы.
Список это сложный объект из нескольких элементов, каждый уважающий себя программист имеет одну переменную длина.