[fluff] what do you think of this unintuitive Nix expression

I think the Nix language has a bunch of unintuitive sharp corner cases.
I tried to make a short expression that contains a few of them, to confuse.

{ a ? f ? a, f, g }:
  with { x = "a"; g = _: g; };
  !f a ? x && g x a
1 Like

The intended counterintuitive things are:

  • The first ? refers to defaulting the argument, the second ? refers to checking if f has an a entry
  • That you can refer to other arguments in argument defaults
  • The second a does not refer to the first a
  • That either:
    • f, which is a function, can be used as the left-hand side of ? without error
    • f is a functor which can be called and used as an attrset
  • That ! applies to f a ? x and not f, f a, or f a ? x && g x a
  • The x in the right-hand side of the last ? does not refer to the x from the with, but the x in g x does
  • The g after the && does not refer to the g from the with
1 Like

Same as I think with most languages; you’re not really going to see these edge cases in “real” code, so they aren’t particularly impactful in day-to-day use. You can write unreadable gobeldygook in all languages, see codegolfing. The lack of variable names and clear purpose only obfuscates it more.

I think the difficulty of finding the origin of error messages, especially in conjunction with NixOS, is far more of an issue.

with and ? are definitely known to be a bit confusing, though. with especially is considered an antipattern, you’ve not even shown the worst. Explicitly named variables having priority is pretty easy to grok once you’ve come across it, but what happens if you have two withs that share an attribute name?

2 Likes

I didn’t want to say Nix is more unintuitive! It’s just a bit of fun to bring out all the sharp corners of the language.

1 Like