Very nice work! My only suggestions are to split your large-ish function into several smaller, simpler pieces, and to give each of those pieces its own docstring:
(require '[clojure.string :as str])
"A vector of abbreviations for the twelve months, in order."
["Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"])
"Returns the abbreviation for a month in the range [1..12]."
(get month-names (dec month)))
"Returns a vector of the year, month, and day from an ISO 8601 date string."
(mapv #(js/parseInt %) (str/split date #"-0?")))
"Converts an ISO 8601 date string to one of the format \"(D)D Mon YYYY\"."
(let [[year month day] (parse-iso-date date)]
(str day " " (month-name month) " " year)))
This is considerably longer, but most of that additional length is from the fact that now more things are named and documented. The advantage of this approach is that if you find later that you want to use only one or two of these individual parts, or use them in a different way (e.g. when writing another function for a different date format), you can do so without having to duplicate the functionality in your
However, I was a bit confused by your comment about libraries:
As I don't need anything else, I don't want to pull in libs like cljs-time.
One of the greatest features of ClojureScript is that it emits code that is compatible with the advanced mode of the Google Closure optimizing compiler. The impact of this is explained more in the ClojureScript unveiling video (slides are available here). Basically, in ClojureScript, your app can depend on as many libraries as you want, and when you compile it, its final size will only depend on the size of the specific parts of those libraries that you actually end up using.