Skip to content

Sequence Decomposition #1144

@rhdunn

Description

@rhdunn

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

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 $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 sequence 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 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.

Assigning the rest of a sequence

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, rows ...) := fn:parse-csv("test.csv")

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

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 a 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    EnhancementA change or improvement to an existing featureXPathAn issue related to XPath

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions