Notes about things I learned
Sometimes I find I've got a function like this:
(defn calculate-something [a]
(if (some-test? a)
(let [b (read-from-db a)]
(some-transform a b))
(some-other-transform a)))
Basically, I need to read from the database (or any other impure place) in the middle of the function, after checking whether the read is necessary/possible.
That function has a signature like [& params] => result. A quick way to make that function pure is to give it a signature of [memo & params] => effect, where effect is either [:result some-data] or [:query & query-params].
So we'd write the above as:
(defn calculate-something [memo a]
(let [q [:read-from-db a]
a? (some-test? a)]
(cond
(and a? (contains? memo q))
(let [b (get memo q)]
[:result (some-transform a b)])
a? [:query q]
:else [:result (some-other-transform a)])))
Then in another layer of the app where purity isn't required, call the function in a loop until it returns a result, and interpret :query forms as needed.
(defn get-something! [conn a]
(loop [memo nil i 0]
(when (> i 10) (throw (ex-info "Too many queries")))
(let [[cmd data] (calculate-something memo a)]
(case cmd
:result data
:query (let [memo (assoc memo data (execute-query! conn data))]
(recur memo (inc i))))))
You could make this support getting multiple queries to execute per call of the calculate-something function.
execute-query! could be a multimethod or a simple case expression.
You could also make the impure wrapper agnostic of the pure function it calls:
(defn run-with-queries [conn f & params]
(loop [memo nil i 0]
(when (> i 10) (throw (ex-info "Too many queries")))
(let [[cmd data] (apply f memo params)]
(case cmd
:result data
:query (let [memo (assoc memo data (execute-query! conn data))]
(recur memo (inc i)))))))
Published: 2026-06-29
Tagged: clojure
I intend to add tips about optimizing Clojure programs here as I learn them.
Your Clojure program is using a lot of memory and you don't know why. Take a heap dump, load it in Eclipse Memory Analyze (MAT), look at the "Leak Suspects", and start with the biggest.
Published: 2026-05-15
Tagged: clojure
Suppose you have some UI in a website that should render a list of items. Let's call it FancyList. Usage locations of FancyList provide the list of items, each with a label, and, crucially, any other content that is rendered however the usage location requires.
In UI libraries like React and Svelte, components allow customized rendering using callback functions or slots. In React this might look like:
See the Pen Untitled by tom connors (@tomconnors) on CodePen.
In Svelte we use snippets but the concept is pretty much the same; the caller defines how items are rendered and the FancyList calls that logic.
We don't have a similarly convenient option for rendering child element lists when using web components. You can't pass a function to a web component with just HTML:
<!-- This doesn't solve our problem -->
<fancy-list items="[...]"></fancy-list>
The best option I've found is conceptually pretty simple: instead of passing the items as an attribute of the web component, pass them as children. Structure the children so that the web component can easily pull out the information it needs, and include any customized rendering directly in the DOM.
See the Pen Untitled by tom connors (@tomconnors) on CodePen.
There are some important things to note:
parseLightDom. You can imagine more complex versions of this function for more complex situations.<slot> elements because we have a list of items where each can render differently.Published: 2026-02-28
Tagged: clojure