Wishful Coding

Didn't you ever wish your
computer understood you?

I'm tired of the NoSQL buzz, and bring you SlouchDB

It has all the features your favorite NoSQL database has.

  • Fast
  • Scalable
  • Concurrent
  • Key/value store
  • Document orientated
  • MapReduce
  • In-memory
  • Persistent *
  • NoSQL
  • REST API *
  • Written in X, so...
* Requires a few extra lines.

The implementation looks like this.

(ns slouchdb)

; Fast scalable in-memory concurrent NoSQL database
(def db (ref {:bob  {:age 59 :sex :male}
              :bill {:age 17 :sex :male}
              :mary {:age 28 :sex :female}}))

;; Views ;;

(defn total-age []
  (reduce + (pmap (comp :age val) @db))) ; Parallel MapReduce!

;; Examples ;;

(println (apply str (interpose \newline
  ["Get an item"
  (:bob @db)
  "MapReduce"
  (total-age)
  "Add/update an item"
  (dosync (alter db assoc-in [:bill :age] 25))
  "Delete an item"
  (dosync (alter db dissoc :mary))])))

; For scaling, press CMD or CTRL and + or -

; For a persistent version, see java.io.Serializable

; For a REST API, check out Moustache and Aleph.
Published on

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