Functional programming is all about controlling side-effects in your program.
According to Wikipedia:
[…] a function or expression is said to have a side-effect if it modifies some state outside its scope or has an observable interaction with its calling functions or the outside world besides returning a value. For example, a particular function might modify a global variable or static variable, modify one of its arguments, raise an exception, write data to a display or file, read data, or call other side-effecting functions.
Haskell is particularly explicit about these side-effects.
Here are a few examples of functions from the Haskell standard library:
-- Write a string to the standard output device
putStrLn :: String -> IO ()
-- Read a file and returns the contents of the file
readFile :: FilePath -> IO String
Both of these functions are returning a special type; the IO monad
. It represents the result of a computation involving I/O (writing to the console or reading a file on disk).
A particularity of Haskell is that it even consider your program as an IO monad
.
The following example is a simple hello world:
main :: IO ()
main = do
putStrLn "Hello, World!"
You can see that in the type definition the main function returns an IO monad
of any type (unit here).
Now imagine that you want to create a program that doesn't invoke any side-effect functions. From the Haskell point of view this program would do absolutely nothing, you even cannot express it since the main needs an IO monad
.
Is it possible a write a side-effect free program in Haskell?
The answer is no. A program is by definition (in Haskell at least) a side-effect.