Why Not a Function #30: id
(import '(java.util UUID))
Random ramblings about Clojure, ClojureScript and other development tools
(import '(java.util UUID))
(import '[goog.i18n NumberFormat] '[goog.i18n.NumberFormat Format])
(import '[goog.i18n NumberFormat] '[goog.i18n.NumberFormat Format])
(defn xsd-decimal-fmt [x] (String/format "%.2f" (to-array [x])))
(require '[cljs-time.core :as t])
(defn list-index-of
[list element]
(let [r (reduce
(fn [n x] (if (= x element) (reduced n) (inc n)))
0 list)]
(when (not= r (count list))
r)))
(require '[goog.dom.xml :as xml])
(import
'(javax.xml.validation SchemaFactory)
'(javax.xml XMLConstants)
'(javax.xml.transform.stream StreamSource)
'(org.xml.sax ErrorHandler)
'(java.net URL))
(require '[clojure.data.xml :as xml] '[clojure.java.io :as io])
(import '(java.io ByteArrayOutputStream))
(def ffilter (comp first filter))
(defn add-leading-zeros
[n s]
(str/replace s #"\d+"
#(str/join (concat (repeat (- n (count %)) "0") [%]))))
(def keep-identity-2 (partial keep (comp seq (partial keep identity))))
(require '[clj-time.core :as t] '[clj-time.periodic :as tp])
(require '[clj-time.core :as t])
(require '[clj-time.core :as t])
(import '(java.util UUID))
(import '(java.nio ByteBuffer) '(java.util UUID))
(defn deep-merge-with [f m1 m2] (deep-merge m1 m2 :with f))
(defn deep-merge
[m1 m2 & {:keys [with]}]
(into {}
(map (fn [k]
(let [v1 (get m1 k)
v2 (get m2 k)]
[k (cond
(and (map? v1) (map? v2)) (deep-merge v1 v2 :with with)
(and with (contains? m1 k) (contains? m2 k)) (with v1 v2)
(contains? m2 k) v2
:else v1)]))
(set/union (keys m1) (keys m2)))))
(defn some-map [m] (remove-vals m nil?))
(defn remove-vals [m f] (into {} (remove (comp f val) m)))
(defn map-vals [m f] (into {} (map (fn [[k v]] [k (f v)]) m)))
(defn conj-sort-v [v x by] (->> ((fnil conj []) v x) (sort-by by) (vec)))
(defn conj-some [coll x] (if (some? x) (conj coll x) coll))
(defn assoc-non-empty-in
[m ks v]
(if (or (nil? v) (= v ""))
(let [ret (dissoc-in m ks)]
(if (= (get-in ret (butlast ks)) {})
(dissoc-in ret (butlast ks))
ret))
(assoc-in m ks v)))
(defn update-if [m k f] (if (contains? m k) (update m k f) m))
(defn assoc-ins
[m ks-v-s]
(reduce (fn [r [ks v]] (assoc-in r ks v)) m (partition 2 ks-v-s)))
(defn dissoc-in
[m [k & knext :as ks]]
(cond
(and knext
(contains?
(get-in m (butlast ks))
(last ks))) (update-in m (butlast ks) dissoc (last ks))
(not knext) (dissoc m k)
:else m))
(defn unapply [f & args] (f args))
unapply
is a kind of a reverse of apply
from Clojure.
`apply’ lets us use a collection instead of multiple arguments:
(apply + [1 2])
=> 3
unapply
lets us use multiple arguments instead of a collection:
(defn counts [coll] (map count coll))
=> #'user/counts
(unapply counts "why" "not" "a" "function")
=> (3 3 1 8)
(defn unfnil
[f]
(fn [& args]
(let [val (apply f args)]
(if (empty? val)
nil
val))))
unfnil
is a kind of a reverse of fnil
from Clojure.
For example, fnil
can be used with conj
like this: (fnil conj #{})
which will replace the first argument to conj
with #{}
if it is nil
. Useful if we want a set instead of a list, because conj
with nil
produces a list.
(update {:alarm true} :days (fnil conj #{}) :monday)
=> {:alarm true, :days #{:monday}}
unfnil
is the reverse, for instance (unfnil disj)
with #{:a} :a
produces a nil
instead of an empty set. Unlike fnil
, unfnil
works with collections only.
(update *1 :days (unfnil disj) :monday)
=> {:alarm true, :days nil}
figwheel-main
is a re-write of Figwheel, that doesn’t depend on lein-cljsbuild
config and doesn’t require Leiningen at all. Migrating a Leiningen project to it is not too difficult but there may be a few gotchas, depending on your project, as figwheel-main
doesn’t support all of the config options of lein-figwheel
. Also, our specific case was to continue using Cursive nREPL integration - something we were enjoying with lein-figwheel
.
I’ve found a bug in our deep-merge
fn
. It was used to override default parameters but some defaults were not overwritten. This is how our deep-merge
looked like: