The day that NixOS will not poop out a stack trace about the internals of modules.nix when you make an infinite loop that doesn't mention a single file that you touched will be the day we go mainstream.
Like. Can we say with good conscious this is a good experience if you make a trivial beginner mistake? This error tells me NOTHING. it doesn't even mention the file or line I touched.
The most frustrating part is that this stacktrace seems to crash at a part that is clearly designed to print out useful error messages?
"while evaluating the option ${showOption loc}"
So I guess somebody tried to fix this? but fucked up?
"Sorry but we crashed trying to tell you the thing we want to tell you"
Okay thanks man
@joepie91 config.networking.hostName is not a NixOS Module system expression; it's a host language expression. So there is tight coupling there.
@joepie91 Lazy evaluated languages make it really easy to make eDSLs like this. But it means that errors of the host language leak into your DSL language. And that's a downside of the eDSL approach.
@arianvp Hmm. Could this hypothetically be addressed by exposing more introspection capabilities for the language semantics, so that the eDSL evaluator can make use of the host language's features but still have sufficient insight into and control over its semantics that it could produce credible error messages?
@joepie91 sure can. And we already do a bit of that. e.g. we added `builtins.unsafeGetAttrPos`
@arianvp So we "just" need a well-considered set of introspection capabilities with sufficient coverage of language semantics, basically?
(I say this with a feeling of dread about Nix core getting this kind of stuff right... 😐 )
@arianvp @joepie91
We might be able to add a `fix`-like builtin that emits a custom error message so that the module system could add a hint to the error message about what to do instead. Instead of the error message being a mere string, we could allow the module system to pass a function so that we can temporarily give it dark powers like inspecting the trace and seeing whether a given expression is a thunk or not. By passing such a function as an argument to the custom error message function, it can't leak or contaminate the heap, so resuming evaluation as in --keep-going is still safe.
> Nix core
I think you're referring to a past team that never really got off the ground. We now have the _Nix team_ instead, which is doing a good job. Nix isn't bus factor 1 anymore, with multiple maintainers capable of doing good reviews and merges, and we're still growing and improving.
> so that we can temporarily give it dark powers
That's also the sort of thing I was thinking about, yes. To get *really* good error messages, that can be independently developed and improved from within the module system (without requiring upstream review for every change, which would make this nonviable) it would need pretty wide-ranging access to the runtime semantics.
That wide-ranging access could (and probably should!) be restricted to error conditions, though, to ensure that typical evaluation semantics don't get modified by 'clever' hacks too much.
> I think you're referring to a past team that never really got off the ground.
Possibly. I'm wary of promises of improvement due to those promises having been made several times in the past, and it turning out that many of the same systemic issues were still present. The bus factor was a major issue, true, but not the *only* one either.
So this has become an "I'll believe it when I see it" sort of thing - I can certainly be convinced that things have improved, but only through sustainable visible improvements, not just promises and ideas :) Trust takes time and effort to regain.
@joepie91 @arianvp The callback approach basically gives you that.
> I'll believe it when I see it
Of course.
Two things are true here:
- It's up to the project to show that it is capable of improving, e.g. accepting new maintainers, merging good contributions
- It's up to the community to help out where they can. Nix maintenance is still largely a volunteer effort
@joepie91 The problem here is that the eDSL evaluator doesn't fully specify the semantics. We use the host language for part of the semantics (most prominently tying the recursive knot).
We could go the bazel way and make targets strings "//config/networking/hostName" and then resolve those in the Module System evaluator. But instead we make use of the host language and type config.networking.hostName. This means this is hard to solve