Nix functions declaration:
| ie. declaration |
|
ie. call |
f = a: a + 1 |
takes one numerical arg a |
f 42 |
f = a: a + "1" |
takes one string arg a |
f "42" |
f = a: a ++ [1] |
takes one list arg a |
f [42 43] |
f = a: a.b + 1 |
takes one attr set a, with b attr |
f { b = 42; } |
f = { b }: b + 1 |
takes one attr set a, with b attr |
f { b = 42; } |
|
but fails with unknown attrs |
f { b = 42; c = 43; } |
f = { b, ...}: b + 1 |
ignores unknown attrs |
f { b = 42; c = 43; } |
f = { b, ...}@a: b + 1 + a.c |
put all attrs in a |
f { b = 42; c = 43; d = 44; } |
f = { ... }: 1 + 1 |
ignore all attrs, but has to be attr set |
f { b = 42; } |
note: nix functions always takes one argument only, but this one argument can be an attr set with N attrs. Alternatives to expecting more arguments are expecting a list and currying (a function that returnas a function like: a: b: a +b).
Nix Modules Declaration:
Nix modules is a framework, used by NixOS, that not only imports your config files, but does other funkier things likes validation (ie an config has to be declared as option before it is used), merge, etc.
Modules examples:
{ # no args at all
imports = [ ./otherModule.nix ];
programs.firefox.enable = true;
}
ARGS: { # ses previous table
imports = [ ./otherModule.nix ];
myConfig = true; # only fails because myConfig isn't defined
}
- Function with options (when defining your own options)
{lib, config, ...}: {
imports = [ ./otherModule.nix ];
options.myConfig = lib.options.mkEnableOption "MyConfig"; # see also mkOption
# now the previous example works
# This is the same as `programs.firefox.enable` of first example,
# but since this files has `options`, it requires `config` prefix to set configs
config.programs.firefox.enable = config.myConfig;
# ^-- this `config` and this other --^, have same name are different,
# first one is what we set,
# the second one is what some one, some else will set and came from arguments
}
What arguments:
Most commons are pkgs, lib and config, but docs, say there is also options
We can define new arguments where Nix Modules framework is used (NixOS, Home-Manager, DevShell, DevEnv, etc):
nixpkgs.lib.nixosSystem {
modules = [ ./configuration.nix ];
system = "x86_64-linux";
specialArgs = { inputs = inputs; };
};
Now all my nix modules has an attr in argument inputs; while is common for flake users to do the same, modules expecting inputs in argument will only work for them, affecting reusability of your modules with other non flake users or even flake users who doesn’t set this argument.
There is another way to add arguments to modules, by setting it in any module.
{
_module.args.myArg = 2;
}
Note that arguments defined this way cannot be used for imports
{ inputs, myArg, ...}:
{
imports = [
./${inputs.someFlakeDep}/otherModule.nix # may work if planets are aligned
./${myArg}/otherModule.nix # fail for sure
];
}