Bug 1680 - [FS] editorial: 4.12.5 Constructor Functions
: [FS] editorial: 4.12.5 Constructor Functions
Status: CLOSED FIXED
Product: XPath / XQuery / XSLT
Formal Semantics 1.0
: Last Call drafts
: All All
: P2 minor
: ---
Assigned To: Jerome Simeon
: Mailing list for public feedback on specs from XSL and XML Query WGs
:
:
:
:
:
  Show dependency treegraph
 
Reported: 2005-07-17 08:22 UTC by Michael Dyck
Modified: 2007-09-30 04:29 UTC (History)
0 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
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.


  翻译: