
Bulat Ziganshin wrote:
apfelmus wrote:
avoid the small layer of imperative code, of course. But the more you treat imperative code as somewhat pure, the greater the danger that the purely functional logic will be buried inside a mess of imperative code. In other words, the goal is exactly to make IO and STM uncommon, otherwise you loose the power the purely functional approach offers.
it's point of view of theoretical purist. i consider Haskell as language for real world apps and need to write imperative code appears independently of our wishes. in paricular, it's required to write very efficient code, to interact with existing imperative APIs, to make programs which has explicit memory control (as opposite to lazy evaluation with GC)
No and yes. As I said, it is of course desirable to be able to describe genuinely imperative behavior elegantly in Haskell, like explicit memory control or concurrently accessing a bank account. However, most "genuinely imperative" things are often just a building block for a higher level functional model. The ByteString library is a good example: the interface is purely functional, the internals are explicit memory control. It's a bad idea to let the internal memory control leak out and pollute an otherwise purely functional program with IO-types. Also, many "genuinely concurrent" things just aren't. An example are UNIX pipes like say cat Main.hs | grep "Warm, fuzzy thing" The OS creates a processes for "cat" and "grep" running concurrently and "cat" passes a stream of characters to "grep". By blocking on the reader and the write side, "grep" reads what "cat" writes in real-time. Well, but that's just good old lazy evaluation! Regards, apfelmus