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
Functions that determine equality of two sequences or equality of two arrays #99
Comments
As the function can be implemented with just a few statements… let $seq1 := (1, 2, 3)
let $seq2 := (1, 2, 3)
return count($seq1) = count($seq2) and (
(: or array:for-each-pair :)
every $b in for-each-pair($seq1, $seq2, deep-equal#2) satisfies $b (: = true() :)
) …I wonder if the use case is prevalent enough to justify an extra function? The underlying question may be more general: Do we expect XQuery 4 to provide hundreds of helper functions, or do we expect it to mainly provide functions for things that cannot be implemented otherwise, or would be less efficient with standard XQuery? |
It would be nice to have some node/id based examples as well although I guess that would be easier using XQuery or XSLT where you can construct nodes than in pure XPath where you are not able to do that. |
@ChristianGruen Yes, and thinking in the same line FXSL for XSLT 1.0 helps us do everything, and shows that everything can be done just with XSLT 1.0, thus we do not need any higher version of XSLT. I know that such statements are an overstretched, almost ridiculous extreme. While they are (mainly) true, they totally ignore maybe the most important factor in programming languages -- convenience and understandability. Just that some complex expression as the above can be written by 5% of all developers doesn't mean that the remaining 95% will ever even try writing it -- not because that they can't but because this requires too-much unnecessary effort -- both to write and even more, to understand later. |
@martin-honnen Yes, this can be done even in pure XPath. |
@ChristianGruen Good question, I actually have proposed only the functions that I believe are the most important, and not the myriad of other functions that I have considered as possible to have. Equality, When deciding whether or not to include a new function we should ask ourselves to what extent that function helps us increase both the expressive power and understandability of the language. I strongly believe the proposed functions on sequences are probably the strongest candidates that satisfy these criteria. |
I experimented with XQuery and the following example:
|
@martin-honnen Great,
so that we see in the inequality with the reverse, that value-equality isn't used |
@martin-honnen I came up with this pure XPath example, which shows the evaluation with different let $compare := function($it1 as item(), $it2 as item()) as xs:boolean
{deep-equal($it1, $it2)},
$compare2 := function($it1 as item(), $it2 as item()) as xs:boolean
{if($it1 instance of node() and $it2 instance of node())
then $it1 is $it2
else $compare($it1, $it2)
},
$sequence-equal := function($seq1 as item()*, $seq2 as item()*,
$compare as function(item(), item()) as xs:boolean,
$self as function(*)) as xs:boolean
{
let $size1 := count($seq1), $size2 := count($seq2)
return
if($size1 ne $size2) then false()
else
$size1 eq 0
or
$compare(head($seq1), head($seq2)) and $self(tail($seq1), tail($seq2), $compare, $self)
}
return
let $inSeq := ( (1, 2, 1) !parse-xml("<v>" || . || "</v>"))
return
(
$sequence-equal($inSeq, $inSeq, $compare, $sequence-equal), (: returns true() :)
$sequence-equal($inSeq, reverse($inSeq), $compare, $sequence-equal), (: returns true() :)
$sequence-equal($inSeq, $inSeq, $compare2, $sequence-equal), (: returns true() :)
$sequence-equal($inSeq, reverse($inSeq), $compare2, $sequence-equal) (: returns false() :)
) |
In writing up the proposal for An example might be
which test whether the children of $chap comprise four elements with the specified local names. This use case works with the function as proposed, but the name |
The proposed function However it seems too-much more complicated in meaning (and even in its name) than the simpler and more easily understood
Compare with strings, where we have both the We can also make a parallel with another case of two proposals, one for concrete, specific functions ( |
I think you may have missed my point: I'm proposing |
@michaelhkay It will require a strenuous mental effort, and probably not always successful, in order to discover that one could uses "matches" for "equals" Why in the case of strings we have both functions and not just Why do we use: "abcd" eq "abcd" and not matches("abcd", "abcd" ) This may be just a linguistic problem, but I personally find it significantly disturbing. We vould try to have both matches-sequence($seq1, $seq2 ->{ op:same-key($it1, $it2) } But even in this case we have a problem: I personally believe that for two sequences to be "matching" they are not required at all to have the same length. But for two sequences to be "equal", they must be of the same length. |
The only standard XPath 3.1 function that compares two arrays or two sequences for equality is the deep-equal() function.
It implements "value-based equality" which may not always be the equality one needs to check for. For example, the standard XPath 3.1 operator is implements a check for "identity-based equality" on nodes.
Thus for two nodes
$n1
and$n2
it is possible that:deep-equal($n1, $n2) ne ($n1 is $n2)
The functions defined below can be used to verify a more generic kind of equality between two sequences or between two arrays. These functions accept as a parameter a user-provided function
$compare()
, which is used to decide whether or not two corresponding items of the two sequences, or two constituents of the two arrays are "equal".Examples:
Possible implementations:
fn:sequence-equal
:fn:array-equal
:The text was updated successfully, but these errors were encountered: