Nix is an expression language, not a programming language. The end result of any piece of code must always be a value.
Whatâs the value of your expression when options.location.atHome = true?
Itâs undefined? Thatâs not legal. Therefore, an if expression must always have an else branch.
The next part of your confusion is that the return value of your expression is an attrset binding which is not a valid data type in Nix. You can only do it the other way around; bind an attrset key to the value of an expression like this:
{
foo = if cond then "bar" else "baz";
}
You could use lib.optionals as @jlode mentioned. Itâs effectively the same as
networking.nameservers = if (options.location.atHome == false) then
[ "9.9.9.9" "149.112.112.112" ]
else
[ ];
For NixOS module purposes, there is the mkIf function which effectively âunsetsâ the value if the condition is false.
This would be considered cleaner since youâre explicitly saying that the value should only be touched if the condition is true; with optionals youâd explicitly be setting the value to [ ] eventhough you didnât intend to set it at all.
Some people have written themselves a mkIfElse wrapper for this purpose. I proposed it should be added to Nixpkgs but I donât think that has happened yet.
I get errors: error: attribute 'config' already defined at /etc/nixos/file.nix I have read that there can be only one config, so is two working a side effect or something?
Where can I read up on the mkMerge?
I have also tried putting mkMerge on top â that worked.
Now i have
Yup, thatâs the expected solution to the first half of this post.
In Nix, lib.mkIf !atHome is parsed as âexproperatorexprâ, and ! isnât an infix binary operator. When using ! or prefix - at the beginning of an argument to a function, you need to wrap it in parentheses (much like Haskell, if youâre familiar): lib.mkIf (!atHome).