Just to be clear... Are you saying "amen" to not running out of fossil fuels, or to the possibility of a large number of people dying from heat stress, or both?
As I understand it, one thing the tutorial didn't go into, which I think is an important subtlety, is that it's not enough to have an implementation of "bind" to have a monad interface. You also need an implementation of "return : a -> m a" (i.e. a way of making sources of 'a's when given an 'a'), AND a proof that these implementations together satisfy the monad laws (i.e. that they "play nicely" together).
Without all three components, you can have something that "looks like" a monad, in that it has definitions for "bind" and "return", but isn't actually one, because those particular definitions don't also satisfy the monad laws.
Per the very last section, I chose to elide those. That's mostly because few languages worry about "laws" anyhow, and the lawfulness is less consequential in a non-lazy language because even if you nominally screw up the lawfulness, the code will still reliably do whatever it does. While I suspect we could find a pretty solid plurality of HN readers to be at least somewhat appalled at the idea, I think the generally programming world is not generally worried about it.
Plus it's rather like giving out criteria for how the frosting on the cake will be judged when most of the contestants are submitting piles of slightly dampened raw flour with an egg cracked over it and being offended when you won't agree that's a "cake".
Ah yep - I missed that mention of "lawfulness" in the last section. I guess the minor gripe I have is that that really isn't anything to do with Haskell: it's that you only have a monadic interface when the laws are satisfied (and Haskell itself doesn't, and can't, enforce the laws: you have to check them / others using your interface have to trust that you've checked them.)
I don't quite follow why you're making a distinction for non-lazy languages?
If you want to actually use any generic monad combinators with your monad interface, and expect it to behave sensibly, then the laws had better be satisfied!
But yeah... Nice article, and I really liked your "Noun / Adjective" distinction.
My understanding, which may be incorrect, is that the major reason that lawfulness matters in Haskell is the laziness makes it so that unlawful monads won't just do "something that violates the laws", an abstract, mathematical consideration that maybe you care about, maybe you don't, but that the combination of the laziness and the aggressively optimizing compiler means that result will be very unpredictable, and slight and seemingly isomorphic source changes can result in unpredictable results.
In Python, if I write an iterator on something pretending to be a list, and when it sees strings it doesn't just return an uppercased string but actually modifies the contents of the list to be uppercased, that's stupid, but at least since it's a strict language that isn't interleaved with IO and all the other stuff flying around in Haskell it will be consistently stupid. It isn't going to blow up or behave differently if I accidentally flip an "a + b" into a "b + a" somewhere.
It's bad, but Haskell has a whole different level of bad if you screw with it and don't play within the sandbox.
There is a definite "I'm being more pragmatic here than the average Haskell programmer" effect going on here. I... how to put this... "won't blink" is too strong, but... if I need to violate a law, if I need to write something like the stupid iterator above, I am in fact willing to. I have the decency to feel bad about it, and there will be extensive and probably bitingly sarcastic comments attached to it, but I'll do it. (Generally only when I don't control one end of the source code, though. If I have full control I never do anything that stupid.) But in Haskell it's a particularly bad idea, mostly because of the laziness and its interaction with other things.
And, heh, in a world where the struggle to explain what monads even are to people, monad combinators aren't even on my horizon.
The events of October 7th were an atrocity. The illegal settlements and extrajudicial killing of Palestinians prior to October 7th was an atrocity. The launching of rockets into Israel were atrocities. Israeli citizens cheering and watching from deck chairs while white phosphorus was dropped onto Gaza was an atrocity. And this ongoing slaughter, starving of civilians, murder of people waiting for aid in designated humanitarian areas, targeting of doctors, journalists, aid workers, double tapping of hospitals, missile strikes on other sovereign states who are hosting negotiations... Those are atrocities. The whole history is riddled with atrocity on both sides.
The only way out of this, while retaining some shred of humanity is through diplomacy, upholding international law, and centring the role of civil society and the huge numbers on both sides who want a peaceful, just coexistence.
The whole thing is sickening. Also hard to see how this can possibly improve Israel's security in the long term.
reply