diff --git a/doc/manual/src/language/operators.md b/doc/manual/src/language/operators.md index 32398189d..797f13bd3 100644 --- a/doc/manual/src/language/operators.md +++ b/doc/manual/src/language/operators.md @@ -1,28 +1,167 @@ # Operators -The table below lists the operators in the Nix language, in -order of precedence (from strongest to weakest binding). +| 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 | +| Logical disjunction (`OR`) | *bool* `||` *bool* | left | 13 | +| [Logical implication] | *bool* `->` *bool* | none | 14 | + +[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 + +Select the attribute denoted by attribute path *attrpath* from [attribute set] *attrset*. +If the attribute doesn’t exist, return *value* if provided, otherwise abort evaluation. + + + +An attribute path is a dot-separated list of attribute names. +An attribute name can be an identifier or a string. + +> *attrpath* = *name* [ `.` *name* ]... +> *name* = *identifier* | *string* +> *identifier* ~ `[a-zA-Z_][a-zA-Z0-9_'-]*` + +[Attribute selection]: #attribute-selection + +## Has attribute + +> *attrset* `?` *attrpath* + +Test whether [attribute set] *attrset* contains the attribute denoted by *attrpath*. +The result is a [Boolean] value. + +[Boolean]: ./values.md#type-boolean + +[Has attribute]: #has-attribute + +## Arithmetic + +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. + +See also [Comparison] and [Equality]. + +The `+` operator is overloaded to also work on strings and paths. + +[arithmetic]: #arithmetic + +## String concatenation + +> *string* `+` *string* + +Concatenate two [string]s and merge their string contexts. + +[String concatenation]: #string-concatenation + +## Path concatenation + +> *path* `+` *path* + +Concatenate two [path]s. +The result is a path. + +[Path concatenation]: #path-concatenation + +## Path and string concatenation + +> *path* + *string* + +Concatenate *[path]* with *[string]*. +The result is a path. + +> **Note** +> +> The string must not have a string context that refers to a [store path]. + +[Path and string concatenation]: #path-and-string-concatenation + +## String and path concatenation + +> *string* + *path* + +Concatenate *[string]* with *[path]*. +The result is a string. + +> **Important** +> +> 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]. + +[store path]: ../glossary.md#gloss-store-path +[store]: ../glossary.md#gloss-store + +[Path and string concatenation]: #path-and-string-concatenation + +## Update + +> *attrset1* + *attrset2* + +Update [attribute set] *attrset1* with names and values from *attrset2*. + +The returned attribute set will have of all the attributes in *e1* and *e2*. +If an attribute name is present in both, the attribute value from the former is taken. + +[Update]: #update + +## Comparison + +Comparison is + +- [arithmetic] for [number]s +- lexicographic for [string]s and [path]s +- item-wise lexicographic for [list]s: + elements at the same index in both lists are compared according to their type and skipped if they are equal. + +All comparison operators are implemented in terms of `<`, and the following equivalencies hold: + +| comparison | implementation | +|--------------|-----------------------| +| *a* `<=` *b* | `! (` *b* `<` *a* `)` | +| *a* `>` *b* | *b* `<` *a* | +| *a* `>=` *b* | `! (` *a* `<` *b* `)` | + +[Comparison]: #comparison-operators + +## Equality + +- [Attribute sets][attribute set] and [list]s are compared recursively, and therefore are fully evaluated. +- Comparison of [function]s always returns `false`. +- Numbers are type-compatible, see [arithmetic] operators. +- Floating point numbers only differ up to a limited precision. + +[function]: ./constructs.md#functions + +[Equality]: #equality + +## Logical implication + +Equivalent to `!`*b1* `||` *b2*. + +[Logical implication]: #logical-implication -| Name | Syntax | Associativity | Description | Precedence | -| ------------------------ | ----------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| Select | *e* `.` *attrpath* \[ `or` *def* \] | none | Select attribute denoted by the attribute path *attrpath* from set *e*. (An attribute path is a dot-separated list of attribute names.) If the attribute doesn’t exist, return *def* if provided, otherwise abort evaluation. | 1 | -| Application | *e1* *e2* | left | Call function *e1* with argument *e2*. | 2 | -| Arithmetic Negation | `-` *e* | none | Arithmetic negation. | 3 | -| Has Attribute | *e* `?` *attrpath* | none | Test whether set *e* contains the attribute denoted by *attrpath*; return `true` or `false`. | 4 | -| List Concatenation | *e1* `++` *e2* | right | List concatenation. | 5 | -| Multiplication | *e1* `*` *e2*, | left | Arithmetic multiplication. | 6 | -| Division | *e1* `/` *e2* | left | Arithmetic division. | 6 | -| Addition | *e1* `+` *e2* | left | Arithmetic addition. | 7 | -| Subtraction | *e1* `-` *e2* | left | Arithmetic subtraction. | 7 | -| String Concatenation | *string1* `+` *string2* | left | String concatenation. | 7 | -| Not | `!` *e* | none | Boolean negation. | 8 | -| Update | *e1* `//` *e2* | right | Return a set consisting of the attributes in *e1* and *e2* (with the latter taking precedence over the former in case of equally named attributes). | 9 | -| Less Than | *e1* `<` *e2*, | none | Arithmetic/lexicographic comparison. | 10 | -| Less Than or Equal To | *e1* `<=` *e2* | none | Arithmetic/lexicographic comparison. | 10 | -| Greater Than | *e1* `>` *e2* | none | Arithmetic/lexicographic comparison. | 10 | -| Greater Than or Equal To | *e1* `>=` *e2* | none | Arithmetic/lexicographic comparison. | 10 | -| Equality | *e1* `==` *e2* | none | Equality. | 11 | -| Inequality | *e1* `!=` *e2* | none | Inequality. | 11 | -| Logical AND | *e1* `&&` *e2* | left | Logical AND. | 12 | -| Logical OR | *e1* || *e2* | left | Logical OR. | 13 | -| Logical Implication | *e1* `->` *e2* | none | Logical implication (equivalent to !e1 || e2). | 14 | diff --git a/doc/manual/src/language/values.md b/doc/manual/src/language/values.md index 08baa8f95..3973518ca 100644 --- a/doc/manual/src/language/values.md +++ b/doc/manual/src/language/values.md @@ -85,9 +85,10 @@ Numbers, which can be *integers* (like `123`) or *floating point* (like `123.43` or `.27e13`). - Numbers are type-compatible: pure integer operations will always - return integers, whereas any operation involving at least one - floating point number will have a floating point number as a result. + See [arithmetic] and [comparison] operators for semantics. + + [arithmetic]: ./operators.md#arithmetic + [comparison]: ./operators.md#comparison - Path