snix/tvix/eval/src
sterni 3b33c19a9c fix(tvix): don't call function eagerly in genList, map & mapAttrs
mapAttrs, map and genList call Nix functions provided by the caller and
store the result of applying them in a Nix data structure that does not
force all of its contents when forced itself. This means that when such
a builtin application is forced, the Nix function calls performed by the
builtin should not be forced: They may be forced later, but it is also
possible that they will never be forced, e.g. in

    builtins.length (builtins.map (builtins.add 2) [ 1 2 3 ])

it is not necessary to compute a single application of builtins.add.

Since request_call_with immediately performs the function call
requested, Tvix would compute function applications unnecessarily before
this change. Because this was not followed by a request_force, the
impact of this was relatively low in Nix code (most functions return a
new thunk after being applied), but it was enough to cause a lot of
bogus builtins.trace applications when evaluating anything from
`lib.modules`. The newly added test includes many cases where Tvix
previously incorrectly applied a builtin, breaking a working expression.

To fix this we add a new helper to construct a Thunk performing a
function application at runtime from a function and argument given as
`Value`s. This mimics the compiler's compile_apply(), but does itself
not require a compiler, since the necessary Lambda can be constructed
independently.

I also looked into other builtins that call a Nix function to verify
that they don't exhibit such a problem:

- Many builtins immediately use the resulting value in a way that makes
  it necessary to compute all the function calls they do as soon as
  the outer builtin application is forced:

  * all
  * any
  * filter
  * groupBy
  * partition

- concatMap needs to (shallowly) force the returned list for
  concatenation.

- foldl' is strict in the application of `op` (I added a comment that
  makes this explicit).

- genericClosure needs to (shallowly) force the resulting list and some
  keys of the attribute sets inside.

Resolves b/272.

Change-Id: I1fa53f744bcffc035da84c1f97ed25d146830446
Reviewed-on: https://cl.tvl.fyi/c/depot/+/8651
Autosubmit: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
2023-05-26 22:35:39 +00:00
..
builtins fix(tvix): don't call function eagerly in genList, map & mapAttrs 2023-05-26 22:35:39 +00:00
compiler feat(tvix/eval): unthunk empty lists and attribute sets 2023-05-25 11:28:13 +00:00
tests fix(tvix): don't call function eagerly in genList, map & mapAttrs 2023-05-26 22:35:39 +00:00
value fix(tvix): don't call function eagerly in genList, map & mapAttrs 2023-05-26 22:35:39 +00:00
vm refactor(tvix/eval): use &Path instead of PathBuf 2023-05-22 09:43:33 +00:00
chunk.rs feat(tvix/eval): implement Chunk::extend method 2023-05-25 11:28:13 +00:00
errors.rs feat(tvix/eval): report all known spans on infinite recursion 2023-03-17 19:32:38 +00:00
io.rs refactor(tvix/eval): stop borrowing &mut self 2023-05-25 11:11:59 +00:00
lib.rs feat(tvix/eval): add Evaluation::strict to toggle top-level deepseq 2023-03-22 13:44:20 +00:00
nix_search_path.rs refactor(tvix/eval): use &Path instead of PathBuf 2023-05-22 09:43:33 +00:00
observer.rs chore(tvix): Generator{Request|Response} -> VM{Request|Response} 2023-03-14 09:22:22 +00:00
opcode.rs refactor(tvix/eval): flatten call stack of VM using generators 2023-03-13 20:30:59 +00:00
pretty_ast.rs fix(tvix/eval): fix current clippy warnings 2022-12-25 18:25:06 +00:00
properties.rs refactor(tvix/eval): Don't (ab)use PartialEq for Nix equality 2022-09-18 22:03:41 +00:00
source.rs chore(tvix/eval): implement std::error::Error for tvix_eval::Error 2023-01-02 22:24:43 +00:00
spans.rs refactor(tvix/eval): implement From<Span> for LightSpan 2023-03-04 15:18:37 +00:00
systems.rs fix(tvix/eval): fix current clippy warnings 2022-12-25 18:25:06 +00:00
test_utils.rs test(tvix/eval): Add proof-of-concept test for Chunk 2022-09-18 17:55:06 +00:00
upvalues.rs fix(tvix/eval): remove impl PartialEq for Value 2022-11-04 00:30:13 +00:00
warnings.rs chore(tvix/eval): delete "useless parenthesis" warning/optimisation 2023-01-23 17:59:06 +00:00