In this example, you've had to internalize a bit of extra knowledge, and have an extra "gotcha" to watch out for. A job that could have been done by a computer, if things were kept pure, now has to be done by you, incurring slight amounts of mental overhead.
I don't program routinely in Haskell (although things are quickly headed in that direction), but I think the sentiment of that community is: 1. Keeping a large system consistent in your head is hard 2. Offloading the constant checking of that consistency, in any amount, to a computer, is a huge win that compounds quickly over time.
Note that the "hardness" of holding a large system in your head, and the "hardness" of Haskell's learning curve have to be qualitatively different for those assumptions to hold. In my experience, they are; essentially, you're making a large upfront cognitive investment in order to save slight amounts of mental overhead every day.
> Offloading the constant checking of that consistency, in any amount, to a computer, is a huge win that compounds quickly over time.
True. And therefore offloading a less amount to the computer (by being mostly but not totally functional) is less of a win, but still a win.
It's very likely that, in reality, you would forget the exception could be thrown until it happened in production.
So the advantages of the Haskell type system and purity guarantees, I think, often come down to the compiler preventing you from making certain errors that don't surface in other languages until you run the program. (Disclaimer: not a Haskell programmer.)
Example time: I program python, not C++. And in the example with the try-catch I would have wrapped it around the loop anyway. So for me it wasn't quite convincing that there is a problem in the first place. Sure someone who hasn't crashed a few programs due to lazy evaluaton might run into trouble in such kind of situation. But after a few times you understand that being defined and being executed are different things and then you wrap the execution. As far as I can see the whole problem described with the example doesn't exist if you intuitively wrap the foreach loop and not the definition statement for q.
So, would really appreciate if someone could explain it in a more nooby fashion to me. Thanks.