Tengo una pregunta sobre Clojure: Estoy tratando de aprender el idioma yendo a través de Project Euler y no entiendo lo que está pasando debajo del capó: El siguiente código está diseñado para use return una lista de todos los números primos hasta lim
. Creo que debería ser O (n) en el espacio dinámico porque hago una lista de todos los números hasta lim
, y luego los filtro uno por uno mientras muevo el primero a una nueva lista. (Yo sé que en realidad estoy haciendo nuevas listas de cada reaparecer, pero no pensé que tomarían más memoria?) De todas formas estoy funcionando con estePregunta para principiantes sobre el montón y la basura en Clojure
(defn getAllPrimes [lim]
(defn getPrimes [primes numlist]
(if (not-empty numlist) ;base case;
(recur (cons (first numlist) primes) ;put the prime on to the prime list
(filter
(fn [x] (not (div? x (first numlist)))) ;remove the prime and all its multiples from the numlist
(rest numlist)))
primes)); return the primes
(getPrimes() (range 2 lim))) ;call the recursive function with and empty prime list to be filled up and a full numlist to be emptied
Y sigo quedando sin espacio de almacenamiento dinámico, cuando llamo
(apply + (getAllPrimes 2000000))
, pero no me quedo sin espacio en
(apply + (filter even? (range 2000000)))
Así que creo que no debo entender cómo están las listas de basura recogidas en las llamadas que se repita y en realidad estoy usando O (n * n) montón o algo.
Esto se responde con anterioridad aquí: La respuesta corta es que el filtro crea una secuencia perezosa y está llamando filtro sobre filtro a través de ... y finalmente apila desbordamiento. Una forma de resolver esto (como lo sugiere dreish) es realizar la secuencia en cada paso mediante un 'doall '. –