lib.lists.foldl': Make stricter, tests and docs#256544
Conversation
0f181d9 to
7ccf457
Compare
7ccf457 to
c7270e0
Compare
c7270e0 to
4edb148
Compare
|
I now also added |
940da1d to
c529951
Compare
c529951 to
aef4719
Compare
There was a problem hiding this comment.
In my suggestions I'm using two academic terms (denotational vs operational semantics) that could be considered to make the text slightly less accessible to newcomers. However, I believe they can still infer the meaning from context, and having the terms, we give them an opportunity to better understand the functional programming context. foldl' exists precisely for "advanced" reasons, which aligns with these two terms.
(Not sure that I should be explaining myself in this regard, as I feel this should be normal, but now I already wrote it so here ya go)
lib/lists.nix
Outdated
There was a problem hiding this comment.
| is semantically the same as | |
| is denotationally equivalent to |
If we're going to talk about the semantics, we have to pick the right semantics.
We should then also (later) discuss the other semantics, the operational semantics:
+However, operationally, the accₙ bindings are optimized away using a single memory location instead.There was a problem hiding this comment.
I actually don't think we need to mention the operational semantics. It's not very useful information and pretty much an implementation detail.
I am now using "is (denotationally) equivalent to" though.
lib/lists.nix
Outdated
There was a problem hiding this comment.
Stack overflows aren't part of the Nix language semantics, so I'd phrase this a bit differently.
Also I would refrain from comparing these two models, precisely because they're different kinds of models. They are not to be treated as example code.
Furthermore, even if you did, the example with the lets and seqs will still overflow the stack.
| The only difference is that the second version would always cause a stack overflow for large enough lists, | |
| which isn't a problem with this function. | |
| The most significant benefit of `foldl'` over any hand-written recursion is that it gives the Nix evaluator the opportunity to avoid a stack overflow, even if regular calls are susceptible to this error condition. |
There was a problem hiding this comment.
I now removed any text after the code. It's really not that important to point out the difference, nobody would ever write that code anyways.
And the think about stack overflows is already mentioned in an earlier paragraph, so I don't think it needs to be repeated. I did reword that slightly though. (diff)
aef4719 to
a9c39cd
Compare
While I did learn about denotational vs operational semantics in university, I had to refresh my memory of it. I really don't think this is necessary in any way, even for advanced users. However, I now added |
Nix 2.3, the minimum Nix version supported by Nixpkgs, has `builtins.foldl'` already.
a9c39cd to
b4aba29
Compare
lib/lists.nix
Outdated
There was a problem hiding this comment.
| Compared to regular recursive functions, this allows avoiding stack overflows on large lists. |
This sentence doesn't belong in this paragraph, because the paragraph is about strictness, not the stack behavior. Specifically this seemed to refer to the preceding sentence, which would be an incorrect relation.
Alternatively, you could move this sentence after "Before each application of the operator, the accumulator value is evaluated.", in which case it does hold up.
However, the relation between strictness and stack overflows is mostly an implementation detail, so I'd be happy to present these aspects in separate paragraphs.
lib/lists.nix
Outdated
There was a problem hiding this comment.
| is (denotationally) equivalent to | |
| is (denotationally) equivalent to the following, but with the added benefit that `foldl'` itself will never overflow the stack. |
Co-Authored-By: Robert Hensing <[email protected]>
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.
See the parent commit for the same change to lib.lists.foldl'
b4aba29 to
dd72ff2
Compare
|
@roberth Your suggestions sound good to me, applied! |
lib.lists.foldl': Make stricterlib.lists.foldl': Make stricter, tests and docs
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
Description of changes
Makes
lib.lists.foldl'always evaluate its accumulator argument before starting the iteration.Before:
After:
This is technically a backwards-incompatible change, which is why it needs to be done in Nixpkgs and not Nix itself, see NixOS/nix#7158.
In practice, the chance of this actually causing issues for anybody are slim. In fact, Haskell accidentally did the same in 2015, and nobody seems to have a problem with it, despite there being many more users.
This work is sponsored by Antithesis ✨
Things done