tags:

views:

525

answers:

1

What is the Clojure equivalent (for the exact algorithm) of the following Python code?

from itertools import count
from math import sqrt

def prime_gen():
   primes = []
   for n in count(2):
       if all(n%p for p in primes if p <= sqrt(n)):
           primes.append(n)
           yield n
+4  A: 

This is as Pythonish as I can make it:

(def prime-gen
     (let [primes (atom [])]
       (for [n (iterate inc 2)
             :when (not-any? #(zero? (rem n %))
                             (filter #(<= % (Math/sqrt n)) 
                                     @primes))]
         (do (swap! primes conj n)
             n))))

(take 10 prime-gen)  ; => (2 3 5 7 11 13 17 19 23 29)

Clojure doesn't consider the integer 0 to be boolean false. It took me a few minutes to figure out that your Python code was taking advantage of this.

Here are some other prime number algorithms in Clojure. There's also a prime number implementation in clojure.contrib.lazy-seqs.

Brian Carper
It doesn't need to be Pitonish :) If there is a more idiomatic clojure solution for the same algorithm, please send it too.
Roskoto
You should follow the link. There are many examples and answers there. Also http://clj-me.cgrand.net/2009/07/30/everybody-loves-the-sieve-of-eratosthenes/#comments.
dnolen
Well, it's not all that un-Clojurish other than mutating an `atom`. It'd take some contortions to avoid using an `atom` though. Some algorithms demand side-effects and a non-functional programming style (especially things like sorting-in-place, shuffling, specific mathematical functions etc.) and it's OK to switch to using mutable data structures in those cases. That's why Clojure makes them available. You could even dive down and use native Java data structures for these kinds of things.
Brian Carper