libexpr: Remember intermediate values on exception #8585
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.
Motivation
Preserve sharing in case of an exception. When an exception occurs, the original expression, or a similar expression with shared values may be retried. Intermediate values should be retained as much as possible.
TODO:
Context
We want the rules about memoization of let bindings to hold even when an exception occurs.
This is slightly counterintuitive, because we might think that we'd have better luck next time if we didn't memoize the result of the let binding.
However this contradicts the design goal of having a declarative language and therefore idempotent evaluation.
So instead of maintaining doubt about this situation, we choose to lean into the language semantics and exploit the idempotency. This improves the performance asymptotically and significantly in scenarios where we may evaluate more than once. These scenarios include:
tryEval
has been used, such as in these test cases, ornix-build
withrecurseForDerivations
,:r
.Checklist for maintainers
Maintainers: tick if completed or explain if not relevant
tests/**.sh
src/*/tests
tests/nixos/*
Priorities
Add 👍 to pull requests you find important.