{
a = 1;
b = <if stars align and enough goats have been sacrificed> 2;
c = 3;
}
to evaluate to one of
{ a = 1; b = 2; c = 3; }
{ a = 1; c = 3; }
depending on whether the stars have aligned and enough goats have been sacrificed.
In the past I have used all sorts of ugly and long-winded hacks to implement such things, and I’d like to start using some clean, canonical mechanism … and it’s taking me far too long to find a satisfactory answer in the docs.
What is a sensible way of doing this sort of thing?
If you can use lib from nixpkgs the most common way would be the first example, if you haven’t, you had to use the second (or hide behind a function yourself):
{a = 1; c = 3} // lib.optionalAttrs cond {b = 2;};
# ---
{a = 1; c = 3} // if cond then {b = 2;} else {};
I basically need an unique symbol that I know nobody else will use in their libraries. With algebraic data types, Maybe or Option would do the trick; in dynamic languages I’d use gensym in Lisp, or create a new type with a single instance in Python (or just use my_none = object()). I just need a mechanism for creating something that is guaranteed to be unequal to anything that already exists.
This is agonizing. I’ve been wanting (and not managed) to find the time to grok the module system for ages. The temptation to spend time on it now is huge, but I’m getting too many levels away from the immediate problem that I need to solve … soon.
One thing: I came to Nix for the statelessness, so anytime I see <nixpkgs ...> I run away in terror; can your test.nix example somehow be made more flaky?
The current state of Nix is far from ideal, but considering that Flakes is still experimental and will likely change considerably in the future, I prefer recommending stable ways of pinning Nixpkgs instead:
let
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/af21c31b2a1ec5d361ed8050edd0303c31306397";
lib = import (nixpkgs + "/lib");
in lib.evalModules {
...
}