I’m starting to sense that the community is potentially at risk of one day fracturing into two distinct factions the longer that flakes linger as an unstable novelty. On the one hand, flakes offer an integrated approach to a problem that many people have tried to solve using quite a few external tools introduced throughout the years. For those who have jumped on the bandwagon, flakes, while far from perfect, seem like the proper approach, at least in theory.
After all, why should we delegate revision management and modularization to an external tool when this is really a core language problem? For many, myself included, using an external tool just feels like the wrong way to do things, and we’ve taken up an active role in evangelizing flake usage, if for no other reason than to flesh out their problems and bring a stronger final product to a stable release.
On the other hand, it’s clear there are some warts that make using flakes quite unattractive for long timer nixers, and their complaints are far from irrelevant. Many respected members of the community seem to have taken up quite a negative view on flakes, and their stance seems justified in many respects.
Rather than letting the division fester and grow into something more sinister, why not attempt to bring these two viewpoints together and find a compelling solution that addresses the problem of flakes head on?
A nice end goal for this thread would be some form of draft RFC to fix what currently urks the community about flakes so we can finally have a proper solution to the problems that they try to address. The faster we can get a solution into a stable release, the less chance we have of something like a hard fork dividing the community.
Of course solving what’s wrong with flakes isn’t a trivial problem, and that’s probably got something to do with why many of us have put it off until now. I’ll try to kick things off with a few of the issues I’ve experienced with flakes since they were first introduced.
I understand time is precious, and especially for those not to invested in flakes, it may not seem worth the effort, but voicing your opinion here will give us more insight into how to properly address this going forward.
I’ll start with a list of a few things I really feel need to be improved before a stable release is cut:
While flakes work fairly nicely at the top-level of a project, they really fall short when attempting to use them from inside the project as a sort of module layer. If you put in enough (quite a bit of effort really), you can actually do some pretty cool things with subflakes, like modularizing your dependency structure, i.e.
inputs. This allows a cleaner solution to the miriad of
fetch*functions in nixpkgs, as one can simply point the
srcof a derivation to an input.
However, the interface is anything but intuitive at the moment. One must continually specifying
flake = falsefor every input that you wish to use as a package source. I’m starting to think that maybe we should have a separate notion entirely to complement flakes. Something that is very similar to a
flake.nixbut isn’t directly accessible to the outside world the way subflakes are currently.
Maybe there could even be a few different types of interal subflakes (or modules if you prefer), all hidden from the outside world by default and cleanly referencable from the top-level
sources.nixfor packages sources, a
mod.nixfor interal library functions, a
pkgs.nixfor logically related package definitions, etc. Each one should be known to Nix in advance and easily referenced in a flake url. Maybe you could name the file whatever you want, and specify it’s module type in the flake uri itself, e.g.
Solving this problem nicely might put the argument to rest that flakes only make sense if we decentralize nixpkgs. A solution of this kind would allow us to keep the monorepo in tact, while having a clear and idiomatic modularization paradigm.
Another annoyance I’ve run into is the restrictions on specifying inputs themselves. I realize these restrictions are in place for a very good reason, i.e. to prevent impurity from leaking in. But really, all I want to do is specify inputs in a less verbose way. One solution might be to allow inputs to be optionally specified in a list, or imported from a
inputs.tomlfile in the toplevel that only contains a list of flake uris. So instead of
inputs.someInput.url = "git:some/git/ref";, it could be
inputs = [ "git:some/git/ref" "github:owner/repo/branch" ];.
It seems like a missed opportunity to go to the trouble of defining a nice uri spec for flakes, only to require such a verbose declaration before you can actually use it. Combined with the different module types mentioned in the previous bullet point, we could avoid having to repetively specify things like
flake = falseby giving sane defaults to inputs of a given type.
I’ll leave it at that for now, as this has taken longer than I initially planned and I’m gettng pretty tired, but I hope we can all come together on this and produce a final product we can all be glad to use. I may update this list later with some additional insights, but hopefully it’s enough to get the conversation started.