> Granted, that is noisier than the Python, despite being a direct translation.
My complaint isn't the noise. My complaint is: can you explain what withJump does? Like, not the intention of it, but what it actually does? This is a rhetorical question--I know what it does--but if you work through the exercise of explaining it as if to a beginner, I think you'll quickly see that this is isn't trivial.
> 1. You don't get weird semantics around mutating the loop variable, and it remaining in scope after loop exit
Is this an upside? It's certainly unintuitive, but I can't think of a case this has ever caused a problem for me in real code.
> 2. You can "break" through any number of nested loops, not just to the nearest enclosing loop (which is actually more useful when dealing with weird edge cases, not less)
Again, is this actually a problem? Any high school kid learning Python can figure out how to set a flag to exit a loop. It's not elegant or pretty, but does it actually cause any complexity? Is it actually hard to understand?
And lots of languages now have labeled breaks.
Arguably the Lua solution (gotos) is the cleaner solution here, but that's not popular. :)
> 3. You can see exactly what effects are possible in any part of the program (which again is actually more useful when dealing with weird edge cases, not less)
What does this even mean? In concrete terms, why do you think I can't see what effects are possible in Python, and what problems does that cause?
In all three of the cases that you mention, I can see a sort of aesthetic beauty to the Haskell solution, which I appreciate. But my clients don't look at my code, they look at the results of running my code.
> Regarding laziness and performance, that is a resolved issue. I have an article that explains that: http://h2.jaguarpaw.co.uk/posts/make-invalid-laziness-unrepr...
The fact that you need a blog post to tell people how to resolve an issue exemplifies my point that this is not resolved. Nobody needs to be told how to turn off laziness in Python, because it's not turned on.
The fact is, Haskell does the wrong thing by default here, and even if you write your code to evaluate eagerly, you're going to end up interfacing with libraries where someone didn't do that. Laziness still gets advertised up front as being one of the awesome things about Haskell, and while experience Haskell developers are usually disillusioned with laziness, many Haskell developers well into the intermediate level still write lazy code because they were told early on that it's great, and haven't yet experienced enough pain with it to see the problems.