Hacker News new | ask | show | jobs
by yogthos 1350 days ago
As the saying goes, a bad workman always blames his tools. You can make a mess in any language, and Clojure is no exception.

There are plenty of ways to mitigate the problems the author describes. A few of these things would be having coding standards to ensure that code is written in a way everyone is comfortable with. This also covers things like adding schemas and documentation for maintainability. Doing pairing and code reviews so that multiple developers are familiar with different parts of the codebase. Having good tests so that you can have confidence that the code does what's intended when you make changes.

I'm also not sure what makes Clojure esoteric. It's a clean and well designed language that embodies good principles. It's a niche language, but far from being esoteric. I've been using Clojure for over a decade now, and I've seen the opposite of developer churn. Most people are pretty happy to stay at a company using Clojure. The fact that there is high churn is suggestive of a toxic environment that drives people away.

Finally, here's [1] a talk from a founder of a Clojure startup that grew into a large successful company. Clojure didn't get in the way of that.

[1] https://www.youtube.com/watch?v=u-4FiFpkPlQ

4 comments

I don't understand this reputation either. There are very large systems built on other Lisps, and they didn't collapse. What makes Clojure different?

For example, Emacs has a massive amount of Elisp. Elisp is much more primitive than Clojure, and traditionally libraries don't use e.g. data schemas [1] as runtime contracts for data.

Obviously, once a system built on top of a dynamic language grows beyond certain threshold, you need to be very disciplined as there are no static types to ensure some degree of correctness.

With that said, it would be interesting to have a language from the ML family as a viable contender. Perhaps a modernized version of Standard ML. Or perhaps OCaml, if it gains some traction with multicore and algebraic effects.

F# is nice, but it's a bit of a watered down version of SML due to the lack of functors. Scala is too complex and far from ML in some regards. Haskell is good, but lacks critical developer mass and some libraries / laziness overcomplicate certain usecases.

[1] https://github.com/plumatic/schema

I offered a counter example to the comment author too (Clojure has been wonderful for us), but I do wonder if there is one area where OO languages excel above functional: the shape of the code hints at the shape of the data.

In Lisp, function names describe actions. In OO, classes, inheritance, static properties, and getters and setters give at-a-glance hints as to the shape of the application's data model. In Clojure, we compensate, as you pointed out, with forms of documentation. I'll take that trade-off any day—I never want to go back to classes! But it's perhaps one reason for which Clojure has a reputation of being hard to read by other devs.

since around the early 80s it was common to write large Lisp software using class-oriented or even class-based OOP (a few used also prototype-based OOP). For example Flavors for the MIT Lisp Machine was class-based: multiple-inheritance, mixins, message sending with single dispatch, ... CLOS (the Common Lisp Object System) then changed OOP such that it better fits into Lisp: generic functions with multiple dispatch, classes, multiple-inheritance, meta object protocol, ... One of the drawbacks of those systems is that the code gets assembled at runtime (though cached) and thus to read and understand code one might need support from class/function browsers.
You can make a mess in any language, yes. But some languages tend to produce more messes than others. If your tool is mis-used more than other tools, at some point, it's not the fault of the users.
> If your tool is mis-used more than other tools, at some point, it's not the fault of the users

And Clojure isn't misused more than anything else. In fact, I've got a feeling it's less so.

The difference is just that you can scapegoat it, and people will believe you.

You can't blame Java for the failure of your project, cause everybody knows Java has worked fine for so many other teams, but nobody knows Clojure, so you can blame it for all your failures and people gives you the benefit of the doubt.

When you have a bad code base, and it's Java, people blame the people who wrote the code. When you have a bad code base and it's Clojure, people blame Clojure. Go figure!

I’ve personally had to deal with far more and worse messes in Python, Java and Javascript than I ever did in Clojure. (Started using Clojure ~13 years ago, but have been in jobs that use the other languages I’ve mentioned in that time too, not always exclusively using Clojure, although there were periods where I was).

I have mentioned a few times in the past, on HN and Reddit and elsewhere, that my biggest personal dream language wishlist item is “Clojure but with static types”, however, while that’s something I dream of having, it hasn’t held me or the language back in any meaningful way. The thing that makes Clojure less mess-inducing in my opinion is largely the fact that it’s data is immutable by default. An immutable-Python would be something I’d be interested in trying.

> I have mentioned a few times in the past, on HN and Reddit and elsewhere, that my biggest personal dream language wishlist item is “Clojure but with static types”, however, while that’s something I dream of having, it hasn’t held me or the language back in any meaningful way.

Sadly, Rich Hickey has always been pretty opposed to typing in Clojure. Enforcing values to be not null is basically table stakes for typed systems, and yet he doesn’t seem to think it’s valuable or feasible,

https://github.com/matthiasn/talk-transcripts/blob/master/Hi...

It does make me sad every time I have to deal with macro systems in non Lisp languages (Julia, Scala).

Yeah. By dream of I mean “if I had a on of free time, it’s something I’d love to make because I want it” while knowing it will never happen. I know that Clojure itself will never support it, outside of external projects like Typed Clojure
Are you familiar with Carp [1]?

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

YMMV, but "messes" are for me things that manifest in projects spanning both multiple contributors and non-trivial periods of time. And in that framing, in my experience, the most effective individual proxy for "is this project a mess" is whether or not it's implemented in a dynamically typed language. Python, Javascript, Clojure, Ruby, my experience is that they all break down at scale, far more than equivalent projects in statically typed languages.
I’ve seen what I would consider messes in C++ and Java too, so it’s not exclusive to dynamically typed languages, but I’ve certainly seen enough in Python and Javascript to understand what you’re saying. It’s also a reason why I dream of a Clojure-like language with first class static typing, but, alas…
I've certainly seen far worse messes produced in languages like Java than in Clojure myself.
> As the saying goes, a bad workman always blames his tools.

And many times purveyors of a bad tool blame the workman.

If Clojure was a bad tool then people wouldn't be using it in the first place. There is a big barrier to getting started with Clojure because it's semantically different from mainstream languages. The mere fact that people use it and there are successful companies built on it demonstrates that the language does provide value.
You can say that about every language that's ever been used in a successful business. By that argument PHP is about the best language out there.
Your argument is based on a fallacy. The whole reason PHP became popular was that it was easy to get started with. The barrier for using PHP or JavaScript is very low. The opposite is true for a language like Clojure.