3 ms·
>So why hasn't it happened? Off the top of my head, memory safety challenges for junior Haskellers (laziness footguns), State monad being fundamentally flawed:
by thdhhghgbhy 2y ago
>So why hasn't it happened?
Off the top of my head, memory safety challenges for junior Haskellers (laziness footguns), State monad being fundamentally flawed: there is an inability to get at and log your application state just before a crash, bloated tooling, GHC frequently breaking existing code. Laziness and monadic code makes debugging painfully difficult.
I like Haskell for Advent of Code only.
- AnimalMuppet 2y ago> State monad being fundamentally flawed Could you explain a bit about what you mean here? In what way is it fundamentally flawed? I'm not saying you're wrong; I just want to understand.
- thdhhghgbhy 2y agoBasically StateT uses Either to model either the application state or an error. So if your application throws, you lose the current state forever. They sort of painted themselves into a corner with this choice of type, there's no real way out now. This explains in more detail: https://github.com/haskell-effectful/effectful/blob/master/transformers.md https://github.com/haskell-effectful/effectful/blob/master/t... I agree loosely with what haskman above says about creating relatively bug free applications, the guard rails are so robust. But those same guard rails mean you can paint yourself into a corner that it is harder to get out of without imperative state, case in point above.
- tome 2y agoI acknowledge that those things can be challenging, however I'd like to respond to some of the specific issues: - Space leaks due to laziness are a solved problem. I explain the technique to solve it at: https://h2.jaguarpaw.co.uk/posts/make-invalid-laziness-unrepresentable/ https://h2.jaguarpaw.co.uk/posts/make-invalid-laziness-unrep... This technique has not completely percolated throughout the community, but I am confident that it does actually resolve the "laziness causes space leaks issue" - Flawed state monad: well, you point out the analysis of its flaws from the effectful documentation. That's correct. The solution is: just use effectful (or another similar effect system. I recommend my own: Bluefin) - GHC breakage: I've been keeping an inventory of breakage caused by new GHC versions, since GHC 9.8: https://github.com/tomjaguarpaw/tilapia/ https://github.com/tomjaguarpaw/tilapia/ There has been very little! The Haskell Foundation Stability Working Group has had a massive effect in removing breakage from the ecosystem. - Laziness and monadic code makes debugging painfully difficult: I mean, sort of, but if you're using monadic code in the style of a decent effect system like effectful or Bluefin this is a non-problem. It's hardly different from programming in, say, Python from the point of view of introducing debugging printfs or logging statements.
- thdhhghgbhy 2y agoThanks, I've followed along with a lot of your posting on the Haskell discourse. One thing regarding this matter: >well, you point out the analysis of its flaws from the effectful documentation. That's correct. Thinking deeper about this, that there is essentially no way to fix this issue with StateT, because of the type choice, the monad, the composability requirement, all conspiring together to not be undone, does that signal something deeper that is wrong with the flexibility of Haskell, that we can progressively paint ourselves into a corner like this. Could it not happen again, but with another late breaking requirement, for effectful, or bluefin?
- tome 2y ago> I've followed along with a lot of your posting on the Haskell discourse Ah, that's great to know, thanks. It's rarely clear to me whether people read or are interested in what I say! Well, yes, in principle even a design that is perfect according to some spec could be completely wrong if the spec needs to change. and impossible to tweak to match the new spec. This is true of any language or any system. This raises a few important questions: 1. How easy does a language make it to "unpaint" yourself from a corner? In Haskell it's easier than in any other language I've experienced, due to its legendary refactoring experience. For example, if you "incorrectly" used the State monad and got stuck, you can wrap it up in an abstract type, change all the use sites, check that it still compiles and passes the tests, then change the definition to use new "uncornered" implementation, again check it compiles and passes the tests, then unwrap the abstract type (if you like, this stage is probably less important), then add the new feature supported by the new implementation. 2. How likely is it to paint yourself into a corner in the first place? In Haskell, again, less likely than any other language I've experienced, because the constructs are so general. There is far more opportunity to tweak a design when you have general constructs to work with. (That said, I've met many Haskell behemoths that couldn't be easily tweaked so, particularly contorted type class hierarchies. I recommend not designing those.) 3. Why won't effectful or Bluefin lead to "corners"? Because they're just Haskell's IO, wrapped up in a type system that gives fine-grained control over effect tracking. Anything you can do in Bluefin and effectful you can do in IO, and vice versa. So to really paint yourself into a corner with IO-based effect systems it would have to be something that you can't do in IO either, and at that point we're talking about something that can't be done in Haskell at all. So there's no real downside to using IO-based effect systems in that regard.