This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.
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).
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
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?
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
(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 )
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
(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 )
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.