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.1.5 Function Calls DEv / rule (1|2|3) These three rules are all mostly the same (though that fact is obscured by irrelevant differences). Refactor! You could have one rule that does almost everything, but "calls out" to a judgment that handles the essential differences between locally-declared, imported, and built-in/external functions. The new judgment would have a form something like: FUNC-REMAINDER applied to Value1, ..., Valuen yields Value where FUNC-REMAINDER is a symbol for "the remainder of the function definition" that dynEnv.funcDefn maps to. (The built-in/external alternative of the new judgment would subsume DEv / rule 4.) This would also allow refactoring of some of the DErr rules.
Agreed, we may find a better way to write those rules. Here are some proposed rules to address the comment, trying to improve on the readability for the existing rules. - Jerome Notations --------- We should introduce a new formal grammar production: [Formal] FunctionSig ::= "declare" "function" QName "(" ParamList? (")" | (")" "as" SequenceType)) Such production is notably used in the static context (for statEnv.funcType). Dynamic semantics ----------------- Here is the generic rule function function calls: dynEnv |- Expr1 => Value1 ... dynEnv |- Exprn => Valuen statEnv |- QName of func expands to expanded-QName statEnv.funcType(expanded-QName) = { FunctionSig1, ..., FunctionSigm } FunctionSigi = declare function expanded-QName(Type1, ..., Typen) as Type statEnv |- Value1 against Type1 promotes to Value1' ... statEnv |- Valuen against Typen promotes to Valuen' dynEnv |- function expanded-QName with types (Type1,...,Typen) on values (Value1',...,Valuen') yields Value statEnv |- Value against Type promotes to Value' ------------------------------------------------------------------------------------------- dynEnv |- QName ( Expr1, ..., Exprn ) => Value' This uses the following auxiliary judgment: dynEnv |- function expanded-QName with types (Type1,...,Typen) on values (Value1',...,Valuen') yields Value which is defined as follows: * For user-defined functions: dynEnv.funcDefn(expanded-QName(Type1, ..., Typen)) = (Expr, Variable1, ... , Variablen) dynEnvDefault + varValue( Variable1 => Value1; ...; Variablen => Valuen) |- Expr => Value --------------------------------------------------------------------------------------------------------- dynEnv |- function expanded-QName with types (Type1,...,Typen) on values (Value1,...,Valuen) yields Value * For built-in or functions: dynEnv.funcDefn(expanded-QName(Type1, ..., Typen)) = #BUILT-IN "The built-in function" expanded-QName "(See [Functions and Operators] or [7 Additional Semantics of Functions]) applied to" (Value1,...Value2) "yields the value" Value --------------------------------------------------------------------------------------------------------- dynEnv |- function expanded-QName with types (Type1,...,Typen) on values (Value1,...,Valuen) yields Value * For external functions: dynEnv.funcDefn(expanded-QName(Type1, ..., Typen)) = #EXTERNAL "The external function" expanded-QName "applied to" (Value1,...Value2) "yields the value" Value --------------------------------------------------------------------------------------------------------- dynEnv |- function expanded-QName with types (Type1,...,Typen) on values (Value1,...,Valuen) yields Value * For imported functions: Note that this case also checks that the parameteres can be promoted in the context of the imported module. dynEnv.funcDefn(expanded-QName(Type1, ..., Typen)) = #IMPORTED(URI) URI =>module_statEnv statEnv1 URI =>module_dynEnv dynEnv1 statEnv1.funcType(expanded-QName) = { FunctionSig1', ..., FunctionSigm' } FunctionSigi' = declare function expanded-QName(Type1', ..., Typen') as Type' dynEnv1.funcDefn(expanded-QName(Type1', ..., Typen')) = (Expr, Variable1, ... , Variablen) statEnv1 |- Value1 against Type1 promotes to Value1' ... statEnv1 |- Valuen against Typen promotes to Valuen' dynEnvDefault + varValue( Variable1 => Value1; ...; Variablen => Valuen) |- Expr => Value --------------------------------------------------------------------------------------------------------- dynEnv |- function expanded-QName with types (Type1,...,Typen) on values (Value1,...,Valuen) yields Value
(In reply to comment #1) > > [Formal] FunctionSig ::= "declare" "function" QName "(" ParamList? (")" | (")" > "as" SequenceType)) This doesn't agree with your uses of the symbol: > FunctionSigi = declare function expanded-QName(Type1, ..., Typen) as Type > ... > FunctionSigi' = declare function expanded-QName(Type1', ..., Typen') as Type'
(In reply to comment #1) > > * For imported functions: > > Note that this case also checks that the parameteres can be promoted > in the context of the imported module. I think XQuery 3.1.5 is saying that the conversion (incl. promotion) is done once, but the resulting value must "match the expected type" twice (in both modules). (Though I'm not sure if there's a case where the two interpretations would have different outcomes.) If my reading is correct, then you'd replace > statEnv1 |- Value1 against Type1 promotes to Value1' > ... > statEnv1 |- Valuen against Typen promotes to Valuen' with 'matches' premises. But in either case, I think Type1 and Typen should be Type1' and Typen' (the types in the signature in the defining module).
Agreed on comment #2. Thanks for the catch. We should have the grammar match the signature used in the rules. I also agree on comment #3 (although it took me a while longer to get there. I think both are good amendments to the proposal. - Jerome
The working groups have adopted the proposes resolution, with your amendments. Best, - Jerome