14 ms·
I rage quit Haskell when I saw all the promises for application correctness fall like a house of cards by realizing I can write to a file after it has been clos
by noncoml 6y ago
I rage quit Haskell when I saw all the promises for application correctness fall like a house of cards by realizing I can write to a file after it has been closed when using lazyIO.
- dpc_pw 6y agoI'm not a Haskeler, but didn't they add affine/linear types recently that could help?
- gizmo686 6y agoLinear types don't help here. The complaint is that with lazyIO, even if your code does the write before closing the file, the actual order the operations occur in could change, to put the close first. If you look at the lazyIO documentation, you will see: >Although this module calls unsafeInterleaveIO for you, it cannot take the responsibility from you. Using this module is still as unsafe as calling unsafeInterleaveIO manually. Thus we recommend to wrap the lazy I/O monad into a custom newtype with a restricted set of operations which is considered safe for interleaving I/O actions. https://hackage.haskell.org/package/lazyio-0.1.0.4/docs/System-IO-Lazy.html https://hackage.haskell.org/package/lazyio-0.1.0.4/docs/Syst... TLDR, don't use lazy IO.
- taktoa 6y agoThe lazyio package is not what people are talking about when they say "lazy IO".
- dragonwriter 6y ago> The lazyio package is not what people are talking about when they say "lazy IO". I don't know which people you are talking about, but it clearly was in this specific subthread which started with a complaint about “LazyIO”, not “lazy IO”, and where the only use of “lazy IO” in a post before yours was in a post where all previous references were to “lazyIO” and it's specific package documentation, and contextually the “lazy IO” references was about the same thing, not something else.
- alisonkisk 6y agoYou can write bad code in any language if you try hard enough. No one should use lazyio (or any library) for important work without checking the code or at least the docs to see if the code is intentionally bad (and renaming "unsafeInterleaveIO" to "lazyIO.InterleaveIO" is intentionally bad). One of Haskell's known weaknesses is that there are no curated catalogs of high quality libraries. The industrial strength stuff sits on package servers alongside the broken toys. I once got an apology from a major luminary in Haskell, author of dozens of high quality packages, because I used a package he wrote that turned out to be an abandoned broken experiment, but not documented as such.
- marcosdumay 6y agoSo, was that on the second page of a tutorial? Yes, Haskell has those gotchas like "don't use lazy IO", "there are partial functions on the Prelude", "String is slow", and "code may throw exceptions where you don't expect". They are there mostly because of history and the language would be better without them. Yet, they are easily avoided and aren't that many (those above are most of them). If you rage quit every toolset that has problems, I have some really bad news for you.
- ulrikrasmussen 6y agoAnd actually all of those things are problems with the default prelude and not the language core. There are alternative preludes that one can use, and hopefully these warts will be fixed in the future. It takes time because it's a breaking change though.
- tmountain 6y agoHere's a nice summary of some of the more popular preludes. https://guide.aelve.com/haskell/alternative-preludes-zr69k1hc https://guide.aelve.com/haskell/alternative-preludes-zr69k1h...
- asplake 6y agoAre there from-scratch tutorials based on any of these?
- tmountain 6y agoThis is a good primer. https://www.stephendiehl.com/posts/protolude.html https://www.stephendiehl.com/posts/protolude.html
- asplake 6y agoThanks. I meant a recommendable tutorial for Haskell newbies that starts from scratch with modern/sane defaults. I’ve seen webdev examples with quite offputting boilerplate that I’m told could be dealt with by a prelude and I wonder if it’s a problem that people are trying to solve.
- Blikkentrekker 6y agoWell, that's not really covered by correctness guarantees and nor could it — what happens does not lead to undefined behavior and memory corruption but “external correctness” related to writing to files depends on what the outside world does with the file to begin with. There are other strange things in the IO monad, such as the ability to observe evaluation orders by throwing exceptions.
- a1369209993 6y ago> There are other strange things in the IO monad, such as the ability to observe evaluation orders by throwing exceptions. That's not specific to IO; you can more or less always observe evaluation order by throwing exceptions: bar = error "bar" baz = error "baz" foo = (bar,baz) :: (Int,Int) main = print foo -- well, I guess you need IO to run anything at all `bar` is evaluated first (at least on my machine), as evidenced by: $ ./test test: bar CallStack (from HasCallStack): error, called at test.hs:1:7 in main:Main
- gizmo686 6y ago> I guess you need IO to run anything at all Its a bit more that that. You need to be in IO in order to catch an exception. That is to say, if you have: bam :: (Int, Int) -> String There is no way to write: bam (x,y) = "bar" if x is called first "baz" if y is called first. However, if you were to instead have: bam :: (Int,Int) -> IO String Such a function is possible to write, as you can now catch the exception and do something with it.
- a1369209993 6y agoFair enough [edit: distinction to make], but the problem is still the existence of exceptions (at least as something that doesn't always terminate the process, but that's implied by most useful definitions of "exception" anyway), not anything that would be true of a hypothetical alternate version of Haskell that still had IO, but didn't have exceptions.
- Blikkentrekker 6y ago
- chowells 6y agoUm. No, you can't. I don't know what you are talking about. What you are describing is not and cannot be how lazy IO works. Lazy IO is always on the read side. Lazy IO, like the partial functions in Prelude, is a convenience hack for making some very low-complexity things easy. I don't have a problem with it existing, because I am fine with matching my tool complexity with the problem complexity. And also, I understand what it does. I'm surprised I'm the first person to point out that your assertion is not an accurate description of anything that actually happens.
- dragonwriter 6y ago> I rage quit Haskell when I saw all the promises for application correctness fall like a house of cards by realizing I can write to a file after it has been closed when using lazyIO. The promises aren't “using Haskell magically causes correctness”, but “Haskell provides powerful tools that most other languages don't that enable correctness”. But, you know, the people that need to telegraph “rage quitting” a language are usually the people chasing an unreasonable silver bullet and misinterpreting things through that lens to start with.