I agree that the current documentation and implementation are not 
inconsistent.  Implicit in my question was a concern about efficiency. 
I have been assuming that being allowed to write <=> methods that return 
   any number less than zero or any number greater than zero is more 
efficient than having to include the extra code to "clamp" those values 
to -1 and +1.

A simple benchmark is included.  It shows that it is about 25% faster to 
write a "loose" <=> method than a "strict" <=> method. (But only if the 
loose <=> method returns an Integer.  If it returns a Float, then the 
loose method is actually slower.)

Anyway, it is this efficiency issue that is at the root of my question.
Given that Ruby's documentation is not always really detailed, I 
wondered if the docs are really definitive here.  If it is actually 
legal to write a loose <=> method, it would be nice to know that!

     David

Benchmark code follows:
class Slow
   def initialize(x)
     @x = x
   end

   def value
     @x
   end

   def <=>(other)
     y = other.value
     if @x < y
       -1
     elsif @x > y
       1
     else
       0
     end
   end
end

class Fast
   def initialize(x)
     @x = x
   end

   def value
     @x
   end

   def <=>(other)
     other.value - @x
   end
end

f = []
s = []

100000.times do
   x = rand(100000)
   f << Fast.new(x)
   s << Slow.new(x)
end

require 'benchmark'
include Benchmark

bmbm(2) do |x|
   x.report("Fast") { f.sort }
   x.report("Slow") { s.sort }
end


------------------------------------------------
Here are the benchmark results on my aging Linux system:

Rehearsal ----------------------------------------
Fast   4.390000   0.000000   4.390000 (  4.403584)
Slow   5.640000   0.020000   5.660000 (  5.657363)
------------------------------ total: 10.050000sec

            user     system      total        real
Fast   4.020000   0.000000   4.020000 (  4.025188)
Slow   5.500000   0.000000   5.500000 (  5.503963)



Marte Raphael Y. Soliza wrote:
> I think there's nothing wrong with the implementation and documentation. 
> True, an erronous implementation of <=> will still work if this is the 
> implementation, but if we use exact comparisons such as == -1, 
> trichotomy might be broken. For example, if two comparable objects of 
> the same class, say a and b, are compared, and a is neither less than, 
> equal, nor greater than b, then what is the relationship of a to b? This 
> will give us a hint that the implementation of <=> is incorrect, and 
> that's good, but I believe it's better (and safer) to have a fallback. 
> If we throw an error that results from <=> returning a value other than 
> -1, 0, and 1, then it might have an impact to efficiency especially in 
> sorting huge array of values because we added an overhead of checking if 
> the value returned is correct.
> 
> On 4/1/07, *David Flanagan* <david / davidflanagan.com 
> <mailto:david / davidflanagan.com>> wrote:
> 
>     Replying to my own post...
> 
>     Let me add that the existing numeric <=> operators all do appear to
>     strictly return -1, 0, or +1.  That is, they don't simply return y-x to
>     compute a value less than, equal to, or greater than zero.  This would
>     argue that the current documentation of Comparable is correct, but that
>     the implementation is written so that it works even for broken <=>
>     operators.
> 
>     Anyway, I should say that it was probably presumptuous of me to assume
>     that the documentation is incorrect.  Everything I've seen in writing
>     says that <=> must return -1,0, or +1.  The implementation in compar.c
>     makes it appear that this is not the case, however. I was not able to
>     find any discussion of the return value of <=> in the ruby-talk
>     archives...
> 
> 
> 
> -- 
> "Life is unfair... but beautiful."
> Scarlette Krimson