Home Explore Blog CI



nix

5th chunk of `doc/manual/source/language/syntax.md`
ad6dd6174e3a30411e591e6aaa52429545bd66e126bfae6b0000000100000cd6
    you can access attribute names as `a`, using `args.a`, which was
    given as an additional attribute to the function.

    > **Warning**
    >
    > `args@` binds the name `args` to the attribute set that is passed to the function.
    > In particular, `args` does *not* include any default values specified with `?` in the function's set pattern.
    >
    > For instance
    >
    > ```nix
    > let
    >   f = args@{ a ? 23, ... }: [ a args ];
    > in
    >   f {}
    > ```
    >
    > is equivalent to
    >
    > ```nix
    > let
    >   f = args @ { ... }: [ (args.a or 23) args ];
    > in
    >   f {}
    > ```
    >
    > and both expressions will evaluate to:
    >
    > ```nix
    > [ 23 {} ]
    > ```

  - All bindings introduced by the function are in scope in the entire function expression; not just in the body.
    It can therefore be used in default values.

    > **Example**
    >
    > A parameter (`x`), is used in the default value for another parameter (`y`):
    >
    > ```nix
    > let
    >   f = { x, y ? [x] }: { inherit y; };
    > in
    >   f { x = 3; }
    > ```
    >
    > This evaluates to:
    >
    > ```nix
    > {
    >   y = [ 3 ];
    > }
    > ```

    > **Example**
    >
    > The binding of an `@` pattern, `args`, is used in the default value for a parameter, `x`:
    >
    > ```nix
    > let
    >   f = args@{ x ? args.a, ... }: x;
    > in
    >   f { a = 1; }
    > ```
    >
    > This evaluates to:
    >
    > ```nix
    > 1
    > ```

Note that functions do not have names. If you want to give them a name,
you can bind them to an attribute, e.g.,

```nix
let concat = { x, y }: x + y;
in concat { x = "foo"; y = "bar"; }
```

## Conditionals

Conditionals look like this:

```nix
if e1 then e2 else e3
```

where *e1* is an expression that should evaluate to a Boolean value
(`true` or `false`).

## Assertions

Assertions are generally used to check that certain requirements on or
between features and dependencies hold. They look like this:

```nix
assert e1; e2
```

where *e1* is an expression that should evaluate to a Boolean value. If
it evaluates to `true`, *e2* is returned; otherwise expression
evaluation is aborted and a backtrace is printed.

Here is a Nix expression for the Subversion package that shows how
assertions can be used:.

```nix
{ localServer ? false
, httpServer ? false
, sslSupport ? false
, pythonBindings ? false
, javaSwigBindings ? false
, javahlBindings ? false
, stdenv, fetchurl
, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null
}:

assert localServer -> db4 != null; ①
assert httpServer -> httpd != null && httpd.expat == expat; ②
assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl); ③
assert pythonBindings -> swig != null && swig.pythonSupport;
assert javaSwigBindings -> swig != null && swig.javaSupport;
assert javahlBindings -> j2sdk != null;

stdenv.mkDerivation {
  name = "subversion-1.1.1";
  ...
  openssl = if sslSupport then openssl else null; ④
  ...
}
```

The points of interest are:

1.  This assertion states that if Subversion is to have support for
    local repositories, then Berkeley DB is needed. So if the Subversion
    function is called with the `localServer` argument set to `true` but

Title: Nix Functions: Scoping, Conditionals, and Assertions
Summary
This section continues discussing Nix functions, highlighting the scope of bindings within a function expression and demonstrating how parameters can use other parameters' values (including those from `@`-patterns) as defaults. It then moves on to describe conditional expressions using `if-then-else` and assertions using `assert` for verifying conditions. A Subversion package example showcases how assertions can be used to enforce dependencies and requirements based on configuration options.