Wishful Coding

Didn't you ever wish your
computer understood you?

Cooperative concurrency in Clojure

Today I had an interesting discussion about cheap preemptive threads in Clojure. Someone claimed Haskell can easily start 10.000 threads without getting slow, while Clojure - and native threads in general - do get slow after a couple of thousands.

After a discussion about Agents and thread pools, I proposed cooperative concurrency as a cheap solution. Cooperative concurrency isn't exactly preemptive, but it works. This is a for-fun implementation of trampoline using a hidden gem in Clojure called PersistentQueue.

Like trampoline, recursive functions return another function, which get called in a loop. Unlike trampoline, mine takes a seq of functions, puts them into a queue and executes the frontmost function, putting the result on the back of the queue.

Below is an example of the classic mutual recursive odd and even functions running in parallel, or alternating actually. Like pcalls, but on a single thread.

(ns cooperative)

(defn cooperative-tasks
  "Trampoline over a queue for
  cooperative multitasking"
  [fs]
  (if (not-any? fn? fs)
    fs
    (recur
      (doall (for [f fs]
        (if (fn? f)
          (f)
          f))))))


(comment
  (declare my-odd?)

  (defn my-even? [n]
    (if (zero? n)
      true
      #(my-odd? (dec (Math/abs n)))))

  (defn my-odd? [n]
    (if (zero? n)
      false
      #(my-even? (dec (Math/abs n)))))

  (cooperative-tasks [#(my-odd? 50009) #(my-odd? 50008) #(my-even? 50008) #(my-even? 50009)])
)

Happy Christmas!

(ns xmas)

(doseq [line (concat (take 9 (map #(apply str
                                          (take (+ (rem % 3)
                                                   (int (/ % 3)))
                                                (repeat "*")))
                                  (range 20)))
                     (take 2 (repeat "*")))]
  (println (format "%1$30s*%1$s" line)))

;                              *
;                             ***
;                            *****
;                             ***
;                            *****
;                           *******
;                            *****
;                           *******
;                          *********
;                             ***
;                             ***
Published on

8 ways to tell how many Xes are in a list

Inspired by a question on #clojure. There we go.

mrBliss(1):

(count (filter #{1} '(1 2 4 5 1 5 2))) ; Use this

Raynes:

(count ((group-by identity [1 2 3 4 5 1 5 2]) 1))

Me(1):

(get (frequencies [1 2 3 1 2 3]) 1) ; Or this

Me(2):

(reduce #(if (= %2 1) (inc %1) %1) 0 [1 2 3 2 3 1])

Me(3)

(count (nth (partition-by identity (sort [ 1 2 3 1 2 3])) 0))

mrBliss(2):

(count (remove (complement #{1}) '(1 2 3 1 2 3))) ; But don't ever do this

_ato(1):

((fn f [[x & xs :as coll]] (cond (= coll '(1)) 1, (nil? xs) 0, :else (apply + (map #(f (take-nth 2 %)) [coll xs])))) [1 2 3 4 5 1 5 2])

_ato(2):

(let [s (sort [1 2 3 4 5 1 5 2])] (- (.lastIndexOf s 1) (.indexOf s 1) -1))

But at least Clojure has an awesome and helpful community!

Published on