one of those blogs

The Way Nature Creates Things

Dogma From The Top

The best thing about the Clojure community is a large number of independent thinkers. The second best thing that allows this community to exist is the Clojure language itself, that have the hammock philosophy and great tools to enable thinkers to think and create. Often I notice myself following a “90 / 10” rule: where I spend 90% of the time thinking (brain, REPL, google, papers, people, sleep, etc..) and 10% of the time creating once thoughts are solidified.

As any vibrant community Clojure has “the powers that be” that provide guidance to people who need it. This guidance could be either: very helpful or lacking context + real world examples => let’s call it “dogma from the top”.

While I am not a biologist, I like to draw a parallel between software programs created by developers and things “naturally” created by nature. When I am in the beautiful garden or diving in the ocean, I find a lot less dogma, and a lot more fruits of mutation and centuries of trial and error development. It’s amazing. So much bigger and more honest than… “singletons are bad”.

Yes, this short story is about Mount, or rather it is about perception and understanding.

Singletons are Bad

If the context is not provided, “singletons”, or “global singletons” when referring to Clojure vars, have no quality of being bad or good. It’s just the word. Is “paper” bad? How about “inheritance”, is it bad? Well, what if it’s in millions of dollars?

The claim from the top is that keeping state in Clojure vars is bad, because global singletons are bad. Ok more context, but still no context to measure the goodness. When I ask for a concrete example, or two, that would “teach me” why Clojure var is such a horrible place to keep state, the only concrete example I get is:

“Because you can develop and run tests within the same REPL / runtime”

It turns out that some people develop and run tests within the same REPL.

I like my tests run in a separate REPL, moreover I like to run a watcher in that REPL which will rerun tests on any change I make and will notify me with a pass/fail sound / color in that terminal. This can be easily done with Boot: boot watch speak test. Can also be done with Leiningen via lein-test-refresh: lein test-refresh.

Another benefit of running tests in a separate REPL / runtime: it ensures a clean, isolated environment where tests are run. And since most people still use Leiningen this saves a lot of time.

But I do respect that people could have different workflows and they like running tests within the same REPL they develop. And there is Yurt that allows to create as many different yurts as needed in the same runtime.

notice how “database” is just a function, can be reused as many times as needed. user and product DBs can live within different namespaces if needed.

Yes, if “defstate” was a simple “def”, “def user-db” would be limiting, since how would you restart it for example. But “defstate” plugs “user-db” into a lifecycle aware Mount where “user-db” becomes a managed component (in a good sense) of an application.

Context is King

And here we arrived at the context: (defstate state :start (f1) :stop (f2)) is not just some global singleton which is claimed to be bad, but it is a living component that can be started, restarted, referenced and healed when it’s abused. Is it bad? Not from my experience, it’s actually quite excellent 🙂

This entry was posted on Wednesday, April 20th, 2016 at 01:08 and is filed under clojure, component, mount.
You can follow any comments to this entry through the RSS 2.0 feed.
Both comments and pings are currently closed.