Skip to content
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

256: Context for default parameter values #375

Conversation

michaelhkay
Copy link
Contributor

@michaelhkay michaelhkay commented Feb 27, 2023

This is an attempt to resolve issue #256 by providing details of the static and dynamic context for evaluating default parameter values, including providing a mechanism for accessing parts of the static and dynamic context of the caller.

If this PR is accepted we will need to follow up with (a) similar changes to XSLT, and (b) use of the new notation in the signatures of standard functions and operators that have context-dependent default values for parameters.

Note that the PR also breaks up the rather unwieldy sections for Function Declarations and Variable Declarations into more manageable subsections, which has involved some re-ordering; some of the change marking may therefore be spurious.

@ChristianGruen
Copy link
Contributor

ChristianGruen commented Mar 5, 2023

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 caller-context()?context-item() possibly be shortened to context()?item()?

<item><p>The required type of the parameter is given by the <code>TypeDeclaration</code>, defaulting to <code>item()*</code>.</p></item>
<item><p>The default value of the parameter is given by the expression that follows the <code>:=</code> symbol; if there
is no default value, then the parameter is a required parameter.</p></item>
<item><p><code>$fn:caller-context()?context-item()</code> provides the context item of the caller.</p></item>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the dollar characters need to be removed.

@michaelhkay
Copy link
Contributor Author

michaelhkay commented Mar 10, 2023

I have revised the proposal after our initial review. The revision includes changes to XSLT and F&O.

  • I decided to go for a magic variable ($context) rather than a magic function (fn:caller-context). Several reasons: the scope of the name is local; it doesn't require a namespace; it's easy to determine statically whether the feature is used; there are no messy edge cases involving things like fn:function-lookup.
  • I decided we only need to provide access to two context components, the context item and the default collation, because those are the only two used by functions in the core function library.
  • I decided to expose these as zero-arity functions rather than direct data values. This is primarily so we can mimic the behaviour of system functions with an argument that defaults to ".", namely that a dynamic error occurs if there is no context item.

Copy link
Contributor

@ChristianGruen ChristianGruen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the revised proposal.

  • I decided to go for a magic variable ($context) rather than a magic function (fn:caller-context). Several reasons: the scope of the name is local; it doesn't require a namespace; it's easy to determine statically whether the feature is used; there are no messy edge cases involving things like fn:function-lookup.

Thinking of try/catch, I would have liked to vote against the usage of magic variables. It feels confusing to me if variables are used in the code that are declared nowhere before.

I have further concerns regarding $context that I believe would not apply to a fn:context function:

  • The proposed variable looks like a local variable and can easily be mixed up.
  • If a $context variable is declared in an outer scope, the result of an existing $context variable declaration changes.
  • Similarly, if a $context variable is declared, it’s not possible in this scope to access the magic variable anymore.
  • In a library module, it feels unorthodox to have global variables that are not namespaced.

Thinking of fn:function-lookup, don't we have to deal with these case anyway? It would e.g. be legal to write (some weird) things as:

let $jupiterize := function(
  $input,
  $collation := function-lookup(xs:QName('fn:default-collation'), 0)()
) {
  compare($input, 'Jupiter', $collation) = 0
}
return //planet[$jupiterize(.)]

Finally, as a general note, having »constant variables« seems strange to me, even though it's technically sound.

@ChristianGruen ChristianGruen changed the title Context for default parameter values 256: Context for default parameter values May 2, 2023
@michaelhkay
Copy link
Contributor Author

I have decided to scrap this PR and to come up with a new proposal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants