Java Reference
In-Depth Information
side effect may not be visible to a program, but it's visible to the programmer in terms of slower
execution!
Our guideline is that to be regarded as functional style , a function or method can mutate only
local variables. In addition, objects it references should be immutable. By this we mean all fields
are final, and all fields of reference type refer transitively to other immutable objects. Later you
may also permit updates to fields of objects that are freshly created in the method, and so aren't
visible from elsewhere, and that aren't saved to affect the result of a subsequent call.
Our previous guideline is incomplete, and there's an additional requirement on being functional,
which feels less important at first. To be regarded as functional style, a function or method
shouldn't throw any exceptions . There's a simple overlegalistic explanation: you can't throw an
exception because this means a result is being signaled other than being passed as a proper
result via return as in the black-box model discussed previously. But then this seems countered
by practical mathematical use: although legally a mathematical function gives exactly one result
for each possible argument value, many common mathematical operations are what we should
properly call partial functions . That is, for some or most input values they give exactly one
result, but for other input values they're undefined and don't give a result at all. An example is
division when the second operand is zero or sqrt when its argument is negative. It might seem
natural to model these situations by throwing an exception as Java does. There's some scope for
debate here, with some authors arguing that uncaught exceptions representing fatal errors are
okay, but it's the act of catching an exception that represents nonfunctional control flow, in that
it breaks the simple “pass arguments, return result” metaphor pictured in the black-box model,
leading to a third arrow representing an exception, as illustrated in figure 13.4 .
Figure 13.4. A function throwing an exception
So how might you express functions like division without using exceptions? The answer is to use
types like Optional<T>: instead of sqrt having signature “double sqrt(double) but may raise an
exception,” it would have signature "Optional<Double> sqrt(double)"—either it returns a value
that represents success or it indicates in its return value that it couldn't perform the requested
 
Search WWH ::




Custom Search