Why "reading from a file" is not pure function?

A pure function allways returns the same value given the same input. Otherwise it is based on side effects (like changing a file). If you read from a file the results might change without the parameters given to the function changing.

The relevant concept is 'referential transparency'. This means you can substitute a function call and a given set of parameters with the result the function would return. Reading from a file is therefore not referentially transparent!


If a function is pure, then it is always safe to perform common subexpression elimination i.e. you could replace the following pseudocode

do {
  x = readFile "file.txt"
  writeFile "file.txt" "Goodbye"
  return (x + readFile "file.txt")
}

with

do {
  x = readFile "file.txt"
  writeFile "file.txt" "Goodbye"
  return (x + x)
}

and you would get the same result. But plainly, because of the call to writeFile which appears between the two calls to readFile in the first example, this is not a safe transformation to make, and therefore the function is not pure.


In functional programming, a function is pure if

  1. The function always evaluates the same result value given the same argument value(s). The function result value cannot depend on any hidden information or state that may change while program execution proceeds or between different executions of the program, nor can it depend on any external input from I/O devices.
  2. Evaluation of the result does not cause any semantically observable side effect or output, such as mutation of mutable objects or output to I/O devices.

I/O can be modelled in a pure way if

  1. the sequence of operations on the relevant I/O devices is modeled explicitly as both an argument and a result, and
  2. I/O operations are taken to fail when the input sequence does not describe the operations actually taken since the program began execution.

That is, instead of actually reading from a file, you get the "file's content" as a parameter, and instead of actually writing to a file, you return the "file's output" as a value. This seems to be a thought exercise in most practical languages.