2023-06-01 - Learning Journey Working Group - Meeting Notes #11


  • @infinisil: Maybe more asynchronous work, shorter meetings?
    • @zmitchell: Meetings good for figuring things out quickly
    • @infinisil: We have a small roadmap now, could work on that now before trying to figure out more things
    • @zmitchell: Need to ensure we’re not wasting time on the wrong things. There’s no product we’re trying to get out, no rush.
    • @infinisil: Cadence matters a bit imo, docs team is fairly slow, 3 hour of meetings per week doesn’t justify the low amount of asynchronous work
    • @zmitchell: Had to get the team off the ground first, look at project boards, figuring out the direction
  • Tracking issue for tutorials: Learning Journey tutorial series · Issue #572 · NixOS/nix.dev · GitHub
    • @zmitchell: Previous tutorials all about entering environments.
    • @zmitchell: Next tutorial: Doing a build, leading to sharing between shell.nix and default.nix
    • @zmitchell: default.nix and shell.nix are very similar
    • @infinisil: I feel like always having a default.nix is a good convention, shell.nix only refers to .shell from default.nix
    • @henrik-ch: Tutorial on how to migrate a shell.nix to a default.nix?
    • @khaled: I thought there might be a step where we introduce a default.nix
    • @infinisil: And then point out the problem how updating one doesn’t update the other?
    • @zmitchell: shell.nix only makes sense if you want extra things not in the default.nix
    • @infinisil: How about creating a separate default.nix in the tutorial that creates the build
    • @zmitchell: buildPythonApplication or stdenv.mkDerivation. Most people won’t do C stuff, rather language-specific stuff
      • @infinisil: stdenv.mkDerivation is only lightly tied to C
    • @zmitchell: At some point show how arbitrary commands in a build can be done, but not now
    • @zmitchell: What should be built?
    • @infinisil: Tutorial proposal:
      • Explain how we haven’t built our own code purely yet, only entered an environment and might have called pip install or so. Explain how that’s impure.
        • Sandbox? Disabled by default on Darwin
      • Create a shell.nix to have an environment containing cargo/rustc, then enter it and build the project impurely in the environment
      • Start by creating a simple project to demonstrate from within the environment, which language?
        • Try just runCommand "myProject" {} "pip build"?
          • @zmitchell: Problem, no way to build a python project
        • @zmitchell: python setup.py build wheel, but annoying to write a setup.py file
        • @khaled: pyproject.toml?
        • @zmitchell: How about Rust, there’s an easy command to build that.
          • @infinisil: Sounds good, compiled language makes it clear what is being built
        • @zmitchell: Go also exists
        • @zmitchell: We can use cargo new --bin my_proj to get a working project
      • Build it impurely in the environment → works
      • Make sure that we’re not using any dependencies → no internet required, works in the sandbox
        Create a default.nix with a
        runCommand "myProject" { ... } ''
          cargo build
        Observe failure, explain it (source isn’t available)
        runCommand "myProject" { ... } ''
          cd ${./.}
          cargo build
        Explain how ${} imports paths into the store
        Fails with not writable
        runCommand "myProject" { ... } ''
          cp ${./.} .
          chmod +w . -R
          cargo build
        Fails: $out empty
        runCommand "myProject" { ... } ''
          # copy the source
          cp ${./.} .
          chmod +w . -R
          # build
          cargo build
          # install
          mkdir -p $out/bin
          mv target/debug/myProject $out/bin
        Then show how mkDerivation makes this easier:
        stdenv.mkDerivation {
          name = "myProject";
          src = ./.;
          buildPhase = ''
            cargo build
          installPhase = ''
            mkdir -p $out/bin
            mv target/debug/myProject $out/bin
      • @zmitchell: That’s probably enough for the first tutorial
      • @khaled: Unsure about this direction. Should we assume knowledge of previous tutorials?
        • Showed Python tutorial, shouldn’t we continue the previous one?
        • Did we go the Rust path because there’s no easy build step for Python?
        • @zmitchell: Python is hard, building it at all and figuring out Python-specific build stuff. Comparatively, Rust is pretty straightforward
          • We should teach one hard thing at a time, e.g. showing a build at all, iteratively showing why it fails, learning one thing at a time.
          • Later we can show the Python stuff
        • @khaled: Rust-specific things still need to be done
        • @infinisil: With Python it’s also hard to explain what installing means, requires wrapping with Python interpreter, copying the source
      • Then do a buildRustPackage, maybe in the next tutorial

Action items

  • @zmitchell: Create an issue for this derivation tutorial

Just to follow up on the Python packaging issues, I looked into what you need to build with a pyproject.toml and these were some helpful links I found:

With setup.py, which it sounds like is deprecated or soon will be at this point, you can use setuptools to do something like python setup.py build, whereas with pyproject.toml you get the benefit of a declarative package definition but now you need another tool (build) to actually build a wheel.

We chose to go with Rust in this case because the workflow is much simpler:

  • cargo new --bin my_project
  • cargo build

You get a “hello world” package with no dependencies and are able to build it with two commands. That frees up cognitive load to think about the actual Nix stuff.