Mam prosty kalkulator liczby pierwszej w clojure (nieefektywny algorytm, ale próbuję po prostu zrozumieć zachowanie powtarzam na teraz). Kod to:Przepełnienie podczas używania recur w clojure
(defn divisible [x,y] (= 0 (mod x y)))
(defn naive-primes [primes candidates]
(if (seq candidates)
(recur (conj primes (first candidates))
(remove (fn [x] (divisible x (first candidates))) candidates))
primes)
)
Działa tak długo, jak długo nie próbuję znaleźć zbyt wielu liczb. Na przykład:
(print (sort (naive-primes [] (range 2 2000))))
działa. W przypadku wszystkiego, co wymaga większej rekurencji, pojawia się błąd przepełnienia.
(print (sort (naive-primes [] (range 2 20000))))
nie będzie działać. Zasadniczo, czy używam recur lub call naive-primes ponownie bez próby TCO, nie wydaje się, aby robiło to jakąś różnicę. Dlaczego otrzymuję błędy w przypadku dużych rekursji podczas korzystania z funkcji recur?
Czy recur wymaga pętli, aby uzyskać rekurencję ogona? Nie widzę pętli w twoim kodzie. Uczyniłbym to jako odpowiedź, ale wciąż uczę się Clojure. – octopusgrabbus
Twój kod działa dla mnie w Clojure 1.2.1 i 1.3. Jedyny błąd, jaki w końcu dostaję, to "OutOfMemoryError", gdy znajduję liczby pierwsze do 200 000. –
@octopusgrabbus, no, recur mogą być również używane w ten sposób (również w ramach funkcji). Zobacz http://clojure.org/special_forms#recur. –