-
-
Notifications
You must be signed in to change notification settings - Fork 13.8k
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
Pop, object system with multiple-inheritance for nix #116275
base: master
Are you sure you want to change the base?
Conversation
Ping? |
As already mentioned on IRC, this is something that should probably be done through an RFC. This also helps with getting discussions and feedback going. |
I agree with @infinisil, this is a major change that should be done via an RFC. In general I think we should be very careful about adding something like this, since Nixpkgs already has way too many composition/overriding mechanisms, making Nix quite hard to learn (see Lisp Curse). Alternatively you could make it available as a flake, since that way people can use it easily without having to add it to Nixpkgs. |
I agree with @infinisil, this is a major change that should be done via an RFC. In general I think we should be very careful about adding something like this, since Nixpkgs already has way too many composition/overriding mechanisms, making Nix quite hard to learn (see [Lisp Curse](http://www.winestockwebdesign.com/Essays/Lisp_Curse.html)).
An annoying part is that module system is really heavy (but we need a comparison there) and also pretty unusually designed compared to anything outside Nix. And the rest are used for being lighter (but weak).
Alternatively you could make it available as a flake, since that way people can use it easily without having to add it to Nixpkgs.
Flakes as an alternative to RFCs sounds a bit ironic…
But the point of POP in the first place is to make maintenance of a language ecosystem inside Nixpkgs easier.
|
POP attempts to establish existing object model on top of the hacks which piled up on Nix. While similarities are nice to notice and might help reasoning, we should not forget the specificity of the problem we are attempting to solve. This makes me wonder, would there be any equivalent to #10851 description in object literature? |
I created RFC 0091 for POP in Nixpkgs. |
Note regarding #10851 that multiple inheritance would allow you to define dependencies between your security patches, so that they are applied in order and never redo effects twice or undo each other's effects by being included twice. |
Yeah, applying patches correctly with proper dependencies computed in Nix code is exactly the kind of things that gets rejected because people pretend Nix can avoid being a general purpose computing language (and well, its evaluator is inefficient) |
(I would probably just merge it with POP inside Gambit directory for now, but with top-level |
I could move the code to be under the gerbil directory, but so as not to cause chicken-and-egg issues, it has to be addressed from a name outside of the gerbil hierarchy, because the gerbil hierarchy depends on it. Thus, I could register, e.g. |
What's the chicken-and-egg issue? You could have a local |
I suppose the chicken-and-egg issue is that I was trying to extract pop from the self value of gerbil-support, rather than from its super value. That could be solved that way. OR, just like I have a top-level entry for gerbil-support, I could have a top-level entry for POP, or a lib entry for it, pointing to the gerbil directory. |
Of all the modules out there, which do something non-trivial with respect to combination with other modules? |
I read the module documentation at https://nixos.org/manual/nixos/stable/index.html#sec-writing-modules and while it is very interesting indeed, it's a very different mechanism from the extension system / object system that POP extends.
So I'm not sure what the question or challenge exactly are with respect to "comparing POP and the NixOS module system". On the one hand, POP is a much simpler mechanism meant to replace the Nix extension system and not the NixOS module system. On the other hand, POP does have extension mechanisms with which the more elaborate aspects of the module system could be plugged in, yielding a variant of the module system that deals with imports as dependencies to be combined each a single time in a proper order. |
I wrote an article about the principles underlying POP, that will be published at the Scheme and Functional Programming Workshop 2021: http://fare.tunes.org/files/cs/poof.pdf |
I marked this as stale due to inactivity. → More info |
This just happened: https://github.com/divnix/POP (planned as a dependency for https://github.com/divnix/grafonnix) |
Like the many Jsonnet-style object systems already in Nix, pop combines instance field values and composable prototype information in a same attrset. However pop also implements CLOS-style DAG-based multiple inheritance.
Also use foldr when it makes sense.
@fare Could you explain the POP-native approaches to the following Nixpkgs extension patterns? First, many objects in Nixpkgs exhibit multiple "axes" of extensibility. Your standard package derivation object
The effective "shallow" overlay in I would figure that ideally, all this extensibility can & should be (able to be) handled in the same inheritance DAG, to avoid overly constraining the order of prototype composition. If a package function within a package set acts like a normal proto for the package set, then Additionally, you can have functions that wrap My guess is that with POPs, Also, if I want to write a robust transformer function for package POPs that can be relied upon to transform the package object before the transformations of Second, how would POPs handle the sort of detached extensibility present in objects like Also, while fiddling with my own mini POP implementation, I realized that |
Reading through the “Prototypes: Object Orientation, Functionally” paper, it says that the C3 Linearization algorithm used for sorting the inheritance DAG into an inheritance list «ensures that the precedence list of an object always contains as ordered sub-lists (though not necessarily with consecutive elements) the precedence list of each of the object’s super-objects, as well as the list of direct supers» and that «It also favors direct supers appearing as early as possible in the precedence list». I believe my concern here is that, if a package POP object has a prototype of In a sense, I want to automatically introduce a new, possibly virtual node to the inheritance DAG, one that represents the interface provided by the proto I think the idea of (virtual) "interface" protos / inheritance DAG nodes are important, as both the protos Unfortunately, C3 linearization only natively supports supers, so something would need to be figured out to support nodes advertising subs. Either a DAG where nodes map to both subs and supers would need to be converted into an equivalent DAG where nodes map to only supers, or a different algorithm would be required. If the patterns described here can be sanely handled without equipping protos with sub lists (in addition to their existing super lists), please let me know. Otherwise, I'd consider the subs issue a blocker for robust use of POP throughout Nixpkgs. |
If you want to ensure that P occurs after Q, |
Add a new experimental library: POP, a prototype object system with multiple inheritance.
I use POP a lot to customize the Gerbil packages, as defined in
#114449
Motivation for this change
I needed a prototype object system to customize my configurations. As compared to the many unassuming object systems already in Nix, I tweaked the API so the types are slightly simpler, then I added multiple inheritance to it because it enabled more modular configurations.
Things done
sandbox
innix.conf
on non-NixOS linux)nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
./result/bin/
)nix path-info -S
before and after)