From 31ba0a2ded2900d8bdc0529a6a7007d00ab189cb Mon Sep 17 00:00:00 2001 From: "Reece H. Dunn" Date: Thu, 18 Oct 2018 20:20:55 +0100 Subject: [PATCH 1/8] Proposal for Tuple Sequence and Array Decomposition --- tuple-decomposition.md | 119 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 tuple-decomposition.md diff --git a/tuple-decomposition.md b/tuple-decomposition.md new file mode 100644 index 0000000..711722b --- /dev/null +++ b/tuple-decomposition.md @@ -0,0 +1,119 @@ +# Tuple Decomposition + +**Author**: Reece H. Dunn. 67 Bricks. + +This proposal allows fixed length sequences and arrays to be decomposed and assigned to separate variables in a single declaration. + + +## Description + +\[Definition: A *tuple sequence* is a fixed length sequence, where the items in the array represent distinct parts of an object, not an ordered collection of objects.\] For example, a 2D point could be represented as a tuple sequence, where the first value will be the x coordinate and the second value the y coordinate. + +\[Definition: A *tuple array* is a fixed length array, where the items in the array represent distinct parts of an object, not an ordered collection of objects.] The 2D point example could also be represented as an array with 2 values. An array can also be used for objects that contain optional items. + +\[Definition: A *tuple* is a tuple sequence or tuple array.\] + +Given a tuple such as `(1, 2, 3)`, the values within that sequence or array cannot easily be extracted. With the current version of XPath and XQuery, they need to be assigned to a temporary variable first. For example: + + let $result := get-camera-point() + let $x := $result[1] + let $y := $result[2] + let $x := $result[3] + return "(" || $x || "," || $y || "," || $z || ")" + +This proposal would allow this to be written more concisely as: + + let ($x, $y, $z) := get-camera-point() + return "(" || $x || "," || $y || "," || $z || ")" + +An XPath or XQuery processor may implement this by transforming it to the expanded form above with `$result` being a unique variable that is not visible to the expression. + +For tuple sequences, `$tuple[N]` would be used to extract the nth item in the tuple sequence. If the item does not exist, an empty sequence is returned. + +For tuple arrays, `$tuple(N)` or `array:get($tuple, N)` would be used to extract the nth item in the tuple array. If the item does not exist, an `err:FOAY0001` (array index out of bounds) error will be raised. + +This would apply to any variable declaration or binding where `:=` is used to assign a variable to an expression. Specifically: + +1. variable declarations, including decomposition of default values (XQuery) +1. context item declaration (XQuery) +1. let clauses (XPath/XQuery) +1. for clauses (XPath/XQuery) +1. grouping spec (XQuery) + +### Variation: Separate Tuple Array Decomposition Syntax + +If the tuple decomposition is being performed on a tuple array, it may be better to use array syntax to define the composition: + + let [$x, $y, $z] := get-camera-point() + return "(" || $x || "," || $y || "," || $z || ")" + +The `(...)` syntax would then be *tuple sequence decomposition*, while the `[...]` syntax would be *tuple array decomposition*. + +This would allow XPath/XQuery processors to report an error if tuple sequence decomposition was used on tuple arrays, and when tuple array decomposition was used on tuple sequences. + +This would make it clearer to the user when a sequence is expected and when an array is expected, and thus when out of bounds access would result in an empty sequence or an error. + +This does add an additional level of complexity to the language grammar, but may help processors decide how to decompose the tuple values as determining whether the tuple type being decomposed is a sequence or array can be determined during the static analysis phase. + +### Assigning the rest of a sequence or array + +It can be useful to only extract part of a sequence or array (e.g. the heading of a table), and store the rest of the items in another variable. For example: + + let ($heading as array(xs:string), $rows as array(xs:string)*) := load-csv("test.csv") + +It may be useful to define a shorthand for selecting the rest of the sequence or array. Using the CSV example above: + + let ($heading, $rows*) := load-csv("test.csv") + +The other occurrence indicators would also be usable after the last variable binding. + +### Influences + +Tuple decomposition is found in various languages such as Python, Scala, and C#. These languages also have support for tuple types. + +Python has support for specifying that a variable is assigned the remaining values in the tuple. + +## Use Cases + +There are many cases where fixed size sequences (*tuple sequences*) may be used such as points, complex and rational numbers, sin/cos, and mul/div. This makes extracting data from these simpler, and may also be used to aid readability by assigning descriptive names to each of the tuple items. + +### Potential Confusion and Complexity + +From a user's perspective it would be confusing if an item in the sequence is an empty sequence, as the items after that would be assigned to the wrong variable. However, this is no different from them using the long form to extract the values from the tuple sequence. + +There is a potential for confusion if changing from a sequence return type to an array, where the code may subsequently raise an `err:FOAY0001` error. The reason for this is hidden from the user. + +There is complexity for the semantics of variable declarations, especially those with external values. If this is deemed too complex, it can be dropped from this proposal. + + +## Examples + +Extracting values from a tuple sequence: + + declare function sincos($angle as xs:double?) { + math:sin($angle), math:cos($angle) + }; + + let $angle := math:pi() + let ($sin, $cos) := sincos($angle) + return $sin || "," || $cos + +Extracting values from a tuple array: + + declare function sincos($angle as xs:double?) { + [ math:sin($angle), math:cos($angle) ] + }; + + let $angle := math:pi() + let ($sin, $cos) := sincos($angle) + return $sin || "," || $cos + +Extracting values with typed variables: + + let ($x as xs:double, $y as xs:double) := polar-to-cartesian(1.0, math:pi()) + return "x=" || $x || ", y=" || $y + + +## Grammar + +TBD. \ No newline at end of file From 805c0e1d5b6ff5cd4b2b52d007092decbd27e88d Mon Sep 17 00:00:00 2001 From: "Reece H. Dunn" Date: Sun, 28 Oct 2018 19:44:25 +0000 Subject: [PATCH 2/8] tuple decomposition: replace references to tuples with direct references to the XPath/XQuery sequence and array types. --- tuple-decomposition.md | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/tuple-decomposition.md b/tuple-decomposition.md index 711722b..c01d22e 100644 --- a/tuple-decomposition.md +++ b/tuple-decomposition.md @@ -1,19 +1,15 @@ -# Tuple Decomposition +# Sequence and Array Decomposition **Author**: Reece H. Dunn. 67 Bricks. -This proposal allows fixed length sequences and arrays to be decomposed and assigned to separate variables in a single declaration. +**Revision**: 2 +This proposal allows sequences and arrays to be decomposed and assigned to separate variables in a single declaration. -## Description - -\[Definition: A *tuple sequence* is a fixed length sequence, where the items in the array represent distinct parts of an object, not an ordered collection of objects.\] For example, a 2D point could be represented as a tuple sequence, where the first value will be the x coordinate and the second value the y coordinate. -\[Definition: A *tuple array* is a fixed length array, where the items in the array represent distinct parts of an object, not an ordered collection of objects.] The 2D point example could also be represented as an array with 2 values. An array can also be used for objects that contain optional items. - -\[Definition: A *tuple* is a tuple sequence or tuple array.\] +## Description -Given a tuple such as `(1, 2, 3)`, the values within that sequence or array cannot easily be extracted. With the current version of XPath and XQuery, they need to be assigned to a temporary variable first. For example: +Given a sequence such as `(1, 2, 3)`, the values within that sequence or array cannot easily be extracted. With the current version of XPath and XQuery, they need to be assigned to a temporary variable first. For example: let $result := get-camera-point() let $x := $result[1] @@ -28,9 +24,9 @@ This proposal would allow this to be written more concisely as: An XPath or XQuery processor may implement this by transforming it to the expanded form above with `$result` being a unique variable that is not visible to the expression. -For tuple sequences, `$tuple[N]` would be used to extract the nth item in the tuple sequence. If the item does not exist, an empty sequence is returned. +For sequences, `$seq[N]` would be used to extract the nth item in the sequence. If the item does not exist, an empty sequence is returned. -For tuple arrays, `$tuple(N)` or `array:get($tuple, N)` would be used to extract the nth item in the tuple array. If the item does not exist, an `err:FOAY0001` (array index out of bounds) error will be raised. +For arrays, `$array(N)` or `array:get($array, N)` would be used to extract the nth item in the array. If the item does not exist, an `err:FOAY0001` (array index out of bounds) error will be raised. This would apply to any variable declaration or binding where `:=` is used to assign a variable to an expression. Specifically: @@ -42,18 +38,18 @@ This would apply to any variable declaration or binding where `:=` is used to as ### Variation: Separate Tuple Array Decomposition Syntax -If the tuple decomposition is being performed on a tuple array, it may be better to use array syntax to define the composition: +If the decomposition is being performed on an array, it may be better to use array syntax to define the composition: let [$x, $y, $z] := get-camera-point() return "(" || $x || "," || $y || "," || $z || ")" -The `(...)` syntax would then be *tuple sequence decomposition*, while the `[...]` syntax would be *tuple array decomposition*. +The `(...)` syntax would then be *sequence decomposition*, while the `[...]` syntax would be *array decomposition*. -This would allow XPath/XQuery processors to report an error if tuple sequence decomposition was used on tuple arrays, and when tuple array decomposition was used on tuple sequences. +This would allow XPath/XQuery processors to report an error if sequence decomposition was used on arrays, and when array decomposition was used on sequences. This would make it clearer to the user when a sequence is expected and when an array is expected, and thus when out of bounds access would result in an empty sequence or an error. -This does add an additional level of complexity to the language grammar, but may help processors decide how to decompose the tuple values as determining whether the tuple type being decomposed is a sequence or array can be determined during the static analysis phase. +This does add an additional level of complexity to the language grammar, but may help processors decide how to decompose the values as determining whether the type being decomposed is a sequence or array can be determined during the static analysis phase. ### Assigning the rest of a sequence or array @@ -75,11 +71,11 @@ Python has support for specifying that a variable is assigned the remaining valu ## Use Cases -There are many cases where fixed size sequences (*tuple sequences*) may be used such as points, complex and rational numbers, sin/cos, and mul/div. This makes extracting data from these simpler, and may also be used to aid readability by assigning descriptive names to each of the tuple items. +There are many cases where fixed size sequences may be used such as points, complex and rational numbers, sin/cos, and mul/div. This makes extracting data from these simpler, and may also be used to aid readability by assigning descriptive names to each of the items in the sequence. ### Potential Confusion and Complexity -From a user's perspective it would be confusing if an item in the sequence is an empty sequence, as the items after that would be assigned to the wrong variable. However, this is no different from them using the long form to extract the values from the tuple sequence. +From a user's perspective it would be confusing if an item in the sequence is an empty sequence, as the items after that would be assigned to the wrong variable. However, this is no different from them using the long form to extract the values from the sequence. There is a potential for confusion if changing from a sequence return type to an array, where the code may subsequently raise an `err:FOAY0001` error. The reason for this is hidden from the user. @@ -88,7 +84,7 @@ There is complexity for the semantics of variable declarations, especially those ## Examples -Extracting values from a tuple sequence: +Extracting values from a sequence: declare function sincos($angle as xs:double?) { math:sin($angle), math:cos($angle) @@ -98,7 +94,7 @@ Extracting values from a tuple sequence: let ($sin, $cos) := sincos($angle) return $sin || "," || $cos -Extracting values from a tuple array: +Extracting values from an array: declare function sincos($angle as xs:double?) { [ math:sin($angle), math:cos($angle) ] @@ -116,4 +112,10 @@ Extracting values with typed variables: ## Grammar -TBD. \ No newline at end of file +TBD. + + +## Version History + +1. Initial proposal. +1. Remove references to tuples, except for the influences section. From ccb636c012c4bf851249f55c86ecec09baba4086 Mon Sep 17 00:00:00 2001 From: "Reece H. Dunn" Date: Sun, 28 Oct 2018 19:57:13 +0000 Subject: [PATCH 3/8] sequence and array decomposition: update the syntax from feedback by Michael Kay and Christian Gruen. --- tuple-decomposition.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tuple-decomposition.md b/tuple-decomposition.md index c01d22e..ed5f7db 100644 --- a/tuple-decomposition.md +++ b/tuple-decomposition.md @@ -19,7 +19,7 @@ Given a sequence such as `(1, 2, 3)`, the values within that sequence or array c This proposal would allow this to be written more concisely as: - let ($x, $y, $z) := get-camera-point() + let $(x, y, z) := get-camera-point() return "(" || $x || "," || $y || "," || $z || ")" An XPath or XQuery processor may implement this by transforming it to the expanded form above with `$result` being a unique variable that is not visible to the expression. @@ -40,7 +40,7 @@ This would apply to any variable declaration or binding where `:=` is used to as If the decomposition is being performed on an array, it may be better to use array syntax to define the composition: - let [$x, $y, $z] := get-camera-point() + let $[x, y, z] := get-camera-point() return "(" || $x || "," || $y || "," || $z || ")" The `(...)` syntax would then be *sequence decomposition*, while the `[...]` syntax would be *array decomposition*. @@ -55,11 +55,12 @@ This does add an additional level of complexity to the language grammar, but may It can be useful to only extract part of a sequence or array (e.g. the heading of a table), and store the rest of the items in another variable. For example: - let ($heading as array(xs:string), $rows as array(xs:string)*) := load-csv("test.csv") + let $(heading as array(xs:string), rows as array(xs:string)...) := + load-csv("test.csv") It may be useful to define a shorthand for selecting the rest of the sequence or array. Using the CSV example above: - let ($heading, $rows*) := load-csv("test.csv") + let $(heading, rows ...) := load-csv("test.csv") The other occurrence indicators would also be usable after the last variable binding. @@ -91,7 +92,7 @@ Extracting values from a sequence: }; let $angle := math:pi() - let ($sin, $cos) := sincos($angle) + let $(sin, cos) := sincos($angle) return $sin || "," || $cos Extracting values from an array: @@ -101,12 +102,12 @@ Extracting values from an array: }; let $angle := math:pi() - let ($sin, $cos) := sincos($angle) + let $[sin, cos] := sincos($angle) return $sin || "," || $cos Extracting values with typed variables: - let ($x as xs:double, $y as xs:double) := polar-to-cartesian(1.0, math:pi()) + let $(x as xs:double, y as xs:double) := polar-to-cartesian(1.0, math:pi()) return "x=" || $x || ", y=" || $y @@ -118,4 +119,4 @@ TBD. ## Version History 1. Initial proposal. -1. Remove references to tuples, except for the influences section. +1. Remove references to tuples, except for the influences section. Update the syntax to use the suggested syntax from Michael Kay and Christian Grün. From 6da0f12df9fa1f503377e6962759b253cf9ac05d Mon Sep 17 00:00:00 2001 From: "Reece H. Dunn" Date: Sun, 28 Oct 2018 20:27:16 +0000 Subject: [PATCH 4/8] sequence and array decomposition: use the array notation for array decomposition, per consensus. --- tuple-decomposition.md | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/tuple-decomposition.md b/tuple-decomposition.md index ed5f7db..fd33b17 100644 --- a/tuple-decomposition.md +++ b/tuple-decomposition.md @@ -7,14 +7,14 @@ This proposal allows sequences and arrays to be decomposed and assigned to separate variables in a single declaration. -## Description +## Sequence Decomposition -Given a sequence such as `(1, 2, 3)`, the values within that sequence or array cannot easily be extracted. With the current version of XPath and XQuery, they need to be assigned to a temporary variable first. For example: +Given a sequence such as `(1, 2, 3)`, the values within that sequence cannot easily be extracted. With the current version of XPath and XQuery, they need to be assigned to a temporary variable first. For example: let $result := get-camera-point() let $x := $result[1] let $y := $result[2] - let $x := $result[3] + let $z := $result[3] return "(" || $x || "," || $y || "," || $z || ")" This proposal would allow this to be written more concisely as: @@ -22,34 +22,34 @@ This proposal would allow this to be written more concisely as: let $(x, y, z) := get-camera-point() return "(" || $x || "," || $y || "," || $z || ")" -An XPath or XQuery processor may implement this by transforming it to the expanded form above with `$result` being a unique variable that is not visible to the expression. +These are equivalent in this proposal, except that `$result` is not a statically known variable binding in the sequence decomposition let clause. -For sequences, `$seq[N]` would be used to extract the nth item in the sequence. If the item does not exist, an empty sequence is returned. +For each variable declaration in the sequence decomposition at index `N`, and `$expr` being the result of the for/let expression, then `$expr[N]` is the value bound to the variable declaration as a new variable binding. If the value does not exist, an empty sequence is returned. -For arrays, `$array(N)` or `array:get($array, N)` would be used to extract the nth item in the array. If the item does not exist, an `err:FOAY0001` (array index out of bounds) error will be raised. +A sequence decomposition can be used in any for or let clause binding to decompose the items in a sequence. If the type of the for or let clause binding expression is not a sequence, an `err:XPTY0004` error is raised. -This would apply to any variable declaration or binding where `:=` is used to assign a variable to an expression. Specifically: -1. variable declarations, including decomposition of default values (XQuery) -1. context item declaration (XQuery) -1. let clauses (XPath/XQuery) -1. for clauses (XPath/XQuery) -1. grouping spec (XQuery) +### Array Decomposition -### Variation: Separate Tuple Array Decomposition Syntax +Given an array such as `[1, 2, 3]`, the values within that array cannot easily be extracted. With the current version of XPath and XQuery, they need to be assigned to a temporary variable first. For example: -If the decomposition is being performed on an array, it may be better to use array syntax to define the composition: + let $result := get-camera-point() + let $x := $result?(1) + let $y := $result?(2) + let $z := $result?(3) + return "(" || $x || "," || $y || "," || $z || ")" + +This proposal would allow this to be written more concisely as: let $[x, y, z] := get-camera-point() return "(" || $x || "," || $y || "," || $z || ")" -The `(...)` syntax would then be *sequence decomposition*, while the `[...]` syntax would be *array decomposition*. +These are equivalent in this proposal, except that `$result` is not a statically known variable binding in the array decomposition let clause. -This would allow XPath/XQuery processors to report an error if sequence decomposition was used on arrays, and when array decomposition was used on sequences. +For each variable declaration in the array decomposition at index `N`, and `$expr` being the result of the for/let expression, then `$expr?(N)` is the value bound to the variable declaration as a new variable binding. If the value does not exist, an `err:FOAY0001` (array index out of bounds) error will be raised. -This would make it clearer to the user when a sequence is expected and when an array is expected, and thus when out of bounds access would result in an empty sequence or an error. +An array decomposition can be used in any for or let clause binding to decompose the items in an array. If the type of the for or let clause binding expression is not a sequence, an `err:XPTY0004` error is raised. -This does add an additional level of complexity to the language grammar, but may help processors decide how to decompose the values as determining whether the type being decomposed is a sequence or array can be determined during the static analysis phase. ### Assigning the rest of a sequence or array @@ -64,24 +64,25 @@ It may be useful to define a shorthand for selecting the rest of the sequence or The other occurrence indicators would also be usable after the last variable binding. + ### Influences Tuple decomposition is found in various languages such as Python, Scala, and C#. These languages also have support for tuple types. Python has support for specifying that a variable is assigned the remaining values in the tuple. + ## Use Cases There are many cases where fixed size sequences may be used such as points, complex and rational numbers, sin/cos, and mul/div. This makes extracting data from these simpler, and may also be used to aid readability by assigning descriptive names to each of the items in the sequence. + ### Potential Confusion and Complexity From a user's perspective it would be confusing if an item in the sequence is an empty sequence, as the items after that would be assigned to the wrong variable. However, this is no different from them using the long form to extract the values from the sequence. There is a potential for confusion if changing from a sequence return type to an array, where the code may subsequently raise an `err:FOAY0001` error. The reason for this is hidden from the user. -There is complexity for the semantics of variable declarations, especially those with external values. If this is deemed too complex, it can be dropped from this proposal. - ## Examples From 8fbf9a71ea14d8854c23211cf0747d51824b8901 Mon Sep 17 00:00:00 2001 From: "Reece H. Dunn" Date: Sun, 28 Oct 2018 20:28:44 +0000 Subject: [PATCH 5/8] Move {tuple => sequence-map-array}-decomposition.md. --- tuple-decomposition.md => sequence-map-array-decomposition.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tuple-decomposition.md => sequence-map-array-decomposition.md (100%) diff --git a/tuple-decomposition.md b/sequence-map-array-decomposition.md similarity index 100% rename from tuple-decomposition.md rename to sequence-map-array-decomposition.md From 4b3feaeccee61dc4607fcdf7746fe83f0ce2a756 Mon Sep 17 00:00:00 2001 From: "Reece H. Dunn" Date: Sun, 28 Oct 2018 20:45:01 +0000 Subject: [PATCH 6/8] sequence-map-array-decomposition: Describe map decomposition syntax and rules. --- sequence-map-array-decomposition.md | 36 ++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/sequence-map-array-decomposition.md b/sequence-map-array-decomposition.md index fd33b17..d0ed581 100644 --- a/sequence-map-array-decomposition.md +++ b/sequence-map-array-decomposition.md @@ -1,4 +1,4 @@ -# Sequence and Array Decomposition +# Sequence, Map, and Array Decomposition **Author**: Reece H. Dunn. 67 Bricks. @@ -24,7 +24,7 @@ This proposal would allow this to be written more concisely as: These are equivalent in this proposal, except that `$result` is not a statically known variable binding in the sequence decomposition let clause. -For each variable declaration in the sequence decomposition at index `N`, and `$expr` being the result of the for/let expression, then `$expr[N]` is the value bound to the variable declaration as a new variable binding. If the value does not exist, an empty sequence is returned. +For each variable declaration in the sequence decomposition at index `N`, and `$expr` being the result of the for/let expression, then `$expr[N]` is the value bound to the variable declaration as a new variable binding. If the value does not exist, an empty sequence is bound to the variable. A sequence decomposition can be used in any for or let clause binding to decompose the items in a sequence. If the type of the for or let clause binding expression is not a sequence, an `err:XPTY0004` error is raised. @@ -51,18 +51,42 @@ For each variable declaration in the array decomposition at index `N`, and `$exp An array decomposition can be used in any for or let clause binding to decompose the items in an array. If the type of the for or let clause binding expression is not a sequence, an `err:XPTY0004` error is raised. -### Assigning the rest of a sequence or array +### Map Decomposition + +Given a map such as `{x: 1, y: 2, z: 3}`, the values within that map cannot easily be extracted. With the current version of XPath and XQuery, they need to be assigned to a temporary variable first. For example: + + let $result := get-camera-point() + let $x := $result?(x) + let $y := $result?(y) + let $z := $result?(z) + return "(" || $x || "," || $y || "," || $z || ")" + +This proposal would allow this to be written more concisely as: + + let ${x, y, z} := get-camera-point() + return "(" || $x || "," || $y || "," || $z || ")" + +These are equivalent in this proposal, except that `$result` is not a statically known variable binding in the map decomposition let clause. + +For each variable declaration with EQName `var` in the map decomposition, and `$expr` being the result of the for/let expression, then `$expr?(var)` is the value bound to the variable declaration as a new variable binding. If the value does not exist, an empty sequence is bound to the variable. + +An array decomposition can be used in any for or let clause binding to decompose the items in an array. If the type of the for or let clause binding expression is not a sequence, an `err:XPTY0004` error is raised. + + +### Assigning the rest of a sequence, map or array It can be useful to only extract part of a sequence or array (e.g. the heading of a table), and store the rest of the items in another variable. For example: let $(heading as array(xs:string), rows as array(xs:string)...) := load-csv("test.csv") -It may be useful to define a shorthand for selecting the rest of the sequence or array. Using the CSV example above: +or without specifically declared types: let $(heading, rows ...) := load-csv("test.csv") -The other occurrence indicators would also be usable after the last variable binding. +For a map decomposition, the value of the last variable binding contains all entries in the map that have not been assigned to previous variable bindings in the map decomposition. + +If there are no items remaining in the sequence, map, or array, the result is an empty sequence, map, or array respectively. ### Influences @@ -120,4 +144,4 @@ TBD. ## Version History 1. Initial proposal. -1. Remove references to tuples, except for the influences section. Update the syntax to use the suggested syntax from Michael Kay and Christian Grün. +1. Remove references to tuples, except for the influences section. Update the syntax to use the suggested syntax from Michael Kay and Christian Grün. Define syntax and rules for map decomposition, as suggested by Michael Kay. From ae6645d4f7297a9f7fb43805ac9fafefa89b4ed2 Mon Sep 17 00:00:00 2001 From: "Reece H. Dunn" Date: Sun, 28 Oct 2018 21:06:13 +0000 Subject: [PATCH 7/8] sequence-map-array-decomposition: Add a grammar for the new syntax. --- sequence-map-array-decomposition.md | 30 ++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/sequence-map-array-decomposition.md b/sequence-map-array-decomposition.md index d0ed581..95a43db 100644 --- a/sequence-map-array-decomposition.md +++ b/sequence-map-array-decomposition.md @@ -4,7 +4,7 @@ **Revision**: 2 -This proposal allows sequences and arrays to be decomposed and assigned to separate variables in a single declaration. +This proposal allows sequences, maps, and arrays to be decomposed and assigned to separate variables in a single declaration. ## Sequence Decomposition @@ -135,13 +135,37 @@ Extracting values with typed variables: let $(x as xs:double, y as xs:double) := polar-to-cartesian(1.0, math:pi()) return "x=" || $x || ", y=" || $y +Extracting a single value from a map: + + for ${width} in get-items() ! get-area(.) return $width + ## Grammar -TBD. +__New Symbols__: + + DecompositionVarNames ::= SequenceDecompositionVarNames + | ArrayDecompositionVarNames + | MapDecompositionVarNames + SequenceDecompositionVarNames ::= "(" DecompositionVarNameList ")" + ArrayDecompositionVarNames ::= "[" DecompositionVarNameList "]" + MapDecompositionVarNames ::= "{" DecompositionVarNameList "}" + DecompositionVarNameList ::= VarName ("," VarName)* "..."? + +__Modified Symbols (XPath)__: + + SimpleForBinding ::= "$" (VarName | DecompositionVarNames) "in" ExprSingle + SimpleLetBinding ::= "$" (VarName | DecompositionVarNames) ":=" ExprSingle + +__Modified Symbols (XQuery)__: + + ForBinding ::= "$" (VarName | DecompositionVarNames) TypeDeclaration? + AllowingEmpty? PositionalVar? "in" ExprSingle + LetBinding ::= "$" (VarName | DecompositionVarNames) TypeDeclaration? + ":=" ExprSingle ## Version History 1. Initial proposal. -1. Remove references to tuples, except for the influences section. Update the syntax to use the suggested syntax from Michael Kay and Christian Grün. Define syntax and rules for map decomposition, as suggested by Michael Kay. +1. Remove references to tuples, except for the influences section. Update the syntax to use the suggested syntax from Michael Kay and Christian Grün. Define syntax and rules for map decomposition, as suggested by Michael Kay. Specify the grammar section. From bc6cb1b579d688ba0088abfe0e73b7e633f964aa Mon Sep 17 00:00:00 2001 From: "Reece H. Dunn" Date: Sun, 28 Oct 2018 21:24:24 +0000 Subject: [PATCH 8/8] sequence-map-array-decomposition: Fix TypeDeclaration parsing. --- sequence-map-array-decomposition.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/sequence-map-array-decomposition.md b/sequence-map-array-decomposition.md index 95a43db..e37230b 100644 --- a/sequence-map-array-decomposition.md +++ b/sequence-map-array-decomposition.md @@ -142,7 +142,7 @@ Extracting a single value from a map: ## Grammar -__New Symbols__: +__New Symbols (XPath and XQuery)__: DecompositionVarNames ::= SequenceDecompositionVarNames | ArrayDecompositionVarNames @@ -150,18 +150,26 @@ __New Symbols__: SequenceDecompositionVarNames ::= "(" DecompositionVarNameList ")" ArrayDecompositionVarNames ::= "[" DecompositionVarNameList "]" MapDecompositionVarNames ::= "{" DecompositionVarNameList "}" + +__New Symbols (XPath)__: + DecompositionVarNameList ::= VarName ("," VarName)* "..."? +__New Symbols (XQuery)__: + + DecompositionVarNameList ::= VarName TypeDeclaration? + ( "," VarName TypeDeclaration? )* "..."? + __Modified Symbols (XPath)__: - SimpleForBinding ::= "$" (VarName | DecompositionVarNames) "in" ExprSingle - SimpleLetBinding ::= "$" (VarName | DecompositionVarNames) ":=" ExprSingle + SimpleForBinding ::= "$" ( VarName | DecompositionVarNames ) "in" ExprSingle + SimpleLetBinding ::= "$" ( VarName | DecompositionVarNames ) ":=" ExprSingle __Modified Symbols (XQuery)__: - ForBinding ::= "$" (VarName | DecompositionVarNames) TypeDeclaration? + ForBinding ::= "$" ( ( VarName TypeDeclaration? ) | DecompositionVarNames ) AllowingEmpty? PositionalVar? "in" ExprSingle - LetBinding ::= "$" (VarName | DecompositionVarNames) TypeDeclaration? + LetBinding ::= "$" ( ( VarName TypeDeclaration? ) | DecompositionVarNames ) ":=" ExprSingle