3 ms·
> There is no way to know what's being passed around without reading the source of the whole chain. But that's not what a Clojure dev would do. 1) We use Mall
by erichocean 2y ago
> There is no way to know what's being passed around without reading the source of the whole chain.
But that's not what a Clojure dev would do.
1) We use Malli [0] (or similar) to check specs and coerce types if needed at every point. Checks can be left on in production (I do), or disable–up to you.
2) If the coercion is difficult, use something like Meander. [1]
3) If even that isn't straightforward and you need actual logic in the loop, use Specter. [2]
4) If you're not sure what going on at intermediate steps, use FlowStorm [3].
5) But you're going to be processing a lot of data you haven't seen before! Use, Malli with test.check [4] and make use of property-based testing with generators.
None of this is "advanced" Clojure, this is bread-and-butter stuff I use every day.
6) Need a Notebook-like experience to get better visualization of intermediate data? Use Clerk [5].
7) Need special checks on API usage within your codebase? Use clj-kondo [6] with custom linters. They're less than 10 lines each.
Unlike default-mutable languages, or typed, it's safe and easy to use libraries with Clojure and they tend to have very little churn. Total opposite from Python or JavaScript (if you're used to that).
It's almost impossible to give the impression of what it is like to develop with Clojure if you've only ever used languages with static typing, or languages from the Algol family.
Honestly, I hated Clojure's syntax at first BECAUSE I COULDN'T READ IT, and I loathed "structural editing." After 2-3 weeks, I read it just fine and it's hard to remember I ever couldn't do so. Now I like it, and structural editing makes it so easy to change your code, I couldn't live without it at this point.
Basically, all my "fears"/dislikes were unfounded—it was a skill issue on my part, not a problem with Clojure.
[0] https://github.com/metosin/malli https://github.com/metosin/malli
[1] https://github.com/noprompt/meander https://github.com/noprompt/meander
[2] https://github.com/redplanetlabs/specter https://github.com/redplanetlabs/specter
[3] https://www.flow-storm.org/ https://www.flow-storm.org/
[4] https://github.com/clojure/test.check https://github.com/clojure/test.check
[5] https://clerk.vision/ https://clerk.vision/
[6] https://github.com/clj-kondo/clj-kondo https://github.com/clj-kondo/clj-kondo
- maleldil 2y agoThat's a lot of different tools for something that could simply be a statically defined type with compile-time checking.
- erichocean 2y agoNo it can't, but hey, there's a talk about that! The Value of Values: https://www.youtube.com/watch?v=-I-VpPMzG7c https://www.youtube.com/watch?v=-I-VpPMzG7c Using types to model data is a terrible idea.
- hombre_fatal 2y agoMost people don't use those libraries, nor do most libraries use those libraries. They don't help me understand most code out there beyond my carefully orchestrated app code. I'm back to reading the source. But this long list of runtime libraries is definitely a downside of Clojure. It's people trying to grapple with things mostly solved with static typing where you can just write a(b(c())) and it fails before it hits your fancy yet-another-thing-to-learn Malli library in runtime. They might be great libraries, but you're only seeing one side of the trade-off. I learned Emacs with evil-mode, paredit, nrepl/cider, and Clojure in my early 20s and used them for six years, and I was pretty gung-ho about it like you. But eventually I started using static typed languages for work and decided that I couldn't go back. It's like trying to read Javascript after you've spent five years with Typescript. You just think "wow, I can't believe I did that for so long." And I'm remembering times I've used paper and pencil to figure out how map is being transformed as it's passed through library code. I don't miss that.
- ldite 2y ago> But that's not what a Clojure dev would do. Apparently I and my fellow Clojure devs aren't real Clojure devs. Or perhaps you mean "true" clojure developers, or "good" clojure developers. (cf. https://en.wikipedia.org/wiki/No_true_Scotsman https://en.wikipedia.org/wiki/No_true_Scotsman) And even if we were Clojure devs we've inherited multiple big Clojure codebases that were apparently written by non-Clojure devs, and heavily refactoring is not on the to-do list.