I rage quit Haskell when I saw all the promises for application correctness fall like a house of cards by realizing I can write to a file after it has been closed when using lazyIO.
Yes, Haskell has those gotchas like "don't use lazy IO", "there are partial functions on the Prelude", "String is slow", and "code may throw exceptions where you don't expect".
They are there mostly because of history and the language would be better without them. Yet, they are easily avoided and aren't that many (those above are most of them). If you rage quit every toolset that has problems, I have some really bad news for you.
Thank you. You demonstrate very well what the problem is with the Haskell community, and that in a topic about Haskell adoption.
For a language to be adopted it must be beginner friendly. And by beginner friendly, I don't mean easy. It can have a steep learning curve as long as it enables the user to be productive, otherwise the beginner will give up quickly.
For the experienced user things like, "don't use lazy IO", "there are partial functions on the Prelude", "String is slow", and "code may throw exceptions where you don't expect", may be obvious, but are not for the beginner. I don't remember exactly how I ended up using "lazy IO", but trust me it wasn't because I ignored a big fat warning that I should NOT be using it.
It's gotchas like these that prevent the beginner from being productive.
Then the beginner reaches out to the community sharing his experience and gets a defensive and passive aggressive reply like yours. It's enough to make them not want to touch that language ever again.
You think you are defending your favorite language, but actually you are doing more harm.
Honestly, I'm not much concerned with beginner friendliness. As long as there are enough users to maintain and improve its ecosystem, it will stay a good language. The moto of "avoid success at all costs" was correct, and if beginner friendliness comes at the expense of expert usefulness, I'll be glad the second is chosen.
That said, none of that applies to those gotchas. They are clear problems with the language. None of them are obvious, but all of them are widely discussed so you will see them early when learning the language. Learning the gotchas of an ecosystem is a central part of learning any tool on informatics, and as gotchas go, one of the strong points of Haskell is that there are very little of them.
You are making a very common complaint, that comes from ignoring the problems of the tools you know while making a fuzz over anything you find on the new one. It's almost certain that whatever languages you are used to, they have a much larger pile of gotchas than Haskell (because Haskell has an atypical small number of them), but that doesn't stop them from being useful.
> You are making a very common complaint, that comes from ignoring the problems of the tools you know while making a fuzz over anything you find on the new one. It's almost certain that whatever languages you are used to, they have a much larger pile of gotchas than Haskell (because Haskell has an atypical small number of them), but that doesn't stop them from being useful.
"Yeah well your language isn't good either" isn't a very good argument for why a language is _better_. If the idea is "Haskell works better than other languages as long as you happen to know how to make it so", isn't that just every language that exists? Due to Haskell's branding, I was under the impression that the issues the above user is describing should be impossible. If Haskell doesn't even make good on those guarantees, but instead shifts that guarantee as "Things you should've known not to do" onto the user, how is that different from any other language?
edit And since this thread has a lot of tension and vague hostility, I will add, I am not attacking you or the language you enjoy. I legitimately would like to better understand.
Hum... I do think "Haskell has an unusually low amount of gotchas" isn't a subjective argument that applies to any language. Also, no, yours "Haskell works better than other languages as long as you happen to know how to make it so" can't apply to every language, by construction you can only put one language on it¹, unless you assume that Haskell is the only language the developer knows well, what would make for a really lame argument.
But "you won't be able to use it well if you don't learn how to use it" does indeed apply to all languages. Yet, it's more relevant for some, and Haskell is one of those more affected by it.
It is a fact that Haskell is not beginner friendly. Your first program on it will suck, whatever proficiency you have with other languages (there are some people that argue that it is easier if you know less beforehand). It takes some learning before you are able to get the better safety, high productivity and easy collaboration people talk so much about (and even then, you won't get those for every problem, the language has limitations too).
1 - The statement is false anyway. There's no such language one can single out there without more context.
Code written in Haskell is only safe if the authors of such code take advantage of the features that the language provides to write safe code. Haskell makes it ergonomic to write safe code, not mandatory. It turns out that the authors of Haskell's Prelude 30 years ago didn't get things quite right. We're still dealing with that today and it takes time and effort to fix things.
It's not a binary classification of "Haskell safe, everything else unsafe". It's a gradation. Haskell provides more such features and more ergonomically (goes the claim, and it's one I happen to agree with).
Another point is that beginner-friendly languages don't always make expert-friendly languages. Python is great for beginners, but I have seen its lack of types create heaps of brittle code at companies that no one wants to touch.
Some of the "C++ contenders" (besides Rust) like Nim, Zig, and potentially Swift seem to balance this line well: simple to start using, but grow with one's expertise.
I wrote quite a bit of Haskell several years ago and sadly I have to agree! I understand why all the cruft is kept around - for one backwards compatability. But they really need a clean break to remove all the cruft and simplify things. There shouldn't be so many ways to do things (especially if some of those ways are just flat out wrong).
So you went from hearing some promises to discovering gotchas in complex, decades old technology, decided to stop and then school the haskell community on topics they are very well aware of.
How very modest of you, if only they could listen.
haskell is a language for experts. quite frankly, it does not need runaway success to be successful. it can remain a top 20 or whatever language popularity-wise and remain best-in-class for experts.
once you are the expert, you would waste your time to use other programming languages.
also - the post you are replying to isn't condescending. the haskell community just doesn't treat beginners like infants who need coddling. haskellers tend to give the nuanced & truthful answer to questions.
Expert in what? Programming? Lambda calculus? Category theory? Let’s not pretend that you are simply an expert in something randomly, it takes a lot of practice, mistakes, and actually being a beginner before being an expert. Even if you are an expert in the above you still are a beginner when learning Haskell the first time, and you will make mistakes, so having beginner friendly resources is important.
Quite frankly, it’s this kind of gatekeeping attitude - that Haskell is meant for “us” and to become one of us, you have to be an expert, and we aren’t going to coddle you - is a kind of attitude that significantly contributes to the lack of good and welcoming beginner resources and causes very few people to actually pick up and stick with the language. You can be a “language for experts” and still have good, beginner friendly learning resources to welcome more into some community.
It's a language for experts in Haskell. It isn't optimized for the beginner, and all the proposed fixes to issues don't work due to that. We can't just remove lazy IO or partial head without significant impacts, so we coexist with them - tutorials and all.
There are plenty of beginner-friendly resources already (more & more every year), but they can't erase worse ones from the Internet. The Haskell community lacks the sort of strong-fisted leadership to accomplish that by design.
That said, acting like a tutorial mentioning lazy IO or partial head/tail is a killer is a little ridiculous. Neither of those things are atrociously problematic, so learning about them early is fine. You may get cut due to them, but getting cut is okay if you don't flip the table.
Also I (and most of Haskell posters) do not gatekeep. The community will go well out of its way to respond to any questions beginners have with blog-post-quality comments in the various forums (mailing list, reddit, irc, slack, github issues, etc) There is definitely a teaching culture, which is the opposite of gatekeeping.
Well kind of yes and no. As far as GHC is concerned, `Prelude` is just a module like any other, within `base`, a package like any other.
We could special-case it, but on the other hand, there are already multiple other solutions in this space that are more generally useful. Alternate Preludes (and compiler support of -XNoImplicitPrelude) `hlint` can also be customized to do exactly what you're asking for as well.
That's going to make it very hard for me to run a business, which involves sourcing, hiring, and training a potentially large number of people. Hiring only experts is a tremendous business cost.
That's potentially true, and also fine. Success for a programming language doesn't mean it has to be a good language for a corporation's interests.
Haskell is first and foremost a gigantic personal productivity booster. It allows me to do bigger and more complex projects on my own or with one or two others. These projects are not for corporate interests although that can be for personal profit. I am pretty confident I will be able to stop giving my labor to any corporation within the 10 year mark of my career, and Haskell will be a big reason why.
But I still try to convince corporations to use Haskell since then we offload the cost of learning onto a corporation instead of an individual. That feels like a worthwhile re-allocation of capital to me! Corporate Haskellers get paid to gain expertise and keep it forever, leaving corporation with nothing besides their direct labor. Luckily it's easy to convince a corporation of anything with what amounts to propaganda & politics.
> If you rage quit every toolset that has problems, I have some really bad news for you.
As someone who has tried to learn Haskell twice and failed (and trust me I went way beyond the second page of a tutorial ;-), I don't think the issue is that Haskell has problems. As you hinted every language has problems. The issue is that for a lot of people Haskell requires significantly more effort to learn than other languages and doesn't have a lot publicly available software to show off for. So when we learn Haskell and stumble on problems, we are less forgiving than with other languages because we have spent more effort and we don't have enough examples of useful software made with Haskell to reassure us that our efforts will eventually pay off.
We loose confidence because it seems that the promises of correctness aren't fulfilled and we don't have enough evidence that we aren't wasting our time. We would need at least to see the light at the end of the tunnel to keep us motivated. The sad thing is that if we decided to spend long hours of our free time learning this language instead of doing other things it's because we really believe in ideas behind it. What we have read about the language obviously speak to us but at some point we loose motivation because we don't get any tangible results.
I'm pretty sure that a good part of why it clicks for some people and not others is due to the amount of mathematical literacy. I don't have a strong mathematical background so the amount of effort for me to learn the language is probably much higher than it is for someone better at math. I have to invest more so I expect more in return, which in my personal experience Haskell fails to deliver. To appeal to a wider audience Haskell needs to be pretty much flawless and also to have more public software to showcase.
> We loose confidence because it seems that the promises of correctness aren't fulfilled and we don't have enough evidence that we aren't wasting our time. We would need at least to see the light at the end of the tunnel to keep us motivated.
Sometimes you go into the tunnels that are not tunnels but rather mines, and you go there not to see the light at the end of it, but rather to dig diamonds.
Sorry you had a bad experience. Hopefully the Haskell Foundation will be able to put resources into the beginner experience and you will find it easier in the future.
And actually all of those things are problems with the default prelude and not the language core. There are alternative preludes that one can use, and hopefully these warts will be fixed in the future. It takes time because it's a breaking change though.
Thanks. I meant a recommendable tutorial for Haskell newbies that starts from scratch with modern/sane defaults. I’ve seen webdev examples with quite offputting boilerplate that I’m told could be dealt with by a prelude and I wonder if it’s a problem that people are trying to solve.
> And actually all of those things are problems with the default prelude and not the language core.
This directly means "a problem with the lanuage" to any beginner with the language. Since it's the default Prelude. So a beginner has to somehow learn that there are issues with Prelude, that there are other preludes, find the differences between them, select one, and then reconcile the inevitable differences between those preludes and the official one when reding various docs.
...
And then figure out wich of the two dozen language extensions you need to use to even write something useful beyond a "Hello, world".
We didn't throw away C++ back when the STL was no good. Why should the situation with Haskell be different? (And Prelude's problems are way less severe than the problems the STL used to have.)
Um. No, you can't. I don't know what you are talking about. What you are describing is not and cannot be how lazy IO works. Lazy IO is always on the read side.
Lazy IO, like the partial functions in Prelude, is a convenience hack for making some very low-complexity things easy. I don't have a problem with it existing, because I am fine with matching my tool complexity with the problem complexity.
And also, I understand what it does. I'm surprised I'm the first person to point out that your assertion is not an accurate description of anything that actually happens.
> I rage quit Haskell when I saw all the promises for application correctness fall like a house of cards by realizing I can write to a file after it has been closed when using lazyIO.
The promises aren't “using Haskell magically causes correctness”, but “Haskell provides powerful tools that most other languages don't that enable correctness”.
But, you know, the people that need to telegraph “rage quitting” a language are usually the people chasing an unreasonable silver bullet and misinterpreting things through that lens to start with.
The complaint is that with lazyIO, even if your code does the write before closing the file, the actual order the operations occur in could change, to put the close first.
If you look at the lazyIO documentation, you will see:
>Although this module calls unsafeInterleaveIO for you, it cannot take the responsibility from you. Using this module is still as unsafe as calling unsafeInterleaveIO manually. Thus we recommend to wrap the lazy I/O monad into a custom newtype with a restricted set of operations which is considered safe for interleaving I/O actions.
> The lazyio package is not what people are talking about when they say "lazy IO".
I don't know which people you are talking about, but it clearly was in this specific subthread which started with a complaint about “LazyIO”, not “lazy IO”, and where the only use of “lazy IO” in a post before yours was in a post where all previous references were to “lazyIO” and it's specific package documentation, and contextually the “lazy IO” references was about the same thing, not something else.
You can write bad code in any language if you try hard enough. No one should use lazyio (or any library) for important work without checking the code or at least the docs to see if the code is intentionally bad (and renaming "unsafeInterleaveIO" to "lazyIO.InterleaveIO" is intentionally bad).
One of Haskell's known weaknesses is that there are no curated catalogs of high quality libraries. The industrial strength stuff sits on package servers alongside the broken toys.
I once got an apology from a major luminary in Haskell, author of dozens of high quality packages, because I used a package he wrote that turned out to be an abandoned broken experiment, but not documented as such.
Well, that's not really covered by correctness guarantees and nor could it — what happens does not lead to undefined behavior and memory corruption but “external correctness” related to writing to files depends on what the outside world does with the file to begin with.
There are other strange things in the IO monad, such as the ability to observe evaluation orders by throwing exceptions.
Fair enough [edit: distinction to make], but the problem is still the existence of exceptions (at least as something that doesn't always terminate the process, but that's implied by most useful definitions of "exception" anyway), not anything that would be true of a hypothetical alternate version of Haskell that still had IO, but didn't have exceptions.