Unpopular opinion: Maybe `stateVersion` shouldn't exist at all

there could be differentiation between what modules are obviously needed to be enabled for the functionality of another module ( and not suspected to change much over time ) and what needs granularity.

Haven’t read most of this thread; just here because I was pinged by:

which is just a huge misrepresentation. See https://github.com/NixOS/nixpkgs/pull/509450 for the sort of docs I think stateVersion ought to have.

6 Likes

I think your own statements on the thread misrepresented yourself

but great, as long as it gets documented properly and not shoved off to code, since code is not ever acceptable documentation.

1 Like

I currently stand by those statements as well (ā€˜for implementation details’ and ā€˜that repeats the code’ are meaningful qualifiers!), and believe that the implementation I’ve proposed is consistent with both. I’m happy to engage on the nuances and potentially further evolve my position if and only if you want that, but maybe it’d be best to do so in another thread or a private channel.

4 Likes

Though note that it’s still used in Postgres (I guess you did say ā€œmostā€ for a reason.)

2 Likes

Maybe I’m confused, but I think the whole point of having a programs.*.enable is to set other options and do more configuration generally. Otherwise you would just add the package to environment.systemPackages directly, no?

When the point is the magic, why define the same behavior multiple places within nixpkgs? Generally code reuse and DRY would be considered a good architectural design, I think, and the nuts/bolts are still there to play with if you are a user that wants to see and use the plumbing directly.

2 Likes

These release notes? They have stateVersion all over them.

I only see mentioned explicitly a few times ( at least in the latest release ).

I don’t really see the point in having this thread another time. The current situation sucks, yes, but we have good proposals for fixing it. @rhendric 's PR is kind of the last possible word on the topic of stateVersion.

Once/if it lands, and other modules adopt the same pattern, the issue will already be largely resolved through better documentation, and long-term removal becomes much more feasible. The only thing that’s left to do is actual work.

If you haven’t read the thread, this one (and its linked predecessors) likely covers everything you want to say: Incrementally salvaging stateVersion

4 Likes

Interesting, back when I tried to bump it years ago, at least the releases I bumped over did not have any mention, though I do not remember which those were. I concluded it would be for all other notes as well, but indeed there are ~70 mentions currently on the linked site.

I see what you mean. I also know that Hyprland needs this to work, but the only issue is that this chain-initiation is the default behavior I’ve been emphasizing throughout this post. No one can be 100% certain that this default behavior will still make sense 10 years from now, which is why stateVersion was introduced, to ensure future compatibility with the current defaults. That’s why I keep stressing the importance of module transparency and documentation. In my view, modules should be atomic. Even if one module needs to depend on another, the maintainer shouldn’t merge the two. That’s something the user should handle. This might sacrifice user-friendliness for now (though documentation can make up for that), but it ensures maintainability in the future.

English isn’t my first language, so I had an LLM review my wording. Do you have a problem with that?

I’ve read it, and as I mentioned in my previous reply, I do agree that this PR serves as a ā€œtransitional solution.ā€ However, I have reservations about treating it as a ā€œfinal solution,ā€ because the module is still attempting to maintain this compatibility, albeit by shifting the anchor from the global stateVersion to the local stateVersion. Maintainers should remain cautious about these unsustainable if-else statements.

Yes, from a user-friendliness perspective, this is ok. The average user probably doesn’t care at all about what these switches do behind the scenes; as long as they work, that’s all that matters.
However, for maintainers, they’re in for a maintenance nightmare. They’re not only maintaining current modules but also historical ones. I have a very bold prediction: if nixpkgs continues to exist in the future, eventually all modules will inevitably try to reference stateVersion because they all have default values. Given enough time, these defaults are likely to change, and once they do, you’ll have to reference stateVersion.
And as you say that if users want full control, they can just use the basic components. But the problem is, how do you know what the default behaviors of each module are? The answer is you don’t. So you’d have to dig into the source code to check the default values of every module you use and see if they match your expectations. When users want more control, they have to delve deep into the code and become Nix experts. I think this clearly puts the cart before the horse when it comes to user-friendliness.

1 Like

The trick is, and what you would know if you had read the other threads completely, ultimatively remove individual modules state versions, step by step with clear migration paths.

Really not providing defaults anymore for things that can not have a default.

With the regular deprecation process.

This ultimatively will reduce stress on the poeple who actually have to migrate their systems.

1 Like

Oh, sorry, I was indeed focused on replying to my own post. I read that post yesterday, so there might be some parts I’ve forgotten or overlooked. I’ll take a closer look at it later.

1 Like

I don’t believe you that you used the LLM only to review your wording.

1 Like

Believe what you want, my friend. It’s clear you’re more interested in laughing at my wording than the actual technical discussion. Anyway, I’m going to assume you have more important things to do. Or if you don’t, I certainly do. Goodbye.

NixOS, like many functional programming (FP) projects, are in pursuit of some form of mathematical perfection. Yet the ultimate purpose of any software is to be useful for human beings. stateVersion, similar to --impure, are ugly escape hatches from an otherwise ā€œpureā€ system. People want escape hatches and their needs are real.

There are people in the world who want the declarative feature of Nix, the most up-to-date software from nixpkgs, but lack spare time (or ā€œOCDā€) to be reading release notes every day. A project might say to these people ā€œyour needs are insatiableā€ and they’d be right. But those projects tend to never catch on. Other projects respond with ā€œwell ok here’s your escape hatchā€ā€”you end up with an ugly feature which adds complexity and costs developers hours to maintain. Millions of people will rely on it, often thanklessly.

In other words, yes it’s actually a popular discussion that stateVersion should be reworked or removed. Though it may very well be because of stateVersion’s imperfect design that NixOS gained enough traction over the years and found people like us to argue over it.

I normally just do stateVersion = builtins.substring 0 5 nixpkgs.lib.version; in my flake.nix and inherit it for every configuration.