basexxpath-3.0

error in declaring higher-order functions in XPath 3.0: must declare return type?


Following @DimitreNovatchev's article Programming in XPath 3.0, and using BaseX GUI as the test environment, I tried some of the examples that define functions that accept functions as parameters. E.g. with

let $compose :=
         function($f as function(), $g as function())

(The rest of the code isn't relevant to this error, but you can see it as the third example under Function Composition.)

I get this error from BaseX:

Error:
Stopped at 43-compose.xpath, 2/39:
[XPST0003] Expecting 'as', found ','.

The point where the error was detected was on the second line, just before the comma. Apparently, the processor expects the $f parameter declaration to say not just that $f should be a function, but also the return value of the function.

I don't know whether it's right for BaseX to expect that or not. Presumably, Dimitre's examples tested successfully before he made that presentation at Balisage. Maybe something changed in the XPath 3.0 spec between that article and when BaseX was released?


Solution

  • OK, found the answer. I got an evaluation key for Saxon EE, so I was able to try another processor. For future reference, this was the command line:

    C:\Program Files\Saxon>java -cp saxon9ee.jar net.sf.saxon.Query -s:"input.xml" -
    q:"ex5.xpath" -qversion:3.0
    

    Note that -qversion:3.0 is currently required in order to get any 3.0 functionality.

    Saxon throws an error at the same point, but gives a helpful suggestion on how to fix it:

    Error on line 2 column 39 of ex5.xpath:
     XPST0003 XQuery syntax error near #... function($f as function(), $#:
      function() is no longer allowed for a general function type: must be function(*)
    

    I changed function() to function(*) wherever a general function type was wanted, and the errors went away, both in BaseX and in Saxon.

    So apparently BaseX was correct (but Saxon's error message was more helpful, as is often the case!). Sounds like something did change in the spec recently. I haven't been able to figure out what the relevant change was, from the change log. But regardless of what changed, the spec currently says that a FunctionTest must have either a * within the parentheses, or an as after them. (This applies to declarations of parameters that are functions, but does not apply to inline functions themselves.)