Home Explore Blog CI



nix

3rd chunk of `doc/manual/source/language/syntax.md`
c2a5d39e3ad08e2031b9f3d5c5f10b987baf2c526df9a3260000000100000fa1
a string), that attribute is simply not added to the set:

```nix
{ ${if foo then "bar" else null} = true; }
```

This will evaluate to `{}` if `foo` evaluates to `false`.

A set that has a [`__functor`]{#attr-__functor} attribute whose value is callable (i.e. is
itself a function or a set with a `__functor` attribute whose value is
callable) can be applied as if it were a function, with the set itself
passed in first , e.g.,

```nix
let add = { __functor = self: x: x + self.x; };
    inc = add // { x = 1; }; # inc is { x = 1; __functor = (...) }
in inc 1 # equivalent of `add.__functor add 1` i.e. `1 + self.x`
```

evaluates to `2`. This can be used to attach metadata to a function
without the caller needing to treat it specially, or to implement a form
of object-oriented programming, for example.

## Recursive sets

Recursive sets are like normal [attribute sets](./types.md#attribute-set), but the attributes can refer to each other.

> *rec-attrset* = `rec {` [ *name* `=` *expr* `;` `]`... `}`

Example:

```nix
rec {
  x = y;
  y = 123;
}.x
```

This evaluates to `123`.

Note that without `rec` the binding `x = y;` would
refer to the variable `y` in the surrounding scope, if one exists, and
would be invalid if no such variable exists. That is, in a normal
(non-recursive) set, attributes are not added to the lexical scope; in a
recursive set, they are.

Recursive sets of course introduce the danger of infinite recursion. For
example, the expression

```nix
rec {
  x = y;
  y = x;
}.x
```

will crash with an `infinite recursion encountered` error message.

## Let-expressions

A let-expression allows you to define local variables for an expression.

> *let-in* = `let` [ *identifier* = *expr* ]... `in` *expr*

Example:

```nix
let
  x = "foo";
  y = "bar";
in x + y
```

This evaluates to `"foobar"`.

## Inheriting attributes

When defining an [attribute set](./types.md#attribute-set) or in a [let-expression](#let-expressions) it is often convenient to copy variables from the surrounding lexical scope (e.g., when you want to propagate attributes).
This can be shortened using the `inherit` keyword.

Example:

```nix
let x = 123; in
{
  inherit x;
  y = 456;
}
```

is equivalent to

```nix
let x = 123; in
{
  x = x;
  y = 456;
}
```

and both evaluate to `{ x = 123; y = 456; }`.

> **Note**
>
> This works because `x` is added to the lexical scope by the `let` construct.

It is also possible to inherit attributes from another attribute set.

Example:

In this fragment from `all-packages.nix`,

```nix
graphviz = (import ../tools/graphics/graphviz) {
  inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
  inherit (xorg) libXaw;
};

xorg = {
  libX11 = ...;
  libXaw = ...;
  ...
}

libpng = ...;
libjpg = ...;
...
```

the set used in the function call to the function defined in
`../tools/graphics/graphviz` inherits a number of variables from the
surrounding scope (`fetchurl` ... `yacc`), but also inherits `libXaw`
(the X Athena Widgets) from the `xorg` set.

Summarizing the fragment

```nix
...
inherit x y z;
inherit (src-set) a b c;
...
```

is equivalent to

```nix
...
x = x; y = y; z = z;
a = src-set.a; b = src-set.b; c = src-set.c;
...
```

when used while defining local variables in a let-expression or while
defining a set.

In a `let` expression, `inherit` can be used to selectively bring specific attributes of a set into scope. For example


```nix
let
  x = { a = 1; b = 2; };
  inherit (builtins) attrNames;
in
{
  names = attrNames x;
}
```

is equivalent to

```nix
let
  x = { a = 1; b = 2; };
in
{
  names = builtins.attrNames x;
}
```

both evaluate to `{ names = [ "a" "b" ]; }`.

## Functions

Functions have the following form:

```nix
pattern: body
```

The pattern specifies what the argument of the function must look like,
and binds variables in the body to (parts of) the argument. There are
three kinds of patterns:

  - If a pattern is a single identifier, then the function matches any
    argument. Example:

    ```nix

Title: Recursive Sets, Let-Expressions, Inheriting Attributes, and Functions in Nix
Summary
This section covers several important features of the Nix language: recursive sets, let-expressions, inheriting attributes, and functions. Recursive sets allow attributes to refer to each other, while let-expressions introduce local variables. The `inherit` keyword simplifies copying variables from the surrounding scope or from other attribute sets. Finally, it briefly introduces functions, specifying their basic structure.