Prior to Clojure I feel that I didn't really know how to do things well.
In the context of the domain I have the most experience with, web applications, I'd summarize the bulk of programming as defining data, data transformations and shoving data through APIs. Once you get the hang of it, Clojure makes it trivial to transform datastructures from A to B. This has enormously expanded the kinds of problems I can solve.
When Rich says "It was impossible to avoid the sinking feeling that I had been “doing it wrong” by using C++/Java/C# my whole career."
I feel somehow that this is the case for the majority of people but they don't realize it yet because their experience is the most popular trendy language or framework. I've seen many examples of libraries in different languages having enormous amounts of commits and hundreds issues for problems that are trivial to solve in Clojure.
I was in the same boat, constantly grabbing for frameworks and if one wasn't available that made my task simple, would struggle trying to bend the frameworks or language I was using to come up with a solution.
I'm not a language geek and I don't write code outside my work for fun. I want to spend the least amount of time possible in front of the computer and sleep knowing my web applications won't topple over. Clojure has fit me so well that I don't think I would have accomplished what I have in other languages.
Could you elaborate on a problem that illustrates this property of Clojure? This sounds awesome, but I have a hard time understanding what you're getting at without knowledge of Clojure.
Here is a very simple example that I think does a great job of illustrating how Clojure was designed to deal with "data" in a straight-forward and concise way:
(defn csv-data->maps [csv-data]
(map zipmap
(repeat (first csv-data))
(rest csv-data)))
This is a function that, when given a contents of a CSV file (list of sequences), converts it to a list of maps, where the keys are the column headers.I'm sure there are clever ways of accomplishing this in other languages, but the default way a Java/C# dev would probably approach this is to create a class that represents the CSV columns, and imperatively iterate over the contents.
With Clojure, the above function is idiomatic, and 4 lines long.
When it comes to "information processing" systems, which is what a lot of us work on, having a language with a primary purpose to provide powerful and concise tools to process that information is.. I don't know, liberating? (maybe not the best choice in words).
(this example was a bit of an eye-opener for me, coming from a .Net background, as I was writing some simple Clojure code that needed to read in some data and was struck at how simple this solution is)
If you really wanted to (and you understand Clojure's destructuring and lambda syntax) you could even do it in two lines:
(defn csv-data->maps [[head & lines]]
(map #(zipmap head %) lines))
i prefer perl
It may look terse, but its not code golf.
Any Clojure developer would understand what this does (its actually pretty straight forward), but to an outsider, it definitely looks strange.
Part of using Clojure is becoming familiar with the language, its syntax, and its idioms.
Rich even has a section in "Simple made easy" where he talks about this very thing; its on us to become familiar with the tools we are using.
Do you have any recommendations of online resources or books that can get a web programmer (experience in PHP / C# ) up to speed with clojure ecosystem ?
I would highly recommend learning the spirit of Clojure first:
https://changelog.com/posts/rich-hickeys-greatest-hits
https://www.youtube.com/watch?v=vK1DazRK_a0
There are a few classes of tech that are uniquely Clojure:
Data driven DSLs:
- https://github.com/noprompt/garden
- https://github.com/weavejester/hiccup
- https://github.com/seancorfield/honeysql
Hyper normalised relational databases:
- https://github.com/replikativ/datahike
Advanced SPA tech (hyper normalised data driven):
- http://fulcro.fulcrologic.com/
- https://wilkerlucio.github.io/pathom/v2
Once you understand the spirit and rationale for Clojure it becomes apparent why other communities don't have this kind of tech yetOnce it gets down to practical things I recommend using clj-Kondo with type hints, Cursive for Intellji, make sure you learn how to hot code inject new code into your running program using your editor shortcuts, and TDD in Clojure is also excellent and immediate: https://cursive-ide.com/userguide/testing.html
Also look out for GraalVM and Babashka we're using it to compile fast native binaries out of Clojure