Эффективная функция сбора в Common Lisp

Я изучаю Lisp и написал следующую функцию для сбора списка результатов) .

(defun collect (func args num)
  (if (= 0 num)
      ()
      (cons (apply func args)
        (collect func args (- num 1)))))

Результат такой же, как и у встроенной функции цикла.

CL-USER> (collect #'random '(5) 10)
(4 0 3 0 1 4 2 1 0 0)
CL-USER> (loop repeat 10 collect (random 5))
(3 3 4 0 3 2 4 0 0 0)

Однако моя функция сбора срывает стек, когда я пытаюсь сгенерировать список длиной 100 000 элементов

CL-USER> (length (collect #'random '(5) 100000))
Control stack guard page temporarily disabled: proceed with caution

В то время как версия цикла не работает

CL-USER> (length (loop repeat 100000 collect (random 5)))
100000

Как можно Я делаю свою версию более компактной, есть ли альтернативы consing? Я думаю, что это хвостовая рекурсия. Я использую sbcl. Любая помощь была бы отличной.

5
задан Sard 19 December 2010 в 00:27
поделиться