-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Function declarations: static and dynamic context for default parameter values #256
Comments
We should perhaps think ahead and ask what we would want to do if we extend inline functions to allow default parameter values. How would we bind any variable references appearing in the default value expression in this case? One solution to the problem might be to say that when the user writes a default value expression as
the actual interpretation is that we create a default value function defined as |
I clearly remember proposing exactly this in the past few days -- must see where ... |
Found it: here |
I've been giving further thought to this. We have a number of built-in functions where the default for the $collation argument is "the default collation in the static context of the function call". (Recall that in XSLT, the default collation can vary from one instruction to another, using the While it's intuitive to allow the syntax The same is true for a default based on the dynamic context: the idea of making the default a function that uses the dynamic context of the caller doesn't work, because there's no way of writing a user-defined function that returns the context item of the caller. There's a circularity here: accessing properties of the static or dynamic context of the caller is currently a magic capability available only to built-in functions, and I think we can only provide the same capability to user-defined functions by invoking similar magic. My next idea is to interpret the default value as a macro, causing a function call to be statically expanded. So specifying "." as the default value for $collation causes a function call At present a function item referencing a context-dependent function always contains a binding of the context properties that it depends on. For example default-collation#1 binds the context at the point where the function reference is evaluated. We could consider allowing a function item to have an unbound context, for example default-collation##1 gives you a function that uses the context of the caller when the function item is eventually invoked. But this seems a lot of complexity for a simple requirement. A pragmatic solution to the dilemma might be:
|
I propose to resolve this as follows. XQuery and XSLT might use slightly different wording, but the technical effect is the same. The static context for the default value expression is the same as the static context for an initializing expression of a global variable except that (a) in-scope-variables is empty, (b) context item static type is item(). The dynamic context for the default value expresion is the dynamic context of the function call or function reference, except that available documents, available text resources, available collections, default collection, available URI collections, and default URI collection are all empty. |
I'm really struggling to see how to make I think I'm going to recommend scaling back our ambitions here, and propose that default values for functions should be evaluated in the same way as initialisers for global variables. This loses all ability to make the default depend on the context of the caller of the function. |
One disadvantage is that the notation we use in functions and operators, for example declaring a parameter as Perhaps we could formalise the "magic" as follows: we define a function (Alternative: rather than a magic function |
Some feedback from the XQuery perspective: I would be satisfied if we restricted parameter default values to literals. It feels confusing to me that something that is called a “default value” can be dynamic. Perhaps it’s still tolerable though to use I see an analogy with annotations: Annotation values are limited to literals. With RESTXQ, for example, annotations are also used to define default values. If we lift the restriction, it seems consistent to me to treat annotation values and parameter default values similarly. By the way, It’s inconvenient that there’s currently no way to supply Boolean annotation values. Maybe we could allow certain alias constructs in the syntax for both annotations and parameter defaults:
|
My starting point here has always been that user functions should be able to do anything that built-in functions can do (or at any rate, anything that we find it useful for them to do). Note that XSLT allows the default collation to be changed with much finer granularity than XQuery, so it's much more likely that the default collation for a function call will be different from the default collation of the function declaration. |
It could be helpful to have one or two examples in the specification for function items. Is the following expression correct? let $filter := function(
$item := caller-context()?context-item()
) {
$item = 'Jupiter'
}
return //planet[$filter()] Next, the naming is pretty technical. Could |
Resolved by PR #512 |
In the new text for default values on parameters in XQuery function declarations, we don't say clearly what the static context for the default value expression is. In particular we don't say that it excludes the other parameters of the function. The XSLT spec has similar (though slightly different) shortcomings.
There's a slight complication in that we say the dynamic context for the default value expression is the dynamic context of the function call. But what if the default value is a variable reference
$x
? Statically, this will be (presumably, though we don't currently say) be bound to a global variable$x
. Now, we say (under "dynamic context") that the dynamic "variable values" contains the same [expanded QNames] as the [in-scope variables] in the [static context] for the expression. But, the static context for the default value expression and the static context for the function call have different in-scope variables and they must therefore have different variable values in the dynamic context, so it's wrong to say that the dynamic context for the default value expression is the same as that of the function call.My first instinct would be to restrict the default value to being what XSLT calls a "static expression" (this isn't defined in XQuery, but it could be defined easily enough). However, that would disallow using "." as the default value expression, which is something we wanted to permit.
The next option would be to say that the dynamic context for a default value expression is the same as the dynamic context of the function call except that "variable values" contains bindings for global variables only. This feels rather kludgey, but it's workable in principle. (It's worth noting, and might be worth noting in the spec, that in XQuery all components of the dynamic context except the focus and the variable values are typically immutable within an execution scope. The same isn't true in XSLT, where we have additional dynamic context components like regex-group() and current-output-uri() to worry about.).
The text was updated successfully, but these errors were encountered: