<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://www.w3.org/Bugs/Public/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4"
          urlbase="https://www.w3.org/Bugs/Public/"
          
          maintainer="sysbot+bugzilla@w3.org"
>

    <bug>
          <bug_id>27537</bug_id>
          
          <creation_ts>2014-12-08 16:27:46 +0000</creation_ts>
          <short_desc>[XP31] Sequence on lhs of arrow operator</short_desc>
          <delta_ts>2015-07-07 16:05:44 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>XPath / XQuery / XSLT</product>
          <component>XPath 3.1</component>
          <version>Last Call drafts</version>
          <rep_platform>SGI</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Michael Kay">mike</reporter>
          <assigned_to name="Jonathan Robie">jonathan.robie</assigned_to>
          <cc>botond23</cc>
    
    <cc>jmdyck</cc>
    
    <cc>josh.spiegel</cc>
          
          <qa_contact name="Mailing list for public feedback on specs from XSL and XML Query WGs">public-qt-comments</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>116016</commentid>
    <comment_count>0</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2014-12-08 16:27:46 +0000</bug_when>
    <thetext>Botond Biró raised this on public-qt-comments:

What is the expected behavior if the arrow postfix operator is applied to a sequence containing more than one item?

Does the semantic equivalence &quot;$seq=&gt;$f(…) is the same as $f( $seq, … )&quot; also hold when count($seq) != 1?
ex, ( 1, 2, 3 ) =&gt; avg() or ()=&gt;count()

In the last call working draft the wording for arrow postfix definition implies that a [single] item is expected, but don’t see why or if this restriction would be necessary.

“[Definition: An arrow operator is a postfix operator that applies a function to an item, using the item as the first argument to the function.] If $i is an item and f() is a function, then $i=&gt;f() is equivalent to f($i), and $i=&gt;f($j) is equivalent to f($i, $j).”

If the single restriction doesn&apos;t apply, then I suggest modifying the definition to reflect this. 

And a question related to operator precedence: currently it is not possible to use a node selection on the lhs of an arrow operator without wrapping it with extra parenthesis:
$DAYS//@From =&gt; max() - syntax error
($DAYS//@From) =&gt; max() - ok
is it planned for the arrow operator to be moved above the step expression(i.e. get lower precedence) so that one can use a node selection =&gt; without the need of the extra parenthesis?

MHK comment:

I don&apos;t think there was ever any intention to restrict the LHS to a single item. The definition should be:

[Definition: An arrow operator is a postfix operator that applies a function to an value, using the value as the first argument to the function.] If $s is a sequence and f() is a function, then $s=&gt;f() is equivalent to f($i), and $s=&gt;f($j) is equivalent to f($s, $j).

As regards the operator precedence, I can see the case for making 

/section/para =&gt; count()

mean count(/section/para)

One can also see a case for richer expressions on the right, e.g.

$input =&gt; $function-lib?cosine

For an example of a surprise coming from the current rules, consider

-1 =&gt; abs()

which returns -1.

There would seem to be a case for decoupling the arrow operator from the Postfix construct, and having

[95]   	CastExpr ::= ArrowExpr ( &quot;cast&quot; &quot;as&quot; SingleType )?
[NN]    ArrowExpr ::= UnaryExpr &quot;==&gt;&quot; UnaryExpr</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>116017</commentid>
    <comment_count>1</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2014-12-08 16:30:38 +0000</bug_when>
    <thetext>In the last line, s/==&gt;/=&gt;/</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>116069</commentid>
    <comment_count>2</comment_count>
    <who name="Jonathan Robie">jonathan.robie</who>
    <bug_when>2014-12-09 20:32:56 +0000</bug_when>
    <thetext>In today&apos;s call, we agreed to allow the left hand side to be a sequence, in which case the sequence is passed as the first argument to the function.

We did not have agreement to change precedence.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>116150</commentid>
    <comment_count>3</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2014-12-11 15:39:07 +0000</bug_when>
    <thetext>The minutes here differ from the updates made to Bugzilla. Therefore reopening. The minutes record a decision to leave the bug open until next week, and do not record the agreement (and lack of agreement) reported by Jonathan.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>116152</commentid>
    <comment_count>4</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2014-12-11 15:59:53 +0000</bug_when>
    <thetext>Note also:

(a) (editorial) the production for ArrowFunctionSpecifier should be included in section  3.2.3

(b) contrary to my comment #0, the syntax could probably become

[NN]    ArrowExpr ::= UnaryExpr &quot;=&gt;&quot; ArrowFunctionSpecifier ArgumentList

The effect of the change would be to make unary +/-, !, and / on the left bind more tightly than =&gt;, for example

-1 =&gt; abs()
//x =&gt; count()
a!tokenize()!upper-case() =&gt; distinct-values()

now work as one might expect. (Note, it&apos;s natural to put spaces around the lower-precedence operator).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>116289</commentid>
    <comment_count>5</comment_count>
    <who name="Jonathan Robie">jonathan.robie</who>
    <bug_when>2014-12-14 23:14:33 +0000</bug_when>
    <thetext>(In reply to Michael Kay from comment #3)
&gt; The minutes here differ from the updates made to Bugzilla. Therefore
&gt; reopening. The minutes record a decision to leave the bug open until next
&gt; week, and do not record the agreement (and lack of agreement) reported by
&gt; Jonathan.

I believe the problem is in the minutes. I suggest we close this bug, which is filed against the specification and correct the minutes.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>116291</commentid>
    <comment_count>6</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2014-12-14 23:56:30 +0000</bug_when>
    <thetext>Jonathan, you may believe the minutes are wrong, but if there is a conflict between the minutes and the bug resolution then we should leave the bug open until the conflict is resolved.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>116469</commentid>
    <comment_count>7</comment_count>
    <who name="Botond Biró">botond23</who>
    <bug_when>2014-12-18 09:50:35 +0000</bug_when>
    <thetext>(In reply to Michael Kay from comment #4)

&gt; (b) contrary to my comment #0, the syntax could probably become
&gt; 
&gt; [NN]    ArrowExpr ::= UnaryExpr &quot;=&gt;&quot; ArrowFunctionSpecifier ArgumentList

I think one would also need to change the occurrence of the part after the UnaryExpr:
-min occur zero- to fix parsing of simple unary expressions 
-max occur unbounded - to support chaining
So the EBNF should look sg. like:

[NN]    ArrowExpr ::= UnaryExpr (&quot;=&gt;&quot; ArrowFunctionSpecifier ArgumentList)*</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>116472</commentid>
    <comment_count>8</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2014-12-18 10:04:21 +0000</bug_when>
    <thetext>Thanks, yes, that problem was discovered when the WG reviewed this on Tuesday. The current state is that we&apos;re sympathetically inclined to the proposal, and looking in detail at the grammar implications and at further use csses.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>116842</commentid>
    <comment_count>9</comment_count>
    <who name="Michael Dyck">jmdyck</who>
    <bug_when>2015-01-06 18:18:21 +0000</bug_when>
    <thetext>More explicitly, the productions:
    CastExpr    ::= UnaryExpr ( &quot;cast&quot; &quot;as&quot; SingleType )?
    ...
    PostfixExpr ::= PrimaryExpr ( ... | Lookup | ArrowPostfix )*

would become:
    CastExpr    ::= ArrowExpr ( &quot;cast&quot; &quot;as&quot; SingleType )?
    ArrowExpr   ::= UnaryExpr ( &quot;=&gt;&quot; ArrowFunctionSpecifier ArgumentList )*
    ...
    PostfixExpr ::= PrimaryExpr ( ... | Lookup )*

I did a trial parser/applet build with these edits and they don&apos;t appear to
cause any problems (ambiguities or conflicts).

----

Here&apos;s the pertinent chunk of the XQuery/XPath 3.x expression hierarchy,
(where &quot;v&quot; can be read as &quot;directly derives&quot;), with the
current and proposed levels for ArrowExpr/ArrowPostfix.

    CastExpr
      v             &lt;- proposed position of ArrowExpr
    UnaryExpr
      v
    ValueExpr
      v
    SimpleMapExpr
      v
    PathExpr
      v
    RelativePathExpr
      v
    StepExpr
      v
    PostfixExpr    &lt;- current level of ArrowPostfix

----

Here are some example queries that will be treated differently under
the status quo vs the proposed change.

Mike&apos;s examples above [in support of the proposed change] correspond to
examples &quot;UnaryExpr&quot;, &quot;PathExpr 2&quot;, and &quot;SimpleMapExpr 2&quot;.

Perhaps the strongest argument against the proposed change would be based
on the last three examples (&quot;PostfixExpr N&quot;), in which a query such as
    $a=&gt;f()[1]
would become a syntax error. Instead, you would have to write
    ($a=&gt;f())[1]
to get the effect that the former query currently has.

(Note that where an example uses a VarRef, any other PrimaryExpr would do,
e.g. a FunctionCall or a ContextItemExpr, which might make the example
more realistic.)

---------------------------------------------------------------------------
UnaryExpr:

                         - $x =&gt;f()

currently: equiv to      - ($x =&gt;f())

proposed:  equiv to      (- $x) =&gt;f()

---------------------------------------------------------------------------
ValueExpr -&gt; ValidateExpr:

                        validate {Expr} =&gt;f()

currently: syntax error

proposed:  equiv to     (validate {Expr}) =&gt;f()

---------------------------------------------------------------------------
ValueExpr -&gt; ExtensionExpr:

                        (#pragma#) {Expr} =&gt;f()

currently: syntax error

proposed:  equiv to     ((#pragma#) {Expr}) =&gt;f()

---------------------------------------------------------------------------
SimpleMapExpr 1:

                        $a =&gt;f() ! $b =&gt;g()

currently: equiv to     ($a =&gt;f()) ! ($b =&gt;g())

proposed:  syntax error

---------------------------------------------------------------------------
SimpleMapExpr 2:

                        $a ! $b =&gt;f()

currently: equiv to     $a ! ($b =&gt;f())

proposed:  equiv to     ($a ! $b) =&gt;f()

---------------------------------------------------------------------------
SimpleMapExpr 3:

                        a/b ! c/d =&gt;f()

currently: syntax error

proposed:  equiv to     (a/b ! c/d) =&gt;f()

---------------------------------------------------------------------------
PathExpr 1:

                        / $a =&gt;f()

currently: equiv to     / ($a =&gt;f())

proposed:  equiv to     (/ $a) =&gt;f()

---------------------------------------------------------------------------
PathExpr 2:

                        / a =&gt;f()

currently: syntax error

proposed:  equiv to     (/ a) =&gt;f()

---------------------------------------------------------------------------
RelativePathExpr 1:

                        $a =&gt;f() / $b =&gt;g()

currently: equiv to     ($a =&gt;f()) / ($b =&gt;g())

proposed:  syntax error

---------------------------------------------------------------------------
RelativePathExpr 2:

                        $a / $b =&gt;g()

currently: equiv to     $a / ($b =&gt;g())

proposed:  equiv to     ($a / $b) =&gt;g()

---------------------------------------------------------------------------
RelativePathExpr 3:

                        a / b =&gt;g()

currently: syntax error

proposed:  equiv to     (a / b) =&gt;g()

---------------------------------------------------------------------------
StepExpr -&gt; AxisStep:

                        child:a[1] =&gt;f()

currently: syntax error

proposed:  equiv to     (child:a[1]) =&gt;f()

---------------------------------------------------------------------------
PostfixExpr 1:

                        $a =&gt;f() [1]

currently: equiv to     ($a =&gt;f()) [1]

proposed:  syntax error

---------------------------------------------------------------------------
PostfixExpr 2:

                        $a =&gt;f() (&quot;arg&quot;)

currently: equiv to     ($a =&gt;f()) (&quot;arg&quot;)

proposed:  syntax error

---------------------------------------------------------------------------
PostfixExpr 3:

                        $a =&gt;f() ?key

currently: equiv to     ($a =&gt;f()) ?key

proposed:  syntax error

---------------------------------------------------------------------------</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>117084</commentid>
    <comment_count>10</comment_count>
    <who name="Jonathan Robie">jonathan.robie</who>
    <bug_when>2015-01-13 16:52:11 +0000</bug_when>
    <thetext>The Working Group agreed to this change.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>121776</commentid>
    <comment_count>11</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2015-07-06 08:54:09 +0000</bug_when>
    <thetext>The change has not yet been applied to the specification.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>121855</commentid>
    <comment_count>12</comment_count>
    <who name="Josh Spiegel">josh.spiegel</who>
    <bug_when>2015-07-07 16:05:31 +0000</bug_when>
    <thetext>I think it is now.</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>