ACTION-1935 - Send an e-mail proposing a lighter syntax for the function element

All,

This is in response to "ACTION-1935 - Send an e-mail proposing a
lighter syntax for the function element" from the weekly call of
2013-02-20 [1].

In that call I voiced some doubts about what we should do with the
proposed `function` element. Also, I suggested that the syntax of the
`function` element should be as lightweight as possible. So here are
some thoughts and a proposal.

## Do we need a `function` element at all?

I think that, ideally, we shouldn't need it, and that the expression
language should provide native support for functions.

However, we are constrained by how far current implementations are
from supporting XPath 3 and/or XQuery. Implementations today are still
on XPath 2 (or even XPath 1), and the reality is that XPath 3 is not
out yet and that there might not even be an open-source implementation
of it before a long time. (In particular, the status of Saxon in this
respect is unclear.)

Another option is that implementations could use XQuery. However, at
this time no implementation supports XQuery, and it is not in the
scope of XForms 2 to mandate support for XQuery.

Finally, support for JavaScript is a quite obvious option, whether on
the client or on the server. However, the reality again is that XForms
remains heavily based on XPath, and there is a real need for
supporting custom functions with XPath without mandating support for
JavaScript.

In short, I am leaning again towards specifying support for the
`function` element.

## Do we want support for nested variables?

Similar thinking applies to variables. The only difference would be to
say that, for most scenarios, variables are not needed. My initial
suggestion, for simplicity and to make the syntax lightweight, was to
not support them. But it seems that there is a desire from other group
members to support them, therefore my proposal includes them.

## Proposed syntax

### Lighweight syntax

First, I suggest a lightweight syntax, for the cases where you don't
need variables. This is the original suggestion I had made here [2]:

    <function signature="my:sumproduct($p as xs:decimal*, $q as
xs:decimal*) as xs:decimal">
        sum(for $i in 1 to count($p) return $p[$i]*$q[$i])
    </function>

With the lightweight syntax, you don't have any nested elements under
the `function` element. The body of the `function` element contains an
expression in the language specified. The result of the function is
the result of the evaluation of that expression (with the appropriate
conversion given the `as` of the function signature).

### Full syntax

The full syntax, on the other hand, allows nesting `var` elements and
a final `result` element.

This proposal removes the `sequence` and `script` elements.

As discussed a long time ago with Mike Kay, we don't need to be
attached to the name `sequence`, especially since we are not mandating
support for the complete sequence constructors of XSLT 2/3. Further,
since the `sequence` element is only intended to provide the result
value of the function, the name `result` seems appropriate.

The `script` elements is not needed either. When using XPath, we can
expect that either the lightweight syntax will be used, or the syntax
with `var` and `result`. If using another language (typically
JavaScript), then hopefully the language supports native variables and
doesn't require the use of the `var` and `result` elements.

The implementation language of the function can be specified with a
`type` attribute directly on the function element. Some further
examples:

    <function signature="my:sumproduct($p as xs:decimal*, $q as
xs:decimal*) as xs:decimal">
        <result value="sum(for $i in 1 to count($p) return $p[$i]*$q[$i])"/>
    </function>

    <function signature="my:foo($p as xs:decimal*) as xs:decimal"
override="no" type="text/javascript">
        foo(XForms.var.p);
    </function>

    <function signature="my:foo($p as xs:decimal*) as xs:decimal" override="no">
        <var name="v1" value="$p[1]"/
        <var name="v2" value="$p[2]"/
        <result value="$v1 + $v2"/>
    </function>

Feedback welcome,

-Erik

[1] http://www.w3.org/2013/02/20-forms-minutes.html
[2] http://lists.w3.org/Archives/Public/public-forms/2013Feb/0004.html

Received on Tuesday, 26 March 2013 23:11:04 UTC