Java Reference
In-Depth Information
neither of them. By contrast, the first version relies on the fact that after the call concat(subans,
subans2), no one refers to the value of subans ever again. It turns out that, for our definition of
subsets, this is indeed the case, so surely using the cheaper version of concat is better. Well, it
depends on how you value your time spent later searching for obscure bugs compared with the
additional cost of making a copy.
No matter how well you comment that the impure concat is “only to be used when the first
argument can be arbitrarily overwritten, and only intended to be used in the subsets method,
and any change to subsets must be reviewed in the light of this comment,'' somebody sometime
will find it useful in some piece of code where it apparently seems to work, and your future
nightmare debugging problem has just been born. We revisit this issue in the next chapter in
section 14.2 , “Persistent data structures.”
Takeaway point: thinking of programming problems in terms of function-style methods that are
characterized only by their input arguments, and their output result (that is, what to do) is often
more productive than thinking how to do it and what to mutate too early in the design cycle. We
now turn to recursion in more detail, a technique promoted in functional programming to let
you think more in terms of this what to do style.
13.3. Recursion vs. iteration
Pure functional programming languages typically don't include iterative constructs like while
and for loops. Why? Because such constructs are often a hidden invitation to use mutation. For
example, the condition in a while loop needs to be updated; otherwise the loop would execute
zero or an infinite number of times. But for a lot of use cases loops are perfectly fine. We've
argued that to be functional style you're allowed mutation if no one can see you doing it,
meaning it's acceptable to mutate local variables. Using the for-each loop in Java, for(Apple a :
apples { } decodes into the Iterator shown here:
Iterator<Apple> it = apples.iterator();
while (it.hasNext()) {
Apple apple = it.next();
// ...
}
This isn't a problem because the mutations (both changing the state of the Iterator with the
method next and assigning to the variable apple inside the while body) aren't visible to the caller
of the method where the mutations happen. But using a for-each loop, such as a search
 
Search WWH ::




Custom Search