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.