Warning! Nix language!

2025-02-05

These are some notes about the Nix language:

Nix language is ugly; it’s hard to read. (Only my opinion, of course.) I will take (probably non-working) flake.nix, shape it, and explain the sections as I understand them.

Also, reading the code from top to bottom is a bit misleading, because Nix is declarative. It means that by writing Nix code, the relations are specified, not the steps or commands.

{
  outputs = {
    self,
    nixpkgs,
    flake-utils,
    ...
  }: let
    inherit (flake-utils.lib) eachDefaultSystem filterPackages;

    name = "package_name";
    version = "0.1.0";

    pypkg = {
      buildPythonPackage,
      pkgs,
    }:
      buildPythonPackage {
        pname = name;
        inherit version;
        nativeCheckInputs = [pkgs.ruff];
      };
  in
    {
      overlays.default = final: _: {
        "${name}" = final.callPackage pypkg {};
      };
    }
    // eachDefaultSystem (system: let
      pkgs = nixpkgs.legacyPackages.${system}.extend self.overlays.default;
    in {
      packages.default = pkgs.python3Packages."${name}";
      legacyPackages = pkgs;
      devShells = filterPackages system {
        default = pkgs.mkShell {
          packages = with pkgs; [
            ruff
          ];
        };
      };
    });
}

Let’s reshape the code, because { } is attribute set and : defines functions and that’s important. There are also let ... in ... and with ... blocks that benefit from different indentation.

{
  outputs =
    {
      self,
      nixpkgs,
      flake-utils,
      ...
    }
  :
    let
      inherit (flake-utils.lib) eachDefaultSystem filterPackages ;

      name = "package_name" ;
      version = "0.1.0" ;

      pypkg =
        {
          buildPythonPackage,
          pkgs,
        }
      :
        buildPythonPackage
        {
          pname = name ;
          inherit version ;
          nativeCheckInputs = [ pkgs.ruff ] ;
        }
      ;
    in
        {
          overlays.default =
            final
          :
            _
          :
            {
              "${name}" = final.callPackage pypkg {} ;
            }
          ;
        }
      //
        eachDefaultSystem
        (
          system
        :
          let
            pkgs = nixpkgs.legacyPackages.${system}.extend self.overlays.default ;
          in
            {
              packages.default = pkgs.python3Packages."${name}" ;
              legacyPackages = pkgs ;

              devShells =
                filterPackages
                system
                {
                  default =
                    pkgs.mkShell
                    {
                      packages =
                        with pkgs ;
                        [
                          ruff
                        ]
                      ;
                    }
                  ;
                }
              ;
            }
        )
  ;
}

I don’t think this is awesome. I think this is really bad.

go back