Gathering additional arguments passed to a function

Take this example:

{ pkgs, arg1, arg2, ...}@args:
let
  extraArgs = pkgs.lib.removeAttrs args ["pkgs" "arg1" "arg2" ];
in 
  # ....

It places any arguments supplied via ... into the extraArgs variable. The problem I have with this approach is that the arguments specified in the attribute set have to be duplicated. If in the future, I add an additional argument to the set, I may meet an unexpected result if I didn’t update the list accordingly.

Is there a way to accomplish the above without hardcoding the attribute names in the list? All I’m after is an attribute set that includes the contents of ... and nothing else.

You can use functionArgs in a somewhat convoluted way:

let
  f = { pkgs, arg1, arg2, ... }@args: let
    extraArgs = builtins.removeAttrs args extraArgNames;
  in # ...;
  extraArgNames = builtins.attrNames (builtins.functionArgs f);
in f

Adds an extra level of indentation and yuckiness but it works just fine.

Woah, the scoping on that makes my head hurt. If you add several dozen lines into the function then it gets even worse since the declaration and usage move further apart. It does, however, meet the intended goal :stuck_out_tongue: