Nicest way to inherit to list

Continuing the discussion from The papercut thread - post your small annoyances/confusions here:

There was talk in the papercut thread about with being bad practice, which from an abstract viewpoint I agree with. One of the most common use cases for with are package lists.

packages = with pkgs; [ curl htop vim ...];

The use of with here is not very nice because I cannot be sure that every package is taken out of pkgs. But using inherit and a let bind (as seen in the linked thread) would be very tedious because I would write every package name twice.
We don’t have that when specifying attribute sets. There I can do

options = { inherit (my-config) color height extraPackages };

or something … But

packages = [inherit (pkgs) htop curl vim ...];

is obviously a syntax error. Is there a nice way to declare the list I want with only once writing pkgs and only once writing the package names?

3 Likes

The simplest solution that comes to mind would be

packages = builtins.attrValues { inherit (pkgs) htop curl vim; };

but that is far from elegant.

See also Language feature proposal: exclusive 'with' · Issue #1361 · NixOS/nix · GitHub for a discussion about implementing with statement with higher binding power.

6 Likes

builtins.attrValues is what I usually do. Not elegant, but gets the job done nice and concisely.

1 Like