Creating users from a list

I’m trying to create users from a list like this:

users.users =
let
u = [ "one" "two"];
in
{
"${u}" = {
     isNormalUser = true;
    };
};

But it fails with: error: cannot coerce a list to a string.

I saw examples using builtins.map or builtins.listToAttrs functions, but it is unclear to me, how to go about this “simple” use-case correctly in nix.

Using those functions is the “simple” way:

users.users = let
  users = [ "one" "two"];
in builtins.listToAttrs (map (user: lib.nameValuePair user {
  isNormalUser = true;
}) users);

Nix doesn’t have any syntactic sugar for unrolling a list and applying a function to it. You need to tell it to do that. This is a design decision - personally I think this usually makes the language more comfortable to read because you need to know less, but opinions can differ.

“${var}” just takes the value of var and puts it in the string, and if var is not a string nix complains (so you need to toString it).

1 Like

Makes sense, indeed. Thanks a bunch for the example and the explanation.

FWIW, I tend to find the following construction easier to read because of the different order of arguments, and because the thing being constructed is more visibly an attrset element.

  users.users =
    let
      inherit (lib.lists) foldl forEach;
      users = [ "one" "two" ];
    in

    foldl (a: b: a // b) { } (
      forEach users (user: {
        user = {
          isNormalUser = true;
        };
      })
    );

They’re doing exactly the same thing: making a list of single-element attrsets, then merging them.

The advantages if this form are even more apparent when there are multiple nested loops to iterate over; you just throw a flatten around the loops.

1 Like

I often hear about how *nix is not well documented and personally, i think that this is not the case.
Nonetheless, it appears to me that most of time i am truly learning something about nix is when reading through other peoples nix code like e.g. your examples or nixpkgs and trying to understand what’s happening. Well, that is what it is worth to me, at least. So thank you too, @uep.

1 Like