17

By definition, a pure function is deterministic + no side effect.

Is there any example for a function which has no side effects, but is non-deterministic? I.e., a function without side effects, but not pure.

To me non-deterministic function comes from randomness. But random generator has side effect. AFAIK random generator's implementation mutates some global state.

EDIT: duplicate with https://stackoverflow.com/q/54992302

Doc Brown
  • 218,378

5 Answers5

38

Of course this depends on the definitions. Let's drop "pure" which has a definition in your question that clearly makes non-deterministic pure functions impossible as being deterministic is a requirement for being pure. Let's instead assume these simple definitions:

  • A function is deterministic if its output strictly depends on its inputs, i.e. it will never return different results if called with the same parameters.
  • A function is side-effect-free if it does not effect any outside state, i.e. there is no external state that could tell you whether the function was called or not.

So a side-effect-free nondeterministic function would need to access external state that is modified not by itself but by something else in its environment. For example, a function that returns the current temperature in my room would be side-effect-free (it does not change it) but nondeterministic (you don't know which result it will return when you call it again at another time).

By your definition, such a function isn't pure as it depends on other data besides its parameters.

26

A properly working classical computer is, by definition, deterministic. That is, the output of the same series of steps with the same inputs will produce the same result. When we talk about non-determinism in that context, what that typically means (in my experience) is that there are implicit inputs whose state can vary.

If we accept the above, then a non-deterministic function with no side effects might be something like a pseudo-random number generator that uses the system clock time to generate numbers, the distinction being that it doesn't change any state as part of its execution. It's not pure because it depends on state.

I think it's important to reiterate that the actual function is still deterministic. If you changed such a function to accept a time value instead of using the system clock's state, it will produce the same output for the same time value.

psmears
  • 196
  • 4
JimmyJames supports Canada
  • 30,578
  • 3
  • 59
  • 108
13

There is no need to use some special hardware like a clock or sensors to give an example.

The point is, any function which return value can be influenced by a side effect of other functions is non-deterministic. Still, such functions don't need to have any side-effects by themselves.

Just as simple as

 int myVariable;   // outer scope (!), 
                   // will be changed somewhere else in the program

int MyFunction(){ return myVariable; }

Based on this, I am sure you can now construct arbitrary non-deterministic, side-effect free functions by yourself, they just have to rely on some stateful variable outside the local scope of the function.

Doc Brown
  • 218,378
1

Pure functions are modelled after functions in mathematics (hence pure), which are, fundamentally, just sets of pairs (with some restrictions). Anything that cannot be thought of as a lookup in some (potentially infinite) collection of pairs is, in this sense, impure.

The definition that pure functions are deterministic and without side effects depends on the meanings of "deterministic" and "side effects", which are usually distinct from what programming languages define. This distinction is useful mainly for one thing, crucial to functional languages: you can seamlessly cache the output of the function for the given input, i.e. memoize the function.

A deterministic function does not really have to be predictable in a sense that you can find out the result without ever calling the function, but once you have it, it will never change unless the arguments change. A function which returns the startup time of your program is deterministic, because it never changes during the run-time of the program (context matters here). A function which returns the current weather at the precise point in time it is called is not deterministic (if your program doesn't happen in an instant), but if the time (and location) is an argument, it is deterministic. Even a true random number generator can be deterministic here if you give it an increasing counter (but it is obliged to return the old value for an unchanged counter). Even reading a file or downloading it from web can be deterministic if you cache the result based on the location. See fn:json-doc for example.

The second restriction is that the result (including changes in by-ref arguments) should be the only observable effect of the function. This doesn't mean that the function cannot change any state, but such change must be effectively hidden to the outside world. Caching a value must definitely change some state (to store the value), but if you don't have any way of knowing that, the cache behaves as it was pre-filled with the correct values from the beginning of the program. This is also complementary to the first restriction ‒ if a function modifies externally observable state, another function that reads the state can no longer be deterministic. If there is no such function, then it doesn't matter whether the first function modifies something, as it is not observable. By this token, all deterministic functions in the previous paragraph are also side effect-free, with the exception of sending a web request (which could have side effects). This also depends on what you choose as the environment and what counts as observing: a whole program can have side effects, but its individual functions can all be pure; and using reflection usually does not count as breaking the purity of caching functions.

Based on these definitions, there are a lot of functions that are non-deterministic but without side effects: reading from any sort of sensor, reading from a dynamic web page, reading from a port or a changeable file, getting a (pseudo-)random number (if a non-deterministic function has a side effect only on itself, then it's not really a side effect) etc. All of these functions can also be made deterministic if you "bind" them to something, i.e. a counter, time and so on.

IS4
  • 215
  • 1
  • 7
-1

Any function whose result is dependent on state outside the computer, i.e. functions that read from external devices -- the network, monitoring equipment, user input. results.

Barmar
  • 346