This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 3830 - Static typing of function declarations (K-Function-Prolog)
Summary: Static typing of function declarations (K-Function-Prolog)
Status: CLOSED FIXED
Alias: None
Product: XML Query Test Suite
Classification: Unclassified
Component: XML Query Test Suite (show other bugs)
Version: 1.0.1
Hardware: PC Windows XP
: P2 normal
Target Milestone: ---
Assignee: Frans Englich
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on: 3841
Blocks:
  Show dependency treegraph
 
Reported: 2006-10-13 14:47 UTC by Nick Jones
Modified: 2007-01-22 12:10 UTC (History)
0 users

See Also:


Attachments

Description Nick Jones 2006-10-13 14:47:59 UTC
The following function declarations contain parameters without a declared type. 5.15 of the Formal Semantics states these are given the item()* sequence type. But the functions expected them to be a different type. For example, in function-declaration-006:

declare function local:mysum($i, $j)
{
   let $j := $i + $j
   return $j
};

This does not type check as $i + $j expectes anyAtomicType?


Could these functions be modified to define types for the parameters. Many of them also currently test the results using the "eq" operator, so could they have a return type to ensure this types checks, or have their results tested by the test harness.


K-FunctionProlog-18
K-FunctionProlog-19
K-FunctionProlog-21
K-FunctionProlog-22
K-FunctionProlog-23
K-FunctionProlog-30
K-FunctionProlog-39
K-FunctionProlog-66
K2-FunctionProlog-1
K2-FunctionProlog-2
K2-FunctionProlog-3
K2-FunctionProlog-4
Comment 1 Nick Jones 2006-10-13 17:28:33 UTC
The following function from K2-FunctionProlog-7 fails to static type check

declare function local:myFunction() as xs:float
{
        4.0
};


as 4.0 is xs:decimal, but the return type is of xs:float
Comment 2 Frans Englich 2006-10-13 17:49:10 UTC
Isn't type promotion invoked? See 3.1.5, "The function conversion rules are used to convert an argument value or a return value to its expected type".
Comment 3 Michael Kay 2006-10-13 18:50:40 UTC
But decimal is automatically promoted to float in this context. Surely that applies to static typing too?
Comment 4 Nick Jones 2006-10-16 10:06:29 UTC
(In reply to comment #3)
> But decimal is automatically promoted to float in this context. Surely that
> applies to static typing too?
> 
Having compared the XQuery and Formal Semantics spec, I think they describe different behavior.

The FS 5.15 states: "The function body's type must be a subtype of the expected return type. If static typing fails, a static type error is raised." I can't find any reference to promotition for the static typing of function declarations in the FS.

If you agree I'll re-report this as a bug in the FS.

Comment 5 Frans Englich 2006-10-16 11:04:17 UTC
I looked at it a bit too, with no luck. Another relevant section is 4.1.5 Function Calls, Static Type Analysis that discusses typing of user-defined functions, and defines promotion for /arguments/.

I neither see where atomization is applied for both return value and arguments. For example, I believe this is a valid query:

declare function local:func($arg as xs:integer) as xs:integer
{
   <e>1/<e>
};
local:func(<e>2</e>)

So yes, I would open a FS report. Perhaps we simply fail at reading the spec, but if so, we'll at least get rid of the confusion.

(I have tests locally for scenarios like this that hopefully will make it into the XQTS.)


Frans
Comment 6 Nick Jones 2006-11-02 13:29:31 UTC
OK, I'm now happy with K2-FunctionProlog-7. With the function conversion rules applied to the body when static typing it static type checks.
Comment 7 Frans Englich 2006-12-13 11:25:56 UTC
XQuery is inconsistent regarding how the static types are inferred for variable declarations and function declarations.

If a variable declaration has no type declaration, it is inferred from the static type of the assignment expression.

If a function declaration has no type declaration, it defaults to item()*.

Many implement the type inferring in function declarations as an optimization, which is why some pass tests like K-FunctionProlog-18, I guess.

Perhaps the different behaviors should be aligned, just as Mike's suggestion to align conversion rules for variables. (Yes, this is the wrong place for this.)


Frans
Comment 8 Michael Kay 2006-12-13 11:39:43 UTC
I'm no expert, but I think the difference for the inconsistency that Frans notes is that functions can be recursive, but variables can't. If you infer the static type of a function result from its body, then you need some mechanism to ensure that the inference terminates - which is easier to do in a real product than in a specification. (IIRC in Saxon I simply probe only one level deep - that is, I look at the function body but not at the internals of any functions that it calls.)
Comment 9 Frans Englich 2006-12-13 12:44:46 UTC
Right! I had completely forgotten implementing that.

I looked at how my implementation does this: when a callsite to a user declared function is asked for its static type, it uses the body of the function it calls, /if/ it's not a recursive call(e.g, the callsite is in the body of the function it calls, or indirectly via a reference). So type inferring should work well, since it infers to any AST depth until it encounters an actual recursive call.
Comment 10 Tim Mills 2007-01-08 14:57:25 UTC
K-FunctionProlog-25 and K-FunctionProlog-65 also have similar problems.

The comment in K-FunctionProlog-65 is also misleading:

(:*******************************************************:)
(: Test: K-FunctionProlog-65                             :)
(: Written by: Frans Englich                             :)
(: Date: 2006-10-05T18:29:39+02:00                       :)
(: Purpose: Since the user function has no declaredreturn type, it is inferred f
rom the body, and therefore its callsite doesn't cause a type error(XPTY0004). :
)
(:*******************************************************:)

The formal semantics specification says:

"If the return type of the function is not provided, it is given the item()* sequence type."
Comment 11 Frans Englich 2007-01-12 18:52:35 UTC
An attempted fix has been committed to CVS, and should be part of XQTS_current.zip. Feel free to verify that the fix is acceptable, and if so, change status to CLOSED. If the attempted fix is not acceptable, reopen this report.

If no opinion about this resolution is expressed within two weeks, it will be closed.

Along with the fix for this report, was committed fixes for other reports as well. Also, a significant amount of new tests were added to cover missing areas and changes in the specifications.
Comment 12 Nick Jones 2007-01-17 18:35:49 UTC
Thanks. Many of them are fixed, but I'm still having problems with:

K-FunctionProlog-21
K-FunctionProlog-22
K-FunctionProlog-23
K2-FunctionProlog-1
K2-FunctionProlog-2
K2-FunctionProlog-3
K2-FunctionProlog-4

these are generally like

declare function local:func($a, $unused, $c)
{
        $a + $c
};

which fails to type check as $a and $c haven't been assigned types, so are assumed item()* for which + is not defined.
Comment 13 Frans Englich 2007-01-21 12:45:55 UTC
A fix has been attempted in CVS, and XQTS_current.zip has been updated to contain the new change. If it can be verified that the change is correct, it would be appreciated.

If this resolution is satisfiable, feel free to change status to closed. Otherwise, reopen this report. If no opinion on the resolution is expressed within two weeks, I will change status to closed.

This change to this report was part of a batch-change of several reports.