Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Array Decomposition #1145

Closed
rhdunn opened this issue Apr 12, 2024 · 1 comment
Closed

Array Decomposition #1145

rhdunn opened this issue Apr 12, 2024 · 1 comment
Labels
Enhancement A change or improvement to an existing feature XPath An issue related to XPath

Comments

@rhdunn
Copy link
Contributor

rhdunn commented Apr 12, 2024

This proposal allows arrays to be decomposed and assigned to separate variables in a single declaration within a for or let expression binding.

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:

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 || ")"

These are equivalent in this proposal, except that $result is not a statically known variable binding in the array decomposition let clause.

Note: The older syntax in XPath-NG was:

let $[x, y, z] := get-camera-point()
return "(" || $x || "," || $y || "," || $z || ")"

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.

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 an array

It can be useful to only extract part of an 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")

If there are no items remaining in the array the result is an empty array.

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.

Examples

Extracting values from an 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
@rhdunn rhdunn added XPath An issue related to XPath Enhancement A change or improvement to an existing feature labels Apr 12, 2024
@rhdunn
Copy link
Contributor Author

rhdunn commented Apr 12, 2024

Duplicate of #37.

@rhdunn rhdunn closed this as completed Apr 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement A change or improvement to an existing feature XPath An issue related to XPath
Projects
None yet
Development

No branches or pull requests

1 participant