Using `fold()` and `reduce()` to compose objects creates deep call stacks
- Dominant language
- Java
- Stars
- 11.5k
- Forks
- 402
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 20
Description
This code will stack overflow:
```pkl
class Num {
value: Int
}
local numbers: List = IntSeq(0, 100000).map((i) -> new Num { value = i })
local adder = (numA: Num, numB: Num) -> new Num { value = numA.value + numB.value }
sum = numbers.reduce(adder).value
```
At the end of each iteration, the returned value from `adder` retains a lazy `value`. The resulting object, as a result, has a `value` member that recurses.
This type of code is less performant, and is also vulnerable to stack overflow exceptions. It's also very hard to understand why this is recursive. We should have some way to avoid deep call stacks here.
Note: a workaround is to force the computation with a `let` expression, e.g.
```pkl
local adder = (numA: Num, numB: Num) ->
let (result = numA.value + numB.value)
new Num { value = result }
```
Contributor guide
Research direction
Start by reproducing the provided `reduce()` example with 100,000 `Num` values and compare it with the `let` workaround. Read the evaluation behavior around lazy `value` members and the `fold()`/`reduce()` operations. Done means object composition avoids recursive call stacks while preserving the computed result.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100