Simple Development Environments with Nix
≺≻ Slidev
≺≻ Slidev example talks
David Binders abstract: “Functional programmers cannot use the same data structures and algorithms that imperative programmers are used to. Functional data structures make it easier to reason about what our code does, but have different performance characteristics. This talk will introduce some of the basic and advanced techniques we use when we implement functional data structures efficiently.”
Abstract
“Setting up development environments is more complex than it should be.
Nix makes entering development environments as easy as running nix develop
, making them simple and reproducible. This talk explores what an ideal workflow could look like and walks through a project setup with Nix, outlining its benefits and deficiencies.”
Outcome: People have experienced the power & simplicity of Nix, and can’t wait to try it out themselves.
Beginnging: Regular thing—you want to try out a new project. So, you clone the repo and follow the README. Unfortunately, it’s only described for macOS and Debian-based distros, and at the point you figured out how to install all the described components, it still does not work, since there’s some system library the author took for granted that you don’t have available.
Now it’s been 30 minutes, and you still haven’t started trying it out locally.
Let’s think for a moment: What should this process look like?
-
git clone repo && cd repo
- ‘Install all necessary dependencies’
- ‘Run the app as intended’
Now, you might ask yourself: That looks like it should be possible with a bash script. Why aren’t people doing this already?
I think it’s because that would need a unified interface, which we don’t have (as in: Only one package manager, only one shell, …) to be maintainable.
And even if we solved that (or put in the maintenance effort):
- How do we ensure that it doesn’t interfere with existing packages (conflicting versions)
Well, there is a unified interface like that: Nix. (And by extension, Guix (System))
Let’s just use it:
> git clone [email protected]:tu-lambda/tu-lambda.github.io
> cd tu-lambda.github.io
> nix develop
... downloading and building everything
🔨 Welcome to devshell!
rps raco pollen start (Runs the project server)
nix-shell> raco pollen start
pollen: starting project server
...
pollen: ready to rock
^C
nix-shell> ^C
> raco pollen start
raco: command not found
And for you, it’s just one command more:
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
You might ask yourself: If this is so great, why isn’t everybody using that already?
- everything is different
- using derivations is absolutely great, writing them is hard.
- Nix Language is.. irritating.
- Documentation has been really bad, but became okay just during the last few years.
To get around that right now, let’s write an example flake with basic primitives only:
{
description = "Flakes, demystified";
inputs = {
nixpkgs = "github:nixos/nixpkgs?ref=nixos-unstable";
};
outputs = { nixpkgs }:
{
devShells.default = nixpkgs.legacyPackages."x86_64-linux".mkShell {
packages = [ nixpkgs.legacyPackages."x86_64-linux".racket ];
shellHook = ''
raco pkg install --auto --skip-install pollen racket-langserver string-interpolation
'';
};
};
}
- zero-to-nix/flake.nix at main · DeterminateSystems/zero-to-nix · GitHub
- pkgs.mkShell | nixpkgs
- mkDerivation - nix-docs
- GitHub - surrealdb/surrealdb: A scalable, distributed, collaborative, document-graph database, for the realtime web
# for the future
packages.default = nixpkgs.legacyPackages."x86_64-linux".stdenv.mkDerivation {
name = "The website of functional coders Tübingen";
src = ./.;
buildInputs = [ racket ];
buildPhase = ''
mkdir output
raco pollen render ./output
'';
installPhase = ''
mkdir -p $out
cp output $out
'';
};
Trade-offs:
- Our OSes are not made for this.
- Writing stuff in the Nix Language is hard.
- A bunch of new concepts: Nix Flakes, Nix Derivations,
- A bunch of commands: nix develop, nix shell,