From caebe4112eb491d0168cf423174bccba918330f6 Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Thu, 22 Dec 2022 21:18:05 +0100 Subject: [PATCH 1/7] reorder columns this is for a simpler transformation into a series of subsections --- doc/manual/src/language/operators.md | 46 ++++++++++++++-------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/doc/manual/src/language/operators.md b/doc/manual/src/language/operators.md index 32398189d..e06e73b2d 100644 --- a/doc/manual/src/language/operators.md +++ b/doc/manual/src/language/operators.md @@ -3,26 +3,26 @@ The table below lists the operators in the Nix language, in order of precedence (from strongest to weakest binding). -| 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 | +| Name | Syntax | Description | Associativity | Precedence | +| ------------------------ | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ---------- | +| Select | *e* `.` *attrpath* \[ `or` *def* \] | 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. | none | 1 | +| Application | *e1* *e2* | Call function *e1* with argument *e2*. | left | 2 | +| Arithmetic Negation | `-` *e* | Arithmetic negation. | none | 3 | +| Has Attribute | *e* `?` *attrpath* | Test whether set *e* contains the attribute denoted by *attrpath*; return `true` or `false`. | none | 4 | +| List Concatenation | *e1* `++` *e2* | List concatenation. | right | 5 | +| Multiplication | *e1* `*` *e2*, | Arithmetic multiplication. | left | 6 | +| Division | *e1* `/` *e2* | Arithmetic division. | left | 6 | +| Addition | *e1* `+` *e2* | Arithmetic addition. | left | 7 | +| Subtraction | *e1* `-` *e2* | Arithmetic subtraction. | left | 7 | +| String Concatenation | *string1* `+` *string2* | String concatenation. | left | 7 | +| Not | `!` *e* | Boolean negation. | none | 8 | +| Update | *e1* `//` *e2* | 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). | right | 9 | +| Less Than | *e1* `<` *e2*, | Arithmetic/lexicographic comparison. | none | 10 | +| Less Than or Equal To | *e1* `<=` *e2* | Arithmetic/lexicographic comparison. | none | 10 | +| Greater Than | *e1* `>` *e2* | Arithmetic/lexicographic comparison. | none | 10 | +| Greater Than or Equal To | *e1* `>=` *e2* | Arithmetic/lexicographic comparison. | none | 10 | +| Equality | *e1* `==` *e2* | Equality. | none | 11 | +| Inequality | *e1* `!=` *e2* | Inequality. | none | 11 | +| Logical AND | *e1* `&&` *e2* | Logical AND. | left | 12 | +| Logical OR | *e1* || *e2* | Logical OR. | left | 13 | +| Logical Implication | *e1* `->` *e2* | Logical implication (equivalent to !e1 || e2). | none | 14 | From e07448ba6bdbbe9fb33fa0b652fef06635f1fc6d Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Thu, 22 Dec 2022 21:21:26 +0100 Subject: [PATCH 2/7] convert table to subsections this form is much easier to maintain (also with minimal diffs), and allows for more details on each operator. this change a purely mechanical transformation, without changing any contents. --- doc/manual/src/language/operators.md | 234 ++++++++++++++++++++++++--- 1 file changed, 209 insertions(+), 25 deletions(-) diff --git a/doc/manual/src/language/operators.md b/doc/manual/src/language/operators.md index e06e73b2d..aeb77b72a 100644 --- a/doc/manual/src/language/operators.md +++ b/doc/manual/src/language/operators.md @@ -1,28 +1,212 @@ # Operators -The table below lists the operators in the Nix language, in -order of precedence (from strongest to weakest binding). +## Select + +> *e* `.` *attrpath* \[ `or` *def* \] + +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. + +Associativity: none + +Precedence: 1 + +## Application + +> *e1* *e2* + +Call function *e1* with argument *e2*. + +Associativity: left + +Precedence: 2 + +## Arithmetic Negation + +> `-` *e* + +Arithmetic negation. + +Associativity: none + +Precedence: 3 + +## Has Attribute + +> *e* `?` *attrpath* + +Test whether set *e* contains the attribute denoted by *attrpath*; return `true` or `false`. + +Associativity: none + +Precedence: 4 + +## List Concatenation + +> *e1* `++` *e2* + +List concatenation. + +Associativity: right + +Precedence: 5 + +## Multiplication + +> *e1* `*` *e2*, + +Arithmetic multiplication. + +Associativity: left + +Precedence: 6 + +## Division + +> *e1* `/` *e2* + +Arithmetic division. + +Associativity: left + +Precedence: 6 + +## Addition + +> *e1* `+` *e2* + +Arithmetic addition. + +Associativity: left + +Precedence: 7 + +## Subtraction + +> *e1* `-` *e2* + +Arithmetic subtraction. + +Associativity: left + +Precedence: 7 + +## String Concatenation + +> *string1* `+` *string2* + +String concatenation. + +Associativity: left + +Precedence: 7 + +## Not + +> `!` *e* + +Boolean negation. + +Associativity: none + +Precedence: 8 + +## Update + +> *e1* `//` *e2* + +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). + +Associativity: right + +Precedence: 9 + +## Less Than + +> *e1* `<` *e2*, + +Arithmetic/lexicographic comparison. + +Associativity: none + +Precedence: 10 + +## Less Than or Equal To + +> *e1* `<=` *e2* + +Arithmetic/lexicographic comparison. + +Associativity: none + +Precedence: 10 + +## Greater Than + +> *e1* `>` *e2* + +Arithmetic/lexicographic comparison. + +Associativity: none + +Precedence: 10 + +## Greater Than or Equal To + +> *e1* `>=` *e2* + +Arithmetic/lexicographic comparison. + +Associativity: none + +Precedence: 10 + +## Equality + +> *e1* `==` *e2* + +Equality. + +Associativity: none + +Precedence: 11 + +## Inequality + +> *e1* `!=` *e2* + +Inequality. + +Associativity: none + +Precedence: 11 + +## Logical AND + +> *e1* `&&` *e2* + +Logical AND. + +Associativity: left + +Precedence: 12 + +## Logical OR + +> *e1* || *e2* + +Logical OR. + +Associativity: left + +Precedence: 13 + +## Logical Implication + +> *e1* `->` *e2* + +Logical implication (equivalent to !e1 || e2). + +Associativity: none + +Precedence: 14 -| Name | Syntax | Description | Associativity | Precedence | -| ------------------------ | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ---------- | -| Select | *e* `.` *attrpath* \[ `or` *def* \] | 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. | none | 1 | -| Application | *e1* *e2* | Call function *e1* with argument *e2*. | left | 2 | -| Arithmetic Negation | `-` *e* | Arithmetic negation. | none | 3 | -| Has Attribute | *e* `?` *attrpath* | Test whether set *e* contains the attribute denoted by *attrpath*; return `true` or `false`. | none | 4 | -| List Concatenation | *e1* `++` *e2* | List concatenation. | right | 5 | -| Multiplication | *e1* `*` *e2*, | Arithmetic multiplication. | left | 6 | -| Division | *e1* `/` *e2* | Arithmetic division. | left | 6 | -| Addition | *e1* `+` *e2* | Arithmetic addition. | left | 7 | -| Subtraction | *e1* `-` *e2* | Arithmetic subtraction. | left | 7 | -| String Concatenation | *string1* `+` *string2* | String concatenation. | left | 7 | -| Not | `!` *e* | Boolean negation. | none | 8 | -| Update | *e1* `//` *e2* | 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). | right | 9 | -| Less Than | *e1* `<` *e2*, | Arithmetic/lexicographic comparison. | none | 10 | -| Less Than or Equal To | *e1* `<=` *e2* | Arithmetic/lexicographic comparison. | none | 10 | -| Greater Than | *e1* `>` *e2* | Arithmetic/lexicographic comparison. | none | 10 | -| Greater Than or Equal To | *e1* `>=` *e2* | Arithmetic/lexicographic comparison. | none | 10 | -| Equality | *e1* `==` *e2* | Equality. | none | 11 | -| Inequality | *e1* `!=` *e2* | Inequality. | none | 11 | -| Logical AND | *e1* `&&` *e2* | Logical AND. | left | 12 | -| Logical OR | *e1* || *e2* | Logical OR. | left | 13 | -| Logical Implication | *e1* `->` *e2* | Logical implication (equivalent to !e1 || e2). | none | 14 | From 63b640e0c224fb959396f287b0db0c746a06c747 Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Thu, 22 Dec 2022 22:10:11 +0100 Subject: [PATCH 3/7] reword descriptions of operators add notes on semantics where appropriate --- doc/manual/src/language/operators.md | 99 +++++++++++++++++----------- doc/manual/src/language/values.md | 2 + 2 files changed, 61 insertions(+), 40 deletions(-) diff --git a/doc/manual/src/language/operators.md b/doc/manual/src/language/operators.md index aeb77b72a..e3a00d32b 100644 --- a/doc/manual/src/language/operators.md +++ b/doc/manual/src/language/operators.md @@ -1,36 +1,36 @@ # Operators -## Select +## Attribute selection > *e* `.` *attrpath* \[ `or` *def* \] -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. +Select the attribute denoted by attribute path *attrpath* from attribute 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. Associativity: none Precedence: 1 -## Application +## Function application -> *e1* *e2* +> *f* *e* -Call function *e1* with argument *e2*. +Call function *f* with argument *e*. Associativity: left Precedence: 2 -## Arithmetic Negation +## Arithmetic negation > `-` *e* -Arithmetic negation. - Associativity: none Precedence: 3 -## Has Attribute +## Has attribute > *e* `?` *attrpath* @@ -40,11 +40,11 @@ Associativity: none Precedence: 4 -## List Concatenation +## List concatenation > *e1* `++` *e2* -List concatenation. +Concatenate lists *e1* and *e2*. Associativity: right @@ -54,7 +54,7 @@ Precedence: 5 > *e1* `*` *e2*, -Arithmetic multiplication. +Multiply numbers *e1* and *e2*. Associativity: left @@ -64,7 +64,7 @@ Precedence: 6 > *e1* `/` *e2* -Arithmetic division. +Divide numbers *e1* and *e2*. Associativity: left @@ -74,7 +74,7 @@ Precedence: 6 > *e1* `+` *e2* -Arithmetic addition. +Add numbers *e1* and *e2*. Associativity: left @@ -84,77 +84,90 @@ Precedence: 7 > *e1* `-` *e2* -Arithmetic subtraction. +Subtract numbers *e2* from *e1*. Associativity: left Precedence: 7 -## String Concatenation +## String concatenation > *string1* `+` *string2* -String concatenation. +Concatenate *string1* and *string1* and merge their string contexts. Associativity: left Precedence: 7 -## Not +## Logical negation (`NOT`) > `!` *e* -Boolean negation. +Negate the Boolean value *e*. Associativity: none Precedence: 8 -## Update +## Merge attribute sets > *e1* `//` *e2* -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). +Return a set consisting of all the attributes in *e1* and *e2*. +If an attribute name is present in both, the attribute value from the former is taken. Associativity: right Precedence: 9 -## Less Than +## Less than > *e1* `<` *e2*, -Arithmetic/lexicographic comparison. +- Arithmetic comparison for numbers +- Lexicographic comparison for strings and paths +- Lexicographic comparison for lists: + Elements at the same index in both lists are compared according to their type and skipped if they are equal. Associativity: none Precedence: 10 -## Less Than or Equal To +## Less than or equal to > *e1* `<=` *e2* -Arithmetic/lexicographic comparison. +- Arithmetic comparison for numbers +- Lexicographic comparison for strings and paths +- Lexicographic comparison for lists: + Elements at the same index in both lists are compared according to their type and skipped if they are equal. Associativity: none Precedence: 10 -## Greater Than +## Greater than > *e1* `>` *e2* -Arithmetic/lexicographic comparison. +- Arithmetic comparison for numbers +- Lexicographic comparison for strings and paths +- Lexicographic comparison for lists: + Elements at the same index in both lists are compared according to their type and skipped if they are equal. Associativity: none Precedence: 10 -## Greater Than or Equal To +## Greater than or equal to > *e1* `>=` *e2* -Arithmetic/lexicographic comparison. +- Arithmetic comparison for numbers +- Lexicographic comparison for strings and paths +- Lexicographic comparison for lists: + Elements at the same index in both lists are compared according to their type and skipped if they are equal. Associativity: none @@ -164,7 +177,12 @@ Precedence: 10 > *e1* `==` *e2* -Equality. +Check *e1* and *e2* for equality. + +- Attribute sets and lists are compared recursively, and therefore are fully evaluated. +- Comparison of functions always returns `false`. +- Integers are coerced to floating point numbers if compared to floating point numbers. +- Floating point numbers only differ up to a limited precision. Associativity: none @@ -174,39 +192,40 @@ Precedence: 11 > *e1* `!=` *e2* -Inequality. +Equivalent to `! (`*e1* `==` *e2* `)` Associativity: none Precedence: 11 -## Logical AND +## Logical conjunction (`AND`) > *e1* `&&` *e2* -Logical AND. +Return `true` if and only if both `e1` and `e2` evaluate to `true`, otherwise `false`. Associativity: left Precedence: 12 -## Logical OR +## Logical disjunction (`OR`) -> *e1* || *e2* +> *e1* `||` *e2* -Logical OR. +Return `true` if at least `e1` or `e2` evaluate to `true`, otherwise `false`. Associativity: left Precedence: 13 -## Logical Implication +## Logical implication -> *e1* `->` *e2* +> *e1* `->` *e2* -Logical implication (equivalent to !e1 || e2). +Return `false` if *e1* evaluates to `true` and *e2* evaluates to `false`, otherwise `true`. + +Equivalent to `!`*e1* `||` *e2*. Associativity: none Precedence: 14 - diff --git a/doc/manual/src/language/values.md b/doc/manual/src/language/values.md index 08baa8f95..d92f287a3 100644 --- a/doc/manual/src/language/values.md +++ b/doc/manual/src/language/values.md @@ -89,6 +89,8 @@ return integers, whereas any operation involving at least one floating point number will have a floating point number as a result. + Floating point numbers only differ up to a limited precision. + - Path *Paths*, e.g., `/bin/sh` or `./builder.sh`. A path must contain at From 969e5ad5bfc6527b8205182e50ba4ec216f218a0 Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Thu, 22 Dec 2022 22:11:17 +0100 Subject: [PATCH 4/7] add semantics of overloaded `+` operator --- doc/manual/src/language/operators.md | 58 +++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/doc/manual/src/language/operators.md b/doc/manual/src/language/operators.md index e3a00d32b..0c8cc6f57 100644 --- a/doc/manual/src/language/operators.md +++ b/doc/manual/src/language/operators.md @@ -70,16 +70,6 @@ Associativity: left Precedence: 6 -## Addition - -> *e1* `+` *e2* - -Add numbers *e1* and *e2*. - -Associativity: left - -Precedence: 7 - ## Subtraction > *e1* `-` *e2* @@ -90,6 +80,16 @@ Associativity: left Precedence: 7 +## Addition + +> *e1* `+` *e2* + +Add numbers *e1* and *e2*. + +Associativity: left + +Precedence: 7 + ## String concatenation > *string1* `+` *string2* @@ -100,6 +100,44 @@ Associativity: left Precedence: 7 +## Path concatenation + +> *path1* `+` *path2* + +Concatenate two paths. +The result is a path. + +## 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. + +Associativity: left + +Precedence: 7 + +## 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. + +Associativity: left + +Precedence: 7 + ## Logical negation (`NOT`) > `!` *e* From 7b2b9e3648920077fb53ced4f0b3bec3e0db5729 Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Thu, 22 Dec 2022 22:25:37 +0100 Subject: [PATCH 5/7] use more self-explanatory placeholder names --- doc/manual/src/language/operators.md | 121 +++++++++++---------------- 1 file changed, 50 insertions(+), 71 deletions(-) diff --git a/doc/manual/src/language/operators.md b/doc/manual/src/language/operators.md index 0c8cc6f57..459ea9945 100644 --- a/doc/manual/src/language/operators.md +++ b/doc/manual/src/language/operators.md @@ -2,11 +2,11 @@ ## Attribute selection -> *e* `.` *attrpath* \[ `or` *def* \] +> *attrset* `.` *attrpath* \[ `or` *value* \] -Select the attribute denoted by attribute path *attrpath* from attribute set *e*. +Select the attribute denoted by attribute path *attrpath* from attribute set *attrset*. An attribute path is a dot-separated list of attribute names. -If the attribute doesn’t exist, return *def* if provided, otherwise abort evaluation. +If the attribute doesn’t exist, return *value* if provided, otherwise abort evaluation. Associativity: none @@ -14,9 +14,9 @@ Precedence: 1 ## Function application -> *f* *e* +> *f* *a* -Call function *f* with argument *e*. +Call function *f* with argument *a*. Associativity: left @@ -24,7 +24,9 @@ Precedence: 2 ## Arithmetic negation -> `-` *e* +> `-` *n* + +Flip the sign of the number *n*. Associativity: none @@ -32,9 +34,9 @@ Precedence: 3 ## Has attribute -> *e* `?` *attrpath* +> *attrset* `?` *attrpath* -Test whether set *e* contains the attribute denoted by *attrpath*; return `true` or `false`. +Test whether attribute set *attrset* contains the attribute denoted by *attrpath*; return `true` or `false`. Associativity: none @@ -42,9 +44,9 @@ Precedence: 4 ## List concatenation -> *e1* `++` *e2* +> *list1* `++` *list2* -Concatenate lists *e1* and *e2*. +Concatenate lists *list1* and *list2*. Associativity: right @@ -52,9 +54,9 @@ Precedence: 5 ## Multiplication -> *e1* `*` *e2*, +> *n1* `*` *n2*, -Multiply numbers *e1* and *e2*. +Multiply numbers *n1* and *n2*. Associativity: left @@ -62,9 +64,9 @@ Precedence: 6 ## Division -> *e1* `/` *e2* +> *n1* `/` *n2* -Divide numbers *e1* and *e2*. +Divide numbers *n1* and *n2*. Associativity: left @@ -72,9 +74,9 @@ Precedence: 6 ## Subtraction -> *e1* `-` *e2* +> *n1* `-` *n2* -Subtract numbers *e2* from *e1*. +Subtract numbers *n2* from *n1*. Associativity: left @@ -82,9 +84,9 @@ Precedence: 7 ## Addition -> *e1* `+` *e2* +> *n1* `+` *n2* -Add numbers *e1* and *e2*. +Add numbers *n1* and *n2*. Associativity: left @@ -140,82 +142,59 @@ Precedence: 7 ## Logical negation (`NOT`) -> `!` *e* +> `!` *b* -Negate the Boolean value *e*. +Negate the Boolean value *b*. Associativity: none Precedence: 8 -## Merge attribute sets +## Update -> *e1* `//` *e2* +> *attrset1* `//` *attrset1* -Return a set consisting of all the attributes in *e1* and *e2*. +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. Associativity: right Precedence: 9 -## Less than +## Comparison + +- Arithmetic comparison for numbers +- Lexicographic comparison for strings and paths +- Lexicographic comparison for lists: + Elements at the same index in both lists are compared according to their type and skipped if they are equal. + +Associativity: none + +Precedence: 10 + +### Less than > *e1* `<` *e2*, -- Arithmetic comparison for numbers -- Lexicographic comparison for strings and paths -- Lexicographic comparison for lists: - Elements at the same index in both lists are compared according to their type and skipped if they are equal. - -Associativity: none - -Precedence: 10 - -## Less than or equal to +### Less than or equal to > *e1* `<=` *e2* -- Arithmetic comparison for numbers -- Lexicographic comparison for strings and paths -- Lexicographic comparison for lists: - Elements at the same index in both lists are compared according to their type and skipped if they are equal. - -Associativity: none - -Precedence: 10 - -## Greater than +### Greater than > *e1* `>` *e2* -- Arithmetic comparison for numbers -- Lexicographic comparison for strings and paths -- Lexicographic comparison for lists: - Elements at the same index in both lists are compared according to their type and skipped if they are equal. - -Associativity: none - -Precedence: 10 - -## Greater than or equal to +### Greater than or equal to > *e1* `>=` *e2* -- Arithmetic comparison for numbers -- Lexicographic comparison for strings and paths -- Lexicographic comparison for lists: - Elements at the same index in both lists are compared according to their type and skipped if they are equal. - -Associativity: none - -Precedence: 10 - ## Equality > *e1* `==` *e2* -Check *e1* and *e2* for equality. +Check expressions *e1* and *e2* for value equality. - Attribute sets and lists are compared recursively, and therefore are fully evaluated. - Comparison of functions always returns `false`. @@ -238,9 +217,9 @@ Precedence: 11 ## Logical conjunction (`AND`) -> *e1* `&&` *e2* +> *b1* `&&` *b2* -Return `true` if and only if both `e1` and `e2` evaluate to `true`, otherwise `false`. +Return `true` if and only if both `b1` and `b2` evaluate to `true`, otherwise `false`. Associativity: left @@ -248,9 +227,9 @@ Precedence: 12 ## Logical disjunction (`OR`) -> *e1* `||` *e2* +> *b1* `||` *b2* -Return `true` if at least `e1` or `e2` evaluate to `true`, otherwise `false`. +Return `true` if at least one of `b1` or `b2` evaluate to `true`, otherwise `false`. Associativity: left @@ -258,11 +237,11 @@ Precedence: 13 ## Logical implication -> *e1* `->` *e2* +> *b1* `->` *b2* -Return `false` if *e1* evaluates to `true` and *e2* evaluates to `false`, otherwise `true`. +Return `false` if *b1* evaluates to `true` and *b2* evaluates to `false`, otherwise `true`. -Equivalent to `!`*e1* `||` *e2*. +Equivalent to `!`*b1* `||` *b2*. Associativity: none From 7da59e94ae6d5123acbca7bdbbef4d08b02fc709 Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Fri, 23 Dec 2022 08:58:19 +0100 Subject: [PATCH 6/7] add links to documentation for data types --- doc/manual/src/language/operators.md | 56 ++++++++++++++++------------ 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/doc/manual/src/language/operators.md b/doc/manual/src/language/operators.md index 459ea9945..1f11e6ac5 100644 --- a/doc/manual/src/language/operators.md +++ b/doc/manual/src/language/operators.md @@ -4,7 +4,7 @@ > *attrset* `.` *attrpath* \[ `or` *value* \] -Select the attribute denoted by attribute path *attrpath* from attribute set *attrset*. +Select the attribute denoted by attribute path *attrpath* from [attribute set] *attrset*. An attribute path is a dot-separated list of attribute names. If the attribute doesn’t exist, return *value* if provided, otherwise abort evaluation. @@ -16,7 +16,7 @@ Precedence: 1 > *f* *a* -Call function *f* with argument *a*. +Call [function] *f* with argument *a*. Associativity: left @@ -26,7 +26,7 @@ Precedence: 2 > `-` *n* -Flip the sign of the number *n*. +Flip the sign of the [number] *n*. Associativity: none @@ -36,7 +36,7 @@ Precedence: 3 > *attrset* `?` *attrpath* -Test whether attribute set *attrset* contains the attribute denoted by *attrpath*; return `true` or `false`. +Test whether [attribute set] *attrset* contains the attribute denoted by *attrpath*; return `true` or `false`. Associativity: none @@ -46,7 +46,7 @@ Precedence: 4 > *list1* `++` *list2* -Concatenate lists *list1* and *list2*. +Concatenate [list]s *list1* and *list2*. Associativity: right @@ -56,7 +56,7 @@ Precedence: 5 > *n1* `*` *n2*, -Multiply numbers *n1* and *n2*. +Multiply [number]s *n1* and *n2*. Associativity: left @@ -66,7 +66,7 @@ Precedence: 6 > *n1* `/` *n2* -Divide numbers *n1* and *n2*. +Divide [number]s *n1* and *n2*. Associativity: left @@ -76,7 +76,7 @@ Precedence: 6 > *n1* `-` *n2* -Subtract numbers *n2* from *n1*. +Subtract [number] *n2* from *n1*. Associativity: left @@ -86,7 +86,7 @@ Precedence: 7 > *n1* `+` *n2* -Add numbers *n1* and *n2*. +Add [number]s *n1* and *n2*. Associativity: left @@ -96,7 +96,7 @@ Precedence: 7 > *string1* `+` *string2* -Concatenate *string1* and *string1* and merge their string contexts. +Concatenate two [string]s and merge their string contexts. Associativity: left @@ -106,19 +106,19 @@ Precedence: 7 > *path1* `+` *path2* -Concatenate two paths. +Concatenate two [path]s. The result is a path. ## Path and string concatenation > *path* `+` *string* -Concatenate *path* with *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. +> The string must not have a string context that refers to a [store path]. Associativity: left @@ -128,13 +128,13 @@ Precedence: 7 > *string* `+` *path* -Concatenate *string* with *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. +> 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]. Associativity: left @@ -144,7 +144,7 @@ Precedence: 7 > `!` *b* -Negate the Boolean value *b*. +Negate the [Boolean] value *b*. Associativity: none @@ -154,7 +154,7 @@ Precedence: 8 > *attrset1* `//` *attrset1* -Update attribute set *attrset1* with names and values from *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. @@ -165,9 +165,9 @@ Precedence: 9 ## Comparison -- Arithmetic comparison for numbers -- Lexicographic comparison for strings and paths -- Lexicographic comparison for lists: +- Arithmetic comparison for [number]s +- Lexicographic comparison for [string]s and [path]s +- Lexicographic comparison for [list]s: Elements at the same index in both lists are compared according to their type and skipped if they are equal. Associativity: none @@ -196,8 +196,8 @@ Precedence: 10 Check expressions *e1* and *e2* for value equality. -- Attribute sets and lists are compared recursively, and therefore are fully evaluated. -- Comparison of functions always returns `false`. +- [Attribute sets][attribute set] and [list]s are compared recursively, and therefore are fully evaluated. +- Comparison of [function]s always returns `false`. - Integers are coerced to floating point numbers if compared to floating point numbers. - Floating point numbers only differ up to a limited precision. @@ -246,3 +246,13 @@ Equivalent to `!`*b1* `||` *b2*. Associativity: none Precedence: 14 + +[string]: ./values.md#type-string +[path]: ./values.md#type-path +[number]: ./values.md#type-number +[Boolean]: ./values.md#type-boolean +[list]: ./values.md#list +[attribute set]: ./values.md#attribute-set +[function]: ./constructs.md#functions +[store path]: ../glossary.md#gloss-store-path +[store]: ../glossary.md#gloss-store From e57165b85a48daba3649b08cff3eab3519bc8dce Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Thu, 5 Jan 2023 15:16:16 +0100 Subject: [PATCH 7/7] bring back table, extract annotations this makes the table less unwieldy, and leaves enough space for extensive explanations. --- doc/manual/src/language/operators.md | 249 +++++++++------------------ doc/manual/src/language/values.md | 7 +- 2 files changed, 82 insertions(+), 174 deletions(-) diff --git a/doc/manual/src/language/operators.md b/doc/manual/src/language/operators.md index 1f11e6ac5..797f13bd3 100644 --- a/doc/manual/src/language/operators.md +++ b/doc/manual/src/language/operators.md @@ -1,117 +1,96 @@ # Operators +| 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 -> *attrset* `.` *attrpath* \[ `or` *value* \] - Select the attribute denoted by attribute path *attrpath* from [attribute set] *attrset*. -An attribute path is a dot-separated list of attribute names. If the attribute doesn’t exist, return *value* if provided, otherwise abort evaluation. -Associativity: none + -Precedence: 1 +An attribute path is a dot-separated list of attribute names. +An attribute name can be an identifier or a string. -## Function application +> *attrpath* = *name* [ `.` *name* ]... +> *name* = *identifier* | *string* +> *identifier* ~ `[a-zA-Z_][a-zA-Z0-9_'-]*` -> *f* *a* - -Call [function] *f* with argument *a*. - -Associativity: left - -Precedence: 2 - -## Arithmetic negation - -> `-` *n* - -Flip the sign of the [number] *n*. - -Associativity: none - -Precedence: 3 +[Attribute selection]: #attribute-selection ## Has attribute > *attrset* `?` *attrpath* -Test whether [attribute set] *attrset* contains the attribute denoted by *attrpath*; return `true` or `false`. +Test whether [attribute set] *attrset* contains the attribute denoted by *attrpath*. +The result is a [Boolean] value. -Associativity: none +[Boolean]: ./values.md#type-boolean -Precedence: 4 +[Has attribute]: #has-attribute -## List concatenation +## Arithmetic -> *list1* `++` *list2* +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. -Concatenate [list]s *list1* and *list2*. +See also [Comparison] and [Equality]. -Associativity: right +The `+` operator is overloaded to also work on strings and paths. -Precedence: 5 - -## Multiplication - -> *n1* `*` *n2*, - -Multiply [number]s *n1* and *n2*. - -Associativity: left - -Precedence: 6 - -## Division - -> *n1* `/` *n2* - -Divide [number]s *n1* and *n2*. - -Associativity: left - -Precedence: 6 - -## Subtraction - -> *n1* `-` *n2* - -Subtract [number] *n2* from *n1*. - -Associativity: left - -Precedence: 7 - -## Addition - -> *n1* `+` *n2* - -Add [number]s *n1* and *n2*. - -Associativity: left - -Precedence: 7 +[arithmetic]: #arithmetic ## String concatenation -> *string1* `+` *string2* +> *string* `+` *string* Concatenate two [string]s and merge their string contexts. -Associativity: left - -Precedence: 7 +[String concatenation]: #string-concatenation ## Path concatenation -> *path1* `+` *path2* +> *path* `+` *path* Concatenate two [path]s. The result is a path. +[Path concatenation]: #path-concatenation + ## Path and string concatenation -> *path* `+` *string* +> *path* + *string* Concatenate *[path]* with *[string]*. The result is a path. @@ -120,13 +99,11 @@ The result is a path. > > The string must not have a string context that refers to a [store path]. -Associativity: left - -Precedence: 7 +[Path and string concatenation]: #path-and-string-concatenation ## String and path concatenation -> *string* `+` *path* +> *string* + *path* Concatenate *[string]* with *[path]*. The result is a string. @@ -136,123 +113,55 @@ The result is a string. > 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]. -Associativity: left +[store path]: ../glossary.md#gloss-store-path +[store]: ../glossary.md#gloss-store -Precedence: 7 - -## Logical negation (`NOT`) - -> `!` *b* - -Negate the [Boolean] value *b*. - -Associativity: none - -Precedence: 8 +[Path and string concatenation]: #path-and-string-concatenation ## Update -> *attrset1* `//` *attrset1* +> *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. -Associativity: right - -Precedence: 9 +[Update]: #update ## Comparison -- Arithmetic comparison for [number]s -- Lexicographic comparison for [string]s and [path]s -- Lexicographic comparison for [list]s: - Elements at the same index in both lists are compared according to their type and skipped if they are equal. +Comparison is -Associativity: none +- [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. -Precedence: 10 +All comparison operators are implemented in terms of `<`, and the following equivalencies hold: -### Less than +| comparison | implementation | +|--------------|-----------------------| +| *a* `<=` *b* | `! (` *b* `<` *a* `)` | +| *a* `>` *b* | *b* `<` *a* | +| *a* `>=` *b* | `! (` *a* `<` *b* `)` | -> *e1* `<` *e2*, - -### Less than or equal to - -> *e1* `<=` *e2* - -### Greater than - -> *e1* `>` *e2* - -### Greater than or equal to - -> *e1* `>=` *e2* +[Comparison]: #comparison-operators ## Equality -> *e1* `==` *e2* - -Check expressions *e1* and *e2* for value equality. - - [Attribute sets][attribute set] and [list]s are compared recursively, and therefore are fully evaluated. - Comparison of [function]s always returns `false`. -- Integers are coerced to floating point numbers if compared to floating point numbers. +- Numbers are type-compatible, see [arithmetic] operators. - Floating point numbers only differ up to a limited precision. -Associativity: none +[function]: ./constructs.md#functions -Precedence: 11 - -## Inequality - -> *e1* `!=` *e2* - -Equivalent to `! (`*e1* `==` *e2* `)` - -Associativity: none - -Precedence: 11 - -## Logical conjunction (`AND`) - -> *b1* `&&` *b2* - -Return `true` if and only if both `b1` and `b2` evaluate to `true`, otherwise `false`. - -Associativity: left - -Precedence: 12 - -## Logical disjunction (`OR`) - -> *b1* `||` *b2* - -Return `true` if at least one of `b1` or `b2` evaluate to `true`, otherwise `false`. - -Associativity: left - -Precedence: 13 +[Equality]: #equality ## Logical implication -> *b1* `->` *b2* - -Return `false` if *b1* evaluates to `true` and *b2* evaluates to `false`, otherwise `true`. - Equivalent to `!`*b1* `||` *b2*. -Associativity: none +[Logical implication]: #logical-implication -Precedence: 14 - -[string]: ./values.md#type-string -[path]: ./values.md#type-path -[number]: ./values.md#type-number -[Boolean]: ./values.md#type-boolean -[list]: ./values.md#list -[attribute set]: ./values.md#attribute-set -[function]: ./constructs.md#functions -[store path]: ../glossary.md#gloss-store-path -[store]: ../glossary.md#gloss-store diff --git a/doc/manual/src/language/values.md b/doc/manual/src/language/values.md index d92f287a3..3973518ca 100644 --- a/doc/manual/src/language/values.md +++ b/doc/manual/src/language/values.md @@ -85,11 +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. - Floating point numbers only differ up to a limited precision. + [arithmetic]: ./operators.md#arithmetic + [comparison]: ./operators.md#comparison - Path