Skip to content

Aspects & Functors

Any Nix attrset with __functor can be called as a function:

let
counter = {
value = 42;
__functor = self: n: self.value + n;
};
in counter 8 # => 50

The __functor receives self (the attrset itself) and returns a function.

Every aspect in Den has a default __functor that inspects context parameters to decide what to produce:

# Default: parametric. inspects context shape
den.lib.parametric {
nixos.foo = 1;
includes = [
({ host }: { nixos.networking.hostName = host.hostName; })
({ user }: { homeManager.home.username = user.userName; })
];
}

Aspects have three kinds of attributes:

Direct settings per Nix class:

den.aspects.igloo = {
nixos.networking.hostName = "igloo";
darwin.nix-homebrew.enable = true;
homeManager.programs.vim.enable = true;
};

A list forming a dependency graph:

den.aspects.igloo.includes = [
# Static: applied unconditionally
{ nixos.programs.vim.enable = true; }
# Parametric: applied when context matches argument shape
({ host, ... }: { nixos.time.timeZone = "UTC"; })
# Reference to another aspect
den.aspects.tools
];

Named sub-aspects scoped to this aspect, accessible via den.aspects.igloo._.name or den.aspects.igloo.provides.name:

den.aspects.igloo.provides.gpu = { host, ... }:
lib.optionalAttrs (host ? gpu) {
nixos.hardware.nvidia.enable = true;
};

Aspects are resolved for a specific class using the den.lib.aspects.resolve API.

module = den.lib.aspects.resolve "nixos" den.aspects.igloo;

Resolution collects all nixos attrs from owned configs, walks includes recursively, applies parametric dispatch, deduplicates, and produces a single deferredModule containing all NixOS configuration.

Contribute Community Sponsor