Why flake must be trivial?

Is there any particular reason why nix flake definition have to be “trivial”?
In particular, why error: flake configuration setting 'foo' cannot be a thunk?

  nixConfig = {
    foo = "${123}";
  };

This is only true for specific attributes. I only knew of inputs, but it seems nixConfig is another.

Keeping them simple forces people to avoid complexity. These attributes are meant to be concise and simple, having them simple like this is preferable.

Note that this isn’t true for outputs, which is where the majority of flake stuff happens anyways.

What exactly are you trying to set in your nixConfig?

It’s to ensure that Nix can obtain the metadata of a flake (such as its inputs) without having to execute a Turing-complete program that may not terminate. That is, a command like nix flake info should finish in some bounded amount of time.

The alternative was to put the metadata in a separate json/toml file but that seemed inconvenient to me.

This restriction could be lifted/relaxed in the future.

11 Likes

As an aside, flakes present an interesting challenge when trying to use them as self-executing polyglot scripts because of this limitation.

2 Likes

To add to Eelco’s post: same reason that Python moving from setup.py to pyproject.toml.

4 Likes

If we “just” implement typed nix with coeffects or some fancy bounded linear logic we can limit the work done for these flake attrs without limiting them to trivial exprs! Shouldn’t take more than a decade.

4 Likes

I’ll just chime in and say that I would really like to see this restriction lifted. I’ve been working on a tool using flakes where the ability to modify inputs programmatically stored in e.g. a JSON file would be very helpful.

I’m currently in the process of implementing a system generating my flake.nix in a pre-commit hook to get around this problem…

1 Like

Check out GitHub - vic/flake-file: Generate flake.nix from module options., it allows you to get around this restriction

In my case it would be awesome if nixConfig would be a function of inputs. This would let me set pre build hook, for example, to something like output of other flake.