Skip to content

Instantly share code, notes, and snippets.

@avernet
Created March 8, 2012 18:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avernet/2002642 to your computer and use it in GitHub Desktop.
Save avernet/2002642 to your computer and use it in GitHub Desktop.
Initial reactions to Custom XPath Functions

Full syntax:

<function name="my:foo" as="number">
   <param name="p" as="number"/>
   <param name="q" as="number"/>
   <sequence select="$p + $q"/>
</function> 

Compact syntax introducing params and select attributes, with params using the ParamList construct from XQuery:

<function name="my:f" as="number" params="p as number, q as number" select="$p+$q"/>

Even more compact, suggested by @ebruchez syntax using part of the FunctionDecl construct from XQuery:

<function signature="my:f(p as number, q as number) as number" select="$p+$q"/>
  • Downsides:
    • Marginally harder to parse.
    • Less XMLish. (Which arguably, can be seen as an advantage.)
  • Upside: compactness, obviously. This is particularly important as this construct would often be used to avoid code duplication by moving a common sub-expression into a function. If the syntax to declare a function is too cumbersome, some will judge the remedy to be worse than desease.

The current proposal only allows functions to be declared at top level of a model. XSLT 2.0 has a similar restriction. While making the job of implementors easier, this may seem unnatural to XForms authors, restricts what they can do with the language, and prevents the code modularity enabled by allowing declaration and use to be close to each other.

Instead, we could:

  • Functions declared at the top level of a model are visible in that model only.
  • Functions declared elsewhere are lexically scoped.

The current proposal makes it an error to access the XPath context. Instead, as in most modern programming languages, the context be what it is at where the function is declared. The same would apply to in-scope variables.

@nvdbleek
Copy link

nvdbleek commented Mar 9, 2012

Comments on 'Evaluation context':

  • Providing access to the 'in scope' variables doesn't do much harm I think because you can only call the function if it is in scope (either lexical scoped (if we allow function definitions anywhere) or if embedded in the current model in scope). And therefore the variables will be available in the static context anyway.
  • Having the focus be based on current context of where the function is defined has a slight downside. An implementation should 'wrap' the xpath functions implementation because he should change the context to the context were the function is defined (but I think it is possible, implementer should take repeat iteration into account). It is also inline with inline function syntax in XPath 3.0

Comments on 'compact syntax':

@avernet
Copy link
Author

avernet commented Mar 13, 2012

It's good to know that XForms allowing functions to access variables in scope and the XPath context where the function is defined would be inline with what XPath 3 is doing.

@nvdbleek
Copy link

Apparently I miss interpreted the XPath 3.0 spec. Michael Kay says "User-defined functions get no context item, position, or size. That's true both for named global functions and inline functions."

So I think our custom functions also shouldn't do that. Now that we have variables you can work around this limitation.

Example:

<var name="context" value="."/>
<var name="context-pos" value="position()"/>
<var name="context-size" value="last()"/>
<function signature="my:f() as number" value="$context-pos = $context-size"/>

@avernet
Copy link
Author

avernet commented Mar 15, 2012

I also misread that part of the XPath spec. I can't imagine that supporting the context, in addition to variables, adds significant complexity to an implementation. So their decision must have been motivated by other reasons, which aren't clear to me. But this being the way functions are defined in XPath 3.0, I agree it isn't unreasonable to follow XPath's footsteps, even if we wouldn't have made the same choice. And as you've shown in the above example, this isn't a show-stopper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment