I think that saving the side effects passed to collect or findAll is a good idea in general, not only to reduce complexity, but make the code more friendly to parallel if parallel execution is needed in the future.
But in the case of each it makes no sense to maintain the free effect of the function, since it will do nothing (in fact, the only purpose of this method is to replace act as a for-each loop). The Groovy documentation provides examples of using each (and its variants eachWithIndex and reverseEach ), which require execution to determine.
Now, from a pragmatic point of view, I think it is sometimes useful to use functions with some side effects in methods like collect . For example, to convert a list to [index, value] a transpose and range pairs, you can use
def list = ['a', 'b', 'c'] def enumerated = [0..<list.size(), list].transpose() assert enumerated == [[0,'a'], [1,'b'], [2,'c']]
Or even inject
def enumerated = list.inject([]) { acc, val -> acc << [acc.size(), val] }
But a collect and the counter also does the trick, and I think the result is the most readable:
def n = 0, enumerated = list.collect{ [n++, it] }
Now this example does not make sense if Groovy provided collect and similar methods with the index-value-param function (see Jira issue ), but this shows that sometimes practicality exceeds the purity of IMO :)