From 1cbffdbd9cf1ee0192949faa1f377b6977a6bf88 Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Sun, 17 Oct 2021 18:35:34 -0700 Subject: [PATCH 01/14] Add "inherit-as-list" syntax construct to the Nix language --- rfcs/0110-inherit-as-list.md | 120 +++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 rfcs/0110-inherit-as-list.md diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md new file mode 100644 index 000000000..d1a3436bc --- /dev/null +++ b/rfcs/0110-inherit-as-list.md @@ -0,0 +1,120 @@ +--- +feature: inherit-as-list +start-date: 2021-10-17 +author: Ryan Burns (@r-burns) +co-authors: (find a buddy later to help out with the RFC) +shepherd-team: (names, to be nominated and accepted by RFC steering committee) +shepherd-leader: (name to be appointed by RFC steering committee) +related-issues: (will contain links to implementation PRs) +--- + +# Summary +[summary]: #summary + +This RFC proposes a new Nix syntax `inherit () [ ]`, which +constructs a list from the values of an attrset. + +The goal is to provide a similarly-terse but more principled alternative +to the often-used `with ; [ ]`. + +# Motivation +[motivation]: #motivation + +It is currently cumbersome to create a list from the values of an attrset. +If one has an attrset `attrs` and wishes to create a list containing some of +its values, one could naively write: + +```nix +[ attrs.a attrs.b attrs.c ] +``` + +To avoid typing `attrs` many times, one will typically use `with` instead: + +```nix +with attrs; [ a b c ] +``` + +However, the `with` expression has many well-known drawbacks, such as +unintuitive shadowing behavior [1], prevention of static scope checking [2], +and reduced evaluation performance [2]. + +* [1] https://github.com/NixOS/nix/issues/1361 +* [2] https://github.com/NixOS/nixpkgs/pull/101139 + +Nonetheless, Nix expression authors are subtly guided toward the `with` form +because it is (or at least appears) simpler than any existing alternatives. + +The goal of this RFC is to provide a similarly-terse alternative which avoids +these drawbacks. + +# Detailed design +[design]: #detailed-design + +The proposed expression syntax is: + +```nix +inherit (attrs) [ a b c ] +``` + +The `inherit` keyword is intentionally reused so as to not add any new +keywords to the Nix grammar. + +As this expression is currently a syntax error, a Nix interpreter which +supports this language feature will be compatible with existing Nix code. + +An implementation PR is pending. + +For MVP functionality, only minor additions to `src/libexpr/parser.y` are +needed. If accepted, the changes to the Nix interpreter can be backported +to current releases if desired. Relevant language documentation and +third-party parsers/linters would also need to be updated. + +# Examples and Interactions +[examples-and-interactions]: #examples-and-interactions + +This would be useful for many languages and frameworks in Nixpkgs which +extract packages from a package set argument. + +For example, `python3.withPackages (ps: inherit (ps) [ ... ])` will serve as a +more fine-grained alternative to `python3.withPackages (ps: with ps; [ ... ])`. +This would apply similarly to `vim.withPlugins`, `lua.withPackages`, etc. + +Certain list-typed `meta` fields could also make use of this feature, e.g.: +```nix +meta.licenses = inherit (lib.licenses) [ bsd3 mit ]; +meta.maintainers = inherit (lib.maintainers) [ johndoe janedoe ]; +``` + +And build inputs which are commonly extracted from attrsets: +```nix +buildInputs = inherit (darwin.apple_sdk.frameworks) [ + IOKit +] ++ inherit (llvmPackages) [ + llvm +]; +``` + +# Drawbacks +[drawbacks]: #drawbacks + +* This will add complexity to the Nix grammar and any third-party tools which + operate on Nix expressions. +* Expressions reliant on the new syntax will be incompatible with + Nix versions prior to the introduction of this feature. + +# Alternatives +[alternatives]: #alternatives + +* Skillful use of `with` to avoid its drawbacks +* Fine-grained attribute selection via existing (more verbose) language + features, such as `builtins.attrValues (inherit (attrs) a b c;)` + +# Unresolved questions +[unresolved]: #unresolved-questions + +How would this feature be adopted, if accepted? + +# Future work +[future]: #future-work + +Determine best practices regarding when this language construct should be used From 7886f942406ae2f0701a053831ca4a25b9057142 Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Sun, 17 Oct 2021 19:07:44 -0700 Subject: [PATCH 02/14] Add more with-expression notes --- rfcs/0110-inherit-as-list.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index d1a3436bc..4637c8a63 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -35,14 +35,19 @@ with attrs; [ a b c ] ``` However, the `with` expression has many well-known drawbacks, such as -unintuitive shadowing behavior [1], prevention of static scope checking [2], -and reduced evaluation performance [2]. +unintuitive shadowing behavior [1][2], prevention of static scope checking [3][4], +and reduced evaluation performance [3]. -* [1] https://github.com/NixOS/nix/issues/1361 -* [2] https://github.com/NixOS/nixpkgs/pull/101139 +* [1] https://github.com/NixOS/nix/issues/490 +* [2] https://github.com/NixOS/nix/issues/1361 +* [3] https://github.com/NixOS/nixpkgs/pull/101139 +* [4] https://nix.dev/anti-patterns/language#with-attrset-expression Nonetheless, Nix expression authors are subtly guided toward the `with` form because it is (or at least appears) simpler than any existing alternatives. +Some alternatives are suggested in +https://nix.dev/anti-patterns/language#with-attrset-expression, but as these +are more verbose and complex than `with`, they are rarely used. The goal of this RFC is to provide a similarly-terse alternative which avoids these drawbacks. From de1c4d2974318173a42edf4e13bebc28084b39d7 Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Sun, 17 Oct 2021 19:52:51 -0700 Subject: [PATCH 03/14] Fix code examples syntax --- rfcs/0110-inherit-as-list.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index 4637c8a63..1d539165d 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -92,11 +92,11 @@ meta.maintainers = inherit (lib.maintainers) [ johndoe janedoe ]; And build inputs which are commonly extracted from attrsets: ```nix -buildInputs = inherit (darwin.apple_sdk.frameworks) [ +buildInputs = (inherit (darwin.apple_sdk.frameworks) [ IOKit -] ++ inherit (llvmPackages) [ +]) ++ (inherit (llvmPackages) [ llvm -]; +]); ``` # Drawbacks @@ -112,7 +112,7 @@ buildInputs = inherit (darwin.apple_sdk.frameworks) [ * Skillful use of `with` to avoid its drawbacks * Fine-grained attribute selection via existing (more verbose) language - features, such as `builtins.attrValues (inherit (attrs) a b c;)` + features, such as `builtins.attrValues { inherit (attrs) a b c; }` # Unresolved questions [unresolved]: #unresolved-questions From 1d1ffeb563842ac240f54ac6a77e4231eb536284 Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Mon, 18 Oct 2021 21:52:05 -0700 Subject: [PATCH 04/14] Update proposed syntax to be more consistent with existing inherit --- rfcs/0110-inherit-as-list.md | 62 ++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index 1d539165d..f5261338b 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -11,8 +11,8 @@ related-issues: (will contain links to implementation PRs) # Summary [summary]: #summary -This RFC proposes a new Nix syntax `inherit () [ ]`, which -constructs a list from the values of an attrset. +This RFC proposes a new Nix syntax `[ inherit () ; ]`, +which constructs a list from the values of an attrset. The goal is to provide a similarly-terse but more principled alternative to the often-used `with ; [ ]`. @@ -55,19 +55,29 @@ these drawbacks. # Detailed design [design]: #detailed-design -The proposed expression syntax is: +The proposed syntax is: ```nix -inherit (attrs) [ a b c ] +[ inherit (attrs) a b c; ] +[ inherit a b c; ] +``` + +These expressions are (respectively) syntactic sugar for: + +```nix +builtins.attrValues { inherit (attrs) a b c; } +builtins.attrValues { inherit a b c; } ``` The `inherit` keyword is intentionally reused so as to not add any new -keywords to the Nix grammar. +keywords to the Nix grammar, and to evoke the similarities with the +existing attribute-based inherit syntax. -As this expression is currently a syntax error, a Nix interpreter which -supports this language feature will be compatible with existing Nix code. +As the `inherit` keyword is currently a syntax error inside a list expression, +a Nix interpreter which supports this new language feature will be compatible +with existing Nix code. -An implementation PR is pending. +This RFC is implemented here: https://github.com/nixos/nix/pull/5402 For MVP functionality, only minor additions to `src/libexpr/parser.y` are needed. If accepted, the changes to the Nix interpreter can be backported @@ -80,25 +90,43 @@ third-party parsers/linters would also need to be updated. This would be useful for many languages and frameworks in Nixpkgs which extract packages from a package set argument. -For example, `python3.withPackages (ps: inherit (ps) [ ... ])` will serve as a +For example, `python3.withPackages (ps: [ inherit (ps) ...; ])` will serve as a more fine-grained alternative to `python3.withPackages (ps: with ps; [ ... ])`. This would apply similarly to `vim.withPlugins`, `lua.withPackages`, etc. Certain list-typed `meta` fields could also make use of this feature, e.g.: ```nix -meta.licenses = inherit (lib.licenses) [ bsd3 mit ]; -meta.maintainers = inherit (lib.maintainers) [ johndoe janedoe ]; +meta.licenses = [ inherit (lib.licenses) bsd3 mit; ]; +meta.maintainers = [ inherit (lib.maintainers) johndoe janedoe; ]; +``` + +List-inherits can be used multiple times in a list-expression, and intermingled +with ordinary list elements without needing to concatenate: + +```nix +buildInputs = [ + a b c /* ordinary list elements */ + inherit (pkgsFoo) d e f; + g h i /* ordinary list elements */ + inherit (pkgsBar) j k l; +]; ``` -And build inputs which are commonly extracted from attrsets: +Sinc attributes inherit from the current scope with `{ inherit a b c; }`, +this RFC proposes a corresponding list-inherit syntax which also inherits +from the current scope. So if the order of the ordinary elements in the +previous list is not significant, one could rewrite the list as: + ```nix -buildInputs = (inherit (darwin.apple_sdk.frameworks) [ - IOKit -]) ++ (inherit (llvmPackages) [ - llvm -]); +buildInputs = [ + inherit a b c; + inherit (pkgsFoo) d e f; + inherit g h i; + inherit (pkgsBar) j k l; +]; ``` + # Drawbacks [drawbacks]: #drawbacks From 2a6bbb49f1c724938776024c041b8b8ef8ef9818 Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Mon, 18 Oct 2021 21:56:01 -0700 Subject: [PATCH 05/14] Remove Nix syntax highlighting from proposed syntax snippets They are highlighted incorrectly as they are not currently valid Nix code --- rfcs/0110-inherit-as-list.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index f5261338b..0b07e32b1 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -57,7 +57,7 @@ these drawbacks. The proposed syntax is: -```nix +``` [ inherit (attrs) a b c; ] [ inherit a b c; ] ``` @@ -95,7 +95,7 @@ more fine-grained alternative to `python3.withPackages (ps: with ps; [ ... ])`. This would apply similarly to `vim.withPlugins`, `lua.withPackages`, etc. Certain list-typed `meta` fields could also make use of this feature, e.g.: -```nix +``` meta.licenses = [ inherit (lib.licenses) bsd3 mit; ]; meta.maintainers = [ inherit (lib.maintainers) johndoe janedoe; ]; ``` @@ -103,7 +103,7 @@ meta.maintainers = [ inherit (lib.maintainers) johndoe janedoe; ]; List-inherits can be used multiple times in a list-expression, and intermingled with ordinary list elements without needing to concatenate: -```nix +``` buildInputs = [ a b c /* ordinary list elements */ inherit (pkgsFoo) d e f; @@ -117,7 +117,7 @@ this RFC proposes a corresponding list-inherit syntax which also inherits from the current scope. So if the order of the ordinary elements in the previous list is not significant, one could rewrite the list as: -```nix +``` buildInputs = [ inherit a b c; inherit (pkgsFoo) d e f; From ad09702fd421f40b1e7a93f95cca15b342db0104 Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Tue, 19 Oct 2021 19:37:14 -0700 Subject: [PATCH 06/14] Simplify desugared form Before: ``` [ inherit (attrs) a b c; ] := builtins.attrValues { inherit (attrs) a b c; } ``` After: ``` [ inherit (attrs) a b c; ] := [ attrs.a attrs.b attrs.c ]; ``` The previous desugaring has some potentially nice properties such as non-significant ordering and no-duplicate enforcement, but was ultimately deemed unintuitive and too surprising in practical use. --- rfcs/0110-inherit-as-list.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index 0b07e32b1..dc06bc660 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -65,8 +65,8 @@ The proposed syntax is: These expressions are (respectively) syntactic sugar for: ```nix -builtins.attrValues { inherit (attrs) a b c; } -builtins.attrValues { inherit a b c; } +[ attrs.a attrs.b attrs.c ] +[ a b c ] ``` The `inherit` keyword is intentionally reused so as to not add any new @@ -112,17 +112,15 @@ buildInputs = [ ]; ``` -Sinc attributes inherit from the current scope with `{ inherit a b c; }`, -this RFC proposes a corresponding list-inherit syntax which also inherits -from the current scope. So if the order of the ordinary elements in the -previous list is not significant, one could rewrite the list as: +The order of the elements is preserved inside of and between inherits, +so the previous is exactly equivalent to ``` buildInputs = [ - inherit a b c; - inherit (pkgsFoo) d e f; - inherit g h i; - inherit (pkgsBar) j k l; + a b c + pkgsFoo.d pkgsFoo.e pkgsFoo.f + g h i + pkgsBar.j pkgsBar.k pkgsBar.l ]; ``` From 75cd80eb102975c7dc4e68b7e11ce41d0c13632a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 12 Jan 2022 15:27:34 +0100 Subject: [PATCH 07/14] Add shepherds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jörg Thalheim --- rfcs/0110-inherit-as-list.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index dc06bc660..c8e77aff6 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -3,8 +3,8 @@ feature: inherit-as-list start-date: 2021-10-17 author: Ryan Burns (@r-burns) co-authors: (find a buddy later to help out with the RFC) -shepherd-team: (names, to be nominated and accepted by RFC steering committee) -shepherd-leader: (name to be appointed by RFC steering committee) +shepherd-team: @synthetica9, @infinisil, @edolstra +shepherd-leader: @edolstra related-issues: (will contain links to implementation PRs) --- From 63ea2a18ccafffcf76a9db49ee0b3597f8f80f32 Mon Sep 17 00:00:00 2001 From: Ryan Burns <52847440+r-burns@users.noreply.github.com> Date: Tue, 5 Jul 2022 17:08:54 -0700 Subject: [PATCH 08/14] Update shepherd team + leader Co-authored-by: Kevin Cox --- rfcs/0110-inherit-as-list.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index c8e77aff6..1a832b8c9 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -3,8 +3,8 @@ feature: inherit-as-list start-date: 2021-10-17 author: Ryan Burns (@r-burns) co-authors: (find a buddy later to help out with the RFC) -shepherd-team: @synthetica9, @infinisil, @edolstra -shepherd-leader: @edolstra +shepherd-team: @synthetica9, @infinisil, @kevincox +shepherd-leader: @kevincox related-issues: (will contain links to implementation PRs) --- From f7730efee7e776bd9d35e3c93ac5e25e36034c2b Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Fri, 29 Jul 2022 00:33:49 -0700 Subject: [PATCH 09/14] Revise to list-like syntax proposed by Synthetica9 The new syntax is ``` attrs.[ a b c ] ``` as sugar for ``` [ attrs.a attrs.b attrs.c ] ``` --- rfcs/0110-inherit-as-list.md | 44 ++++++------------------------------ 1 file changed, 7 insertions(+), 37 deletions(-) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index 1a832b8c9..025a2f664 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -11,7 +11,7 @@ related-issues: (will contain links to implementation PRs) # Summary [summary]: #summary -This RFC proposes a new Nix syntax `[ inherit () ; ]`, +This RFC proposes a new Nix syntax `.[ ]`, which constructs a list from the values of an attrset. The goal is to provide a similarly-terse but more principled alternative @@ -58,22 +58,16 @@ these drawbacks. The proposed syntax is: ``` -[ inherit (attrs) a b c; ] -[ inherit a b c; ] +attrs.[ a b c ] ``` -These expressions are (respectively) syntactic sugar for: +This expression is syntactic sugar for: ```nix [ attrs.a attrs.b attrs.c ] -[ a b c ] ``` -The `inherit` keyword is intentionally reused so as to not add any new -keywords to the Nix grammar, and to evoke the similarities with the -existing attribute-based inherit syntax. - -As the `inherit` keyword is currently a syntax error inside a list expression, +As the token `.` immediately preceding `[` is currently a syntax error, a Nix interpreter which supports this new language feature will be compatible with existing Nix code. @@ -90,38 +84,14 @@ third-party parsers/linters would also need to be updated. This would be useful for many languages and frameworks in Nixpkgs which extract packages from a package set argument. -For example, `python3.withPackages (ps: [ inherit (ps) ...; ])` will serve as a +For example, `python3.withPackages (ps: ps.[ ... ])` will serve as a more fine-grained alternative to `python3.withPackages (ps: with ps; [ ... ])`. This would apply similarly to `vim.withPlugins`, `lua.withPackages`, etc. Certain list-typed `meta` fields could also make use of this feature, e.g.: ``` -meta.licenses = [ inherit (lib.licenses) bsd3 mit; ]; -meta.maintainers = [ inherit (lib.maintainers) johndoe janedoe; ]; -``` - -List-inherits can be used multiple times in a list-expression, and intermingled -with ordinary list elements without needing to concatenate: - -``` -buildInputs = [ - a b c /* ordinary list elements */ - inherit (pkgsFoo) d e f; - g h i /* ordinary list elements */ - inherit (pkgsBar) j k l; -]; -``` - -The order of the elements is preserved inside of and between inherits, -so the previous is exactly equivalent to - -``` -buildInputs = [ - a b c - pkgsFoo.d pkgsFoo.e pkgsFoo.f - g h i - pkgsBar.j pkgsBar.k pkgsBar.l -]; +meta.licenses = lib.licenses.[ bsd3 mit ]; +meta.maintainers = lib.maintainers.[ johndoe janedoe ]; ``` From 35da03c549a9d9a4ce0c2affef95ec97ae5a42f3 Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Sun, 6 Nov 2022 15:44:00 -0800 Subject: [PATCH 10/14] Add additional examples and clarifications for syntax rules --- rfcs/0110-inherit-as-list.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index 025a2f664..bb4679027 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -94,6 +94,20 @@ meta.licenses = lib.licenses.[ bsd3 mit ]; meta.maintainers = lib.maintainers.[ johndoe janedoe ]; ``` +Note that only simple textual attrnames are allowed in the square brackets. +For example, `pkgs.[ (openssl.overrideAttrs { patches = [ ... ]; }) ]` +is currently a syntax error, as is `pkgs.[ "${some_expression}" ]`, +`a.[ b.[ c d ] ]`, and `a.[ [ b c ] [ d e ] ]`. +Future RFCs may add additional support for useful idioms such as +`pkgs.[ python310 python310Packages.pytorch ]` on a case-by-case basis, +but that is not planned for this RFC. + +Other forms of syntax which were considered but are not proposed +in this RFC include: +* `[ inherit (attrs) a b c; ]` +* `[ inherit a b c; ]` +* `inherit (attrs) [ a b c ]` +* `pkgs.{ python = python310; openssl = openssl_3; }` # Drawbacks [drawbacks]: #drawbacks From 167602449d824f789cabdc4dbb1a0df6c347245a Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Mon, 7 Nov 2022 01:36:19 -0800 Subject: [PATCH 11/14] Add @bobvanderlinden to shepherd team --- rfcs/0110-inherit-as-list.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index bb4679027..6c66975ba 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -3,7 +3,7 @@ feature: inherit-as-list start-date: 2021-10-17 author: Ryan Burns (@r-burns) co-authors: (find a buddy later to help out with the RFC) -shepherd-team: @synthetica9, @infinisil, @kevincox +shepherd-team: @synthetica9, @infinisil, @kevincox, @bobvanderlinden shepherd-leader: @kevincox related-issues: (will contain links to implementation PRs) --- From d67d4422bfd91f5408dc0482b4ee33ddf71ec504 Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Sun, 11 Jun 2023 15:50:17 -0700 Subject: [PATCH 12/14] Add tables of alternatives discussed in this RFC An overview of alternatives and their drawbacks (including drawbacks to the syntax currently proposed) are provided in tables in the Alternatives section, as requested by the Nix team. These tables are intended to be an overview of some of the discussion in this RFC and will be updated as discussion continues. --- rfcs/0110-inherit-as-list.md | 49 +++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index 6c66975ba..415a11ff4 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -102,12 +102,8 @@ Future RFCs may add additional support for useful idioms such as `pkgs.[ python310 python310Packages.pytorch ]` on a case-by-case basis, but that is not planned for this RFC. -Other forms of syntax which were considered but are not proposed -in this RFC include: -* `[ inherit (attrs) a b c; ]` -* `[ inherit a b c; ]` -* `inherit (attrs) [ a b c ]` -* `pkgs.{ python = python310; openssl = openssl_3; }` +For a comparison of other forms of syntax considered but not proposed +in this RFC, refer to the Alternatives section. # Drawbacks [drawbacks]: #drawbacks @@ -120,9 +116,44 @@ in this RFC include: # Alternatives [alternatives]: #alternatives -* Skillful use of `with` to avoid its drawbacks -* Fine-grained attribute selection via existing (more verbose) language - features, such as `builtins.attrValues { inherit (attrs) a b c; }` +A number of alternatives have been considered, which can be roughly divided +into syntactic (introducing new syntax which requires changes to the Nix language +to parse) and non-syntactic. + +## Comparison of syntactic alternatives: + +Priority is given to syntax which would be "backwards compatible" with +existing Nix code, meaning that any existing code would be evaluated the +same under an interpreter supporting the new syntax. Conversely, +evaluating new code under an old interpreter which does not support the +new syntax would cause a syntax error. + + +| Syntax | Notes | Cons | +|---|---|---| +| `inherit (attrs) [ a b c ]` | Initial draft | ["confusing that for attribute sets, the inherit keyword is on the inside but here it is on the outside" -jtojnar](https://github.com/NixOS/rfcs/pull/110#discussion_r730527443) | +| `[ inherit (attrs) a b c; ]` | 2nd draft, [proposed by jtojnar](https://github.com/NixOS/rfcs/pull/110#discussion_r730527443) | ["not very happy with reusing inherit here. If I read inherit I read 'right, an attribute-set'." -Ma27](https://github.com/NixOS/rfcs/pull/110#issuecomment-947517675)
["There currently is no separator in lists, and this would add that." -Synthetica9](https://github.com/NixOS/rfcs/pull/110#issuecomment-959114390) | +| `attrs.[a b c]` | 3rd (current) draft, [proposed by Synthetica9](https://github.com/NixOS/rfcs/pull/110#issuecomment-959114390) | Has ["ambiguities [...] which would have to be worked out" -Synthetica9](https://github.com/NixOS/rfcs/pull/110#issuecomment-971760508)
["what `[a b c]` means depends on if it is after `attrs.`" -kevincox](https://github.com/NixOS/rfcs/pull/110#discussion_r933500003)
Needs care to limit scope of this rule, currently limited to single-identifier case (discussions [here](https://github.com/NixOS/rfcs/pull/110#discussion_r1001737515) and [here](https://github.com/NixOS/rfcs/pull/110#discussion_r1013099694)) | +| `[ with attrs | a b c ]` | [Proposed by nrdxp](https://github.com/NixOS/rfcs/pull/110#discussion_r933570815) | ["Looks more foreign", "may also cause confusion with other languages" -kevincox](https://github.com/NixOS/rfcs/pull/110#discussion_r934516433)
["introduces a small inconsistency" vs attribute-set `inherit` -rehno-lindeque](https://github.com/NixOS/rfcs/pull/110#discussion_r973033159) | +| Exclusive `with`, `let with` | [Proposed by infinisil](https://github.com/NixOS/rfcs/pull/110#issuecomment-1319338335) and [later refined](https://github.com/NixOS/rfcs/pull/110#issuecomment-1319338335) | Requires some dynamic behavior to fully replace `with`, including nested usage [-oxalica](https://github.com/NixOS/rfcs/pull/110#issuecomment-1334537982), [-infinisil](https://github.com/NixOS/rfcs/pull/110#issuecomment-1334593541)
May change semantics of existing Nix code | + +Some common threads here are the desire to introduce a syntax form which +is simpler and more ergonomic than existing `with` or alternatives, +naturally guiding users toward a "safer" form. We also desire consistency, +reusing keywords or syntax patterns but only where it would be +harmonious with the existing Nix language. + +## Comparison of non-syntactic alternatives: + +Other alternatives have been proposed where the motivation for `with` +deprecation is acknowledged, but would be resolved without introducing +new syntax to the Nix language. + +| Alternative | Notes | Cons | +|---|---|---| +| `builtins.attrValues { inherit (attrs) a b c; }` | Considered in initial draft | Verbose, cumbersome to compose, not order-preserving | +| `select [ "a" "b" "c" ] attrs` | [Proposed by ocharles](https://github.com/NixOS/rfcs/pull/110#issuecomment-952704340) | ["highlights wrong (strings are not data but literal variable names)" -7c6f434c](https://github.com/NixOS/rfcs/pull/110#issuecomment-952817547)
["`with` is slightly more ergonomic", "the proposed change is arguably same [...] but without semantical gotchas" -7c6f434c](https://github.com/NixOS/rfcs/pull/110#issuecomment-952931398) | +| Deprecation of list-types in NixOS modules and build inputs | [Proposed by infinisil](https://github.com/NixOS/rfcs/pull/110#issuecomment-959757180) | ["order of `buildInputs` is significant so unordered sets cannot be used" -jtojnar](https://github.com/NixOS/rfcs/pull/110#issuecomment-959799730) | # Unresolved questions [unresolved]: #unresolved-questions From d86951436b5961e4f0da48a522133d39d0f11321 Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Sun, 11 Jun 2023 16:03:50 -0700 Subject: [PATCH 13/14] Escape vertical bar character in table markdown --- rfcs/0110-inherit-as-list.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index 415a11ff4..492b3216e 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -134,7 +134,7 @@ new syntax would cause a syntax error. | `inherit (attrs) [ a b c ]` | Initial draft | ["confusing that for attribute sets, the inherit keyword is on the inside but here it is on the outside" -jtojnar](https://github.com/NixOS/rfcs/pull/110#discussion_r730527443) | | `[ inherit (attrs) a b c; ]` | 2nd draft, [proposed by jtojnar](https://github.com/NixOS/rfcs/pull/110#discussion_r730527443) | ["not very happy with reusing inherit here. If I read inherit I read 'right, an attribute-set'." -Ma27](https://github.com/NixOS/rfcs/pull/110#issuecomment-947517675)
["There currently is no separator in lists, and this would add that." -Synthetica9](https://github.com/NixOS/rfcs/pull/110#issuecomment-959114390) | | `attrs.[a b c]` | 3rd (current) draft, [proposed by Synthetica9](https://github.com/NixOS/rfcs/pull/110#issuecomment-959114390) | Has ["ambiguities [...] which would have to be worked out" -Synthetica9](https://github.com/NixOS/rfcs/pull/110#issuecomment-971760508)
["what `[a b c]` means depends on if it is after `attrs.`" -kevincox](https://github.com/NixOS/rfcs/pull/110#discussion_r933500003)
Needs care to limit scope of this rule, currently limited to single-identifier case (discussions [here](https://github.com/NixOS/rfcs/pull/110#discussion_r1001737515) and [here](https://github.com/NixOS/rfcs/pull/110#discussion_r1013099694)) | -| `[ with attrs | a b c ]` | [Proposed by nrdxp](https://github.com/NixOS/rfcs/pull/110#discussion_r933570815) | ["Looks more foreign", "may also cause confusion with other languages" -kevincox](https://github.com/NixOS/rfcs/pull/110#discussion_r934516433)
["introduces a small inconsistency" vs attribute-set `inherit` -rehno-lindeque](https://github.com/NixOS/rfcs/pull/110#discussion_r973033159) | +| `[ with attrs \| a b c ]` | [Proposed by nrdxp](https://github.com/NixOS/rfcs/pull/110#discussion_r933570815) | ["Looks more foreign", "may also cause confusion with other languages" -kevincox](https://github.com/NixOS/rfcs/pull/110#discussion_r934516433)
["introduces a small inconsistency" vs attribute-set `inherit` -rehno-lindeque](https://github.com/NixOS/rfcs/pull/110#discussion_r973033159) | | Exclusive `with`, `let with` | [Proposed by infinisil](https://github.com/NixOS/rfcs/pull/110#issuecomment-1319338335) and [later refined](https://github.com/NixOS/rfcs/pull/110#issuecomment-1319338335) | Requires some dynamic behavior to fully replace `with`, including nested usage [-oxalica](https://github.com/NixOS/rfcs/pull/110#issuecomment-1334537982), [-infinisil](https://github.com/NixOS/rfcs/pull/110#issuecomment-1334593541)
May change semantics of existing Nix code | Some common threads here are the desire to introduce a syntax form which From 7dbdd8e98a7acb633187737a39f759c1fe1120ea Mon Sep 17 00:00:00 2001 From: Ryan Burns Date: Sun, 11 Jun 2023 16:20:22 -0700 Subject: [PATCH 14/14] Update nix.dev links Linked content has moved to recipes/best-practices --- rfcs/0110-inherit-as-list.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rfcs/0110-inherit-as-list.md b/rfcs/0110-inherit-as-list.md index 492b3216e..c104fe439 100644 --- a/rfcs/0110-inherit-as-list.md +++ b/rfcs/0110-inherit-as-list.md @@ -41,12 +41,12 @@ and reduced evaluation performance [3]. * [1] https://github.com/NixOS/nix/issues/490 * [2] https://github.com/NixOS/nix/issues/1361 * [3] https://github.com/NixOS/nixpkgs/pull/101139 -* [4] https://nix.dev/anti-patterns/language#with-attrset-expression +* [4] https://nix.dev/recipes/best-practices#with-scopes Nonetheless, Nix expression authors are subtly guided toward the `with` form because it is (or at least appears) simpler than any existing alternatives. Some alternatives are suggested in -https://nix.dev/anti-patterns/language#with-attrset-expression, but as these +https://nix.dev/recipes/best-practices#with-scopes, but as these are more verbose and complex than `with`, they are rarely used. The goal of this RFC is to provide a similarly-terse alternative which avoids