Jump to content

Overview of the Nix Language

From NixOS Wiki
Revision as of 20:52, 7 October 2017 by imported>Samueldr (quoting with blockquote)

This discussion article covers the syntax, semantics, typing, compilation, tooling and libraries of the Nix Expression Language.

Language Overview

The Nix expression language is a pure, lazy, functional language. Purity means that operations in the language don't have side-effects (for instance, there is no variable assignment). Laziness means that arguments to functions are evaluated only when they are needed. Functional means that functions are “normal” values that can be passed around and manipulated in interesting ways. The language is not a full-featured, general purpose language. Its main job is to describe packages, compositions of packages, and the variability within packages.

— From the nix manual

The language was designed especially for the Nix Package Manager.

Learning the Nix language

The manual provides a reference of the Nix language. All language constructs you may use in nix are defined here, together with code snippets.

Nix By Example is a step-by-step tutorial. The nix pills also provide a lot of insight into the language and functional package management in general.

Notable Language Constructs

Nix looks a lot like JSON with functions but also provides a number of very specialized constructs which can help you build clean and easy to read expressions. In this sub-chapter the most notable constructs will be shown by example:

with statement

The with statement introduces the lexical scope of a set into the expression which follows. Common usages are:

On top of expressions

You will see the with statement a lot at the beginning of expression definition. Most of the time it is used to load the lib functions into the namespace for quick access.

{lib, ... }:

with lib;
{
  options = {
    networking.hosts = mkOption {
      type = with types; attrsOf ( listOf str);
      default = {};
    };
  };
  ...  
}

instead of:

{lib, ... }:
{
  options = {
    networking.hosts = lib.mkOption {
      type = lib.types.attrsOf ( lib.types.listOf lib.types.str);
      default = {};
    };
  };
  ...  
}
In package input definitions
{pkgs}:
{
  ...
  buildInputs = with pkgs; [ curl php coreutils procps ffmpeg ];
}

Instead of :

{pkgs}:
{
  ...
  buildInputs = [ pkgs.curl pkgs.php pkgs.coreutils pkgs.procps pkgs.ffmpeg ];
}
In the package meta tag
{stdenv, ...}:
{
  ...
  meta = with stdenv.lib; {
    license = with licenses; [ lgp3 gpl3 ];
    maintainers = with maintainers; [ adisbladis lassulus ];
  };
}

Instead of :

{stdenv, ...}:
{
  ...
  meta = {
    license = [ stdenv.lib.licenses.lgp3 stdenv.lib.licenses.gpl3 ];
    maintainers = [ stdenv.lib.maintainers.adisbladis stdenv.lib.maintainers.lassulus ];
  };
}
In a default.nix of an external package
with import <nixpkgs> {};
stdenv.mkDerivation rec {
    name = "mytool-env";
    src = ./.;
    buildInputs = with pkgs;[
      python34
      python34Packages.docopt
    ];

    shellHook =''
      export HISTFILE=$PWD/histfile
    '' ;
}

let ... in statement

TODO

inherit statement

TODO

rec statement

TODO

Syntax Highlighting/IDE Support

Nix language has decent syntax highlighting (SH) support among popular code editors, but refactoring/autocomplete is still rare.

Reference: Editor Modes for Nix Files