Why foldRight and reduceRight are NOT tail recursive?

前端 未结 2 886
遥遥无期
遥遥无期 2021-01-02 03:44

Why compiler does not translate Scala

(1,2,3,4,5,6).foldRight(10)(_ * _)

to Java equivalent

final int[] intArray = new int[         


        
2条回答
  •  Happy的楠姐
    2021-01-02 04:23

    It's a question of how the folding proceeds. The foldLeft operation arranges

    Seq(1, 2, 3).foldLeft(10)(_ - _)
    

    as

    (((10 - 1) - 2) - 3)
    

    (which is 4) while foldRight arranges

    Seq(1, 2, 3).foldRight(10)(_ - _)
    

    as

    (1 - (2 - (3 - 10)))
    

    (which is -8).

    Now, imagine you're pulling the numbers 1, 2, and 3 from a bag and making the calculation pencil-on-paper.

    In the foldRight case you're forced to do it like this:

    1. Pull a number n from the bag
    2. Write "n - ?" on the paper
    3. If there are numbers left in the bag, pull another n from the bag, else go to 6.
    4. Erase the question mark and replace it with "(n - ?)"
    5. Repeat from 3.
    6. Erase the question mark and replace it with 10
    7. Perform the calculation

    In the foldLeft case, you can do it like this:

    1. Write 10 on the paper
    2. If there are numbers left in the bag, pull another n from the bag, else go to 5.
    3. Write " - n" beside the expression you already have
    4. Repeat from 2.
    5. Perform the calculation

    but you wouldn't, because you can also do it like this:

    1. Write 10 on the paper
    2. Pull a number n from the bag
    3. Subtract n from the value you have, erase the value and write down the new value instead
    4. Repeat from 2.

    Regardless of how many numbers there are in the bag, you only need to have one value written on paper. Tail Call Elimination (TCE) means that instead of building a large structure of recursive calls on the stack, you can pop off and replace an accumulated value as you go along. (I.e., the recursively expressed computation is essentially performed in an iterative manner.)

    As others have noted, a random-access structure such as an ArrayLike allows the foldRight to be rearranged into a foldLeft operation, and so become eligible for TCE. The description above does hold for cases where this is impossible.

提交回复
热议问题