Some thoughts about Clojure, its latent potential and adoption

Clojure’s hallmark is stability which means slow, carefully considered changes. The main “changes” over the past three years are the growth of the official Clojure CLI/deps.edn in terms of usage and tooling, the growth of Calva in terms of usage and features, the addition of tools.build and a build.clj file for deps.edn projects to provide programmatic builds, and the arrival/growth of visual tooling (Reveal, Portal, etc) some of which is being driven by the data science community.

If anything, Clojure’s ecosystem is becoming less and less like other languages by focusing on a wide selection of simple, composable tools and libraries.

However, as you say of the JS/TS ecosystem, you can pick a curated set of tools and focus your work entirely within that subset of the ecosystem. At work we’ve chosen the Clojure CLI, deps.edn, and build.clj – after migrating from Leiningen to Boot in 2015 and then from Boot to the CLI in 2018 – and we find it works very well for all our needs, and it’s also the path I’ve taken with all my OSS projects.

Thanks for sharing.

One thing I’m seeing is that those are such minor quarrels, and yet it seems it was enough to taint your experience.

If you were say on my team, I could have showed you how to solve these with 30min at your desk.

So I take it that maybe the real root cause is tutorials/guides and I mean, not necessarily the lack of them, but probably more the clarity on which one is up to date and “generally recommend to follow”.

1 Like

So this is the golden path these days? Clojure - Install Clojure

I should ignore the other vscode extension?

I hear this regularly but it’s not an approach that scales.

It’s the same in python when somebody asks what the best way is to install and manage packages for their project and they get 5 different answers each of them incomplete/incomprehensible. Quickest way to turn off somebody who’s new.

Aside from occasionally helping beginners with Leiningen problems, I haven’t used Leiningen for any projects for about seven years (and I haven’t used Boot for over four years). I’ve used the Clojure CLI and deps.edn (and more recently added build.clj) for all my projects, large and small, so yes I think it’s the “golden path” these days. At work, we have over 140k lines of Clojure in a monorepo with 90 Polylith components that builds nearly two dozen deployable artifacts – so the deps.edn/build.clj approach definitely scales up to large projects.

You don’t say what “other vscode extension” you were using so that’s hard to answer. When I first switched from Atom/Chlorine to VS Code, I used Clover (a version of Chlorine for VS Code) on its own, then I added Calva to leverage all the static analysis assistance of LSP/clj-kondo, but I’ve switched completely to Calva now, as the maintainer of Chlorine/Clover is focusing more on the community fork of Atom (can’t remember its name) and he isn’t a fan of Microsoft so I don’t really think Clover is going to get much additional love at this point.

I’ve played around with Elixir which has a much more cohesive development story but keep coming back to Clojure for the syntax, REPL and JVM/JS ecosystems.

I used to think that Clojure needs a Rails but it doesn’t really fit the philosophy of the the language. I also don’t think Clojure will ever be popular but it will endure because of its portability.

1 Like

+1

My perspective isn’t an experienced dev. I have to figure out new things every day I program that it feels like advanced people get to take for granted.

I think leiningen is still good as a “week 1” / “month 1” tool to take the first steps. Here are my 2¢ on the golden path. Sorry to be wordy. Isolating steps helps me a lot personally.

  • Verify java
  • (Optional: jenv is a lifesaver, I use as much as I used pyenv)
  • Install clojure/tools/clojure with a package manager. Even if not needed by lein it’ll be necessary at some point
  • Install leiningen with a package manager
  • Create some disposable lein projects until you can comfortably get a hello world-type environment going with a REPL and editor.
    • Connect and disconnect,
    • Print things,
    • Evaluate forms, (and know the difference! evals should show inline, but yes printing will end up in a console somewhere totally different)
    • Get familiar adding dependencies and requiring them,
    • Try the absolute basics of build/output to whichever your goal is. As in, hello world jarfile, executable, webpage

I think the overhead of touching down in empty/throwaway projects that don’t get anything done is outweighed by avoiding headaches trying to simultaneously get comfortable with your tools and create meaningful things.

  • Then, start over. Lol
  • Create a totally empty deps.edn project. Essentially you can make a src folder and deps.edn file that contains an empty map {}. Since you are already using an all-in-one IDE plugin this project can still at least do something.
  • Add flags one by one, populating projects with dependencies, entry points, testing, command line and jvm opts.

It took remarkably little effort to get back up to speed, doing the same things I did with leiningen, just with more transparency and flexibility. What I see as the only noticeable downside is simple commands got a whole lot more arcane. Eventually remedied with good notes and alias-type setups.

Then a little beyond that,

  • Hone the workflows that cover your use cases
  • Key commands, lisp parediting, selective evaluation(!),…soooo amazing IMO. VS/Calva isn’t emacs but it still gives you a ton of power to make muscle memory take another step out of the pit of absurd tool complexity.
  • Get a feel for where and how classpath type stuff occurs, and how the tools CLI can help make the process more global, repeatable across projects, and plug and play
  • There are actively evolving tools that provide equivalents to parts of pip, node, cargo package management. They are a bit revelatory to me. I had missed installing deps with one command. But don’t want to clog up your headspace further currently.
  • Alongside normal development, test the waters with tools like babashka to see how, where, what clojure can do outside of encapsulated and rote project environments

Doing a zillion things probably isn’t the answer you’re looking for!

But a slow step-by-step approach over the very valid hurdle has been rewarding for me.

Yes, I see you linked clojureVSCode, looks like a personal project that hasn’t been maintained for a couple years, and it won’t do anything Calva can’t

+1!

2 Likes

I’ll go over this stuff or at least I’ll see if I can get the core.logic REPL I need up and running like that.

Ah, I see. It has an awful number of downloads though.

I created an issue and pinged the maintainer on LinkedIn.

Hm hope I’m not spreading misinformation.

Good luck! I’m sure I/we will be happy to see any progress you make working with core.logic

If you want to get started with deps.edn but are intimidated by it, plum might be a good start. It provides an easy way to create projects and add dependencies from the command line. I use it mostly just for starting new projects (the rest I usually do just by editing the deps.edn), but it might be helpful to check it out.

2 Likes

Thanks for the link to plum!

I’ve never used plum before. But I’ve used neil quite a bit. The two seem to have a similar scope.

@mvarela - any thoughts on whether these actually solve the same problem? I see that plum for instance has a plum repl command, which is out of scope for neil. Edit: nope, just a different approach. I stand corrected.

2 Likes

neil has: neil add nrepl which adds an nrepl alias to your project. After that you can do:

clojure -M:nrepl

and get a decent console REPL as well, while also launching an nREPL server (similar to what lein does).

Read more here.

2 Likes

I have never used neil, so I’m not sure how much they overlap in practice. Plum hasn’t been updated for a while, and tbh, I’m not sure how many people use it. I find it practical for getting a project started (which neil doesn’t seem to do?), but as I mentioned above, all the rest I do directly on the deps.edn file from Emacs (this of course includes starting a REPL).

edit: I just saw that neil does have a way to create a project, so I guess it’s probably a better option nowadays, since it’s actively developed, and part of the bb ecosystem. I’ll give it a go to see how it goes.

2 Likes

@Timothy_Baldridge really cool to see you here.

Your videos on YouTube and the other tutorial really helped me understand how core.async was built. As much as I avoid core.async (as I also do async/await and any type of reactive pipelines), I appreciate the ingenuity you put into the compiler. I had never heard of SSA before but after going through those tutorials and stepping through the core.async code - I see that it’s everywhere.

I’d definitely recommend people to your videos as yours as well as Brian Marick’s introductory videos to midje and TDD. They were probably the most influential in my growth in terms of understanding how to program.


The best thing about your videos as well as the midje one is the fact you guys can back it up because you guys actually wrote the damn thing. Going back to the source… so to speak. Unlike a lot of videos these days purely aimed at self promotion.

Clojure IS one of the killer features (for the JVM). If you’re talking about systems and performance with Clojure, you’ll be talking about the JVM and I’d much rather trust the opinion of a JVM expert than a Clojure expert - whatever that means these days.