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

1183 Add transient mode and the transient{} expression #1209

Closed

Conversation

michaelhkay
Copy link
Contributor

Fix #1183

@michaelhkay michaelhkay added XPath An issue related to XPath XQuery An issue related to XQuery Enhancement A change or improvement to an existing feature Tests Needed Tests need to be written or merged labels May 13, 2024
@ChristianGruen
Copy link
Contributor

I’m looking forward to the discussion (the most controversial aspect might be the suggestion to make the behavior completely implementation-defined).

Just one note: I have seen the example with file:append. This function is tagged as nondeterministic in the EXPath File Spec, so I would already expect implementations to suppress loop-lifting strategies whenever this function is spotted in a subexpression (I know this is currently true for Zorba and BaseX). Exact rules for nondeterministic code were always out of scope, but if we asssume that transient is more or less a synonym for tagging code as nondeterministic, another example with a deterministic expression would possibly make more sense. Maybe something like this:

transient {
  for $i in 1 to 5
  return fn:doc('https://nanotime.com')
}

@michaelhkay michaelhkay force-pushed the 1183-transient-expressions branch from e8129d7 to 7631d15 Compare May 20, 2024 22:34
@michaelhkay
Copy link
Contributor Author

Rebased to current master, and fixed a typo.

@michaelhkay michaelhkay force-pushed the 1183-transient-expressions branch from 7631d15 to 58a9c7c Compare May 22, 2024 18:27
@ChristianGruen
Copy link
Contributor

Some questions that I think we should try to answer for us or/and in the spec:

  1. Do we consider this extension to be a primarily vendor-specific extension (which can be relevant enough to add it to the spec)?
  2. Should the extension allow users to do things – across implementations – that they couldn’t do otherwise?
  3. If an expression E is already nondeterministic (such as a file:write function call), will transient { E } change anything?

And a Saxon-specific quetion: If we introduce the extension, would make functions like fn:collection deterministic by default?

@michaelhkay
Copy link
Contributor Author

(1) I don't think a feature that changes the spec, by relaxing constraints that the specification imposes on implementations, can be considered vendor-specific.
(2) The performance effect of using the feature is going to vary from one implementation to another, but that is true of every feature we specify.
(3) Implementations may already provide other ways of labelling things like file:write as nondeterministic, in which case they may not need this new way of doing it; but it's a more interoperable way of doing it than vendor-specific controls.
(4) For collections in Saxon we would probably continue to support configuration-level options, but we might change the defaults.

@ChristianGruen
Copy link
Contributor

Thanks.

(1) I don't think a feature that changes the spec, by relaxing constraints that the specification imposes on implementations, can be considered vendor-specific.

I would like to understand better whether there’s a chance to use transient {} with different implementations and get the same results. In other words, can we imagine a specific use of transient {} from which users of different implementations could benefit the same way? Or is it more like an extension for which you have some use cases in mind for Saxon?

I’m asking those questions because the current prose does not include examples that would help me to understand how we should reasonably support or advocate transient {} at the moment. For time measurements, I think that a dedicated function is a better choice. For parsing text, the default is now nondeterministic. It could possibly be relevant for fn:doc or fn:collection if those functions are not used for database access (on the other hand, we have our own nondeterministic functions for that, which come with additional options).

(2) The performance effect of using the feature is going to vary from one implementation to another, but that is true of every feature we specify.

I see. If it’s mostly about performance, it seems to be a vendor-specific thing indeed.

(3) Implementations may already provide other ways of labelling things like file:write as nondeterministic, in which case they may not need this new way of doing it; but it's a more interoperable way of doing it than vendor-specific controls.

As the File Module states that file:write is ·nondeterministic·, my point of view is that the function is not implemented correctly if the function behaves deterministically. In contrast, if the spec states that a particular function is ·deterministic·, I would expect an processor to implement this function in a way that it always returns the same result.

Maybe I’m being too rigorous here. If it’s no strict requirement of the current specification that a processor adheres to the defined function properties, we should think about introducing additional expressions to enforce determinism, or also context (in)dependency and focus (in)dependency, of functions.

@michaelhkay
Copy link
Contributor Author

Let me just address one of your points:

As the File Module states that file:write is ·nondeterministic·, my point of view is that the function is not implemented correctly if the function behaves deterministically.

I think that's a completely wrong interpretation. "Nondeterministic" means there is no guarantee of how it behaves, it doesn't mean there is a guarantee that it behaves in a particular way.

@ChristianGruen
Copy link
Contributor

I think that's a completely wrong interpretation. "Nondeterministic" means there is no guarantee of how it behaves, it doesn't mean there is a guarantee that it behaves in a particular way.

I can see your point. Why should then someone write transient { file:write(....) } if the only effect is that there will be no guarantee what will happen (if we regard transient to be more or less a synonym for nondeterministic)?

@michaelhkay
Copy link
Contributor Author

Why should then someone write transient { file:write(....) }

My primary use case for this feature has nothing to do with achieving predictable behaviour for nondeterministic functions. It's all about eliminating the cost of achieving predictable behaviour when predictable behaviour isn't required.

@ChristianGruen ChristianGruen added the Blocked PR is blocked (has merge conflicts, doesn't format, etc.) label Sep 6, 2024
@michaelhkay
Copy link
Contributor Author

This proposal met some resistance and I've decided to withdraw it.

@michaelhkay michaelhkay added Abandoned PR was rejected, withdrawn, or superseded and removed Blocked PR is blocked (has merge conflicts, doesn't format, etc.) Tests Needed Tests need to be written or merged labels Sep 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Abandoned PR was rejected, withdrawn, or superseded Enhancement A change or improvement to an existing feature XPath An issue related to XPath XQuery An issue related to XQuery
Projects
None yet
Development

Successfully merging this pull request may close these issues.

transient() - a function to make functions nondeterministic
2 participants