Deprecate foldRight and all lazy folds #2370
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
FoldRight and similar are useless in most cases in arrow atm.
inline
and can thus short circuit using non-local returns.A quick overview of all the types of folds present in arrow atm:
foldLeft = fold
This iterates over the elements in order left to right and accumulates along the wayfoldRight
(withoutEval
) This iterates over the elements in order right to left. I'd argue that this is hardly ever what anyone wants or needs and writingreverse().fold
isn't that annoying or common to warrant a shortcut (especially not one namedfoldRight
)foldRight
(withEval
): This returns a lazy computation that is right nested. This means it only ever iterates the list as far as necessary to calculate a result. Thus it is also safe for infinite structures!foldLeft
(withEval
) This builds a lazy computation that is left nested, which means to produce the final lazy computation we must traverse the entire list first. Highly inefficient when we want to short circuit or when we actually need every result applied.So out of the 4 only the strict
fold
andfoldRight
withEval
seem useful.fold
for obvious reasons, and lazyfoldRight
because it can short circuit at any point by simply not forcing more of the accumulator.The stdlib includes the strict left fold and the strict right fold, so why no lazy folds? Well all of the folds inside the stdlib are inline and thus non-local returns can handle the use-case of short-circuiting way better. It is cleaner, faster and easier to understand to return from a local inline fold function than to explicitly not-bind the lazy accumulator.
The other useful part of lazy folds is that their results themselves are lazy. Top level laziness can be achieved by wrapping them in
Eval.later { .. }
instead.Here is an example how a lazy right fold can be replaced by a normal fold for exactly the same functionality: