From d0f2da214badd4cded6fb00e97af4588da49c0d0 Mon Sep 17 00:00:00 2001 From: sternenseemann Date: Sun, 16 Oct 2022 01:32:55 +0200 Subject: primops: make nature of foldl' strictness clearer * Clarify the documentation of foldl': That the arguments are forced before application (?) of `op` is necessarily true. What is important to stress is that we force every application of `op`, even when the value turns out to be unused. * Move the example before the comment about strictness to make it less confusing: It is a general example and doesn't really showcase anything about foldl' strictness. * Add test cases which nail down aspects of foldl' strictness: * The initial accumulator value is not forced unconditionally. * Applications of op are forced. * The list elements are not forced unconditionally. --- tests/lang/eval-fail-foldlStrict-strict-op-application.nix | 5 +++++ tests/lang/eval-okay-foldlStrict-lazy-elements.exp | 1 + tests/lang/eval-okay-foldlStrict-lazy-elements.nix | 9 +++++++++ tests/lang/eval-okay-foldlStrict-lazy-initial-accumulator.exp | 1 + tests/lang/eval-okay-foldlStrict-lazy-initial-accumulator.nix | 6 ++++++ 5 files changed, 22 insertions(+) create mode 100644 tests/lang/eval-fail-foldlStrict-strict-op-application.nix create mode 100644 tests/lang/eval-okay-foldlStrict-lazy-elements.exp create mode 100644 tests/lang/eval-okay-foldlStrict-lazy-elements.nix create mode 100644 tests/lang/eval-okay-foldlStrict-lazy-initial-accumulator.exp create mode 100644 tests/lang/eval-okay-foldlStrict-lazy-initial-accumulator.nix (limited to 'tests/lang') diff --git a/tests/lang/eval-fail-foldlStrict-strict-op-application.nix b/tests/lang/eval-fail-foldlStrict-strict-op-application.nix new file mode 100644 index 000000000..1620cc76e --- /dev/null +++ b/tests/lang/eval-fail-foldlStrict-strict-op-application.nix @@ -0,0 +1,5 @@ +# Tests that the result of applying op is forced even if the value is never used +builtins.foldl' + (_: f: f null) + null + [ (_: throw "Not the final value, but is still forced!") (_: 23) ] diff --git a/tests/lang/eval-okay-foldlStrict-lazy-elements.exp b/tests/lang/eval-okay-foldlStrict-lazy-elements.exp new file mode 100644 index 000000000..d81cc0710 --- /dev/null +++ b/tests/lang/eval-okay-foldlStrict-lazy-elements.exp @@ -0,0 +1 @@ +42 diff --git a/tests/lang/eval-okay-foldlStrict-lazy-elements.nix b/tests/lang/eval-okay-foldlStrict-lazy-elements.nix new file mode 100644 index 000000000..c666e07f3 --- /dev/null +++ b/tests/lang/eval-okay-foldlStrict-lazy-elements.nix @@ -0,0 +1,9 @@ +# Tests that the rhs argument of op is not forced unconditionally +let + lst = builtins.foldl' + (acc: x: acc ++ [ x ]) + [ ] + [ 42 (throw "this shouldn't be evaluated") ]; +in + +builtins.head lst diff --git a/tests/lang/eval-okay-foldlStrict-lazy-initial-accumulator.exp b/tests/lang/eval-okay-foldlStrict-lazy-initial-accumulator.exp new file mode 100644 index 000000000..d81cc0710 --- /dev/null +++ b/tests/lang/eval-okay-foldlStrict-lazy-initial-accumulator.exp @@ -0,0 +1 @@ +42 diff --git a/tests/lang/eval-okay-foldlStrict-lazy-initial-accumulator.nix b/tests/lang/eval-okay-foldlStrict-lazy-initial-accumulator.nix new file mode 100644 index 000000000..abcd5366a --- /dev/null +++ b/tests/lang/eval-okay-foldlStrict-lazy-initial-accumulator.nix @@ -0,0 +1,6 @@ +# Checks that the nul value for the accumulator is not forced unconditionally. +# Some languages provide a foldl' that is strict in this argument, but Nix does not. +builtins.foldl' + (_: x: x) + (throw "This is never forced") + [ "but the results of applying op are" 42 ] -- cgit v1.2.3