Search code examples
javavavr

Memoization with Vavr seems incosistent


When the function is defined as following

static Function1<BigInteger, BigInteger> fibonacci = Function((BigInteger value) ->
            value.equals(BigInteger.ZERO) ? BigInteger.ZERO
                    : value.equals(BigInteger.ONE) ? BigInteger.ONE
                    : value.equals(BigInteger.valueOf(2)) ? BigInteger.ONE
                    : Program.fibonacci.apply(value.subtract(BigInteger.ONE)).add(Program.fibonacci.apply(value.subtract(BigInteger.valueOf(2))))
    ).memoized();

And called

System.out.println(fibonacci.apply(BigInteger.valueOf(1000)));

It calculated very fast. However if I move the memoized() to function variable as follows

static Function1<BigInteger, BigInteger> fibonacci = Function((BigInteger value) ->
            value.equals(BigInteger.ZERO) ? BigInteger.ZERO
                    : value.equals(BigInteger.ONE) ? BigInteger.ONE
                    : value.equals(BigInteger.valueOf(2)) ? BigInteger.ONE
                    : Program.fibonacci.apply(value.subtract(BigInteger.ONE)).add(Program.fibonacci.apply(value.subtract(BigInteger.valueOf(2))))
    ); // Removed memoized() from here

And called

fibonacci.memoized().apply(BigInteger.valueOf(1000));

It takes very long as if memoized() was not applied.

What might be the reason for that?


Solution

  • Because a) the recursion isn't called on the memoized form, b) the whole point of memoizing is that you need to save the memoization, not create a new memoization each time.

    Program.fibonacci is defined in terms of itself, so the recursion calls that version, not the memoized version.