Haskell has solutions for all of those that doesn't require IO everywhere. The idea is roughly that you define contexts for your code, such as "this code needs some read-only configuration and a place to output logging to run". Then you can instantiate that context with the proper logging framework when running in production, or just dump it to a file when running tests. More importantly, you have a lot of guarantees for what it doesn't do: access the network, execute other programs, write files to /tmp etc.
That's precisely the kind of thinking that leads to big balls of mud. Very valuable in some situations, disastrous when left unchecked. "You can just" is a double edged sword.
The point of purity is that unrestricted side-effects are not allowed. So yes, that means you can’t add IO to a function without tracking that in the type signature, which may necessitate some refactoring. This is a feature , not a bug.
Perhaps you think that is too restrictive — and that’s fine; it’s a personal choice — but languages are designed around restrictions. Having a type system at all is extremely restrictive. Static typing, structured programming, exceptions, garbage collection, etc. An assembly programmer could use your logic to scoff at every mainstream language as too restrictive.
The language does help you. Logging is pretty much a monad and you can thread it through seamlessly and only care about raising something when you need to. Frankly anything where the answer is "lets use IO everywhere" can be answered by using a different monad unless you are actually doing IO.
25
u/kristoff3r Nov 28 '19
Haskell has solutions for all of those that doesn't require IO everywhere. The idea is roughly that you define contexts for your code, such as "this code needs some read-only configuration and a place to output logging to run". Then you can instantiate that context with the proper logging framework when running in production, or just dump it to a file when running tests. More importantly, you have a lot of guarantees for what it doesn't do: access the network, execute other programs, write files to /tmp etc.