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
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.
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.