A question about the arrow operator and predicates
Hi all - I was wondering if anyone would have an insight for me as to why the following expression is wrong: ``` for $s in ("/a/b/c", "/1/2/3") let $t := $s => tokenize("/")[last()] return $t ``` This is because of the predicate filter, but I'm not clear on *why* it's because of that :) Thanks for your help! Best, Bridger PS I don't always remember to look at the optimized query in the Info window, but when I do I always get a hint about something; "util:last()" in this case. correctly ``` for $s in ("/a/b/c", "/1/2/3") let $t := tokenize($s, "/")[last()] return $t ``` ``` for $s in ("/a/b/c", "/1/2/3") let $t := $s => tokenize("/") => util:last() return $t ```
Dear Bridger,
I was wondering if anyone would have an insight for me as to why the following expression is wrong:
for $s in ("/a/b/c", "/1/2/3") let $t := $s => tokenize("/")[last()] return $t
This is due to the grammar rules of XQuery 3.1, which mandate that “=>” is followed by an “ArrowFunctionSpecifier” and an “ArgumentList”. Here are some production rules from the spec: [96] ArrowExpr ::= UnaryExpr ( "=>" ArrowFunctionSpecifier ArgumentList )* [127] ArrowFunctionSpecifier ::= EQName | VarRef | ParenthesizedExpr [122] ArgumentList ::= "(" (Argument ("," Argument)*)? ")" … The arrow function specifier can be an EQName, a variable reference or a parenthesized expression. The last one will do the job: for $s in ("/a/b/c", "/1/2/3") let $t := ($s => tokenize("/"))[last()] return $t Hope this helps, Christian [1] https://www.w3.org/TR/xquery-31/#id-arrow-operator
Thanks for your help! Best, Bridger
PS I don't always remember to look at the optimized query in the Info window, but when I do I always get a hint about something; "util:last()" in this case.
correctly ``` for $s in ("/a/b/c", "/1/2/3") let $t := tokenize($s, "/")[last()] return $t ``` ``` for $s in ("/a/b/c", "/1/2/3") let $t := $s => tokenize("/") => util:last() return $t ```
Christian - As always, thank you so much! On Wed, Mar 31, 2021 at 10:35 AM Christian Grün <christian.gruen@gmail.com> wrote:
Dear Bridger,
I was wondering if anyone would have an insight for me as to why the following expression is wrong:
for $s in ("/a/b/c", "/1/2/3") let $t := $s => tokenize("/")[last()] return $t
This is due to the grammar rules of XQuery 3.1, which mandate that “=>” is followed by an “ArrowFunctionSpecifier” and an “ArgumentList”. Here are some production rules from the spec:
[96] ArrowExpr ::= UnaryExpr ( "=>" ArrowFunctionSpecifier ArgumentList )* [127] ArrowFunctionSpecifier ::= EQName | VarRef | ParenthesizedExpr [122] ArgumentList ::= "(" (Argument ("," Argument)*)? ")" …
The arrow function specifier can be an EQName, a variable reference or a parenthesized expression. The last one will do the job:
for $s in ("/a/b/c", "/1/2/3") let $t := ($s => tokenize("/"))[last()] return $t
It does - I had read some other online notes about parenthesizing part of the left hand side expression, but hadn't parenthesized properly. As a follow up, for my layman's thinking about XPath/XQuery, is this effectively creating a sequence that is then filtered? Or am I mentally overloading the parentheses?
Thanks for the insight! Hope this helps,
Christian
Best, Bridger
Thanks for your help! Best, Bridger
PS I don't always remember to look at the optimized query in the Info
window, but when I do I always get a hint about something; "util:last()" in this case.
correctly ``` for $s in ("/a/b/c", "/1/2/3") let $t := tokenize($s, "/")[last()] return $t ``` ``` for $s in ("/a/b/c", "/1/2/3") let $t := $s => tokenize("/") => util:last() return $t ```
participants (2)
-
Bridger Dyson-Smith -
Christian Grün