Parametric Aspects
import { Aside } from ‘@astrojs/starlight/components’;
What Is a Parametric Aspect?
Section titled “What Is a Parametric Aspect?”A parametric aspect uses a __functor that forwards its received context
to functions in .includes. Den provides several parametric functors in
den.lib.parametric.
den.lib.parametric (the default)
Section titled “den.lib.parametric (the default)”The most common functor. Alias for parametric.withOwn parametric.atLeast:
den.aspects.foo = den.lib.parametric { nixos.networking.hostName = "owned"; # always included includes = [ ({ host, ... }: { nixos.time.timeZone = "UTC"; }) ];};When applied with { host = ...; user = ...; }:
- Owned configs (
nixos.networking.hostName) are included - Static includes are included
- Functions matching
atLeastthe context args are called
parametric.atLeast
Section titled “parametric.atLeast”Only dispatches to functions — does not include owned configs:
F = parametric.atLeast { includes = [ a b c ]; };Applied with { x = 1; y = 2; }:
{ x, ... }: ...→ called (has at leastx){ x, y }: ...→ called (has exactlyx, y){ z }: ...→ skipped (needsz)
parametric.exactly
Section titled “parametric.exactly”Like atLeast, but only calls functions with exactly matching args:
F = parametric.exactly { includes = [ a b c ]; };Applied with { x = 1; y = 2; }:
{ x, ... }: ...→ skipped (has...){ x, y }: ...→ called (exact match){ z }: ...→ skipped
Use exactly to prevent duplicate configs when the same function would
match multiple context stages.
parametric.fixedTo
Section titled “parametric.fixedTo”Replaces the context entirely:
foo = parametric.fixedTo { planet = "Earth"; } { includes = [ ({ planet, ... }: { nixos.setting = planet; }) ];};No matter what context foo receives, its includes always get
{ planet = "Earth"; }.
parametric.expands
Section titled “parametric.expands”Adds attributes to the received context:
foo = parametric.expands { planet = "Earth"; } { includes = [ ({ host, planet, ... }: { nixos.setting = "${host.name}/${planet}"; }) ];};Applied with { host = ...; }, the includes receive
{ host = ...; planet = "Earth"; }.
parametric.withOwn
Section titled “parametric.withOwn”Combinator that adds owned config and static includes on top of any dispatch functor:
parametric.withOwn parametric.atLeast { nixos.foo = "owned"; # included always includes = [ { nixos.bar = "static"; } # included always ({ host, ... }: { ... }) # dispatched via atLeast ];}Matching Rules Summary
Section titled “Matching Rules Summary”| Functor | Owned | Statics | Functions |
|---|---|---|---|
parametric (default) | ✓ | ✓ | atLeast |
parametric.atLeast | ✗ | ✗ | atLeast |
parametric.exactly | ✗ | ✗ | exactly |
parametric.withOwn F | ✓ | ✓ | uses F |
parametric.fixedTo ctx | ✓ | ✓ | fixed ctx |
parametric.expands ctx | ✓ | ✓ | ctx + received |
take.exactly and take.atLeast
Section titled “take.exactly and take.atLeast”For individual functions (not whole aspects), use den.lib.take:
den.default.includes = [ (den.lib.take.exactly ({ host }: { nixos.x = 1; }))];This prevents the function from matching { host, user } contexts,
avoiding duplicate config values.