Conversation
3744a37 to
bbf6d96
Compare
|
This looks alright. I really like the "stack" approach of having the innermost name first. Perhaps this could be reflected in the name, like I'm also wondering about lists. I'm not actually a big fan of those, but perhaps it's useful to include list indices in it? Not sure what the name should be in that case. |
bbf6d96 to
16b35bf
Compare
|
@roberth I like the suggestion of calling it I think using a list like that is fine for now. |
16b35bf to
dcc0b20
Compare
|
@roberth You think this is looking good now? If there aren't any complaints I'll merge it |
roberth
left a comment
There was a problem hiding this comment.
I'd prefer to read modules where information like name is passed down into submodules via the lexical scope, so I don't think we should recommend using this with list indexing operations like . I had to look that one up; don't think I've used it before and for good reason. List indexes have no meaning by themselves and can always be avoided by using high-level list operations like elemAtconcatMap and whatnot, unless you're not managing configuration but implementing clever algorithms which is an entirely separate domain for which the module system is unfit. /rant
tl;dr name things, don't number things. Simple lexical scoping is one of the nicest things in functional programming, so let's use it.
Still I think this feature could be useful for some generic purpose. Did you have something like that in mind?
| # For backwards compatibility, expose the most relevant name | ||
| # directly |
There was a problem hiding this comment.
| # For backwards compatibility, expose the most relevant name | |
| # directly | |
| # Conveniently expose the most relevant name directly |
This is the most used one, so let's keep it around.
|
I marked this as stale due to inactivity. → More info |
|
@roberth But what would the name be? We can't name things without names! There's no inherent naming for the level of submodule recursion |
roberth
left a comment
There was a problem hiding this comment.
Without a compelling use case, I am not convinced that nameStack is better than passing outer names to inner modules via lexical scope.
The module author can choose their own names. |
|
@roberth The problem is that there's no naming of these values defined. To do this you'd have to e.g. extend the definition of attrsOf {
metaName = "myName";
elemType = ...;
}This would then allow you to access { names, ... }: {
result = names.myName;
}I'm also not convinced that this specific PR is a good idea, but I'm also not sure how else it could be done nicer. |
This is an improvement, but I don't think it's necessary. { name, ... }:
let virtualHostName = name;
in {
options.locations = mkOption {
type = submodule ({ name }:
let locationName = name;
in {
config.baseUrl = lib.mkDefault "${virtualHostName}/${locationName}";
});
};
}Granted, this does not work for directly nested |
|
Hm yeah fair enough, let's not do this then. |
Since we have I do think we should use the lexical scope for this, so that we don't need to invent an ad hoc naming system for these "name" variables. |
Motivation for this change
Submodules receive the
nameargument which tells them which attribute they are defined under. E.g.This makes the
foooption evaluate to{ bar = { name = "bar"; }; }However there are also some problems with this, namely (hah):
If the submodule isn't defined under an
attrsOf, thenameisn't relevant at all. E.g.makes the
foooption evaluate to{ name = "foo"; }. This isn't useful at all since the name is just the option name, which you can already know without this.If the submodule is defined under multiple
attrsOf, thenameonly tells you about the latest one. E.g.makes the
foooption evaluate to{ bar = { baz = { name = "baz"; }; }; }. You can see that the submodule doesn't get the information that it's under thebarattribute.This changes fixes both of these problems by:
nameto the last relevant attribute the submodule is defined under, if any. For problem 1 this means that you now get an error that thenameargument isn't passed. Or if the submodule was defined in a deeper attribute set, it would return the attribute name of it, instead of the option name. This is backwards incompatible for submodules that relied on the option name it's defined under to change its behavior, but I think that's fine, because that isn't the intended use ofname.namesargument, which contains them in reverse order. For problem 2 this means thatnamesgives you[ "baz" "bar" ]. This is in reverse such that a static list index can be used to access elements, since the list can be arbitrarily long depending on where the submodule is evaluated.Ping @roberth
@rycee You'll be able to remove this workaround with this change: https://github.com/nix-community/home-manager/blob/249650a07ee2d949fa599f3177a8c234adbd1bee/modules/lib/types-dag.nix#L24-L28
Things done