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

[RFC 0137] Nix language versioning #137

Draft
wants to merge 48 commits into
base: master
Choose a base branch
from
Draft
Changes from 6 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
02e3126
RFC 137: Set Nix language version in magic comment
fricklerhandwerk Dec 12, 2022
bb73166
rewrite arguments to be more precise
fricklerhandwerk Dec 16, 2022
c6d692c
using Nix language version istead would help third-party evaluators
fricklerhandwerk Dec 16, 2022
4265b08
remove non-argument about encouraging a principled approach
fricklerhandwerk Dec 16, 2022
288c7f1
add prior art
fricklerhandwerk Dec 16, 2022
9afffbe
reorder arguments to better capture their relation
fricklerhandwerk Dec 16, 2022
32436e5
Update rfcs/0137-nix-language-version.md
fricklerhandwerk Dec 16, 2022
37cd0bb
assume a fixed version when none is specified
fricklerhandwerk Dec 16, 2022
e1ed3be
answer questions and incorporate suggestions
fricklerhandwerk May 4, 2023
abcda5a
incorporate feedback and re-evaluate
fricklerhandwerk Jun 1, 2023
4c99631
add Perl `use` as prior art
fricklerhandwerk Jun 1, 2023
6ee9ecd
fix typo
fricklerhandwerk Jun 1, 2023
6e081bb
explain exception for bare expressions
fricklerhandwerk Jun 1, 2023
5d125cd
add brain worm syntax
fricklerhandwerk Jun 1, 2023
4776e4e
add Go as prior art
fricklerhandwerk Jun 2, 2023
33af913
fix typo
fricklerhandwerk Jun 2, 2023
38793cf
add roadmap as future work, with example
fricklerhandwerk Jun 2, 2023
cc5b1b4
use the proposed `version` syntax in examples
fricklerhandwerk Jun 8, 2023
3611cd2
add argument against `with import ...;` syntax
fricklerhandwerk Jun 8, 2023
a17e28f
highlight design goals
fricklerhandwerk Jun 8, 2023
29e2424
Update rfcs/0137-nix-language-version.md
fricklerhandwerk Jun 10, 2023
f6d519e
Update rfcs/0137-nix-language-version.md
fricklerhandwerk Jun 11, 2023
3364b1c
Update rfcs/0137-nix-language-version.md
fricklerhandwerk Jun 11, 2023
71ae7e7
fix wording
fricklerhandwerk Jun 12, 2023
0583d77
remove duplicate example
fricklerhandwerk Jun 12, 2023
a7def97
reword drawbacks, move drawbacks and alternatives to end of document
fricklerhandwerk Jun 12, 2023
8413407
fix typo
fricklerhandwerk Jun 13, 2023
e41b750
remove irrelevant argument
fricklerhandwerk Jun 13, 2023
e97309a
remove allusion to timelines
fricklerhandwerk Jun 13, 2023
80255aa
fix typo
fricklerhandwerk Jun 13, 2023
567d2d4
add syntax constraint for shebang lines
fricklerhandwerk Jun 14, 2023
a2f921f
clarify design goal of deliberate forward non-compatibility
fricklerhandwerk Jun 14, 2023
371ddd5
fix typo
fricklerhandwerk Jun 14, 2023
76a3d1f
add risk of increased maintenance burden
fricklerhandwerk Jun 15, 2023
f193f54
add example of best effort interop
fricklerhandwerk Jun 15, 2023
571c807
add argument on version proliferation risk
fricklerhandwerk Jun 15, 2023
d9d6a10
fix typo
fricklerhandwerk Jun 15, 2023
d97603e
add hint at what implementation would look like
fricklerhandwerk Jun 15, 2023
d54d6bc
add argument in favor of semver
fricklerhandwerk Jun 15, 2023
a64de1b
remove reference to `builtins.langVersion`
fricklerhandwerk Jun 22, 2023
c3d5411
promote a major-minor versioning scheme
fricklerhandwerk Jun 22, 2023
8f2cf11
add some details to summary
fricklerhandwerk Jun 22, 2023
8ae831e
add item to the sample change roadmap
fricklerhandwerk Jun 22, 2023
7bb92d4
remove unrelated future work item
fricklerhandwerk Jun 22, 2023
9711fb0
make clear example roadmap talks about major versions
fricklerhandwerk Jun 22, 2023
a461ef9
add another item to motivation section
fricklerhandwerk Sep 6, 2023
3e27f3c
update details on version declaration and backward compatibility
fricklerhandwerk Oct 4, 2023
2fed67c
add shepherd team
fricklerhandwerk Oct 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions rfcs/0137-nix-language-version.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
feature: nix-language-version
start-date: 2022-12-12
author: @fricklerhandwerk
co-authors: @thufschmitt @Ericson2314
shepherd-team:
shepherd-leader:
related-issues: https://github.com/NixOS/nix/issues/7255
---

# Summary
[summary]: #summary

Introduce a convention to determine which version of the Nix language grammar to use for parsing a Nix file.
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved

# Motivation
[motivation]: #motivation

Currently it's impossible to introduce backwards-incompatible changes to the Nix language without breaking existing setups.
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
This proposal is first step towards overcoming that limitation.
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved

# Detailed design
[design]: #detailed-design

Introduce a magic comment in the first line of a Nix file:
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved

#? Nix <version>

where `<version>` is a released version of Nix the given file is intended to work with.
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved

# Examples and Interactions
[examples-and-interactions]: #examples-and-interactions

```nix
#? Nix 2.12
"nothing"
```

# Arguments
[advantages]: #advantages

* (+) Makes explicit what can be expected to work.
* (+) Enables communicating language changes systematically.
* (+) Backwards-compatible
* (+) Allows for gradual adoption: opt-in until semantics is implemented in Nix *and* the first backwards-incompatible change to the language is introduced.
* (+) Visually unintrusive
* (+) Self-describing and human-readable
* (+) Follows a well-known convention of using [magic numbers in files](https://en.m.wikipedia.org/wiki/Magic_number_(programming)#In_files)
* (-) May make the appearance that changing the language is harmless.
* (+) The convention itself is harmless and independent of the development culture around the language.
* (-) The syntax of the magic comment is arbitrary.
* (-) There is a chance of abusing the magic comment for more metadata in the future. Let's avoid that.
* (-) At least one form of comment is forever bound to begin with `#` to maintain compatibility.
* (-) It requires significant additional effort to implement and maintain an appropriate system to make use of the version information.

# Alternatives
[alternatives]: #alternatives

- Never introduce backwards-incompatible changes to the language.
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved

* (+) No additional effort required.
* (-) Requires additions to be made very carefully.
* (-) Makes solving some well-known problems impossible.

fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
- Use the output of [`builtins.langVersion`] for specifying the version of the Nix language.

* (+) This would serve other Nix language evaluators which are not and should not be tied to the rest of Nix.
* (-) `builtins.langVersion` is currently only internal and undocumented.
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
* (+) Documentation is easy to add.
* (-) Requires adding another built-in to the public API.
* (-) Using a language feature requires an additional steps from users to determine the current version.
* (+) We can add a command line option such that it is not more effort than `nix --version`.
* (-) Requires adding another command line option to the public API.
* (+) The Nix language version is decoupled Nix version numbering.
* (+) It changes less often than the Nix version.
* (-) That was probably due to making changes being so hard.
* (-) There are two version numbers to keep track of.
* (-) The magic comment should reflect that it's specifying the *Nix language* version, which would make it longer.
* (-) Renaming the Nix language will be impossible once the mechanism is part of stable Nix.

[`builtins.langVersion`]: https://github.com/NixOS/nix/blob/26c7602c390f8c511f326785b570918b2f468892/src/libexpr/primops.cc#L3952-L3957

- Use a magic string that is incompatible with evaluators prior to the feature, e.g. `%? Nix <version>`.

* (+) Makes clear that the file is not intended to be used without explicit handling of compatibility.
* (-) Cannot be introduced gradually.
* (+) Such a breaking change could also be reserved for later iterations of the Nix language.

# Prior art
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved

- [Rust `edition` field]

Rust has an easier problem to solve. Cargo files are written in TOML, so the `edition` information does not have to be part of Rust itself.
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved

- [Flakes `edition` field]

There had been an attempt to include an `edition` field into the Flakes schema.
It did not solve the problem of having to evaluate the Nix expression using *some* version of the grammar.

[Rust `edition` field]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-edition-field
[Flakes `edition` field]: https://discourse.nixos.org/t/nix-2-8-0-released/18714/6

# Unresolved questions
[unresolved]: #unresolved-questions

- Is the proposed magic number already in use in [other file formats](https://en.m.wikipedia.org/wiki/Magic_number_(programming)#In_files)?
- Should we allow multiple known-good versions in one line?

fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
# Future work
[future]: #future-work

- Define semantics, that is, what exactly to do with the information given in the magic comment.
- Define rules deciding when a change to the language is appropriate to avoid proliferation and limit complexity of implementation.