(1, 2, 3, 4, 5, 6)
is a 6 valued tuple, which doesn't have the foldRight
, but Array(1, 2, 3, 4, 5, 6)
does.
ArrayLike
is a trait subclassing indexed sequences with efficient element access, meaning it has certain methods optimized, including for instance foldRight
. Each array is implicitly converted to a subclass of the ArrayLike
trait. From Scala trunk:
@tailrec
private def foldr[B](start: Int, end: Int, z: B, op: (A, B) => B): B =
if (start == end) z
else foldr(start, end - 1, op(this(end - 1), z), op)
Bytecode:
private static java.lang.Object foldr(scala.collection.IndexedSeqOptimized, int, int, java.lang.Object, scala.Function2);
...
Code:
Stack=6, Locals=6, Args_size=5
0: iload_1
1: iload_2
2: if_icmpne 7
5: aload_3
6: areturn
7: aload_0
8: iload_2
9: iconst_1
10: isub
11: aload 4
13: aload_0
14: iload_2
15: iconst_1
16: isub
17: invokeinterface #21, 2; //InterfaceMethod scala/collection/SeqLike.apply:(I)Ljava/lang/Object;
22: aload_3
23: invokeinterface #72, 3; //InterfaceMethod scala/Function2.apply:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
28: astore_3
29: istore_2
30: astore_0
31: goto 0
LineNumberTable:
line 68: 0
line 67: 6
line 69: 7
EDIT: The method in bytecode is iterative, meaning that the compiler must have applied a tail call optimization.
Without efficient element access (i.e. an efficient apply
method) the best one can do generically is using iterators and a non-tail recursive function to implement foldRight
, or reversing the collection by building a new one and doing a foldLeft
on that (the latter is done, currently). In the case of all sequences with efficient random access, this behaviour is overridden and optimized.