Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libexpr: Remember intermediate values on exception #8585

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

roberth
Copy link
Member

@roberth roberth commented Jun 26, 2023

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:

  • Thoroughly check that this code is correct and that the tests cover all the changes. I originally wrote this as an experiment and I don't think it is ready for production.

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, or
  • traversal of multiple attributes, such as in nix-build with recurseForDerivations,
  • applications that handle missing information by throwing an exception to be handled by a convergent main loop,
  • re-parsing a file that used to have a syntax error in nix repl, without using :r.

Checklist for maintainers

Maintainers: tick if completed or explain if not relevant

  • agreed on idea
  • agreed on implementation strategy
  • tests, as appropriate
    • functional tests - tests/**.sh
    • unit tests - src/*/tests
    • integration tests - tests/nixos/*
  • documentation in the manual
  • documentation in the internal API docs
  • code and comments are self-explanatory
  • commit message explains why the change was made
  • new feature or incompatible change: updated release notes

Priorities

Add 👍 to pull requests you find important.

@github-actions github-actions bot added the tests label Jun 26, 2023
@roberth roberth changed the title libexpr: Memoize partial let and apply results for retries libexpr: Remember intermediate values on exception Jun 26, 2023
@roberth roberth added language The Nix expression language; parser, interpreter, primops, evaluation, etc performance labels Jun 30, 2023
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, or
  - traversal of multiple attributes, such as in `nix-build` with
    `recurseForDerivations`,
  - applications that handle missing information by throwing an
    exception to be handled by a convergent main loop,
  - re-parsing a file that used to have a syntax error in nix repl,
    without using `:r`.
@roberth roberth force-pushed the memoize-let-and-apply-for-retry branch from 2212362 to dcb1cab Compare November 11, 2023 23:59
@github-actions github-actions bot added the with-tests Issues related to testing. PRs with tests have some priority label Nov 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
language The Nix expression language; parser, interpreter, primops, evaluation, etc performance tests with-tests Issues related to testing. PRs with tests have some priority
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant