(defn color-function [{:keys [r g b]}]
(* r g b)) (defn assoc-foo [db bar]
(assoc db :foo bar))
(defn fetch-new-foo [db bar]
(go
(let [bar (<! (get-bar)]
(swap! db assoc-foo bar))))
(swap! db assoc-foo bar)
(fetch-new-foo db bar)
whereas re-frame would make you do this: (re-frame/reg-event-db
::assoc-foo
(fn [db [_ bar]]
(assoc db :foo bar)))
(re-frame/reg-fx
::pull-from-channel
(fn [{:keys [f event]}]
(go
(let [resp (<! (f))]
(re-frame/dispatch (conj event resp))))))
(re-frame/reg-event-fx
::fetch-new-foo
(fn [_ _]
{:pull-from-channel {:f get-bar
:event [::assoc-foo]}}))
(dispatch [::assoc-foo bar])
(dispatch [::fetch-new-foo])
The first one has a lot going for it; swap! is part of the standard library, has a bunch of docs for free, etc.; any clojure editor will pick up on the use of assoc-foo as a function and give you arity warnings if you pass too many parameters, etc.
- Intellij IDEA with the Cursive extension is very popular outside of emacs (I've met more clojure developers who use IDEs than those who don't.)
- Clojure uses the error handling mechanisms of the target runtime. You have try/catch statements and side effects are often used. It's not a no-side-effect language.
- Parentheses are almost always managed with parinfer/paredit and python-style indentation rules in production code I've seen.
You're quite right that performance will be tied to the JVM or V8/SpiderMonkey/etc.