Just because a functional language is functional (perhaps even completely clean like Haskell!) Doesn’t mean that programs written in that language should be clean at startup.
The Haskell approach, for example, when dealing with side effects, can be explained quite simply: let the whole program be clean by itself (this means that functions always return the same values for the same arguments and have no side effect), but let the return value of the main function be an action that can be triggered.
Trying to explain this with pseudo-code, here is some kind of program in an imperative , non-functional language:
main: read contents of abc.txt into mystring write contents of mystring to def.txt
The main procedure above is this: a series of steps that describe how to perform a series of actions.
Contrast this with a purely functional language such as Haskell. In functional languages, everything is an expression, including the main function. Thus, one can read the equivalent of the above program as follows:
main = the reading of abc.txt into mystring followed by the writing of mystring to def.txt
So, main is an expression that, when evaluated, returns an action that describes what to do to execute the program. The actual execution of this action takes place outside the world of programmers. And it really is how it works; The following is a real Haskell program that can be compiled and run:
main = readFile "abc.txt" >>= \ mystring -> writeFile "def.txt" mystring
a >>= b we can say that this means “action a , followed by the result a given to action b ” in this situation, and the result of the operator is the combined actions a and b. The above program, of course, is not idiomatic by Haskell; it can be rewritten as follows (removing the redundant variable):
main = readFile "abc.txt" >>= writeFile "def.txt"
... or using syntactic sugar and the notation:
main = do mystring <- readFile "abc.txt" writeFile "def.txt" mystring
All of the above programs are not only equivalent, but also identical for the compiler.
So files, databases and web servers can be written as purely functional programs: by streaming the action values through the program so that they are combined and, finally, end up in the main function. This gives the programmer tremendous control over the program, and therefore purely functional programming languages are so attractive in some situations.