Last time (or time before last; in any case the post was [:trying-clojure-again]) I mentioned I'm learning Clojure and Luminus is a nice collection of templates.
My revised opinion is that it's not actually a great introduction to Clojure. It sets up a bunch of stuff, a project with some Clojure and Clojurescript will add dozens of packages to your project and there is little hint as to what each does and why it would be useful. I've had better luck working from scratch starting from deps.edn.
Some various observations:
Leiningen is complicated and I wound up using deps.edn
[0] instead. I like it better. I suppose deps.edn
is also complicated, but you can grow it in a straight-forward way: add :paths
to tell clojure where your source lives, add:deps
to download libraries. When it's useful add :aliases
to bundle flag dependent options[1].
I'm sure Leiningen is fine, but I messed around with the Luminus generated project.clj and it's not so hard to get something working, but it's hard to say what is accidental and what is essential.
Luminous is a collection of templates allowing you to quickly setup a skeleton project with tens of libraries wired together. This seemed like a great way to learn clojure; a simple way to mix together libraries I'm interested in and see how they're supposed to work together.
In practice it wasn't a good fit for me. It seems like it'd be great if I was banging out similar projects on a regular basis and already knew what dependencies were useful, but I'm trying to explore possibilities and the template approach means that once a project has been spit out there is really no going back: Luminous can't help you add or remove a dependency from an existing project.
I'm glad I used Luminus for a little while; if nothing else it's a great directory of widely used Clojure libraries, but starting over and adding dependencies one by one to a deps.edn
made me was happier and gave me a better understanding of how the parts of my projects work together.
There is a project Duct which may be an interesting alternative to Luminus. Duct is a framework with provides starter templates so, similar to Luminus, you can invoke a CLI to create a new project and pass flags like +sqlite
to wire in additional dependencies. The difference is that, rather than producing all the glue code from templates, the framework dynamically wires together your dependencies, so adding and removing supported modules is (in principle) trivial. Being able to try out different dependencies in an existing project makes experimenting cheap and seems like a good way to learn. I'll probably give it a shot when I start a new project. Related to Duct, the Integrant project is a component of Duct that I actually use. Integrant allows you to declare inter module dependencies as data (e.g. declare that serving HTTP depends on this database connection etc) and provides setup and teardown functions. It's one of those things that seems like a complicated solution to a non-problem until you're hacking bits of your server to run happily in different environments (e.g. dev and prod) and suddenly the configuration driven module initialization makes sense. [TODO:] Maybe I should write up a blog post about Integrant; I haven't seen a great problem statement for the issues it solves
[0]: a.k.a. clojure CLI Tools and various other names since nothing can just be easy.
[1]: I'm having trouble coming up with a pithy explanation for "aliases". An alias is a set of options which are associated with a flag; if you add a {:aliases {:SOME-FLAG {:extra-deps {DEV-ONLY-PACKAGE {...}} :extra-paths ["env/dev/clj"]}}}
then clojure -A:SOME-FLAG ..
will build :extra-paths
with DEV-ONLY-PACKAGE
available.