Skip to content

Instantly share code, notes, and snippets.

@stianeikeland
Created June 30, 2014 10:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stianeikeland/76fdd89158852e644154 to your computer and use it in GitHub Desktop.
Save stianeikeland/76fdd89158852e644154 to your computer and use it in GitHub Desktop.
Concurrent prime sieve using core.async in clojure
;;; Concurrent prime sieve using core.async in clojure
(ns primesieve.core
(:require [clojure.core.async :as async :refer [go-loop chan >! <! <!! close! filter< to-chan]]))
(def bufsize 512)
(defn gen [upper-limit]
"Returns channel, puts numbers from 2 to upper-limit into channel"
(to-chan (range 2 upper-limit)))
(defn sieve-filter [in prime]
"Returns output channel, reads from input channel
filtering out all numbers divisible by prime"
(filter< #(pos? (rem % prime)) in bufsize))
(defn sieve-builder [in]
"Returns output channel, daisy-chains filter processes for every new prime
received on input channel."
(let [out (chan bufsize)]
(go-loop [in in]
(if-let [prime (<! in)]
(do (>! out prime)
(recur (sieve-filter in prime)))
(close! out)))
out))
(defn collect [in]
"Returns output channel, returns vec containing all values from input chan."
(<!! (async/into [] in)))
(defn primes [upper-limit]
(-> (gen upper-limit)
(sieve-builder)
(collect)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment