2020-07-23 00:17:48 +03:00
# Operators
2023-01-05 16:16:16 +02:00
| Name | Syntax | Associativity | Precedence |
|----------------------------------------|--------------------------------------------|---------------|------------|
| [Attribute selection] | *attrset* `.` *attrpath* \[ `or` *expr* \] | none | 1 |
| Function application | *func* *expr* | left | 2 |
| [Arithmetic negation][arithmetic] | `-` *number* | none | 3 |
| [Has attribute] | *attrset* `?` *attrpath* | none | 4 |
| List concatenation | *list* `++` *list* | right | 5 |
| [Multiplication][arithmetic] | *number* `*` *number* | left | 6 |
| [Division][arithmetic] | *number* `/` *number* | left | 6 |
| [Subtraction][arithmetic] | *number* `-` *number* | left | 7 |
| [Addition][arithmetic] | *number* `+` *number* | left | 7 |
| [String concatenation] | *string* `+` *string* | left | 7 |
| [Path concatenation] | *path* `+` *path* | left | 7 |
| [Path and string concatenation] | *path* `+` *string* | left | 7 |
| [String and path concatenation] | *string* `+` *path* | left | 7 |
| Logical negation (`NOT`) | `!` *bool* | none | 8 |
| [Update] | *attrset* `//` *attrset* | right | 9 |
| [Less than][Comparison] | *expr* `<` *expr* | none | 10 |
| [Less than or equal to][Comparison] | *expr* `<=` *expr* | none | 10 |
| [Greater than][Comparison] | *expr* `>` *expr* | none | 10 |
| [Greater than or equal to][Comparison] | *expr* `>=` *expr* | none | 10 |
| [Equality] | *expr* `==` *expr* | none | 11 |
| Inequality | *expr* `!=` *expr* | none | 11 |
| Logical conjunction (`AND`) | *bool* `&&` *bool* | left | 12 |
2023-01-31 15:20:51 +02:00
| Logical disjunction (`OR`) | *bool* < code > \|\|</ code > *bool* | left | 13 |
2023-11-15 01:03:44 +02:00
| [Logical implication] | *bool* `->` *bool* | right | 14 |
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
[string]: ./values.md#type-string
[path]: ./values.md#type-path
[number]: ./values.md#type-number
[list]: ./values.md#list
[attribute set]: ./values.md#attribute-set
## Attribute selection
2022-12-22 22:21:26 +02:00
2023-10-10 01:32:36 +03:00
> **Syntax**
>
2023-05-11 20:23:13 +03:00
> *attrset* `.` *attrpath* \[ `or` *expr* \]
2022-12-23 09:58:19 +02:00
Select the attribute denoted by attribute path *attrpath* from [attribute set] *attrset* .
2023-05-12 21:03:09 +03:00
If the attribute doesn’ t exist, return the *expr* after `or` if provided, otherwise abort evaluation.
2022-12-22 22:21:26 +02:00
2023-05-11 20:23:13 +03:00
An attribute path is a dot-separated list of [attribute names ](./values.md#attribute-set ).
2022-12-22 22:21:26 +02:00
2023-10-10 01:32:36 +03:00
> **Syntax**
>
2023-05-11 20:23:13 +03:00
> *attrpath* = *name* [ `.` *name* ]...
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
[Attribute selection]: #attribute -selection
2022-12-22 22:21:26 +02:00
2022-12-22 23:10:11 +02:00
## Has attribute
2022-12-22 22:21:26 +02:00
2023-10-10 01:32:36 +03:00
> **Syntax**
>
2022-12-22 23:25:37 +02:00
> *attrset* `?` *attrpath*
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
Test whether [attribute set] *attrset* contains the attribute denoted by *attrpath* .
The result is a [Boolean] value.
2022-12-22 22:21:26 +02:00
2023-10-20 06:11:03 +03:00
See also: [`builtins.hasAttr` ](@docroot@/language/builtins.md#builtins-hasAttr )
2023-01-05 16:16:16 +02:00
[Boolean]: ./values.md#type-boolean
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
[Has attribute]: #has -attribute
2022-12-22 22:21:26 +02:00
2023-10-20 03:45:47 +03:00
After evaluating *attrset* and *attrpath* , the computational complexity is O(log(*n*)) for *n* attributes in the *attrset*
2023-01-05 16:16:16 +02:00
## Arithmetic
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
Numbers are type-compatible:
Pure integer operations will always return integers, whereas any operation involving at least one floating point number return a floating point number.
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
See also [Comparison] and [Equality].
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
The `+` operator is overloaded to also work on strings and paths.
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
[arithmetic]: #arithmetic
2022-12-22 22:21:26 +02:00
2022-12-22 23:10:11 +02:00
## String concatenation
2022-12-22 22:21:26 +02:00
2023-10-10 01:32:36 +03:00
> **Syntax**
>
2023-01-05 16:16:16 +02:00
> *string* `+` *string*
2022-12-22 22:21:26 +02:00
2024-02-04 23:15:20 +02:00
Concatenate two [strings][string] and merge their string contexts.
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
[String concatenation]: #string -concatenation
2022-12-22 22:21:26 +02:00
2022-12-22 23:11:17 +02:00
## Path concatenation
2023-10-10 01:32:36 +03:00
> **Syntax**
>
2023-01-05 16:16:16 +02:00
> *path* `+` *path*
2022-12-22 23:11:17 +02:00
2024-02-04 23:15:20 +02:00
Concatenate two [paths][path].
2022-12-22 23:11:17 +02:00
The result is a path.
2023-01-05 16:16:16 +02:00
[Path concatenation]: #path -concatenation
2022-12-22 23:11:17 +02:00
## Path and string concatenation
2023-10-10 01:32:36 +03:00
> **Syntax**
>
2023-01-05 16:16:16 +02:00
> *path* + *string*
2022-12-22 23:11:17 +02:00
2022-12-23 09:58:19 +02:00
Concatenate *[path]* with *[string]* .
2022-12-22 23:11:17 +02:00
The result is a path.
> **Note**
>
2022-12-23 09:58:19 +02:00
> The string must not have a string context that refers to a [store path].
2022-12-22 23:11:17 +02:00
2023-01-05 16:16:16 +02:00
[Path and string concatenation]: #path -and-string-concatenation
2022-12-22 23:11:17 +02:00
## String and path concatenation
2023-10-10 01:32:36 +03:00
> **Syntax**
>
2023-01-05 16:16:16 +02:00
> *string* + *path*
2022-12-22 23:11:17 +02:00
2022-12-23 09:58:19 +02:00
Concatenate *[string]* with *[path]* .
2022-12-22 23:11:17 +02:00
The result is a string.
> **Important**
>
2022-12-23 09:58:19 +02:00
> The file or directory at *path* must exist and is copied to the [store].
> The path appears in the result as the corresponding [store path].
2022-12-22 23:11:17 +02:00
2024-04-10 00:07:39 +03:00
[store path]: @docroot@/store/store -path.md
2024-04-12 18:06:47 +03:00
[store]: @docroot@/glossary .md#gloss-store
2022-12-22 22:21:26 +02:00
2023-01-26 23:50:36 +02:00
[String and path concatenation]: #string -and-path-concatenation
2022-12-22 22:21:26 +02:00
2022-12-22 23:25:37 +02:00
## Update
2023-10-10 01:32:36 +03:00
> **Syntax**
>
2023-01-19 11:20:41 +02:00
> *attrset1* // *attrset2*
2022-12-22 22:21:26 +02:00
2022-12-23 09:58:19 +02:00
Update [attribute set] *attrset1* with names and values from *attrset2* .
2022-12-22 22:21:26 +02:00
2024-05-27 16:56:52 +03:00
The returned attribute set will have all of the attributes in *attrset1* and *attrset2* .
2023-01-20 14:21:45 +02:00
If an attribute name is present in both, the attribute value from the latter is taken.
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
[Update]: #update
2022-12-22 22:21:26 +02:00
2022-12-22 23:25:37 +02:00
## Comparison
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
Comparison is
2022-12-22 22:21:26 +02:00
2024-02-04 23:15:20 +02:00
- [arithmetic] for [numbers][number]
- lexicographic for [strings][string] and [paths][path]
- item-wise lexicographic for [lists][list]:
2023-01-05 16:16:16 +02:00
elements at the same index in both lists are compared according to their type and skipped if they are equal.
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
All comparison operators are implemented in terms of `<` , and the following equivalencies hold:
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
| comparison | implementation |
|--------------|-----------------------|
| *a* `<=` *b* | `! (` *b* `<` *a* `)` |
| *a* `>` *b* | *b* `<` *a* |
| *a* `>=` *b* | `! (` *a* `<` *b* `)` |
2022-12-22 22:21:26 +02:00
2024-02-04 23:15:20 +02:00
[Comparison]: #comparison
2022-12-22 22:21:26 +02:00
## Equality
2024-02-04 23:15:20 +02:00
- [Attribute sets][attribute set] and [lists][list] are compared recursively, and therefore are fully evaluated.
- Comparison of [functions][function] always returns `false` .
2023-01-05 16:16:16 +02:00
- Numbers are type-compatible, see [arithmetic] operators.
2022-12-22 23:10:11 +02:00
- Floating point numbers only differ up to a limited precision.
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
[function]: ./constructs.md#functions
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
[Equality]: #equality
2022-12-22 22:21:26 +02:00
2022-12-22 23:10:11 +02:00
## Logical implication
2022-12-22 22:21:26 +02:00
2022-12-22 23:25:37 +02:00
Equivalent to `!` *b1* `||` *b2* .
2022-12-22 22:21:26 +02:00
2023-01-05 16:16:16 +02:00
[Logical implication]: #logical -implication
2022-12-22 22:21:26 +02:00