Table of Contents
Source
The source of the file is here: https://github.com/ne9z/dotfiles-flake
Function Currying
Since nix is a functional language with some similarities to Haskell, functions can be declared with just a colon.
doubleIt = a: a * 2
The colon defines a function that has a as a paremeter.
One function can call another function and another in a nearly endless call.
nix-repl> myFunc = a: b: c: a + b + c
nix-repl> myFunc "x" "y" "z"
"xyz"
The benefit is that you can call only 2 variables and return a function that can later be used in another setting.
nix-repl> newFunc = myFunc "hello" "world"
nix-repl> newFunc "!"
"helloworld!"
Above, newFunc is a function that is defined as:
newFunc = a: "helloworld" + a
Function Attributes
Imports
Functions
This is the code:
mkHost = hostName: systemFunc: (
({my-config, zfs-root, pkgs, system, ... }:
nixpkgs.lib.nixosSystem {
inherit system;
modules = [
./modules
(import ./hosts/${hostName}/configuration.nix { inherit pkgs; })
(({ my-config, zfs-root, pkgs, lib, ... }: {
inherit my-config zfs-root;
system.stateVersion = "23.05";
}) {
inherit my-config zfs-root pkgs;
lib = nixpkgs.lib;
})
(import ./configuration.nix { inherit pkgs; })
];
})
(import ./hosts/${hostName} {
system = system;
pkgs = nixpkgs.legacyPackages.${system};
})
);
Note, the above has been simplified and it is likely not to work.
There is a lot of moving pieces above! Namely:
./hosts/${hostName}./hosts/${hostName}/configuration.nix./modules
mkHost is a function that takes in two parameters, hostName, and systemFunc and each of those parameters represents another function. Remember that the : is enough to define a function.
The systemFunc function is defined as:
(import ./hosts/${hostName} {
system = system;
pkgs = nixpkgs.legacyPackages.${system};
})
The hostName function is defined as:
({my-config, zfs-root, pkgs, system, ... }:
nixpkgs.lib.nixosSystem {
inherit system;
modules = [
./modules
(import ./hosts/${hostName}/configuration.nix { inherit pkgs; })
(({ my-config, zfs-root, pkgs, lib, ... }: {
inherit my-config zfs-root;
system.stateVersion = "23.05";
}) {
inherit my-config zfs-root pkgs;
lib = nixpkgs.lib;
})
(import ./configuration.nix { inherit pkgs; })
];
})
Which in itself has multiple inline functions defined. hostName has another function in it that needs as its inputs the following attributes: my-config, zfs-root, pkgs, and system. These attributes are returned from the systemFunc function, because the systemFunc function call another function in it. Namely:
import ./hosts/${hostName}
The contents of this ./hosts/${hostName}/default.nix file are:
{
system,
pkgs,
}: {
inherit pkgs system;
zfs-root = {
...
};
my-config = {
...
};
}
Which, you guessed it, is a function { system, pkgs}: that takes two parameters and returns and attribute set of:
{
system = {...};
pkgs = {...};
zfs-root {...};
my-config = {...};
}
Which satisfies the parameters of hostName!
Question for the reader. Why can't I add more attribute sets to ./hosts/${hostName}/default.nix ?
> Answer
Because hostName function expects only 4 named attributes as its inputs. You can add more attributes to the return of ./host/${hostName}/default.nix, it is just not being used anywhere in the attribute set input arguments.
