Clojure conditional feature reader

I’ve been experimenting with tagged literals and data-readers to create what I’m calling a “conditional feature reader”. The basic element is the condf tag, which works sort of like cond but the tests are “feature requirements”. A feature requirement can be something like clj1.5 (meaning Clojure 1.5) or java1.6+ (meaning JDK 1.6 or greater). For example:

(println #feature/condf [(and jdk1.6+ clj1.5.*) "Ready for reducers" else "No reducers for you."])

I’ve only implemented it for regular Clojure 1.4 and 1.5 (on the JVM), but I’m hoping it might prove useful for other variants such as ClojureScript.

For more details, see:

Moving away from Noir

Anthony Grimes (Raynes) reports on the deprecation of Noir for Clojure web apps:

Chris and I discussed this last night, and we decided that it???s time to deprecate Noir and ask that people focus on Compojure instead. The good news is that you don???t have to give much of anything up if you move to Compojure! A while back when I started moving my own sites to Compojure, I took most of the useful libraries that were embedded in Noir and I split them out into a new library that you can use from Compojure! lib-noir is the legacy of Noir. The best thing that came out of it. It has all the useful stateful sessions, flashes, cookies, as well as the other useful libraries. In fact, the latest release of Noir depends on this library so if you???re using it, you???re already secretly using lib-noir!

For new websites, please use Compojure and lib-noir. This is pretty much just as batteries included as Noir itself ever was! You just have to learn how to write routes with Compojure. It???s easy and just as concise as it was in Noir. You don???t have to use ring-jetty-adapter and stuff, just use the lein-ring plugin to start your server.

Related links:

Roman Numerals in Clojure

I saw this post on Roman Numerals in Clojure:…

This is the sort of little programming problem that can stop useful work dead in its tracks. Here’s my shot at the problem. I think it reads better in that the recursion just deals with the numbers and the Roman numeral strings are mapped latter. It’s also a bit more efficient in the way it tests against the Roman “bases” (as I call them). There’s no need to retest against a high base once your interim value has gone below that mark. In any case, my version is quite a bit faster than the other solution in my micro-benchmarks.

(ns miner.roman
(:require [clojure.test :refer :all]))
;; inspired by
(def roman-map {1000 "M" 900 "CM" 500 "D" 400 "CD"
100 "C" 90 "XC" 50 "L" 40 "XL"
10 "X" 9 "IX" 5 "V" 4 "IV" 1 "I"})
(def roman-bases (sort > (keys roman-map)))
(defn roman-addends [n]
{:pre [(< 0 n 4000)]}
(loop [n n bases roman-bases addends []]
(if (zero? n)
(let [base (first bases)]
(if (>= n base)
(recur ( n base) bases (conj addends base))
(recur n (rest bases) addends))))))
(defn roman [n]
(apply str (map roman-map (roman-addends n))))
;; clojure.pprint/cl-format works but is slow
(defn roman-cl [n]
(clojure.pprint/cl-format nil "~@R" n))
(deftest roman-4k
(doseq [n (range 1 4000)]
(is (= (roman-cl n) (roman n)))))
(def inv-roman-char-map
{\M 1000 \D 500 \C 100 \L 50 \X 10 \V 5 \I 1})
(defn roman-values-seq [rn]
(let [vs (rseq (conj (mapv inv-roman-char-map rn) 0))]
;; going in reverse order is easier,
;; padded zero to simplify prev
(map (fn [v prev] (if (>= v prev) v ( v))) (rest vs) vs)))
(defn parse-roman [rn]
(reduce + (roman-values-seq rn)))
(deftest parse-roman-test
(doseq [n (range 1 4000)]
(is (= n (parse-roman (roman n))))))

view raw


hosted with ❤ by GitHub