Direct-Style Effects Explained
inner-product.com
inner-product.com
The article states that side effects prevent us from achieving "reasoning" and "composition".
Wat?
Side effects are so scary and unapproachable that this crazy labyrinth of monads, purity rules, immutability, and the next big thing of direct-style effects is actually better?
Just do some reasoning about the side effects.
Using such techniques requires an upfront investment of learning how this works, but once that mountain is climbed, programming becomes easier, faster and less error prone in many cases.
The article suggests that this is coming to Scala, and I'm looking forward to being a guinea pig.
This seems to me a bit like complaining that defining C functions and for-loops are so much more verbose than just using JMP instructions in assembly language, so why go to all the trouble of bothering with functions?
The point is that effects and effect handlers are a new form of structured programming, but for effects instead of values. New structure seems heavyweight for trivial things, but ultimately scales and composes better for realistic programs.
Are you sure? It's not just a JMP; for a loop you need a compare and increment/decrement instruction at the very least, and calling a function is way more complex than a JMP: you have to place the function arguments in the right registers and/or on the right place on the stack, you need to save registers that might get clobbered, and you need to push a return address before you jump. So in C these things are definitely more compact to write.
I did get the point about effects introducing a new form of structure and composability, and I'd really like to see that. But at the moment it looks like it is as much work as actually implementing a function call in assembler, the only benefit is that the compiler will check the correctness for you.
Yes, we use complex tools to avoid writing complex, unpredictable and buggy code.
"Look, let me demonstrate that this piece of code is clearly VERY bad:
DoA(); DoB(); DoC();
Such horrors! What if DoB() does some invisible non-composible side effects of launching full nuclear arsenal of unites states? We clearly need some borrow checking, type checking, monads, continuations and a blessing of a pope to rewrite this horrible, horrible mess!!!!!!!!"
And then they proceed with a code example that is just a convoluted mess of "what the fuck" and finish with: "look how beautiful and safe and practical this is! industry is stoopid for not using these awesome features!"
Disclaimer: I tinker with my own PL with algebraic effects and I do think they are useful.
The pure typed religion and huge weight of theory that goes with it is one reason why I find it so sad that Rust has seemingly won out over Zig.
"Wat?"
Have you ever inherited a 1MLoC codebase that you yourself didn't write from scratch, or worked on a large project with at least one other person? How do you know what the side-effects are and where they happen when you aren't intimately familiar with the code you're interacting with? That's the whole point of making effects explicit and available for analysis in the type system.
Side effects are what you care about in a program. The simplest 8-bit CPU has side effects with every single instruction. It's baked into the bedrock, I don't think you can paper it over. Trying to shoehorn the complexity into nothing but function parameters and return values doesn't make the complexity go away, it just necessitates all these other weird contortions that add the complexity back twice over again.
Eventually the entire FP community is going to be engulfed by the event horizon of the zero side effect singularity and disappear completely.
This will be intentional.
Sure it's a scala-focused article but come on -- Haskell is far more ergonomic, and honestly easier on the eyes than Scala.