-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
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
Improve the documentation of lib.extends
and how it relates to overlays
#248220
Conversation
The previous one was unnecessarily confusing.
- Better names: - self -> final - super -> prev - rattrs -> f - f -> overlay - Add documentation to the function arguments - Add some spacing
lib/fixed-points.nix
Outdated
@@ -53,42 +53,96 @@ rec { | |||
else converge f x'; | |||
|
|||
/* | |||
Modify the contents of an explicitly recursive attribute set in a way that | |||
honors `self`-references. This is accomplished with a function | |||
`extends overlay f` applies the overlay `overlay` to the fixed-point function `f` to get a new fixed-point function. |
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.
"Fixed point function" is hard to define and would be a confusing term. I think we can avoid introducing this term.
`extends overlay f` applies the overlay `overlay` to the fixed-point function `f` to get a new fixed-point function. | |
Apply an overlay. | |
Consider `extends overlay f`, where `f` is a function that's suitable for passing to `fix`. | |
Instead of tying the fixed-point, `extends` returns a modification of `f` with the `overlay` applied. | |
This means that the "self" parameter of `f` will not refer to `f`'s return value, but rather to the value after applying the overlay. |
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.
"Fixable function" would be more accurate, but still not helpful.
"Endomorphism" would be hilarious ;)
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.
`extends overlay f` applies the overlay `overlay` to the fixed-point function `f` to get a new fixed-point function. | |
Apply an overlay to a fixed-point function. |
The entire example is expanded with more structure below.
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 think it's very good to mention extends overlay f
in the beginning, so one can immediately know the order of arguments. I've seen complaints about this being unclear before.
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.
Apply an overlay to a fixed-point function.
This is too much and too vague for no reason.
There's really only one way we can "apply" an overlay, and we have to explain what kind of function that is anyway.
"Fixed-point function" sounds nice, and we might have some intuition about what that might be, but this is completely idiosyncratic to Nixers, which makes it bad for an introduction.
In fact it could be defined in either of two ways
- Just
fix
- A function that has a fixed-point, which would be wrong here! The fixed point of
f
is completely irrelevant, if it even exists, because we won't be taking it. Instead we may take the fixed-point of the composition off
with an overlay, butextends
isn't even doing that.
Now this does remind me that "apply" may be the wrong term for this composition. The "application" of a fixed point happens in fix
, or "by" fix
if that's acceptable language.
I don't think "compose" is appropriate either, because composition generally refers to objects of some kind of same-ish type, such as two or more functions, two or more modules, etc. Not operands that need distinct terms for a description.
An accurate introductory description would be "Extend a function by means of an overlay". This is close to @infinisil's original introduction, but without the code. "Use an overlay to extend a function" if we care about argument order in the intro.
I also think it's good to address that f
might be thought of as possibly having a fixed point, but that it won't be used that way.
`extends overlay f` applies the overlay `overlay` to the fixed-point function `f` to get a new fixed-point function. | |
Extend a function using an overlay. | |
Consider the context of an `extend` invocation to be: | |
```nix | |
let f = self: ...; | |
in extends overlay f | |
``` | |
Instead of tying the fixed-point of `f`, `extends` returns a composition of `f` with the `overlay` applied. | |
This means that the `self` parameter of `f` will not refer to `f`'s return value, but rather to the value after applying the overlay. |
Maybe we could cut down a bit on the meta language
`extends overlay f` applies the overlay `overlay` to the fixed-point function `f` to get a new fixed-point function. | |
Extend a function using an overlay. | |
Consider | |
```nix | |
let f = self: ...; | |
in extends overlay f | |
``` | |
Instead of tying the fixed-point of `f`, `extends` returns a composition of `f` with the `overlay` applied. | |
This means that the `self` parameter of `f` will not refer to `f`'s return value, but rather to the value after applying the overlay. |
("with the overlay
applied", "applying the overlay" are valid here because it refers to the overlay as a (curried) function. It would not be valid as a description of the extends
interface. Overexplaining for the purpose of our discussion only)
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 don't think that the descriptive language says much about what's happening - at least not to me - while the later examples explain a lot. It's fine if we say "extend a function with an overlay" if the fixed point aspect doesn't matter, and it's fine to show a brief example for argument order, but then it should also contain a sample overlay.
But still I think it would be enough just to skip that and go right to the next part.
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.
but then it should also contain a sample overlay.
I've assumed that the overlay "type" is described elsewhere. That was probably wrong (?) and we should have a separate section explaining what an overlay is, because most people who need to know about overlays just need to write and understand them, but don't need to call extends
.
We can leave out those details here because exactly how it's wired just follows from the definition of an overlay, and we don't have to refer to the parameters here. (Although maybe it's worth describing some equalities, but then that could all be done in its own section. This amount of detail is just not necessary at the start of the description; as you can see almost everything can be said with just f
, overlay
and self
.)
enough just to skip that and go right to the next part.
Not sure what you mean. Skip introducing names, and assume people read the source? The source doesn't come with these docs as they are extracted, so we can't do that, and nor should we.
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.
Not sure what you mean. Skip introducing names, and assume people read the source?
No, skip the two lines I suggested to leave out. We don't have to define overlays here, just do the same type of sketch you suggested as for the fixed point function.
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-08-17-documentation-team-meeting-notes-73/31853/1 |
lib/fixed-points.nix
Outdated
|
||
```nix | ||
g = self: super: { foo = super.foo + " + "; } | ||
A fixed-point function is a function which is intended to be evaluated by passing the result of itself as the argument, only possible due to Nix's lazy evaluation. |
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 function is a function which is intended to be evaluated by passing the result of itself as the argument, only possible due to Nix's lazy evaluation. | |
A fixed-point function is a function which is intended to be evaluated by passing the result of itself as the argument. | |
This is possible due to Nix's lazy evaluation. |
Co-Authored-By: Valentin Gagarin <valentin.gagarin@tweag.io>
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-09-28-documentation-team-meeting-notes-83/33599/1 |
|
||
where `prev` refers to the result of the original function to `final`, and `final` is the result of the composition of the overlay and the original function. | ||
|
||
Applying an overlay is done with `extends`: |
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 think it'd be easier to read out of context of this file if we say lib.extends
instead of extends
:
Applying an overlay is done with `extends`: | |
Applying an overlay is done with `lib.extends`: |
(here and in the rest of the comment)
The same way you're mentioning lib.fix
below instead of just fix
(although you're using fix
not lib.fix
in the code example..)
I'd suggest to also change the code examples to mention lib.
for better readability, wdyt?
I don't really have the time to work on this, but this has lingered for too long and is good enough. The docs are better than before and that's what matters most, so I'll just make the executive decision to merge this right now (thanks @9999years for the push!). If anybody thinks it should be improved still, please make a follow-up PR |
Description of changes
lib.extends
is the part of Nixpkgs that actually implements how overlays work, but its documentation was rather poor. This is an attempt to improve it.This also relates to @roberth's suggested improvements to the
lib.fix
documentation in #242318 and @amjoseph-nixpkgs's suggested improvements to theextends
documentation in #245825.Things done