|
|
|
|
|
by bunderbunder
4608 days ago
|
|
> You can look at cyclomatic complexity and reusability (both wins for pure functions). Yes, those are both wins for pure functions. But even there you need an asterisk, because side effects do have their place - the fact of the matter is, the primary task of most real-world software can be summed up as "manipulating mutable state". In light of that I don't think you can necessarily jump from the observation that there are many situations where pure functions are easier to work with than impure ones to the conclusion that pure functions are inherently more maintainable. But even if that were granted for the sake of argument, it's not much of a win for Haskell. The ability to create pure functions is a feature of every language that has been invented during the lifetime of probably every person reading this post, and therefore not really a differentiating feature of Haskell. Nor is lack of ability to create impure functions a feature that can be claimed of Haskell, because that simply isn't true. Haskell's real differentiator in that department is just that you've got to jump through hoops to do it. And if your business rules are inherently impure, then it's not clear to me how a language that tries to ghettoize impurity makes them easier to implement. |
|
What you can't do in Haskell is write impure code that claims to be pure (up to the customarily and idiomatically avoided `unsafePerformIO`), or write code whose degree of statefulness is ambiguous. Reliable, explicit, and statically enforced purity holds more than just theoretical benefits. I don't have to read through library code to see if it is thread-safe. I don't have to worry about whether passing a data structure to a library function will result in that structure being mutated behind my back. I don't have to trust code comments that may not be in sync with the current state of the code. Simply by virtue of the fact that a function does not mention `IO` in its type, I can have total confidence that it won't violate my assumptions about its behavior. And I don't even have to take it on faith that the author wrote the correct type for his code; if he hadn't, the compiler would have rejected it. This is the difference between "pure by convention" and "provably pure".
Every language must necessarily have an "IO monad" and interact with the inherently stateful world, or else it is useless. Haskell is different not because you can choose to avoid I/O, but because when you do so, the type system will back you up with perfect accuracy.