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 1680 - [FS] editorial: 4.12.5 Constructor Functions
Summary: [FS] editorial: 4.12.5 Constructor Functions
Status: CLOSED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: Formal Semantics 1.0 (show other bugs)
Version: Last Call drafts
Hardware: All All
: P2 minor
Target Milestone: ---
Assignee: Jerome Simeon
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-07-17 08:22 UTC by Michael Dyck
Modified: 2007-09-30 04:29 UTC (History)
0 users

See Also:


Attachments

Description Michael Dyck 2005-07-17 08:22:55 UTC
4.12.5 Constructor Functions

Norm / rule 1.
[[ AtomicType(Expr) ]]_Expr
    This is gramatically impossible. What you're thinking of is a
    FunctionCall in which the QName (the "function name") is actually the
    name of an atomic type. But (a) there's no AtomicType involved, and
    (b) you can't detect such things syntactically, you have to consult
    the static environment.

    But why bother? Just let it be handled as a FunctionCall (to a
    built-in function).
Comment 1 Jerome Simeon 2006-04-11 22:46:58 UTC
It is not quite correct to rely on function calls here as constructor
functions have the semantics of cast as, not function
calls. Therefore, I kept the rule with 'AtomicTypeName', and added
some text to explain the abuse related to namespace resolution.

- Jerome
Comment 2 Michael Dyck 2006-04-12 09:51:32 UTC
Even changing AtomicType to AtomicTypeName, it's still ungrammatical, because AtomicTypeName doesn't exist in the XQuery grammar. (And even if it did, QName wouldn't derive it.) So the left-hand side of the normalization rule will never match a legal query, and the rule will never be invoked.

Clearly, a call to a constructor function is syntactically a FunctionCall, so the rules of 4.1.5 have to deal with it at some point.

Moreover, the XQuery doc indicates that:
1) unprefixed constructor function names are resolved according to the default function namespace.
2) the 'Function signatures' component of the static context (i.e., statEnv.funcType in the FS doc) contains signatures for constructor functions.

Thus, it should be well-defined to subject constructor names to
    QName of func expands to expanded-QName
and
    statEnv.funcType(expanded-QName,1) = declare function ...

The XQuery doc and the F+O doc appear to put constructor functions on an equal footing with other built-in functions, which suggests that 4.1.5 should handle them like other built-in functions.

However, those docs don't make it entirely clear whether a call to a constructor function:
-- is a call to an actual (built-in) function, where the semantics of that function happen to be defined in terms of a cast expr, or
-- is just a syntactic alias for a cast expr.

If the former, then 4.1.5/STA would probably want to add another item to the list of 3:
    1.5 If the expanded QName for the function corresponds to one of the
        built-in constructor functions, the rules in [...] are applied.

If the latter, then the constructor-specific logic has to get control earlier in the process, presumably in 4.1.5/Norm.

But are there any cases where the two interpretations lead to different results?
Comment 3 Jerome Simeon 2006-04-21 14:48:34 UTC
Michael:

The XQuery 1.0 document is very clear that the semantics of
constructor functions are the same as a cast. This is the actual
definition:

[Definition: The constructor function for a given type is used to
convert instances of other atomic types into the given type. The
semantics of the constructor function T($arg) are defined to be
equivalent to the expression ($arg cast as T?).]

The semantics of function calls have a lot of things going on which
are not happening for constructor functions, notably the function
conversion rules.

That said, you are right that the normalization rule as currently
written does not deal with namespace normalization. The fix
implemented in the FS document currently adds some english prose to
explain what is going on.

I just realized though that we could write the normalization rule as
follows, making namespace resolution explicit. The second precondition
checks that the QName is the name of an atomic type.

  statEnv |- QName of elem/type expands to expanded-QName
  statEnv |- declare type QName restricts AtomicTypeName
  -----------------------------------------------------------
  statEnv |- [QName(Expr)]_Expr == [Expr cast as QName?]_Expr

[That usage for normalization rules is introduced in Section 3.2.2
Normalization mapping rules.]

That may work better than just some english text. Any suggestion or
preference on this?

- Jerome
Comment 4 Michael Dyck 2006-04-21 20:52:42 UTC
(In reply to comment #3)
> 
> The XQuery 1.0 document is very clear that the semantics of
> constructor functions are the same as a cast.

It's clear that the semantics of *something* relating to constructor functions are the same as a cast, but it's not so clear what that something is. See below.

> This is the actual definition:
> 
> [Definition: The constructor function for a given type is used to
> convert instances of other atomic types into the given type. The
> semantics of the constructor function T($arg) are defined to be
> equivalent to the expression ($arg cast as T?).]

A good example of lack of clarity. It *says* it's talking about the semantics of the *function*, but it *looks* like it might be talking about the semantics of the function *call* (and the latter is how you indicate it should be interpreted). That's the distinction I was making in my previous comment. (It would be clear if it said "The semantics of a call to the constructor function...".)

> The semantics of function calls have a lot of things going on which
> are not happening for constructor functions, notably the function
> conversion rules.

Okay. I'm still curious if there are cases where the two interpretations would lead to different results. 

....

> I just realized though that we could write the normalization rule as
> follows, making namespace resolution explicit. The second precondition
> checks that the QName is the name of an atomic type.
> 
>   statEnv |- QName of elem/type expands to expanded-QName
>   statEnv |- declare type QName restricts AtomicTypeName
>   -----------------------------------------------------------
>   statEnv |- [QName(Expr)]_Expr == [Expr cast as QName?]_Expr
> 
> [That usage for normalization rules is introduced in Section 3.2.2
> Normalization mapping rules.]
> 
> That may work better than just some english text. Any suggestion or
> preference on this?

I prefer the inference rule. But it needs some tweaking...

1)
As I pointed out in comment #2, the XQuery doc indicates that unprefixed constructor function names are resolved according to the default function namespace (not the default element/type namespace). Thus, "of elem/type expands to" should be changed to "of func expands to".

2)
For "declare type", I think you mean "define type". But that means the judgment is of the form
    statEnv |- Definition
which I don't think is valid. Instead, what you probably mean is something like
    statEnv.typeDefn(expanded-QName) = define type QName2 AtomicTypeDerivation
(Note that the QName in the Definition won't always be the same as the QName in the FunctionCall, thus QName2.)

3)
Change '==' to '='. See Bug 1548.

4)
The occurrences of 'Expr' as an italicized word should really be 'ExprSingle'.

In sum:
    statEnv |- QName of func expands to expanded-QName
    statEnv.typeDefn(expanded-QName) = define type QName2 AtomicTypeDerivation
    -----------------------------------------------------------
    statEnv |- [QName(ExprSingle)]_Expr = [ExprSingle cast as QName?]_Expr


Given the above, you could make 4.1.5 / Norm / rule 1 more explicit and complementary:

    statEnv |- QName of func expands to expanded-QName
    not( statEnv.typeDefn(expanded-QName) =
                  define type QName2 AtomicTypeDerivation )
    statEnv.funcType(expanded-QName,n) =
                  declare function expanded-QName(Type1, ..., Typen) as Type
    -----------------------------------------------------------
    statEnv |- [QName(Expr1,...,Exprn)]_Expr =
                  QName( [Expr1]_FunctionArgument(Type1), ..., etc )
Comment 5 Jerome Simeon 2006-04-24 17:45:15 UTC
Implemented the inference rule with all the 4 suggested fixes, plus the corresponding change to the normalization of function calls.

The first part of your last comment is more of a general XQuery 1.0 comment. I will let you decide whether you want to bring that item to the attention of the working group as an XQuery comment.

Thanks,
- Jerome
Comment 6 Michael Dyck 2006-09-13 01:51:28 UTC
(In reply to comment #5)
> Implemented the inference rule with all the 4 suggested fixes, plus the
> corresponding change to the normalization of function calls.

For the latter change, you missed the "not(...)" in premise 2.

However, I've just realized that (even with the "not()") that premise won't work, because QName2 and AtomicTypeDerivation are unconstrained, so there's always bindings for them (in fact, infinitely many) that will make the body of the not() false, and thus the premise true, including all the cases where you don't want it to be.

One way to fix this is to introduce an auxiliary judgment:

    statEnv.typeDefn(expanded-QName) = define type QName2 AtomicTypeDerivation
    --------------------------------------------------------------------------
    expanded-QName denotes a constructor function

then replace premise 2 with

    not( expanded-QName denotes a constructor function )
Comment 7 Michael Dyck 2007-09-30 04:28:28 UTC
The unresolved portion of this issue has been entered as FS erratum E008. The changes suggested in Comment #6 have been incorporated into a fix, which I have committed to the source files for the next edition of the FS document. Consequently, I'm marking this issue resolved-FIXED, and CLOSED.