Based on examples in Clojure Analysis Cookbook (plus my codes)