From 3b6169f87be45c77ec4b56d118a5e2c718ff3f2b Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Fri, 22 Sep 2023 12:22:04 +0200 Subject: lib.lists.foldl': Make strict in the initial accumulator To maintain backwards compatibility, this can't be changed in the Nix language. We can however ensure that the version Nixpkgs has the more intuitive behavior. --- lib/lists.nix | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'lib/lists.nix') diff --git a/lib/lists.nix b/lib/lists.nix index 8c5099084bb55..3835e3ba69cb8 100644 --- a/lib/lists.nix +++ b/lib/lists.nix @@ -90,9 +90,12 @@ rec { Reduce a list by applying a binary operator from left to right, starting with an initial accumulator. - After each application of the operator, the resulting value is evaluated. + Before each application of the operator, the accumulator value is evaluated. This behavior makes this function stricter than [`foldl`](#function-library-lib.lists.foldl). + Unlike [`builtins.foldl'`](https://nixos.org/manual/nix/unstable/language/builtins.html#builtins-foldl'), + the initial accumulator argument is evaluated before the first iteration. + A call like ```nix @@ -104,7 +107,7 @@ rec { ```nix let - acc₁ = op acc₀ x₀ ; + acc₁ = builtins.seq acc₀ (op acc₀ x₀ ); acc₂ = builtins.seq acc₁ (op acc₁ x₁ ); acc₃ = builtins.seq acc₂ (op acc₂ x₂ ); ... @@ -135,7 +138,11 @@ rec { # The list to fold list: - builtins.foldl' op acc list; + # The builtin `foldl'` is a bit lazier than one might expect. + # See https://github.com/NixOS/nix/pull/7158. + # In particular, the initial accumulator value is not forced before the first iteration starts. + builtins.seq acc + (builtins.foldl' op acc list); /* Map with index starting from 0 -- cgit 1.4.1