OFFSET偏移
← All articlesOFFSET / FIELD NOTESNO. 022

Nix functions and scope

Identify where each variable comes from in let, inherit, with, and function parameters.

English translation · Code and commands follow the Chinese original.

IN THESE READING PATHSThe Nix language and build model ↗
About 2 min readStart reading

"The key to understanding Nix code is knowing where each variable comes from."


Defining Variables: let ... in#

This is the most common way to define local variables.

let
  myUser = "alice";
  myShell = pkgs.zsh;
in {
  users.users.${myUser} = {
    shell = myShell;
  };
}
  • Rule: let bindings are visible within every binding's value and the expression after in, so bindings can refer to one another. They do not leak outside the expression.

Shorthand Magic: inherit#

Use inherit when you want to assign a variable to an attribute with the same name.

Conventional form:

{
  git = pkgs.git;
  vim = pkgs.vim;
}

Shorthand with inherit:

{
  inherit (pkgs) git vim;
}

This is extremely common in flake.nix and module configurations.


Caution: with pkgs;#

with set; body adds an attribute-lookup scope for body. Existing lexical bindings take precedence; it does not turn the attributes into ordinary let bindings.

with pkgs; [ git vim htop ]
  • Risk: variable-name collisions become easy to introduce and difficult to debug, since it may be unclear whether a variable comes from pkgs or the global scope.
  • Recommendation: using it inside lists [ ... ] is fine, but use it sparingly in large configuration blocks.

Functions and Parameter Breakdown#

The top level of a Nix file is often an anonymous function:

{ config, pkgs, lib, ... }: {
  # 配置内容
}
  • ... (Ellipsis): indicates that the function accepts additional arguments it does not currently need, preventing errors from an argument mismatch.
  • Destructuring: specify the parameter names you need directly inside the braces.

Practical Tip: Nested Scopes#

let
  commonPkgs = with pkgs; [ git vim ];
in {
  environment.systemPackages = commonPkgs ++ (let extra = [ pkgs.htop ]; in extra);
}

The ++ operator combines two lists.#

References & further reading

  1. NixOS manual ↗
  2. Nix language manual ↗

Adapted from technical notes. Examples use generic names.

Continue along a reading path

The Nix language and build model

  1. 01Nix and NixOS: storage, rollback, and declarative thinking
  2. 02Nix syntax: attribute sets, lists, and built-in functions
  3. 03Nix functions and scope
  4. 04Nix attribute sets: recursion and merging
  5. 05Derivations: from expressions to build outputs
CONTINUE READING / NEXT ARTICLENix attribute sets: recursion and merging

Distinguish shallow merging in the language from the merging rules for NixOS module options.