Skip to content
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

Add some Python comprehensions as syntax for attrset generation #2543

Open
danbst opened this issue Nov 16, 2018 · 5 comments
Open

Add some Python comprehensions as syntax for attrset generation #2543

danbst opened this issue Nov 16, 2018 · 5 comments
Labels

Comments

@danbst
Copy link
Contributor

danbst commented Nov 16, 2018

To create a dictionary from list I do like this:

{ lib }:
lib.genAttrs [ "foo" "bar" ] (name: "x_" + name)

This is not nice. What about this:

{
  for name in [ "foo" "bar" ];
    ${name} = "x_${name}";
}

and this

let source = { a = "foo"; b = "bar"; };
in {
  for { name, value } in source;
    ${name} = "x_${name}";
  for { name, value } in source;
    "${name}_value" = "x_${value}";
}

Essentially this will be syntax sugar for inherit:

{ lib }:
{
  inherit (lib.genAttrs [ "foo" "bar" ] (
    name: "x_" + name
  ));
}
@danbst
Copy link
Contributor Author

danbst commented Dec 27, 2018

Another example where this would be nice.
There is code in zram module, which looks like:

    systemd.services =
      let
        createZramInitService = dev:
          nameValuePair "zram-init-${dev}" {
            description = "Init swap on zram-based device ${dev}";
            bindsTo = [ "dev-${dev}.swap" ];
            after = [ "dev-${dev}.device" "zram-reloader.service" ];
            requires = [ "dev-${dev}.device" "zram-reloader.service" ];
            # ...
          };
      in listToAttrs ((map createZramInitService devices) ++ [(nameValuePair "zram-reloader"
        {
          description = "Reload zram kernel module when number of devices changes";
          serviceConfig = {
            # ...
          };
          restartTriggers = [ cfg.numDevices ];
          restartIfChanged = true;
        })]);

It's functional style is a bit mess. When rewriting in comprehension style, it will look like:

    systemd.services = {
      for dev in devices;
        "zram-init-${dev}" = {
            description = "Init swap on zram-based device ${dev}";
            bindsTo = [ "dev-${dev}.swap" ];
            after = [ "dev-${dev}.device" "zram-reloader.service" ];
            requires = [ "dev-${dev}.device" "zram-reloader.service" ];
            # ...
        };
      zram-reloader = {
          description = "Reload zram kernel module when number of devices changes";
          serviceConfig = {
            # ...
          };
          restartTriggers = [ cfg.numDevices ];
          restartIfChanged = true;
      };
    };

This comprehension solution is more natural than listToAttrs, because doesn't require namevalue pair concept and builtins.listToAttrs is trivially implemented with comprehension syntax:

    listToAttrs = l: {
      for x in l; ${x.name} = x.value;
    };

cc @edolstra

@danbst
Copy link
Contributor Author

danbst commented Jul 19, 2019

@volth can you show the desired syntax, how ZRAM example would look like?

@edolstra
Copy link
Member

nameValuePair predates dynamic attributes.

@stale
Copy link

stale bot commented Feb 18, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the stale label Feb 18, 2021
@stale
Copy link

stale bot commented Apr 28, 2022

I closed this issue due to inactivity. → More info

@stale stale bot closed this as completed Apr 28, 2022
@thufschmitt thufschmitt reopened this Feb 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants
@danbst @edolstra @thufschmitt and others