Is it a pure function if it reads some data from o

2019-09-02 08:00发布

问题:

In the book of "functional programming in Scala", it gives some examples about side-effects, like:

  • Modifying a variable
  • Modifying a data structure in place
  • Setting a field on an object
  • Throwing an exception or halting with an error  Printing to the console or reading user input
  • Reading from or writing to a file
  • Drawing on the screen

My question is, is reading some data from outside rathen than the parameters makes the function impure?

E.g.

val name = "Scala"

def upcase() = name.toUpperCase

Is the upcase function pure or not?


Edit: as per this answer: https://stackoverflow.com/a/31377452/342235, my "function" is not actually function, it's a method, so I give a function version of it, and ask the same question:

val name = "Scala"

val upcase: () => String = () => name.toUpperCase

回答1:

Reading from immutable data is not impure; the function will still return the same value every time. If name were a var then that function would be impure, since something external could change name, so multiple calls to upcase() might evaluate to different values.

(Of course it might be possible to e.g. alter name through reflection. Properly we can only talk about purity with respect to some notion of what kind of functions are allowed to call a given function, and what kind of side effects we consider to be equivalent)

It's worth noting that your function is not pure because toUpperCase is not pure; it depends on the system's default Locale, and may produce different results on different systems (e.g. on a Turkish system, "i".toUpperCase == "İ"). You should always pass an explicit Locale, e.g. def upcase() = name.toUpperCase(Locale.ENGLISH); then the function will be pure.



回答2:

Interestingly, the answer is "No", but not for the reason you think it is. Your upcase is not a pure function. It is, however, pure, but it is a method, not a function.