Hacker News new | past | comments | ask | show | jobs | submit login
The Clojure Mindshare (2019) (groundedsage.dev)
78 points by tosh on Dec 31, 2021 | hide | past | favorite | 28 comments



> We are in an industry that is so new, so fast-moving and so financially rewarding that people tend to gravitate towards popular programming languages. These people are quick to migrate to a new technology, they often skip fundamentals or simply have no interest in gaining fundamental knowledge.

One might say that this simply signals the success of these languages in attracting newer programmers. Senior developers should have this fundamental knowledge regardless of language.

I've read numerous impassioned calls to use a given language like this over time. Clojure, Haskell, every flavor of Lisp there is. More times than not, it leads me to a few weeks of buying into the hype, believing it's going to be the most transformational experience I've had as a developer.

Lines like this seduce you so easily; who wouldn't want to be able to express their ideas with so little friction?

> _ is the most expressive and flexible language. You can reach a flow-state where ideas can freely flow from your mind into code

And these languages can be a good way to learn new ideas and paradigms, sure. But for me, a lot of their usefulness ends there.

The tooling, documentation, community, and everything else beyond the language often matter as much as the language itself. And for better or worse, you simply have more eyeballs on these things as the language gets more popular.


> believing it's going to be the most transformational experience I've had as a developer

Learning Clojure was probably the most transformational experience I had as a developer. Before that I knew Python, C#, Java, C++, and a bit of Ruby and JS. But learning Clojure and getting to use the Lisp syntax, an interactive development workflow, learning about FP, the simplicity of immutable data, and the power of macros made programming interesting again and it just turns out I have so much more fun using Clojure to program in.

> You can reach a flow-state where ideas can freely flow from your mind into code

I wouldn't say that's totally the case. While the interactive development and the succinctness and simplicity of Clojure does help with my productivity, coding still requires thoughts, and asking yourself how do I implement this and that and thinking through it is still often needed for all but trivial tasks. The big difference for me is that this process is now a lot more fun and engaging.

It might not be that you'll find a niche language like Clojure more fun and engaging, but it could be that you do, and that's the appeal I think. For some, there's a niche language out there that they just enjoy a lot more for one reason or another.


>The tooling, documentation, community, and everything else beyond the language often matter as much as the language itself. And for better or worse, you simply have more eyeballs on these things as the language gets more popular.

I would argue they matter even more than the language.

Community is probably the main important one, but the others you mention are foundational too. For example having good documentation is crucial and is basically the way people get familiar with the language over time. For Clojure specifically, I think the shit documentation is one reason it will continue to grow slowly, because it reflects poorly on the maintainers and shows they don't care about newcomers or people who don't "know it". It's such a poor reflection on the language that the core documentation is so bad that there's the community one that exists purely to show examples and explain things that the terse docs don't.


It's true, the Clojure ecosystem is especially hostile to newcomers—in my view it's the principle reason the language has not grown more quickly. There are community members have made the documentation much more manageable, but beginners are still very much left to their own to discover solutions to pretty common problems.

But I disagree that it reflects poorly on the maintainers—rather, I think it illustrates that, for the most part, Clojure was created by experienced language pragmatists, for other experienced pragmatists. Clojure tends to be a refuge from other languages, not something a person is born into. The State of Clojure each year consistently shows how many other languages Clojure users already knew before coming to the language. I appreciate how the maintainers value backwards-compatibility (nothing ever breaks, it only gets better), that they are strongly committed to making the language great in the long run, and are unmoved from the language's founding values.

I do hope as a community we can do a better job for newcomers, for all our sakes—new blood brings new perspectives, but it's okay that "growing the community" isn't the Core team's top priority. (But hopefully becomes someone's priority in the community at some point...)


> I appreciate how the maintainers value backwards-compatibility (nothing ever breaks, it only gets better), that they are strongly committed to making the language great in the long run, and are unmoved from the language's founding values.

This shows even in the half-life of the Clojure repo: https://m.imgur.com/a/rH8DC

That image is 5 years old now, I saw it in the 2016 discussion linked below, but the trajectory is clear especially when compared to the other popular repos analyzed in the post.

https://news.ycombinator.com/item?id=13112449


I am teaching myself Clojure now (starting around US Thanksgiving to be ready for some advent-of-code problems in it).

I never found the docs lacking. Of course, I was using the community docs without knowing (nor caring) that they were community rather than core team docs.

Clojure will grow slowly because it’s different (and “harder” in some ways) from other language platforms. I don’t think many people will be turned off by the fact that excellent docs are at a different URL.


But it's also the case that some programming communities are huge but not very intelligent. At the risk of indulging in a cliche, I'll point to the reputation that PHP had for many years, and which it still somewhat has. This was a community that was, for a long time, dominated by WordPress programmers who engaged in every possible worst practice and anti-pattern.

You could, in a sense, get work done in PHP. But you didn't necessarily learn a lot while you were in that community.

I mostly wrote PHP from 1999 to 2009. I got a lot done. I had fun. But it is a language that if you try to go fast, you automatically end up with sloppiness. More than most languages, the entropy sets in fast, the tech debt piles up unless you invest incredible effort to fight back against it.

Ruby was better, and the Ruby community was much more intelligent, but in every Rails project I worked on, once it grew past a certain point, me and my team started having endless debates about "How should we refactor these fat models?"

When I started writing Clojure, one thing that surprised me as how easy it was to avoid tech debt. Writing short functions comes naturally and without effort. Simply getting away from for() loops and using better aggregation structures cleans up the code in astonishing ways. The thoughtfulness and universalness of the seq interface impressed me in 2010 as much as the PHP "array" flexibility had impressed me in 2000. It was an obvious step forward.

You could say I'm taking easy shots by focusing on PHP, but I could say some of the same things about Ruby. Handing blocks to iteration methods is better and cleaner than the ambitious confusion of the PHP array structure, but it still is not as clean or universal as what Clojure achieved with seq.

And as Zach Tellman has said, it's a rare language where you can just scan a file and the syntax of the language tells you so much about the structure of the code. EDN has been designed with an unusual thoughtfulness.


There are also signals that Clojure is genuinely challenging to learn. If a language is favoured by senior developers and the user base tends to be people with a decade of programming experience then that is a hint that newbies can't learn the language.

Maybe that is ok. Having an expert language to bolt on to Javascript or the JVM might be just what the doctor ordered. But there are a lot of tricky aspects to Clojure, and a lot of ideas that are outside the mainstream (eg, not really having variables). And the language leads people into complex nested functional structures that are challenging to debug - breaking up a big map or reduce to debug it when something is going wrong is not much fun. I can see people giving up and going back to for loops rather than toughing it out and learning how to do things functionally.

And the tooling can be atrocious. Running "clj --help" and deciphering what it all means is not for the faint hearted. A user needs to be familiar with Clojure data structures, Java, build system ideas for both (like aliases, coordinates, namespaces, classpath, file loading process) as a prerequisite, then there are no hints from the deps.edn syntax so one has to read the entire manual to know what options there are. Doing something more than running a repl or a single file can easily spiral into an entire weekend project in my experience. That is a bit silly to admit to, but I suspect it is a big barrier in practice. The competition is "pip install" and Python lets multi-file projects work quite well even without understanding the packaging system. For a Java hosted language it is hard to avoid the classpath.


I read the term "fundamentals" so frequently, but so rarely see them enumerated and defined.

What are 'the fundamentals'? K&R? SICP? Someone once answered 'knowing your data structures and algorithms' but the only thing I see more than 'fundamentals' is a derisive attitude toward leetcode (which seems to be about par for 'knowing your data structures and algorithms').


I went through a long clojure/lisp phase and although I’m not using anymore, I became a much better programmer because I can more easily see abstractions and how data flows through more complex systems using OOP or whatever.


I don't get the "fewer libraries/modules is a good thing". I like using libraries where some has already encountered and created work-arounds for all of the edge cases for a really domain specific problem I'm not very familiar with so that I can focus on business logic. Am I missing something? What's fast about blindly discovering a bunch of stumbling blocks that you never imagined existed?

All that said, I'm a fan of lisps, I've just never used one in production.


There are two types of libraries, the ones that deliver domain specific needs, like a web server, an encryption library, a midi library, a GUI library, a diagraming library, a pdf library, a zip library, a logging library, a database connector library, etc.

In Clojure, those all exist, generally by simply reusing the ones that Java or Javascript already invested time and effort into building, though sometimes it has its own as well.

The other type of library are generally conveniences, they either simplify existing APIs, add programming constructs, or template/establish a pattern for doing something. These are the ones you tend to not need as much in Clojure, because the language is already so expressive and succinct, and it is pretty trivial to implement your own custom conveniences directly focused to your application needs and your personal preferences.


I think the point here is that it's better to not need a library in the first place than to have tons of choices.

As an extreme example, consider NPM's left-pad that caused such a huge mess when it was pulled by its author. It's not good that JS has a left-pad package, because it just shows a gaping hole in what should be JS's standard library.

Slightly more abstractly, Clojure's data-oriented paradigm makes a lot of libraries from other languages redundant, because you can simply map and reduce and assoc Clojure maps instead of writing boilerplate.


Perhaps it could have been stated better as “the language design removes the need for a multitude of competing libraries.”

The statement should not be taken out of context from the rest of the paragraph, which includes, “These libraries are also generally very high quality…” This means that the two or three libraries you find are more likely to handle all of those edge cases you mentioned. Some libraries haven’t been updated in years because they’ve solved the problem they set out to solve, and nobody’s found a fault with them since then.


I agree libraries are great when dealing with very specific domain problems (who wants to hand-roll a datetime module?). But there are also a ton of libraries that aren't for such specific domains or which attempt to bridge multiple domains (i.e. frameworks).

The argument made by functional languages like Clojure is that by making heavy use of pure function composition, you don't actually need a million libraries to build large/complex systems. You can do it with a much smaller number of libraries where necessary and take advantage of the language's natural extensibility for the rest.


I love Clojure, but I do miss static types. I'm hoping Carp[0] (mentioned in the article) comes into its own. It seems like it could become my ideal language. The other problem I have with lisps in general is that they seem to encourage clever programming that is hard to read / debug (or maybe they just attract developers who value brevity over clarity... not sure).

[0] https://github.com/carp-lang/Carp


> Lisp is the most expressive and flexible language. You can reach a flow-state where ideas can freely flow from your mind into code

This kind of claim typically comes from someone pretty new to the world of software development.

You can say this of any language, really, and any developer who's reasonably proficient in language X will also claim that with X, their ideas flow directly into code.

> The Lisp programming language Racket is used to teach programming fundamentals in modern Computer Science courses.

Unsurprising cherry picking. How many universities teach Racket compared to, Javascript C/C++, or Java?

The rest of the article is of the same cloth, raving about Lisp and Clojure as the best programming languages ever invented.

You should learn Lisp, no matter what kind of developer you are. But by today's standards, Lisp a pretty antiquated language which still hasn't caught up to modern trends (static types, asynchronism, etc...) and with a very poor tooling (lack of IDE's) and library ecosystem (building websites, parallelism, GUI, etc...).


> which still hasn't caught up to modern trends (static types, asynchronism, etc...)

Ignoring the fact that your modern trends aren't modern. I don't think any of these statements really are true for Lisp as a family of languages:

For example Racket has typed Racket. https://docs.racket-lang.org/ts-guide/

For asynchronicity Clojure has clojure.async https://github.com/clojure/core.async

> and with a very poor tooling (lack of IDE's)

Lisps have fantastic support in Emacs and VSCode and are in general simple enough languages that often the heavyweight of an IDE is not needed. But if you want IDEs there are:

Dr. Racket - https://docs.racket-lang.org/drracket/index.html

Cursive - https://cursive-ide.com/

Emacs/Cider - https://docs.cider.mx/cider/index.html

> and library ecosystem (building websites, parallelism, GUI, etc...)

Websites - Reagent, a ClojureScript wrapper for React https://github.com/reagent-project/reagent

GUIs - Clojure has the entirety of Java to steal GUIs from - Ex: https://github.com/cljfx/cljfx

Just because the Lisp family is old and has a simple syntax does not mean it's an antiquated language or that there are not new developments going on there.


> You should learn Lisp, no matter what kind of developer you are. But by today's standards, Lisp a pretty antiquated language which still hasn't caught up to modern trends (static types, asynchronism, etc...) and with a very poor tooling (lack of IDE's) and library ecosystem (building websites, parallelism, GUI, etc...).

Literally all of these things are present in Common Lisp (ok the static types "full experience" leads you to something like Coalton: https://github.com/coalton-lang/coalton however the plain SBCL experience does have some compile-time type checking). Meanwhile many so-called modern languages still lack Lisp's incremental compilation let alone the full interactive development experience such a feature can help support, an OOP system as flexible as CLOS, they can't gracefully manipulate their own code as data, they don't have anything like the condition system...


> But by today's standards, Lisp a pretty antiquated language which still hasn't caught up to modern trends (static types,

Typed Racket exists, as does syntactic support for static type declarations in Common Lisp (though whether implementations do anything with declarations is up to them; some, however, do offer compile-time checking.)

> asynchronism,

Racket has asynchronisn via both the thread API (which aren't OS thread, but asynchronous tasks with mailboxes) and via promises (promise/force in Racket is pretty much all the good parts of async/await without the bad parts; future/touch provides a similar API for operations that are parallel rather than merely asynchronous.)

> very poor tooling (lack of IDE's)

Racket, CL, and Clojure all have dedicated IDEs; a number of Java-focused IDEs support Clojure as well.

> library ecosystem (building websites, parallelism, GUI, etc...)

Clojure is designed to leverage the JVM ecosystem, so that's clearly not the case for Clojure unless your standard for a library ecosystem is something beyond what the Java world has. (Similarly with ClojureScript and JS.)

But, sure, there's no Lisp-first platform as popular as the JVM, .NET, JS, or CPython.


> Lisp a pretty antiquated language which still hasn't caught up to modern trends (static types, asynchronism, etc...) and with a very poor tooling (lack of IDE's) and library ecosystem (building websites, parallelism, GUI, etc...)

That's pretty much the whole point of Clojure, a modern Lisp, built for concurrent and asynchronous programming, targeting modern platforms like the JVM, CLR, NodeJS, browser JS runtimes, with great IDE and tooling, and access to the largest swath of existing libraries from various ecosystems.

It also has an optional static type checker, though it isn't very popular and so you'll lose type checks at the boundary between your app and all libraries you use (even most of the standard lib). But I wouldn't really call static types a "modern trend" in any way, considering we just had untyped languages overthrow static ones in popularity with the unprecedented rise of Python, Ruby and JavaScript. And the most popular typed languages are still playing catch up to the ML languages of yore in their static type checking capabilities.


The untyped languages rose in popularity in the 2000s and got as mainstream as it gets. But static typing is having a comeback in the past 5-10 years, with go, rust, kotlin, and of course typescript. Almost every dynamic language is getting some flavor of gradual typing and most people seem to love it.


I guess it depends what your mesure criteria are.

Based on this video: https://www.youtube.com/watch?v=UNSoPa-XQN0 JS and Python took the top spot only in the last 5 years, and I'd think they're only continuing to attract more people.

There's been some new typed language also gaining traction, just not as much or as quickly.

Frankly it doesn't seem types or not matter much over the years for popularity.

What I find interesting personally now is that a lot of people come out of school learning Python, an untyped language. I wonder what effect that'll have long term, where as before I feel it was either Java or C++ or another flavor of a typed language that university and schools would teach.


There's definitely a HN bubble bias when it comes to evaluating what's "popular" or "trendy", reading any claim of such on HN must be done with a huge sack of salt.

I wish the "untyped" moniker never caught on, it should be reserved for things that don't tend to actually have type information like assembly and Forth. Python, Ruby, Lisp, etc. are dynamically typed, not untyped. Types are an important concept in them, as are operations on types, type conversions, violations, and so on. It's just that the data itself carries around its type, rather than the symbol it happens to be bound to. Sometimes I think this part of the solution space isn't really explored very deeply -- for instance it enables Lisp's change-class function (http://www.lispworks.com/documentation/HyperSpec/Body/f_chg_...) which is almost absurd to a static mindset, but the deeply dynamic nature of Lisp never really carried over to later dynamic languages either. Though at least Java + JRebel gets close, it can even re-instantiate spring beans used in dependency injection. Personally as languages like PHP and Python and JS "evolve" to have more static typing conventions, they look more and more like Java, except without Java's good parts (mostly in how the JVM works and the tooling built on it) -- so I'd rather just use Java (if I can't use Lisp).

Your question about the long term consequences of Python no longer being niche and often even being taught in schools reminds me of a few things. First, it's funny how far we are from when pg wrote in 2004 http://www.paulgraham.com/pypar.html "people don't learn Python because it will get them a job; they learn it because they genuinely like to program and aren't satisfied with the languages they already know." Or second when Spolsky wrote in 2005 https://www.joelonsoftware.com/2005/12/29/the-perils-of-java... "My God, I thought, they’re trying to dumb down the curriculum even further!" in complaining about JavaSchools -- surely the equivalent python_schools (if there are any now, rather than schools that have merely supplemented with Python) have succeeded in that since the minimal easy Python subset is easier than the minimal easy Java subset. Lastly, we're not that far from when Rob Pike said in 2014 about why he created Go: "The key point here is our programmers are Googlers, they're not researchers. They're typically fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They're not capable of understanding a brilliant language but we want to use them to be able to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt."

I don't really have any predictions. Maybe more of a hot take thought is that if schools keep producing mediocre programmers, using the relative ease of beginner-level Python as a means, big corps will continue to invest in mediocre languages that nevertheless allow the corp to continue hiring hordes of programmers and getting marginally useful stuff out of them. The advantages of individuals who genuinely like programming and of companies able to identify and hire them will still remain -- even if the corp then forces the programmer to use a less-preferred language, for there exist not-dumb programming-liking Go programmers.


I wonder if I other proglangs are really on par Lisp like (open to extension at the meta level) langs. It's true a good perlist or ada coder can flow. But when you reach the limit of a language, you're stuck. These other languages become their own tool, and compound on.


> This kind of claim typically comes from someone pretty new to the world of software development.

Have you ever seen a newbie talking about Clojure? I bet ~98.5% of developers < 5 years experience never heard of it. Let alone claim how good it is.



Fixed above now. The page had https://www.groundedsage.dev/ as the canonical URL, so our software had switched to it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: