[exploratory] Module system types.record, types.fix#257511
[exploratory] Module system types.record, types.fix#257511roberth wants to merge 2 commits intoNixOS:masterfrom
types.record, types.fix#257511Conversation
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-10-31-nixpkgs-architecture-team-meeting-45/34846/1 |
There was a problem hiding this comment.
I feel like fix is rather useless in a world where we still have (more capable) submodules to handle this aspect.
We could first, or only, make record useful on its own, for data modeling use cases, whereas submodule (or usually just evalModules) can continue to fill a more programming-like role.
| mergeDefinitions mkOptionType isAttrs | ||
| ; | ||
|
|
||
| record = args@{ fields, wildcard ? null }: |
There was a problem hiding this comment.
What's missing is something like optionalFields.
It's best not to mix required fields and optional fields, because
- required fields can be returned without looking at their declarations, making it a bit more lazy, which is good for performance and robustness
- if we don't have optional or wildcard fields, we can return all the fields without even looking at the definitions
- it avoids having to partition the required and optional fields at runtime, which we'd then have to do; it's more efficient this way
| then | ||
| if extraData == {} | ||
| then requiredFieldValues | ||
| else throw "A definition for option `${showOption loc}' has an unknown field." |
There was a problem hiding this comment.
Which one? Print at least one attribute name.
| then requiredFieldValues | ||
| else throw "A definition for option `${showOption loc}' has an unknown field." | ||
| else | ||
| requiredFieldValues // |
There was a problem hiding this comment.
Maybe flip the //? I believe their mututally exclusive, so it doesn't really matter, but if @infinisil's lazy attrset update is implemented, I think we'll want to have the more predictable set on the right.
| ) | ||
| extraData; | ||
| nestedTypes = fields // { | ||
| # potential collision with `_wildcard` field |
There was a problem hiding this comment.
Unimportant, but I guess we could rename the original fields of that satisfy regex _*wildcard to get an extra underscore. (The word wildcard looks weird in a regex, but it's just the literal word)
There was a problem hiding this comment.
Should it be an error for nested types to have a wildcard option?
| builtins.addErrorContext ("while evaluating the wildcard field `${fieldName}' of option `${showOption loc}'") ( | ||
| (mergeDefinitions | ||
| (loc ++ [fieldName]) | ||
| wildcard.type |
There was a problem hiding this comment.
| wildcard.type | |
| optionalFields.${fieldName} or wildcard.type |
- move all of this outside the
wildcard == nullconditional above.
|
I think we should forget about |
Description of changes
An exploratory PR to help me and others understand the module system design space.
The
submoduletype (orevalModules) can be thought of as a combination ofSplitting these concepts out might
Observations so far:
The submodule fixpoint is not a fixpoint of merely the
config, but alsooptions.The option type interface is currently not conducive to the transfer of any kind of metadata. This also plagues solutions for built-in assertions and warnings.
recordandfixwere easy to implement. I can't imagine implementingsubmodulein a remotely similar time frame.This was written at nix.camp 🏕️ .
Could implement #158598 except not the
types.fixpart of module evaluation this PR was originally going for.Things done
sandbox = trueset innix.conf? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/)