I think it's less about linters and more about basic tooling for toolchains, dependencies, cross compiling, lsp, etc... compare the Haskell tooling to Rust tooling and it's easy to see how deficient it is.
> Backwards compatibility is simply a design aspect, not some holy commandment you must adhere to all times.
It's also something that has enormous influence on industry adoption.
I adore Haskell the language. I use it daily. But I make no excuses for its many shortcomings. I would love to see Haskell prioritize industry needs over academic purity.
What's the point in creating the N+1th generic blub language?
It's not "worse", it's a tradeoff between backwards compatibility and fixups. Backwards compatibility is a really useful feature in and of itself, and the question is whether this outweighs the usefulness of all the tiny fixups. In my opinion it mostly does.
I think the reason why this is not emphasised more is because breaking compatibility is a visible cost (program broke, time to investigate and fix it) while the pains from maintaining backwards compatibility is an invisible cost. (you can't easily quantify the wasted hours and extra bugs from unintuitive/broken language features) This is kind of a natural consequence of the incentives, so I understand why it happens. I'd be happier if it wouldn't.
> and not allowing for an opportunity to write really good code. Basically, enforced mediocrity.
> straightforward, laziest, zero optimisation code, and giving themselves an excuse for that.
> justify their laziness,
Jesus christ you have so much disdain for such a large set of people. Have you ever considered that you might have a chip on your shoulder about Haskell adoption?
> There should be a place for languages which are ambitious and aren't afraid to break things.
There is - it's research and hobby, not production. Like literally "not afraid to break things" is the antithesis of an industrial language.
Sometimes I wonder if some language communities really are cults. It's the same with Lisp - replace "type system" with "homoiconic" and you have the exact same mantras about ultimate supremacy and "intellectual" superiority. But the proof of the pudding is in the eating and across probably 10 computing devices in my home, not a single one has any Haskell or Lisp programs running on it. Lots of Java, C, C++, Python, Rust, Bash, JavaScript, even Perl (probably) but not a single binary compiled from Haskell or Lisp interpreter to be found. To any reasonable person, that should be a strong signal about the so called "power" and value of their sacred cow.
Put another way: the word language in the concept of programming language isn't accidental and learning a niche programming language is comparable to learning a niche human language - have fun, expand your horizons, but don't pretend it's useful.
Xmonad and pandoc are probably the most heavily used Haskell programs. Not necessarily contradicting your overall point, just exhibiting the two examples that someone might reasonably be expected to run into.
I got rid of xmonad in favor of i3 ages ago - precisely because it doesn't force me to edit a Haskell script just to change a keybinding.
"Have you ever considered that you might have a chip on your shoulder about Haskell adoption?" - No. I barely use Haskell myself. This could have been written about any other language, my opinion would have been similar. I don't have a strong emotional attachment to Haskell specifically.
Haskell is successfully used in industry, in some cases with billions of users.
https://engineering.fb.com/2015/06/26/security/fighting-spam...
I think this is a bit unfair. The author's criticism is that people try very abstract things and don't stick the landing. And to an extent, I agree, but the problem isn't that Haskell is too powerful, it's that it's just barely powerful enough for too many things. Contra the author, GADTs are not one of those things, and snoyman can pry them from my cold dead hands. But singletons clearly are. So are impredicativity, open type families, type level arithmetic, and to some extent Template Haskell. Idiomatic Haskell practically writes itself, but type-level Haskell is at least as hard as C, and it's almost entirely because of how terrible the ergonomics are.
> Third, about backwards compatibility
Strongly agree here, if anything GHC doesn't break backwards compatibility enough. `Num` is an abomination.
So they discover functional programming, and they just get hammered with so very many different ways of doing things. At first it all seems impossible, but then it slowly unlocks itself, and look! All the problems with imperative programs went away! You didn't even properly perceive them before, but they're gone.
You can't hear me, so my tone here is completely serious. I strongly recommend any professional programmer spend some time with a language like this and attain enough fluency to write real, non-trivial code in it, not just map a few lists and maybe use a monad or two. Get something that hits the network or something.
And the problem is, too many of them stop here. Conventional programming sucks. Functional programming rules. Anyone who doesn't use functional programming languages is a loser still wandering blind in the wilderness.
However, there are in fact a lot of practical problems with functional programming languages too, many in the original blog post, others expressed elsewhere. It can be as simple as, that critical library I need is not available in my obscure niche functional programming language, but alas, in the real world, that's enough to be a determining factor.
Where the religious-level advocates of FP lose contact with reality is that there's a third option: You take what you learned in the functional programming world and come back into conventional languages. And I don't mean "use a few maps and jam a monad in to your language even though it completely fails to fit"; that's actually still completely missing the point of functional programming. I mean, you start writing "conventional" code except you pay attention to mutation. You may not write completely pure code everywhere, but the more you mix in the more characteristics of pure code, the more of the benefits you get. (I do think there's an interesting discontinuity at 100% pure, when you can 100% count on it and then build further on that ability to be sure all code is pure, but you do still get a gradient of benefits the more purity you put into your conventional code.) You pay attention to side effects and start isolating them into units instead of mixing them in. You learn how to multithread with messages instead of memory sharing and locks. You don't drag in inappropriate APIs from a foreign paradigm; you take the fact your eyes were opened, and you write code with those now-opened eyes.
And it is not perfect. You will still occasionally have the original imperative problems. But you will have radically, radically fewer of them, so few that the cost/benefit analysis of using the super-strong stuff becomes very difficult to justify, especially over the advantages of being able to use that library you really need. (And see the library has a mutation problem and wrap it in a way that solves it for you, instead of letting it drag the rest of your code base down, etc.)
I have ridden the mighty moonworm... errr... I have fiddled with the Haskell type system and done some interesting things with it. But by and large they really weren't worth it, not in the sense that they don't solve some problem, but in the sense that back in the conventional programming world, I really don't have those problems anymore. No credit for solving problems I don't have.
This is where I diverge with people complaining about not using functional programming. They are comparing writing imperative crap with writing pristine functional code. In this context I don't deny I'd take the functional code too. But I am comparing writing eyes-open conventional code with writing normal functional code. In this context the advantages are a great deal more muted and it isn't anywhere near the day-or-night level of difference... and I gotta say, pitching me back on full-on functional programming by claiming I just don't get it and I just want to write bad code and enable bad code and in general be lazy and bad is bad advocacy in almost every possible sense of that term.
This has unfortunately not been my experience. Working alone, sure, I can write acceptably pure code in a conventional language. But generally the issue isn't what I can do, it's what my coworkers will do. Even if almost everyone manages to maintain strict discipline without the support of the language, it really only takes one "productive" cowboy to create a disaster. The biggest advantage of pure functional programming is that taking the path of least resistance produces code that's still sort of ok.
Sure, it is possible to be very disciplined, avoid messy control flow, be careful with mutation, etc.... then good luck trying to get everyone else to get on board with a very niche coding style, unless if you have the strict authority to enforce it. Sadly, in most cases you don't, so you are stuck with the non-verifiable madness.
In an ideal world, this would work - but in an ideal world, we would also be using better languages with way better guarantees and compile-time checks.
If you want to be wistful for a world where we could use better languages... get in line. It's a long one. But stop expressing it in the form of insulting other people.
You are not the smartest in the room, you are not the only one who has grappled with the issues, and if you'd stop going out of your way to insult everyone else, maybe you could listen to and learn from people offering solutions. Even if they aren't perfect; it's hardly as if you're offering a perfect one either.
This just isn't true.
We write essentially 100% Haskell where I work. All day, every day. Have done for years.
We have a "real world" business, with real customers, who pay real money.
I am not insulting people personally, I am insulting the "worse is better" culture which is prevalent in the profession. No one has an immutable opinion about this, and I do not think that looking down upon an opinion or set of beliefs is a hostile thing. In a (slightly weird) way, it's actually constructive because it might plant a seed of thought in people that it's possible to do better. I'm doing the opposite of looking down at or insulting people here - I am assuming they are rational and capable of thinking, they just haven't encountered a different mindset than the prevalent and trendy one, and that's a perfectly fine thing.
"Developing/using better tools, languages and trying to change developer culture" is a solution. Sure, not a silver bullet or something achievable quickly or easily, but on a smaller scale, it's definitely possible to achieve success.
It's not "laziness". It's understanding that maintaining software long-term is a really significant problem.
The point is that Haskell's position on the abstraction spectrum is no less arbitrary than that of Go or C++. You cannot divorce the relative advantages and disadvantages of various levels of abstraction from the realities of maintenance, development time, readability, complexity, and yes, the fact that not everyone is as big brained as you, because by not writing machine code, you have already acknowledged that these realities matter.
I can just as easily come up with my own programming 'language' where there's a 1-to-1 mapping between a countably infinite set of characters and every unique Turing machine. Want to write a program? Find the right character. This is the most terse, most elegant programming language ever, but clearly helps no-one.
The best abstraction is the one that is the most universally understood.
Five years goes by a lot faster than you might think.
There is something sinister in this - first, in the author's lamentations about bad tooling. Other languages require linters, formatters, static analysers, etc. because the language's built-in features and type system are sub-par. In Haskell, that's not true, so the lack of "sophisticated" tooling is way less painful.
Second, this is similar to the "equalise things by dragging everyone down to the same level"-type of thinking. It "makes maintenance a chore" because the language allows you to be creative and shoot yourself in the foot! Sure, you can have languages like Go where the language is simple and it's hard to write "unreadable" code, but that comes at a cost of being very verbose, and not allowing for an opportunity to write really good code. Basically, enforced mediocrity. "Hard to maintain" is also used as an euphemism for "this is too complex and I can't be bothered to try to understand it" sadly. I find that quite ironic in the face of all the needless complexity in the software industry (just look at k8s, terraform plugins or the web development stack)... I know way too many programmers like that, who argue endlessly about what is the "most readable", which in practice just means to write the most straightforward, laziest, zero optimisation code, and giving themselves an excuse for that. Even if a less-capable language hinders development (either by making things non-verifiable like no proper optional/nullable handling or simply by making the code more verbose and/or less readable) their advocates justify it on the basis of being standard or "best practice". I think Haskell and similar languages intimidate similar people because they can't shrug and say "well the language can't do that" to justify their laziness, but would have to actually make a reason up to why they don't want to write sound, safe and performant programs.
Third, about backwards compatibility.... this is a "damned if you do, damned if you don't" situation. On one hand, you have languages like C++ and JavaScript which are really backwards compatible, and have really sizable drawbacks because of it. Sure, your code will compile in 5 years most likely without changes, but the language as a whole suffers because of it. There should be a place for languages which are ambitious and aren't afraid to break things. Backwards compatibility is simply a design aspect, not some holy commandment you must adhere to all times.