Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why use foldLeft instead of procedural version?

Tags:

People also ask

What is foldLeft?

foldLeft() method is a member of TraversableOnce trait, it is used to collapse elements of collections. It navigates elements from Left to Right order. It is primarily used in recursive functions and prevents stack overflow exceptions.

Is reduce the same as fold?

On the one hand, if we operate only on a non-empty collection and combine all elements into a single result of the same type, then reduce() is a good choice. On the other hand, if we want to provide an initial value or change the result type, then fold() gives us the flexibility to do it.


So in reading this question it was pointed out that instead of the procedural code:

def expand(exp: String, replacements: Traversable[(String, String)]): String = {
  var result = exp
  for ((oldS, newS) <- replacements)
    result = result.replace(oldS, newS)
  result
}

You could write the following functional code:

def expand(exp: String, replacements: Traversable[(String, String)]): String = {
  replacements.foldLeft(exp){
    case (result, (oldS, newS)) => result.replace(oldS, newS)
  }
}

I would almost certainly write the first version because coders familiar with either procedural or functional styles can easily read and understand it, while only coders familiar with functional style can easily read and understand the second version.

But setting readability aside for the moment, is there something that makes foldLeft a better choice than the procedural version? I might have thought it would be more efficient, but it turns out that the implementation of foldLeft is actually just the procedural code above. So is it just a style choice, or is there a good reason to use one version or the other?

Edit: Just to be clear, I'm not asking about other functions, just foldLeft. I'm perfectly happy with the use of foreach, map, filter, etc. which all map nicely onto for-comprehensions.

Answer: There are really two good answers here (provided by delnan and Dave Griffith) even though I could only accept one:

  • Use foldLeft because there are additional optimizations, e.g. using a while loop which will be faster than a for loop.
  • Use fold if it ever gets added to regular collections, because that will make the transition to parallel collections trivial.