Re: [xsl] () eq () vs () = ()

Subject: Re: [xsl] () eq () vs () = ()
From: Brandon Ibach <brandon.ibach@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 3 Oct 2011 06:56:58 -0400
On Mon, Oct 3, 2011 at 6:27 AM, Andrew Welch <andrew.j.welch@xxxxxxxxx> wrote:
> On 3 October 2011 11:11, Brandon Ibach
> <brandon.ibach@xxxxxxxxxxxxxxxxxxx> wrote:
>> On Sat, Oct 1, 2011 at 12:01 PM, Andrew Welch <andrew.j.welch@xxxxxxxxx> wrote:
>>>> deep-equal(A, B) means (count(A) eq count(B) and every $i in 1 to count(A)
>>>> satisfies A[$i] eq B[$i]). Therefore deep-equal((), ()) is true.
>>>
>>> Is it fair to say deep-equal could mean:
>>>
>>> every $i in 1 to max((count(A), count(B))) satisfies A[$i] eq B[$i]
>>>
>>> which would then return false, as its only the length check that is
>>> causing it to return true (and thats only there to avoid also checking
>>> every item in B is equal to A)
>>
>> Even if this is a reasonable definition for deep-equal (disregarding
>> the fact that, as Michael pointed out, it doesn't properly handle
>> values such as NaN or nodes), your assertion that it would return
>> false for deep-equal((), ()) does not hold
>
> The point I was trying to make was if you don't compare the lengths,
> it won't return true because there is nothing to compare, just like =.
>
> You could of course flip that around and say if you start from a
> position of true, there's nothing to make that false, but as = returns
> false, it would make sense to me to start from a position of false.

Your concept of "starting from a position of true/false" is leading
you to faulty logic.  The statements made so far about the meaning of
deep-equal, including yours, have used the XPath "every" operator,
about which the XPath 2 spec (section 3.9, subpoint 2) states
(emphasis mine):

"If the quantifier is every, the quantified expression is true if
every evaluation of the test expression has the effective boolean
value true; otherwise the quantified expression is false. This rule
implies that, __if the in-clauses generate zero binding tuples, the
value of the quantified expression is true__."

Your assertion that the definition you gave would return false for two
empty sequences is simply not correct.  To get a false for two empty
sequences, you'd need something like:

    (every $i in max(count(A), count(B)) satisfies A[$i] eq B[$i]) and
(min(count(A), count(B)) gt 0)

or

    (every $i in max(count(A), count(B)) satisfies A[$i] eq B[$i]) and
    (some $i in max(count(A), count(B)) satisfies A[$i] eq B[$i])

Either of these would, as Michael pointed out, make an element not
deep-equal to itself, if it had no children.

>> I'd echo the comments of others regarding the purpose of deep-equal
>> (identifying an equivalent structure with equivalent values, node
>> names and/or node kinds), the structural equivalence of two empty
>> sequences, and the very much non-intuitive results that would occur if
>> it didn't work the way it did in this case.
>
> ...but there are no equivalent structures or values?

Of course there are.  Empty sequences are perfectly valid structures
and two of them are equivalent structures.  The fact that there are no
values to be equivalent doesn't change that and if you demand that
there must be values, you're going to break some very fundamental
things.

To put it another way, if they aren't the same, how are they different?

The fact that () = () is false doesn't mean they're different, it just
means they have nothing (no values) in common.  Different
operator/function, different semantics, no loss of consistency.

>> That said, I agree that () eq () not returning false() is not
>> necessarily intuitive or always convenient for the XSLT crowd, but as
>> a nod of compatibility for the database/SQL community, which drives
>> much of XQuery, it seems a reasonable thorn to bear, given the
>> seemingly rare situations in which it might cause issues.
>
> Yeah I'm happy with a 'just because' reason, but I don't yet know the
> benefit of returning () over false, and in what situation you would
> use that.

I don't know when you'd use it, either, but knowing that the SQL world
has some significant reliance on particular handling of "null" as a
distinct state/value, I think it's a reasonable compromise, given the
goal for XPath 2 to support the needs of XQuery and its
database-oriented user base, as well.

-Brandon :)

Current Thread