Skip to content

Instantly share code, notes, and snippets.

@ijt ijt/sieve.clj
Last active Feb 21, 2016

Embed
What would you like to do?
Translation of the Go prime sieve to Clojure
;; A concurrent prime sieve translated from
;; https://golang.org/doc/play/sieve.go
;; by Issac Trotts with help from Chris Murphy and glts on Stack Overflow.
(require '[clojure.core.async :as async :refer [<! >! <!! chan go]])
(defn generate-naturals
"Sends the sequence 2, 3, 4, ... to channel 'ch'."
[ch]
(go
(doseq [i (drop 2 (range))]
(>! ch i))))
(defn filter-multiples
"Copies the values from 'in-chan' to 'out-chan', removing
multiples of 'prime'."
[in-chan out-chan prime]
(go
(while true
;; Receive value from 'in-chan'.
(let [i (<! in-chan)]
(if (not= 0 (mod i prime))
;; Send 'i' to 'out-chan'.
(>! out-chan i))))))
(defn filter-primes
"Takes a sequence of natural numbers from 'ch' and daisy-chains
processes to filter out everything but primes, sending them
to 'primes-ch'."
[ch primes-ch]
(go
(loop [ch ch]
(let [prime (<! ch)]
(>! primes-ch prime)
(let [ch1 (chan)]
(filter-multiples ch ch1 prime)
(recur ch1))))))
(defn generate-primes
"Returns a channel that outputs prime numbers."
[]
(let [ch (chan)
primes-ch (chan)]
(generate-naturals ch)
(filter-primes ch primes-ch)
primes-ch))
(defn main
"Prints prime numbers to stdout."
[]
(let [primes-ch (generate-primes)]
(while true
(println (<!! primes-ch)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.