I’m starting to think that maybe monads are only a useful concept in languages without union types, or languages without type-checking - and the reason why I can’t understand their value is because I don’t use the type of language that would benefit from them
I’ve heard a few different arguments for why monads are helpful but they all either don’t make sense to me (their explanation for why monads are better expects me to make an inference that I can’t) or they only make sense in a language with limitations that most popular scripting languages don’t have (for example, a language where any primitive can be null and you have to manually check all the time)
@kasdeya i felt this way after implementing a Maybe in typescript
i made it a class, then realized that it's way more ergonomic to just have the maybe functions like flatMap and unwrapOr etc operate on T | none
monads do make a lot of sense in Rust though because it lets you have “exceptions” at a very low runtime cost
with that said, Rust can go fuck itself
caller: hello function please give me a number, or let me know if you don’t have a number to give me
function: hi, caller! here - take this spoooky quantum box! it may or may not contain a number. no one knows!
c: q-quantum… box?
f: that’s right! it simultaneously contains a value and doesn’t contain a value! if you try to open it there’s a 50% chance that you’ll destroy the universe!
c: I asked for a number, function. how am I supposed to do anything with this?
f: well, you can dispatch a quantum trans-box interaction method which may or may not perform an action on the number that may or may not exist!
c: listen, can you at least tell me for sure if this box has a number in it?
f: nope! that’s the whole point! instead you can just dispatch a multiversal datastream mutator which may or may not hypothetically interact with the number’s superposition!
c: can I just have a little peek into the box and look at the number?
f: you can dispatch a quantum observer which will hypothetically look at the number which may or may not exist! and then it can perform an action while simultaneously not performing an action on the semi-existent number!
c: can I… touch the number?
f: you can split the timeline in two, where one of you handles the nonexistence of the number and the other timeline handles the existence of the number by touching it! and then one of those timelines can handle the action of-
c: okay you know what function? *tears open the box out of pure spite*
*a black hole consumes the universe*
@kasdeya
The interesting thing about monads is that they allow us to (re)define the semicolon
Defining the semicolon is a useful thought exercise because our intuition for what it means is based on a model of computation from half a century ago that hasn't been true for decades — multiple things in the stack feel free to reorder execution, so it's good to think through what we actually mean when we write a sequence of statements in a program
Redefining the semicolon is useful when prototyping new language features
@kasdeya yeah, you're right. Any abstraction is only worth it if you're trying to *be* abstract. If you want to work with more than one concrete type of data in a uniform way, you use some kind of common abstraction that the data types you're interested in share. (doesn't have to be static typing; just mean the colloquial sense of "things i think of differently than other things".)
if you don't have that problem -- true surprisingly often! -- you don't need that abstraction.
@kasdeya Even among monad-knowers, I try to point out that the thing they're talking about isn't a monad, it's just a data type that happens to also implement a common interface. Monad-knowers (which includes me) often get too tangled up on the abstractions. It's healthy to stick to your concrete data until the need for an abstraction actually makes itself known.
@kasdeya yes! also as a secondary benefit by having a "standard" way to represent that, they both encourage folks to use the standard way, and also make it easier to add nice language features built around that standard representation (like the propagation operator)
@kasdeya suddenly, in another timeline, an empty box has been opened