The blunt reason is usually performance. With the reasoning that local (!) vars do not break FP and still allow concurrency to work.

In this case, the reason probably is another. The implementation works also for non-Lists, only using the IterableOnce methods.


The designers of the standard library chose performance over purity.

The main downside is that the standard library is not a good resource for learning about how to write pure functional code.

A secondary downside is that it reduces the incentive for the compiler to optimise pure functional code, because it does not affect the core library.


When you have something like List, which is used very often in nearly every Scala program:

  1. even a very minor speedup (or slowdown) can have a large cumulative effect;

  2. its contributors tend to be ones who know a lot about Scala low-level details (and if some don't, their patches will be reviewed by those who do).

So advice given to people just learning Scala isn't particularly applicable.

For this specific example: @tailrec didn't exist until Scala 2.8, this code was probably written earlier (I haven't checked) and there is not sufficiently good reason to rewrite it.

More Query from same tag