summary refs log tree commit diff
path: root/lib/lists.nix
diff options
context:
space:
mode:
Diffstat (limited to 'lib/lists.nix')
-rw-r--r--lib/lists.nix13
1 files changed, 10 insertions, 3 deletions
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