-
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
fn:void: Naming, Arguments #639
Comments
I read the description of the function in the FO Specification:: This paragraph makes the function completely confusing to me and I wonder what on Earth would ever make me use it: "It is ·implementation-dependent· whether the supplied argument is evaluated or ignored. An implementation may decide to evaluate ·nondeterministic· expressions and ignore deterministic ones." I propose to remove this function from the FO Spec, until a better description is provided, that shows the reader a convincing use case for its unambiguous semantic, usability and value. |
There will definitely be no need for everyone to use the function; it always depends on the use cases you are confronted with, and I assume yours simply don’t apply. It’s easy to confirm that an equivalent function ( map:get(
$map as map(*),
$key as xs:anyAtomicType,
$fallback as function(xs:anyAtomicType) as item()* := fn:void#1
) as item()* …and it can e.g. be used as a compact fallback function for array:get(array { 1, 2, 3 }, 4, void#1) |
I think it's a good name. The English verb "to void" means to cancel something, to nullify it, and that's a good description of what this function is doing; in addition there is a tradition in computing that associates the word "void" with functions that return nothing. I think the main occasions I've needed something like this are in connection with
It's a function I could live without, but it's a simple primitive that makes logical sense. |
I’ve come across an interesting function in Mary Holstege’s nice MathLing library. It’s located in the testlib.xqy module: declare function this:assertFails(
$message as xs:string,
$f as function() as item()*
) as empty-sequence()
{
let $ok :=
try {
($f(), false())=>tail()
} catch * {
true()
}
return (
if ($ok) then ()
else fn:error(QName("http://mathling.com/errors","ml:FAILURE"), "Did not get expected error: "||$message)
)
}; I noticed that the code is evaluated differently, depending on the processor you use. The reason is that there’s no need to evaluate You might think that try {
void($f()),
fn:error(QName("http://mathling.com/errors","ml:FAILURE"), "Did not get expected error: "||$message)
} catch err:* {
(: expected :)
} …but it won’t in practice, as we don’t enforce the evaluation of the argument. I still think it would be a bad idea, but we could think about adding an option that makes the evaluation strategy explicit. I wonder how others would write code like this? How would you proceed to enforce the evaluation of the function that’s supplied to |
Not if the function is indeterministic. We could introduce a new type of function: "external", for which we must not make any assumptions, thus it needs to be evaluated if the expression containing a call to it is evaluated. |
If Thus, |
Some functions in the spec, including |
Then why did these functions get added to the Spec, in the first place? With this clarification they are meaningless! I couldn't find any such rule explicitly stated in the FO 3.1 Spec. Here is the complete definition of nondeterministic: The description of fn:parse-xml says nothing about the fact that the specification doesn't mandate this function to be evaluated. This feels like intentionally misleading... |
Do you refer to
That's no specific property of this function. It’s a general thing that expressions needn't be evaluated if their results are not further processed. |
See my updated comment above. There is no text in the spec saying that an implementation may choose not to evaluate a nondeterministic function. |
That's no specific property of nondeterministic functions. It’s a general thing that expressions needn't be evaluated if their results are not further processed. |
You provided this example:
Why do you think the result of what would be the result of evaluating: if(count(fn:parse-xml($s)) < 2)
then 5
else 7 |
Of course you don't have to evaluate a function if you already know the answer. For example if someone writes |
How can you statically know the value of |
You can't know its actual value, but you can know that it's >= 1. Not that I can see any optimizer taking the trouble to do that. |
@michaelhkay The true expression is this: if(count(fn:parse-xml($s)//*) < 2)
then 5
else 7 And the processor cannot know statically the result of evaluating this |
I can think of cases where it can. For example if $s is
and $v is
then a processor that cares to do the analysis can indeed infer statically that |
We can use something as: if(count(fn:parse-xml(unparsed-text($myUrl))//*) < 2)
then 5
else 7 |
It's not hard to come up with expressions where I can't think of any way of making any static inferences about the result, but I'm not sure what such examples prove! My experience over many years with the test suite is that implementors are very imaginative with the optimizations they discover. Going back a few steps in the thread, you said:
and that is simply incorrect. See XPath 3.1 §2.3.4, for example:
This is equally true of the expression |
Not the result matters here, but the number of resulting items, and this information is statically known for The interesting thing I believe is that we are trying to be smarter than the processor, as there is no vendor-independent way to enforce the evaluation of an expression. The current definition of I have no easy answer, in particular none that would easily be applicable to different processors. |
This text does not mention "nondeterministic". And if the processor cannot skip the evaluation of an expression that depends on the value of a call to a nondeterministic function, then the processor would have to evaluate that call. As for the imagination of implementors, one can use any known law/formula that the Processor cannot prove.. For example, that the root of:
in a close interval containing And the code of the function can use the value of the root (straightforward to calculate using the FXSL function |
I propose that we close this issue unless we can find substantial agreement on what could be changed or better documented. |
The CG agreed to close this issue without action meeting 062 |
A new function
fn:void
was added to the spec (see #359 for details).This issue can be used to discuss alternative names for the function, as was suggested by @dnovatchev.
The text was updated successfully, but these errors were encountered: