Efficient collection function in Common Lisp

I study Lisp and wrote the following function to collect a list of results.

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

He gave a similar result to the built-in loop function.

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)

However, my collection function hits the stack when I try to create a list of 100,000 items long

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

While the loop version is not

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

How can I make my version more space-efficient, are there any consing alternatives? I think the tail is recursive. I am using sbcl. Any help would be great.

+5
source share
3 answers

Lisp ANSI ; , ( SBCL), .

, . , :

    (defun collect (func args num)
      (labels ((frob (n acc)
                 (if (= 0 n)
                     acc
                     (frob (1- n) (cons (apply func args) acc)))))
        (frob num nil)))

( FUNC ARGS , ).

+10

, . ANSI Common Lisp :

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

, COLS. CONS COLLECT. COLLECT . -, , . Lisp .

Common Lisp : DO, DOTIMES, DOLIST, LOOP, MAP, MAPCAR,...

Lisp (TCO). , TCO . , TCO. Common Lisp TCO. TCO ANSI Common Lisp.

Lisp . , , .

. Common Lisp , .

(defun collect (func args num)
  (loop repeat num
        collect (apply #'func args)))

: .

+11

, .

, Common Lisp , .

(defun mycollect (func args num)
  (let ((accumulator '()))     ; it a null list. 
    (loop for i from 1 to num 
      do
      ;;destructively cons up the accumulator with the new result + the old accumulator
      (setf accumulator                   
        (cons (apply func args) accumulator)))
  accumulator))                ; and return the accumulator
+1

All Articles