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

Nix language tutorial #267

Merged
merged 156 commits into from Oct 4, 2022
Merged

Conversation

fricklerhandwerk
Copy link
Collaborator

@fricklerhandwerk fricklerhandwerk commented Jul 15, 2022

based on @tazjin's tazjin/nix-1p and @zimbatm's NixCon 2019 talk Reading The Nix Language

As discussed in #288

To render a preview:

git clone https://github.com/fricklerhandwerk/nix.dev
cd nix.dev
git checkout nix-language-tutorial
nix-shell
./live

source/tutorials/nix-language.md Outdated Show resolved Hide resolved
source/tutorials/nix-language.md Outdated Show resolved Hide resolved
source/tutorials/nix-language.md Outdated Show resolved Hide resolved
source/tutorials/nix-language.md Outdated Show resolved Hide resolved
source/tutorials/nix-language.md Outdated Show resolved Hide resolved
source/tutorials/nix-language.md Outdated Show resolved Hide resolved
source/tutorials/nix-language.md Outdated Show resolved Hide resolved
source/tutorials/nix-language.md Outdated Show resolved Hide resolved
source/tutorials/nix-language.md Outdated Show resolved Hide resolved
source/tutorials/nix-language.md Outdated Show resolved Hide resolved
source/tutorials/nix-language.md Outdated Show resolved Hide resolved
source/tutorials/nix-language.md Outdated Show resolved Hide resolved
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/attribute-set-or-set/14253/7

@domenkozar
Copy link
Member

See #286 for my WIP

@fricklerhandwerk
Copy link
Collaborator Author

fricklerhandwerk commented Jul 28, 2022

  • @fricklerhandwerk every attempt to write an introduction so far degenerated to what the manual should look like
    • idea: focus on only on the parts people will see most of the time
    • @infinisil omit obscure details such as dynamic attribute names
    • @domenkozar people will build simple configs, we should focus on most common work loads
      • @fricklerhandwerk trying to find out what the important 80% are, cannot do it on my own
        • @infinisil maybe just look at common Nix files and explain their components?
          • @fricklerhandwerk the thesis and manual already do this, but it's bumpy
            • the tutorial-style part is derived from the thesis
              • a long time ago was the best we had
                • only one of my ten study subjects found it at all, and had severe trouble
              • it should just go away
          • @domenkozar we should instead use concrete examples to test learning success
    • @infinisil saying Nix is JSON+functions is not enough
      • still need things like attribute acccess operators
    • @Mic92 it took me a while to understand that NixOS modules are functions
      • what should people learn from this, write packages or NixOS modules?
      • wonder if an online REPL would be a good way to help people learn
        • used one when learning programming with Ruby
        • @fricklerhandwerk if it shows to be helpful with actual learners we should invest the effort
        • definitely helped me with understanding how NixOS works
    • @Mic92 introduce unusual constructs that are used commonly in Nix
      • @fricklerhandwerk let us collect some
        • function application without parantheses
        • attribute set arguments
        • import
        • inherit
        • derivations
          • @infinisil this would introduce a lot of complexity and necessarily pull in nixpkgs
            • @fricklerhandwerk no, we just have to say that it is one of the two side effects without going into detail
              • so far we have a huge gap between pure language tutorials and what to do with them, so we need to introduce at least the principle of side effects
            • @domenkozar just show the practically usable bits, no one actually writes a derivation directly
        • string contexts
        • space-separated lists
          • with space-separated function application
    • @olaf start from the use case instead of listing all possibilities
      • attribute sets are a core feature, the material we build with, and
        • explain how to use them
      • @fricklerhandwerk agree, should start from expected knowledge (such as JSON) and build up sophistication guided by need
      • @Mic92 best books I learned from gave me exercises to test what I learned
    • @Ericson2314 should go with this more experimentally
      • @fricklerhandwerk more user study sessions planned, first have to have a workable draft

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2022-07-28-nix-documentation-team-meeting-6/20627/1

@fricklerhandwerk fricklerhandwerk force-pushed the nix-language-tutorial branch 2 times, most recently from 143334f to 90fdd2a Compare August 1, 2022 16:53
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/tweag-nix-dev-update-34/20901/1

@fricklerhandwerk fricklerhandwerk force-pushed the nix-language-tutorial branch 2 times, most recently from c8effaa to b98bdc3 Compare August 18, 2022 17:15
@NixOS NixOS deleted a comment from github-actions bot Aug 18, 2022
@fricklerhandwerk fricklerhandwerk changed the title draft: nix language tutorial Nix language tutorial Aug 23, 2022
@fricklerhandwerk fricklerhandwerk self-assigned this Aug 23, 2022
@fricklerhandwerk fricklerhandwerk marked this pull request as ready for review August 23, 2022 06:51
@fricklerhandwerk fricklerhandwerk requested review from infinisil, bew and domenkozar and removed request for infinisil and bew August 23, 2022 06:53
@fricklerhandwerk
Copy link
Collaborator Author

@domenkozar where can we see the preview?

@domenkozar
Copy link
Member

For some reason it doesn't work, probably because the PR is older than the pages installation. We could fix it by opening a new PR, what do you think?

@fricklerhandwerk
Copy link
Collaborator Author

Shall we instead merge and fix forward? Your editors will have an easier time working on language that way.

@domenkozar domenkozar merged commit 70b0fb5 into NixOS:master Oct 4, 2022
:::{note}
If you are familiar with JSON, imagine the Nix language as *JSON with functions*.

Nix language data types *without functions* work just like their counterparts in JSON and look very similar.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not true. It's fine to say think about Nix as JSON plus functions, but this is only an analogy. Specifically:

  • Strings in C++ Nix are byte sequences and not Unicode-encoded in some shape or form as in JSON.
  • Integers in Nix are 64 bit integers and not represented as floating point numbers as they are in JSON.
  • Floats overall behave weirdly in Nix to the point that you should warn about them, i.e. they get truncated when serializing them in many situations.
  • Due to the nature of Nix's strings, not every legal Nix attribute name is a legal JSON object key.

Copy link
Contributor

@yannham yannham Oct 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the wording "imagine the Nix language as" is somehow similar to saying "think about Nix as", isn't it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but the claim in the second sentence is stronger than that and wrong, as I've pointed out. “Nix language data types without functions” does not work just like their counterparts in JSON.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, we're not saying they work exactly the same. For practical intents and purposes, the differences that you name seem exotic, and if nothing else are completely out of scope of this beginner tutorial. Learners are not even supposed to be able to write any code here, so there is no need for them to know at this point that some attribute names will not properly map to JSON keys.

What do you propose as a change? Say that dead Nix data works "much like" JSON? I wouldn't degrade it to something like "similar to JSON", because there is nothing obvious even from using the Nix language for a few years that would clearly point out a dissimilarity. The problem I have with exposing these edge cases in the first place is that it would mandate explaining them, and that would just be a distraction for everyone - already because it diverts readers' attention to inessential details, but also because giving it the tiny amount of room it deserves is in fact most of the work. How would you put in one brief sentence what makes these two examples semantically different?

I'd be really curious to know what kind of use cases made you discover these thorny edges.

PS: That kind of information belongs to the reference manual, where we have way too little of it. But please let's not dump it on unsuspecting beginners.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel that it is at least implied. With tutorials as the first contact point, one should be careful to avoid creating wrong impressions in readers – even by accident. FWIW my point is not that these differences must be explained, but rather that we should be careful to word it in a way that we don't imply they don't exist.


I'm also not sure these edges are that far out.

The integer thing is a relatively well known JSON pitfall – Nix is not thorny here as it behaves like you'd expect.

> echo 34343499993845656749 | jq
34343499993845658000

The float situation can be discovered quite easily. E.g.:

nix-repl> 1.000004 
1
nix-repl> builtins.toJSON 1.000004
"1"

String indexing, I'd say is a very basic topic that should be covered in a tutorial, since the internal representation is apparent in this, it is relevant. Indexing into non-ASCII strings will unexpectedly e.g. builtins.substring 0 1 "καλημερα" will return in some garbage being returned. E.g. “Nix strings are similar to C strings” is a statement like the one about JSON data, but more accurate.

@mkaito
Copy link

mkaito commented Oct 6, 2022

I finally managed to sit with someone through the tutorial. I wanted someone with a very specific experience; someone with extensive software engineering experience, mild or no devops experience, and zero exposure to Nix. It took a while to make it happen.

On the bright side, they only got stuck on 3 points and had very few questions otherwise, which speaks to the quality of the tutorial.

Here's where they got stuck:

  • In the note about parens and evaluation precedence, the list threw him off. It even threw me off for a hot minute. The example is good, but it's probably worth a passing note about the list and how it works in order to make it easier to understand.
  • Why do we call it "antiquotation"? Their immediate reaction was "why are you using these fancy words, when the entire rest of the world calls it string interpolation?"
  • We mention that builtins is implemented in C++ in Nix itself, but we should also mention, for clarity, that pkgs.lib is implemented in nix in nixpkgs.
  • The second worked example about NixOS modules threw them for a loop completely. I talked to them for half an hour about how modules work and then we just moved on. We should remove this example. Modules are not "basic nix language", and should have their own tutorial (which they probably do, I didn't check). Having them here is a bit of a "rest of the owl" situation.

@tazjin
Copy link
Member

tazjin commented Oct 6, 2022

Why do we call it "antiquotation"?

Do we though? I've never actually heard anyone say that, and usually people talk about interpolation instead. The term really only seems to show up in documentation, in the implementations of Nix, rnix, and Tvix (probably also hnix) they're always referred to as "string interpolation" and "Interpolation parts".

Maybe we should get rid of the "antiquotation" term completely.

@fricklerhandwerk
Copy link
Collaborator Author

fricklerhandwerk commented Oct 7, 2022

@mkaito thank you for this extremely valuable insight. A PR with the changes would be awesome!

@tazjin Agreed, we should rename "antiquotation" to "string interpolation" in the Nix manual. Sometimes it's the small changes that make a big difference. What are "interpolation parts" though? Is it the same thing?

@tazjin
Copy link
Member

tazjin commented Oct 7, 2022

@fricklerhandwerk Interpolation parts are the individual parts of a string with interpolations, e.g. in "one${two}three${four}" the two and four are interpolation parts.

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/where-is-a-vm-documented/22258/10

fricklerhandwerk added a commit to fricklerhandwerk/nix that referenced this pull request Nov 8, 2022
as proposed by @mkaito[1] and @tazjin[2]

[1]: NixOS/nix.dev#267 (comment)
[2]: NixOS/nix.dev#267 (comment)

to keep this change minimal, not included here but should follow:
- restructure the section on the string data type for better overview
- define string interpolation and related terms in one place and link to
  it from all occurrences
- use non-violent language: replace "string coercion" with "string
  representation" (requires some rewording for grammatical consistency)
fricklerhandwerk added a commit to fricklerhandwerk/nix that referenced this pull request Nov 21, 2022
as proposed by @mkaito[1] and @tazjin[2]

[1]: NixOS/nix.dev#267 (comment)
[2]: NixOS/nix.dev#267 (comment)

to keep this change minimal, not included here but should follow:
- restructure the section on the string data type for better overview
- define string interpolation and related terms in one place and link to
  it from all occurrences
- use non-violent language: replace "string coercion" with "string
  representation" (requires some rewording for grammatical consistency)
fricklerhandwerk added a commit to fricklerhandwerk/nix that referenced this pull request Nov 21, 2022
as proposed by @mkaito[1] and @tazjin[2] and discussed with @edolstra
and Nix maintainers

[1]: NixOS/nix.dev#267 (comment)
[2]: NixOS/nix.dev#267 (comment)
fricklerhandwerk added a commit to fricklerhandwerk/nix that referenced this pull request Nov 30, 2022
as proposed by @mkaito[1] and @tazjin[2] and discussed with @edolstra
and Nix maintainers

[1]: NixOS/nix.dev#267 (comment)
[2]: NixOS/nix.dev#267 (comment)
fricklerhandwerk added a commit to fricklerhandwerk/nix that referenced this pull request Dec 13, 2022
as proposed by @mkaito[1] and @tazjin[2] and discussed with @edolstra
and Nix maintainers

[1]: NixOS/nix.dev#267 (comment)
[2]: NixOS/nix.dev#267 (comment)

Co-authored-by: John Ericson <git@JohnEricson.me>
Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
fricklerhandwerk added a commit to fricklerhandwerk/nix that referenced this pull request Dec 13, 2022
as proposed by @mkaito[1] and @tazjin[2] and discussed with @edolstra
and Nix maintainers

[1]: NixOS/nix.dev#267 (comment)
[2]: NixOS/nix.dev#267 (comment)

Co-authored-by: John Ericson <git@JohnEricson.me>
Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
fricklerhandwerk added a commit to fricklerhandwerk/nix that referenced this pull request Dec 30, 2022
as proposed by @mkaito[1] and @tazjin[2] and discussed with @edolstra
and Nix maintainers

[1]: NixOS/nix.dev#267 (comment)
[2]: NixOS/nix.dev#267 (comment)

Co-authored-by: John Ericson <git@JohnEricson.me>
Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
fricklerhandwerk added a commit to fricklerhandwerk/nix that referenced this pull request Jan 2, 2023
as proposed by @mkaito[1] and @tazjin[2] and discussed with @edolstra
and Nix maintainers

[1]: NixOS/nix.dev#267 (comment)
[2]: NixOS/nix.dev#267 (comment)

Co-authored-by: John Ericson <git@JohnEricson.me>
Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet