-
-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A few more steps in explaining the use of fix
in Nix overrides
#228
A few more steps in explaining the use of fix
in Nix overrides
#228
Conversation
cd752d0
to
9af7800
Compare
@@ -51,23 +51,20 @@ | |||
</para> | |||
<screen><xi:include href="./17/fix-function.txt" parse="text" /></screen> | |||
<para> | |||
It's a function that accepts a function <literal>f</literal>, calls <literal>f result</literal> on the result just returned by <literal>f result</literal> and returns it. In other words it's <literal>f(f(f(....</literal> | |||
It's a function that accepts a function <literal>f</literal> and returns a function that recurses over f's arguments. Why is this useful? Because it plays nicely with Nix' laziness: it turns any function that otherwise would happily return (at least some) of its arguments unevaluated, into a function that recursively evaluates its arguments until there is nothing left to evaluate. To fix ideas (pun intended!) consider: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
returns a function that recurses over f's arguments
It does not necessarily return a function:
nix-repl> lib.fix (lib.const "foo")
"foo"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. It does so just in case it is given a function. I think this is the case we're interested in anyway. I hope this is clear enough in the text.
@@ -44,31 +44,20 @@ | |||
<section> | |||
<title>Fixed point</title> | |||
<para> | |||
The fixed point with lazy evaluation is crippling but about necessary in a language like Nix. It lets us achieve something similar to what we'd do imperatively. | |||
A fixed point is a common pattern in lazy languages to ensure that functions that would otherwise return non fully evaluated values do return fully evaluated values. Let's unpack this idea. Remember that in Nix functions are lazy. Consider: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A fixed point is a common pattern in lazy languages to ensure that functions that would otherwise return non fully evaluated values do return fully evaluated values.
I am not sure that forcing strict evaluation (i.e. builtins.seq
) has anything to do with fixed point.
But even if it had, I believe the main purpose of fix point operators in functional languages is facilitating (mutual) recursion when the language lacks support for expressing it explicitly (see https://en.wikipedia.org/wiki/Let_expression).
Now, this is not a problem in Nix, since its let
expression is a let-rec
, so the primary purpose it to allow extensibility of attribute sets (essentially late binding). In my understanding, this is also the motivation for this section, since pkgs
heavily relay on fixed-point for overlays and other extension mechanisms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to imply anything about seq
. But all you said about let-rec is correct. I've boiled it down to minimize jargon.
</para> | ||
<screen><xi:include href="./17/fix-function.txt" parse="text" /></screen> | ||
<literal>How does this related to <literal>fix</literal>? Well it is a function that takes a function f into function g such that g recursively calls f until f can no longer evaluate its arguments. Or in other words: until all thunks have been replaced by the actual values. Consider: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
takes a function f into function g
I do not understand what this means.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be more understandable now.
Just fyi; in case it helps. Or maybe it could be linked to? |
We already link an older version. Might be a good idea to update it.
To be honest, I still find the original version more focused and understandable. People should not really need to care about what a fix point actually is unless they want to. |
Got it. Thank you all for helping improve this, even if it didn't pan out as I wanted at the end. |
After coming back to Nix I absolutely loved the Nix pills! However I felt like the part on
fix
was a bit dense to digest. Here's an attempt to expound it a little bit.