-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Document what Nix *is* #6420
Document what Nix *is* #6420
Conversation
I have the impression we should think about how to deal with terminology in general. One example I already got stuck with is how we introduce what Nix calls "derivation". Since we go from the top level, we correctly call them very generally: "build plan". Build Systems à la Carte sec. 3.2 calls it "task". "(build) recipe" is another term that is currently in the draft. Still have no idea how to approach this to introduce readers into existing jargon. I would like not just to define "derivation" but make clear that it is a custom term for a concept other systems use as well under a different name. There is the glossary in the Nix manual, and that would probably a good point to improve upon while at it. |
This is a great point; I have been using Nix for years and still struggle defining it, even though the gist of it is simple. For me, the difficulty understanding it comes from the way the term has been used in the PhD thesis, the manuals, on the forum, in blog posts, etc. The conceptThere is the concept of "derivation",
These are high-level descriptions and easy to grasp, but to go further from here, one has to have knowledge about the Nix expression language which has a Therefore, I think the most important thing is that once a concept/term is introduced, it should be used consistently in the entire document, even if it means increased verbosity. E.g., using "derivation" instead of "Nix derivation expression" is shorter, but misleading (see next section). Also, definitions should be easy to find; a glossary with non-contradicting entries is a good start, and pointing to definitions in the text where they were first introduced would also be helpful by providing more context. UsageThe confusing part comes from how the term "derivation" is used, as it seemingly means different things depending on context:
Nix derivation expressions vs. store derivationsThis distinction is clearly pointed out in the thesis (emphases mine):
Both describe build actions whose result will end up in the Nix store but
For example, to demonstrate the output variability in the case of Vim: I think the PhD thesis is fairly underappreciated and more parts should be used from it, even though "derivation" is used ambiguously. Some examples of explanations that I found helpful and also a couple that show why the usage can be confusing (emphases mine, and the square brackets are also added by me):
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/documenting-what-is-nix/10177/5 |
@toraritte thank you very much for the clarification and for collecting all the material, this is very valuable.
Fully agree. I have it handy and try to base the explanation on it as much as possible. It's just that the thesis has a very different structure from what we want to do here. The other thing is that the thesis is not even accessible on the web site any more, so chances are highly reduced that people will even see it.
Absolutely, I will see to it. |
@fricklerhandwerk Thank you!
Yes... The explanations are top notch, but unfortunately even definitions/descriptions of the same concepts are scattered all over the place ("derivation" is a case in point). Plus it requires deep understanding in certain topics that makes it hard to consume (at least, for me).
:O Why? Thanks for linking that issue. My biggest problem has always been that it is impossible to link to parts of it (which I would have done countless times for questions and answers alike, for example) as it is not available in HTML form. Another problem with promoting the thesis is that it has been written 16(?) years ago, and because Nix's design has only been documented in issues and pull requests in multiple repos, it takes considerable effort to point out what has changed. (PR #4280 was heartwarming though.) I started annotating the thesis to understand the basics and to point out some of the changes (e.g., organization of Nixpkgs; |
Yeah a lot of what we are doing is just getting the PhD thesis up to date with today's Nix. There are only a few of us that know what has happened since in broad detail, so it's important get that written down! |
To be clear, this is the continuation of that same effort! I just didn't want the work being done in my fork of Nix, which makes it hard for other people to help out. Which I do need! |
Another ambiguity with wording is about the things Nix actually manages. The thesis calls them components:
The term component appears in the manual with that meaning only here and here, the only exceptions being pre-1.0 release notes. Most importantly:
All the material, especially all the internal In that sense, the package/configuration management aspect of Nix only lives in Does that sound reasonable? I fully bought into the concept of components from day one, but the term feels inappropriate for everyday use. Also it would require adding a definition to make the term sound meaningful, and that does not seem suitable for a half-pager introduction. Build Systems à la Carte sec. 3 uses the term value. With @Ericson2314 and @tomberek we figured that the Nix store or the Build Systems So while the store API is indeed a language, using values as a term for build results is highly problematic as it would interfere with the configuration language aspect and confuse people even more. I'm inclined to go with data, as that is still fairly vague but goes in the right direction. Here is a preliminary Rosetta stone for build system terminology, compiled out of desparation.
What do you think? |
The word "component" should be avoided since it is too ambiguous and overloaded. In Nix, a "build plan" is not a "derivation" but a "derivation graph". Derivations are nodes in that graph. Derivations are a tuple (builder, arguments, environment, ...). So "build instructions" probably corresponds most closely with "derivation". (The "builder" itself can be something like "bash", i.e. does not really provide build instructions on its own.) The term "realisation" should probably also be avoided since it's overloaded. E.g. we use realisation for building (as in |
I have been using "build result" for a while now; not flashy at all but, as stated in the thesis, "Nix does not really care what a component actually is. As far as Nix is concerned a component is just a set of files in a file system", and whatever ends up in the Nix store is the output of build actions (whether we are talking about compiling a software, constructing data sets, assembling documents, etc.) (For the sake of bringing examples: https://discourse.nixos.org/t/what-are-interesting-unique-and-or-non-standard-uses-of-nix/12977)
"data" is closer in meaning to what Nix "components" are supposed to represent, but because it is an even more common word, wouldn't its usage be prone to more ambiguity? Some of the examples cited above use the Nix store to house immutable datasets, config files, and so on, so discussions in the context of those projects may become difficult. Another path (that is fraught with its own perils) may be to come up with a bespoke term specific to Nix (and to similar/related build systems even, such as Guix). The upside is that its usage would be unambiguous but
I love this summary; whatever term will get settled on, I believe including this (somewhere) would be helpful towards understanding. Thank you for compiling the table! |
@@ -0,0 +1,37 @@ | |||
# Advanced Topic: Related Work |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is helpful right now. Let's try to keep new material to a minimum, and collect tangential ideas in private. It's hard to keep track of all that stuff in public, and produces a lot of noise.
@edolstra Thank you for the clarification!
While this is true in terms of how Nix is implemented, I disagree conceptually. It is rather arbitrary due to how Unix processes work that there is even a separation between builder, arguments and environment. What's missing from the tuple is the set of build inputs and the output, right? If we ignore implementation details for a moment, a derivation may as well be
And that is only because the separation is technically possible and exploited in practice. As far as we are concerned here, it may be an opaque binary that does not take arguments or consider environment variables, reading from a fixed set of file system objects, producing another file system object with a predefined path.
Maybe "build plan" is misleading. I picked it up from previous drafts of the overview section. Had read it as a "build not yet made" as opposed to only "instructions", which do not include references to build inputs. I thought about using "build task" for "derivation", but that does not really sound meaningful, as it does not capture the "build not yet made" idea. What about changing the table in the following way?
It's just as vague, but has the advantage of not sounding fancy and does not require further definition. I don't see ambiguity as a problem, because the object of interest here is very generic.
All of that is just data.
What are you referring to here, specifically? |
The idea and most of the execution are @fricklerhandwerk's. I changed a few things best I could based on @edolstra's corrections, and a Bazel glossary. Valentin Gagarin <[email protected]>
Are the terms below synonyms?
"Figure 3.1.: Deployment / memory management analogies" says that
1. pointer graph ≈ object graphFairly sure about this one because object graph is only used in figure 3.1 but this quote clears it up:
2. derivation graph ≈ build graph ≈ dependency graph ≈ references graphUp until chapter 5, only dependency graph is used but then it states that
so given all the above, pointer graph ≈ object graph ⇔ dependency graph ≈ references graph. (Also, the references graph is a product of the Derivation graph first shows up on page 108, paragraph 2:
It sounds very much like what a dependency graph is, and they also looks a lot alike: Build graph's first appearance happens on page 114, paragraph 4 ("determine whether the build graph of a component contains certain “bad” sources") but some lines below is the only part that resembles a definition:
Many aspects of Nix's operation are still fuzzy to me so I could only guess about this one. I'm a strong proponent of using terminology consistently in official communications, even if it makes them more verbose and the prose uglier, but if there would be a thesaurus alongside the glossary (or built one into it) that would be just as good. |
Basically to create a word for the purpose of replacing "component". This has been a very effective method during the wave of national language reforms throughout history, but not a fan of it in this case, unless the meaning of the new term can be pinned down exactly. With that said, I like "data" because
edit: Totally forgot about atoms so the term "build result" cannot be applied in the general sense...
|
@toraritte Thanks for pointing out atoms. I think "source files" as a special case of build inputs is commonplace nowadays. |
Just read through the excellent Architecture of Gazelle. They are doing everything right: a high-level overview using well-explained or intuitive terminology, linking to details where needed, yet with descriptions concrete enough to make immediate sense in context of this application. I think we are also moving in the right direction, and maybe should try to observe why the explanation they give is effective to understand the tool.
I simply don't understand why this sort of introduction and overview is not on the front page of every software project and in the first section of every @garbas Do I understand correctly that we want to have exactly that as a short-term goal? I really hoped that would be the point of writing the overview. |
|
||
## Overview | ||
|
||
Nix consists of hierarchical [layers](https://en.m.wikipedia.org/wiki/Multitier_architecture#Layers). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Links to mobile version of Wikipedia (here and in the following) probably unintentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mobile Wikipedia is intentional, as it is less visual noise and page data.
It is used to compose expressions which ultimately evaluate to self-contained *build plans*, used to derive *build results* from referenced *build inputs*. | ||
|
||
::: {.note} | ||
The Nix language itself does not have a notion of *packages* or *configurations*. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've drafted a definition for package in #6507. It is a bit more minimal and more general than the de facto handling of "packages" by the Nix tools.
Nonetheless, it is not part of the language per se, as it is a convention or interface around expressions.
This is the current state, expressed as a concept map. I consider green items ready to merge, yellow and orange need more work. I would like to un-draft this PR once the colored items are all green. The rest is for a different PR. flowchart
store --> derivation & building & obj[store object]
derivation & obj --> closure --> gc[garbage collection]
obj --> path & fso[file system object]
building --> scan
derivation --> building --> obj
closure & path[store path] --> scan[reference scanning]
style store fill:green
style obj fill:green
style closure fill:green
style fso fill:yellow
style path fill:orange
|
Updated concept map: flowchart
store --> obj[store object] & closure & operations
obj --> unix[files and processes] --> fso[file system object] & path
fso --> digest --> ia[input addressing] & ca[content addressing]
digest --> path[store path] --> scan[reference scanning]
operations --> building & gc
closure --> gc[garbage collection] & scan
building --> scan
derivation --> closure & building
style store fill:green
style obj fill:green
style closure fill:green
style fso fill:green
style path fill:green
style unix fill:green
style operations fill:green
style scan fill:yellow
style digest fill:yellow
style ca fill:yellow
style ia fill:yellow
The still open pull requests against this branch are supposed to nail down the green topics. The yellow topics will have enough content to be workable, but may need to be placed somewhere else and possibly reworded to fit their context. |
17bcb45
to
f530e80
Compare
@edolstra @domenkozar @thufschmitt please take a look. It's a large one, thus there are tons of opportunities for bikeshedding. We did a lot of work on making it clear, concise, and correct. |
I've hidden the architecture section until I've had a chance to review it (4eb5666). At first glance, a couple of issues:
|
@edolstra in that case, could you please revert the merge commit so we can continue working on the pull request? |
This part confuses me because the intent was to write the reference (bottom right quadrant), with any explanation (bottom left quadrant) a mere bonus. |
|
||
*(This chapter is unstable and a work in progress. Incoming links may rot.)* | ||
|
||
This chapter describes how Nix works. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may sound like splitting hairs, but instead of the word "Nix", the manuals should say explicitly what the term refers to, even if it is to the detriment of brevity.1 Depending on the context, I saw it used to mean:
- Nix core concepts / paradigm / model
- Nix CLI tools
- Nix expression language
- the implementation of Nix (i.e., the
NixOS/nix
) - the Nix ecosystem as a whole (i.e.,
NixOS/nix
implementation, Nixpkgs, NixOS, even NixOps) - Nixpkgs (rarely, but it still)
- (there is probably more..)
Taking the very next sentence as an example:
It should help users understand why Nix behaves as it does, and it should help developers understand how to modify Nix and how to write similar tools.
- "NIx behaves": I presume this alludes to the Nix model and/or the implementation
- "to modify Nix": To modify a Nix expression, the behavior of the Nix CLI tools, the store object in the Nix store - or something else?
I guess the "Architecture" section is about the model itself, and if so, it would be prudent to start with a short explanation what it is about. (It would be nice to have a specification.) Below are two ways I tried to define "Nix model" to myself:
-
A purely functional deployment model
... then explain what purity2, "functional" (this from PR Greatly expand architecture section, including splitting into abstract vs concrete model #6877), and deployment model mean.
(Took it directly from the thesis; the omission of the word "software" is deliberate.) -
A (new) paradigm of building anything that requires assembly3, and managing the build results. The official term for "build result" is store object because they are kept in the Nix store.
[1]: The definition of "Nix" has been a subject of contention on many online forums, but personally, it even made stop trying out Nix in the beginning and to give up on more certain parts of it a couple of times. I found the tutorials, posts, manuals, etc. confusing because sometimes there were sudden context switches, and not knowing what other aspects of NIx there are, I couldn't connect the dots (heh, still can't most of the time).
[2]: Thesis, page 21 (PDF page 29), 2nd paragraph from bottom.
[3]: My first try was "A (new) paradigm of building digital artifacts3 (where the input can be anything that require assembly), and managing the build results., but the term "digital artifact" seems just as overloaded as "component" or "package":
- Model-Based Systems Engineering (MBSE) wiki: Digital Artifact
- Wikipedia: Digital artifact
- WikiEducator: Digital artefact
- Quora: What is meant by digital artifact?
At the top is the [command line interface](../command-ref/command-ref.md), translating from invocations of Nix executables to interactions with the underlying layers. | ||
|
||
Below that is the [Nix expression language](../expressions/expression-language.md), a [purely functional][purely-functional-programming] configuration language. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I started thinking about the term "Nix", this is the hierarchy that helped me put things into perspective:
┌────────── Nix MODEL ──────────┐
│ │
│ (This would be a spec, but │
│ it is the implementation │
│ itself, right?) │
│ │
└───────────────┬───────────────┘
│
│
│
▼
┌───────────── Nix IMPLEMENTATION ──────────┐
│ ("the core") │
│ │ e.g., modules/c++ files
│ Implementation of the model │ implementing flakes
│ (C++ code defining the building blocks of │
│ Nix: Nix lexer & parser, behaviour of │
│ the Nix store, store objects and actions │
│ etc.) │
│ │
└──────────────────────┬────────────────────┘
│
│
│
▼
┌─────────────── Nix FRONTEND ──────────────┐
│ │
│ + CLI tools that use the "core" libs │ e.g., `nix flakes` commands
│ │
│ + Nix lang │
│ (Well, it is interpreted by the CLI │
│ tools, but this is what is used to │
│ interact with the system. Could be │
│ wrong.) │
│ │
└───────────────────────────────────────────┘
|
||
## Operations | ||
|
||
A Nix store can *add*, *retrieve*, and *delete* store objects. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(and line 75 below:)
It can perform builds, that is, create new store objects by transforming build inputs into build outputs, using instructions from the build tasks.
"Nix store" should be the object of the sentence and not the subject. At least, the way I understand it, the Nix store is the input of (or state manipulated by) these operations, and the Nix implementation performs the actions. (That is, the operations are functions defined by NixOS/nix
implementation, and called by the CLI tools when invoked.)
|
||
[ data ] | ||
| | ||
V | ||
[ store ] ---> add ----> [ store' ] | ||
| | ||
V | ||
[ reference ] | ||
|
||
<!-- --> | ||
|
||
[ reference ] | ||
| | ||
V | ||
[ store ] ---> get | ||
| | ||
V | ||
[ store object ] | ||
|
||
<!-- --> | ||
|
||
[ reference ] | ||
| | ||
V | ||
[ store ] --> delete --> [ store' ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even with the arrows this representation confused me, until I started thinking about the store as the state of a state machine (this wiki, 1st paragraph & this Erlang doc):
State x Input(s) -> Action(s), State'
So maybe making the figures explicit?
INPUT [ data ]
|
V
STATE TRANSITION [ store ] ---> add ----> [ store' ]
|
V
OUTPUT [ reference ]
INPUT [ reference ]
|
V
STATE TRANSITION [ store ] ---> get ----> [ store ]
|
V
OUTPUT [ store object ]
Maybe this is what is meant by a "separate book"? |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/summer-of-nix-documentation-stream/20351/4 |
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2022-08-11-documentation-team-meeting-7/20918/1 |
I want to add FYSA a "niche" angle to the discussion, that might be helpful to broaden the perspective: https://divnix.github.io/std/explain/why-nix.html |
@blaggacao By virtue of what I do every day for the past three months, I'm very aware of what is going on in the community. Please add to pull requests only constructive criticism and keep the noise down. Anything else takes a toll on everyone's cognitive resources. |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/summer-of-nix-documentation-stream/20351/2 |
Revert #6420 "Document what Nix *is*" so we can start over with smaller change sets
Document what Nix *is*
Revert NixOS#6420 "Document what Nix *is*" so we can start over with smaller change sets
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-05-11-learning-journey-working-group-meeting-notes-8/28120/11 |
…what-is-nix"" This reverts commit d8e54d1.
This is "tracking PR" of a community effort to better document what Nix is.
Per the excellent quadrant in https://documentation.divio.com/ (which we should officially adopt to help organize our docs!) this chapter is firstly reference, and secondly explanation.
It is in a permanent draft state, and this branch contains the "overall plan", with many sections mere outlines yet to be filled out.
As self-sufficient parts are finished off, they will be broken off into individual PRs to be merged sooner.
Currently, this is a collaboration between myself and @fricklerhandwerk, but more contributors are strongly encouraged to help out!