- From: Erik Bruchez <erik@bruchez.org>
- Date: Wed, 14 Mar 2012 10:01:21 -0700
- To: public-forms@w3.org
All, I dug up some emails and found Mike's reply in November 2009 on the topic: "I would recommend, if you want to keep things simple, only allowing xforms:sequence [as opposed to also supporting xforms:value-of]. Or naming it xforms:return - that's what it was in XSLT until we generalized it to allow sequence constructors, and in many ways I regret changing it." That sounds like a good suggestion to me, assuming we are going to support an element to specify the result. Now I am wondering if we can do away with nested elements altogether. I would like to see things like this, based on the examples in [1]: Example 1: <function signature="my:sum($p as xs:integer, $q as xs:integer) as xs:integer"> $p + $q </function> Or, using @value: <function signature="my:sum($p as xs:integer, $q as xs:integer) as xs:integer" value="$p + $q"/> Example 2 (XPath 3): <function signature="dollar-round($num as xs:decimal) as xs:string"> let $num100str := string(round($num * 100)), $trunc := substring-before($num100str, '.'), $intpart = substring($trunc, 0, string-length($trunc)-2), $fracpart = substring($trunc, string-length($intpart), 2) return concat($intpart, '.', $fracpart) </function> (I am sure you can write that function better in XPath 2 or XPath 3 BTW!) @value can also be used here, but it's a bit more clumsy visually. Example 3: <function signature="my:sumproduct($p as node()*, $q as node()*) as xs:double"> sum(for $i in 1 to count($p) return $p[$i] * $q[$i]) </function> or: <function signature="my:sumproduct($p as node()*, $q as node()*) as xs:double" value="sum(for $i in 1 to count($p) return $p[$i] * $q[$i])"/> This would work well for JavaScript too: Example 1 (JavaScript): <function signature="my:sum($p as xs:integer, $q as xs:integer) as xs:integer" type="javascript> return p + q </function> <function signature="dollar-round($num as xs:decimal) as xs:string" type="javascript> var num100str = ... var trunc = ... var intpart = ... var fracpart = ... return intpart + "." + fracpart </function> etc. Now unfortunately in XPath 2 we can't use `let`, but maybe we can still get away with the <sequence> or <return> element: <function signature="dollar-round($num as xs:decimal) as xs:string"> <var name="num100str" value="string(round($num * 100))"/> <var name="trunc" value="substring-before($num100str, '.')"/> <var name="intpart" value="substring($trunc, 0, string-length($trunc)-2)"/> <var name="fracpart" value="substring($trunc, string-length($intpart), 2)"/> concat($intpart, '.', $fracpart) </function> This allows functions that don't need variables in XPath 2 to keep the return value as an expression within the body of the <function> element, while still providing help to the poort XPath 2 or XPath 1 users that want to use variables. Alternatively, we could completely get rid of the nested <var> element. This would mostly impact XPath 1 and XPath 2 implementations, with the idea that implementations would tend to migrate to XPath 3 as soon as possible anyway. So to summarize some ideas above: 1. We should consider using <return> instead of <sequence> if we do decide to use an element for return values. 2. However, we should consider *not* using an element for return values at all. 3. We should consider allowing function bodies simply as the content of <function>. 4. We should also support a shorthand with the @value attribute. 5. We might consider dropping support for nested <var> within <function> (not so sure about this one). Food for thoughts. -Erik [1] http://www.w3.org/MarkUp/Forms/wiki/Custom_XPath_functions
Received on Wednesday, 14 March 2012 17:02:14 UTC