A general principle of good programming is encapsulation. Functions should only access what they need to accomplish their task and should minimize side effects and action at a distance.
Perform the following steps to avoid side effects of pure functions:
pure
annotation. It may go before or after the return type, name, and argument list.const
or immutable
objects whenever possible. Use the in
or scope
keywords on your parameters if you will not store a reference to them.static
) variables.pure
based on compile-time arguments, you do not have to explicitly mark it with the pure
keyword. Follow the rules and the compiler will infer its purity based on the purity of its arguments at the usage point.pure
function, for example, to debug, you may do so with the debug statement: debug writeln("debug printing");
. Consider the following code snippet:int foo(int a) pure { return a + 50; }
Pure functions in D are prohibited from accessing non-immutable global data or calling impure functions. There are two exceptions to these general rules: GC memory allocations with new
are always allowed inside pure functions, and impure functions are allowed in debug
statements. Other language features, including mutation of local variables, are allowed, the same as any other function. D treats functional programming as a big-picture design, not an in-function implementation style.
While pure functions may not modify global state, they may modify local variables, including its arguments. A pure function with all immutable arguments is called a strongly pure function. Like in many other programming languages, a strongly pure function may not modify any data external to the implementation and have no side effects.
A pure function with one or more mutable arguments is called a weakly pure function. Weakly pure functions are often a surprise for programmers coming from other languages because they allow mutation to data passed to it.
The benefit of pure functions is to statically enforce that the pure function's result is dependent only on the data you explicitly pass to it, making all its requirements obvious at the call point and limiting the amount of code you have to look at to understand the program's current state.
3.14.246.148