I love your observation about the two completely different points of view regarding “for loop, early return, and how to model state” – that’s very insightful.
I think it depends on the Scala code you’ve been exposed to. In my experience, there are two very different schools of Scala usage: the “better Java” crowd and the “almost Haskell” crowd. Or at least that was my experience when I was deep in the Scala community ('09-'11) before I switched to Clojure. I thought that the “better Java” usage would probably die out and a lot of those folk would switch back to Java… but maybe the percentage of the “almost Haskell” crowd just remained very low, based on what you’re saying you’ve seen?
Definitely take it all as anecdotal, but I’d say at my company it’s very much “a better Java”.
I think when Scala is introduced in a team, there might be one or two initial devs who are interested in its functional and Haskell-esque aspects. But the rest of their team will just use it as “a better Java”. And eventually when those initial one or two leave the team, others will replace them also just using Scala as “a better Java”.
So eventually, you’ve got way more devs using Scala “as a better Java” and never really trying to learn FP or the deep intricacies and concepts of Scala.
I also think Scala is not chosen for new things as often since Kotlin came around.
So probably when I get someone from a prior Scala team, and teach them Clojure, they’re more likely to be of the “I just used it like a better Java”.
Also, a lot of people’s use of Scala sometimes is more minimal, having used it for Spark.
I’m sure there’s some team where everyone is more into Scala as a better Haskell, but probably I never got someone from a team like that.
I’ve wondered too if Scala obfuscates FP too much. Sometimes all the type related complexities and the existence of classes can obfuscate the essence of FP, like the fundamentals. Not sure if that’s true, but I had that thought.
Where are the available books or courses that are for complete beginers to programming? Clojure is loosing potential users by only having resources for people already experienced with programming.
What about academia? I cry sometimes at the things new grads have been taught. Any signs of Clojure being used to teach methods in university courses? Perhaps again marketing to academic conferences would help?
I had thought part of the idea of the Nubank purchase of Cognitech was to boost conferences and community building - to sensibly safeguard their own investments in the language. But I haven’t been aware of any great impact, albeit there’s been a pandemic in the meantime.
I’m fairly confident that when people say “python is easy”, what they are really talking about the application of it towards a specific task NOT the programming language itself. They mean, for example, someone wrote a very specific guide in python.
I’m dropping in after learning the languages originally 3 years ago. It feels like very little has changed in those 3 years?
I like the language a lot and reach for it when I don’t want to deal with the computing archeology of having to run a traditional LISP/Scheme. What’s most off-putting to me is all the non-language stuff:
The VScode integration, the one I tried didn’t work (GitHub ticket) so I ended back up at Calva which kinda works but it’s always difficult to figure out which of the options you need (9 options when starting a REPL).
The REPL itself is very messy and can’t figure out whether it’s a REPL or an editor. I have to manually eval things or not? REPLs are praised as the magical thing but never could get them to work in a way I would consider nice and was told to watch an hour long screencast (nonstarter). Example: I Alt-Enter an expression and it then prints the output in a totally unrelated place. Shouldn’t these two things belong together?
Five ways of doing anything, lein, deps, don’t know anymore. Exacerbated by the split between Clojure and Clojurescript which makes it 10 ways to do anything.
What I’m looking at mostly (I main python):
Rust: cargo test; cargo run; One way of doing things. Just works. You can do really weird things with a Rust project and swap things out but I need to read some advanced books to figure that out. Nobody talks about it.
Roc: charming evolution of Elm/Haskell that maybe will get some stuff right, but too experimental and small to be used for anything at the moment
Javascript/Typescript: I like to hate on this a lot but playing around with small languages, the benefits that a large language has in terms of resources, documentation etc. becomes all the more evident. Also 10 ways to do anything but if I choose to live within this or that framework, things mostly work.
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.
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”.
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.
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
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.
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.
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.
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.