Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add attrpath notation equivalent to elemAt #10949

Open
rhendric opened this issue Jun 23, 2024 · 1 comment
Open

Add attrpath notation equivalent to elemAt #10949

rhendric opened this issue Jun 23, 2024 · 1 comment
Labels
feature Feature request or proposal language The Nix expression language; parser, interpreter, primops, evaluation, etc

Comments

@rhendric
Copy link
Member

Is your feature request related to a problem? Please describe.

I'm in a REPL. I'm exploring parts of Nixpkgs. I type a partial expression:

nix-repl> someExpr.foo
{ bar = { ... }; ignoreThis = { ... }; moreStuff = { ... }; }

I hit up-arrow and keep typing to drill deeper:

nix-repl> someExpr.foo.bar
{ baz = true; qux = [ ... ]; quux = { ... }; }

nix-repl> someExpr.foo.bar.qux
[ { ... } ]

nix-repl> someExpr.foo.bar.qux.0
error: attempt to call something which is not a function but a list

       at «string»:1:1:

            1| someExpr.foo.bar.qux.0
             | ^

Of course that doesn't work. I don't actually type that. What I actually do is hit up-arrow, then hit Home, then type builtins.elemAt, then hit End, then type 0.

nix-repl> builtins.elemAt someExpr.foo.bar.qux 0
{ greatMoreStuff = { ... }; }

Now what do I get to do? That's right, hit up-arrow, then hit Home, then type (, then hit End, then type ).greatMoreStuff.

It's a tiny papercut of a problem, but it makes me die a little every time I see a list in a complicated Nix expression. In many other languages with left-to-right dotted accessor syntax, I'd be able to write someExpr.foo.bar.qux[0].greatMoreStuff, or someExpr.foo.bar.qux.0.greatMoreStuff. Why not in Nix?

Describe the solution you'd like

I'd like the Nix attrpath grammar rule to be extended with some notation that's equivalent to builtins.elemAt, such as attrpath.0, attrpath[0], attrpath@0 if you like—any available syntax is fine with me as long as the result is still an attrpath, and thus can be extended with more attribute selectors without enclosing the entire previous base expression plus attrpath in parentheses the way that (builtins.elemAt ... 0).greatMoreStuff requires. I would even be happy with reusing the existing syntax attrpath.${0} and supporting integers applied to lists with that in addition to strings applied to attrsets.

Describe alternatives you've considered

Not caring about the tiny details that make Nix uncomfortable relative to other languages.

Additional context

I imagine this needs an RFC, given NixOS/rfcs#148, but I wanted to float this here first to see if there's an instant hell-no.

Priorities

Add 👍 to issues you find important.

@rhendric rhendric added the feature Feature request or proposal label Jun 23, 2024
@roberth
Copy link
Member

roberth commented Jun 29, 2024

I personally think the cost benefit works out slightly in favor of having this feature.
It's rare to need elemAt, and most functions should not use it, but it's useful in the repl.

We don't get to change usable syntax (perhaps until NixOS/rfcs#137), so we don't have a lot of choice.

attrpath.0

Unfortunately, this is equivalent to attrpath .0, a function application with argument 0.0.

attrpath[0]

Same, but with a list.

attrpath@0

Currently an @ always creates a binding. I'd like to reserve it for that purpose.

attrpath.${0}

This would make type inference worse (e.g. in https://github.com/oxalica/nil), as the lhs can be a list or attribute set, and the rhs can be an int or string. Also the property that the types need to match up may be hard to express in a type system.

How about...

  • attrpath.$[0]

It being distinct makes type inference easy, and helps readers.

[ reminds of lists, and $[ is still available as far as the grammar's concerned.

@roberth roberth added the language The Nix expression language; parser, interpreter, primops, evaluation, etc label Jun 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Feature request or proposal language The Nix expression language; parser, interpreter, primops, evaluation, etc
Projects
None yet
Development

No branches or pull requests

2 participants