Subject: comparators and "error"

From: Arnt Gulbrandsen <[email-masked]>
Date: Tue, 2 May 2006 17:43:44 +0200

I've been doing some editing on the draft, trying out how some things 
suggested look in prose.

1. It seems useful to me that e.g. ascii-numeric can distinguish between 
comparing nonequal numbers and comparing out-of-scope input.

Take the equality operation as an example:

"Match" means that the collation knows how to work on the input, and the 
two inputs are equal as defined by the collation.
"No-match" means that the collation knows how, and the two are unequal.
"Error" means that it doesn't know how to.

Conflating the two latter cases smells of bad design to me, even though 
the difference may not be useful in every case.

2. Even though a collation specification distinguishes between 
"no-match" and "error", there's no requirement that all protocols must. 
If the distinction between "no-match" and "error" is pointless in e.g. 
sieve, can't simply sieve treat the two as equal? Ie. "match" is true, 
"no-match" is false and "error" is false?

Arnt

---

From: Dave Cridland <[email-masked]>
Date: Tue, 02 May 2006 20:49:48 +0100

On Tue May  2 16:43:44 2006, Arnt Gulbrandsen wrote:
> "no-match" and "error", there's no requirement that all protocols 
> must. If the distinction between "no-match" and "error" is 
> pointless in e.g. sieve, can't simply sieve treat the two as equal? 
> Ie. "match" is true, "no-match" is false and "error" is false?

I need to think on your argument some more, but note that there's two 
forms of "error"

A) You tried to compare a valid input string against an invalid input 
string.

B) You tried to compare two invalid input strings.

It's only case A that's really occured much in the wild, and that's 
because only one mechanism - Sieve variables - allows for that case 
to happen except in moments of silliness.

Specifically, one operand for a comparator is usually provided by the 
client (in ACAP) or the script creator (in Sieve). With Sieve 
variables, both can be derived from the message, which presumably 
isn't known in advance.

I suspect that for Sieve, case A is obviously not a fatal error, and 
probably indicates a non-match. Case B is a little trickier - there's 
a reasonable argument that it ought to result in a match. ("Blue" and 
"Yellow" do have equally non-existent numeric value, after all, and 
they collate equally at the end, and "i;octet" has that funny bit 
about the equality of two NIL values in ACAP, which of course you're 
all familiar with.)

Dave.
-- 
           You see things; and you say "Why?"
   But I dream things that never were; and I say "Why not?"
    - George Bernard Shaw

---

From: Alexey Melnikov <[email-masked]>
Date: Wed, 10 May 2006 15:02:40 +0100

Arnt Gulbrandsen wrote:

> 1. It seems useful to me that e.g. ascii-numeric can distinguish 
> between comparing nonequal numbers and comparing out-of-scope input.
>
> "Match" means that the collation knows how to work on the input, and 
> the two inputs are equal as defined by the collation.
> Conflating the two latter cases smells of bad design to me, even 
> though the difference may not be useful in every case.

I agree.

> must. If the distinction between "no-match" and "error" is pointless 
> in e.g. sieve, can't simply sieve treat the two as equal? Ie. "match" 
> is true, "no-match" is false and "error" is false?

Yes, that is a possibility.

Maybe we should add a new match type :failedmatch which can help 
distinguish the no-match case from the error?

---

From: Arnt Gulbrandsen <[email-masked]>
Date: Wed, 10 May 2006 16:20:46 +0200

Alexey Melnikov writes:
>> in e.g. sieve, can't simply sieve treat the two as equal? Ie. 
>> "match" is true, "no-match" is false and "error" is false?
>

Mark Davis suggested renaming "error" as "undefined". I disagreed then, 
but I think I agree now.

Arnt

---

From: Dave Cridland <[email-masked]>
Date: Wed, 10 May 2006 18:30:19 +0100

On Wed May 10 15:02:40 2006, Alexey Melnikov wrote:
> 
> Arnt Gulbrandsen wrote:
> 
>> I've been doing some editing on the draft, trying out how some 
>> things suggested look in prose.
>> 
>> "Match" means that the collation knows how to work on the input, 
>> and the two inputs are equal as defined by the collation.
I'm really not so sure. On the face of it, it sounds like bad design, 
but I think there's at least two cases here - an attempt to compare 
"fish" and "bicycle", and an attempt to compare "fish" and "2". I 
have a feeling this is an important distinction.

Arguably, "fish" is equal in numeric value to "bicycle" - they both 
have no numeric value, so it's the same as comparing NIL and NIL with 
"i;octet".

Equally, "2" has a numeric value of 2, whereas "fish" does not, so 
they are unequal - like comparing NIL and an existing string with 
"i;octet".

Dave.

---

From: Arnt Gulbrandsen <[email-masked]>
Date: Wed, 10 May 2006 21:09:17 +0200

> have a feeling this is an important distinction.

It is precisely the distinction between "neither input is valid" and 
"one input is valid, the other not".

> have no numeric value, so it's the same as comparing NIL and NIL with 

Or as comparing null with null in SQL.

> they are unequal - like comparing NIL and an existing string with 

Or as comparing 2 with null in SQL. And wouldn't you know, SQL is 
different from ACAP in this respect.

x=> select 42 as answer where 2=2;
  answer
--------
      42
(1 row)

x=> select 42 as answer where 2!=0;
  answer
--------
      42
(1 row)

Makes sense so far? Let's compare things with null a little:

x=> select 42 as answer where 2=null;
  answer
--------
(0 rows)

x=> select 42 as answer where 2!=null;
  answer
--------
(0 rows)

x=> select 42 as answer where not(2=null);
  answer
--------
(0 rows)

x=> select 42 as answer where null=null;
  answer
--------
(0 rows)

I'd rather not venture into this dark and confusing maze of null/nil 
semantics. These are choices for the protocol to make, say I.

Instead, I think I'll add a fourth operator, valid, which indicates 
whether a given string is valid input for the collation. It's not 
really necessary. indomain(a) is true if and only if a=a. But it sounds 
sensible. Permits protocols to differentiate between one and two 
invalid inputs if they want to, without resorting to hacks like a=a.

Arnt

---

From: Dave Cridland <[email-masked]>
Date: Wed, 10 May 2006 23:22:59 +0100

On Wed May 10 20:09:17 2006, Arnt Gulbrandsen wrote:
> 
> Dave Cridland writes:
>> I'm really not so sure. On the face of it, it sounds like bad 
>> design, but I think there's at least two cases here - an attempt 
>> to compare "fish" and "bicycle", and an attempt to compare "fish" 
>> and "2". I have a feeling this is an important distinction.
> 
> It is precisely the distinction between "neither input is valid" 
> and "one input is valid, the other not".
> 
>> Arguably, "fish" is equal in numeric value to "bicycle" - they 
>> both have no numeric value, so it's the same as comparing NIL and 
>> NIL with "i;octet".
> 

Good for SQL... ACAP's definitions regarding this are a lot less 
clear.

> I'd rather not venture into this dark and confusing maze of 
> null/nil semantics. These are choices for the protocol to make, say 
> I.
> 
> 
I think - but I'm not absolutely sure - that the question has already 
been settled.

In RFC2244, section 3.4, which is the authoritative definition of 
comparators:

1) "i;octet" specifically states that NIL is equal only to itself. 
(Second paragraph in its definition, last sentence)

2) "i;ascii-casemap" specifically states that it applies a mapping 
then does "i;octet". So NIL==NIL again.

3) "i;ascii-numeric" then complicates my argument, because "All 
values which do not begin with a US-ASCII digit are considered equal 
with an ordinal value higher than all non-NIL single-valued 
attributes" - that certainly seems to mean "fish" == "bicycle", but 
I'm not sure if it means "fish" != NIL or "fish" == NIL. It says 
nothing to me about whether NIL == NIL.

> really necessary. indomain(a) is true if and only if a=a. But it 
> sounds sensible. Permits protocols to differentiate between one and 
> two invalid inputs if they want to, without resorting to hacks like 
> a=a.

I'm entirely happy to have an additional operator, however, I'd 
prefer to standardize the behaviour somewhat. In particular, I'd 
quite like it settled as to whether NIL==NIL in general, and whether 
invalid input is equal to NIL - at the very least as a default.

Dave.