privat/nit — pull request #803 by privat (2014-10-02 18:11:28+00:00)
Title: Improve Comparator type-kindness

The Comparator class in Nit was a PITA because, with the traditional modelization with a generic class, Comparator is contravariant but Nit only allows covariance in its genericity.

Example:

~~~nit
var ao = new Array[Object].with_items(2,1,10)
ao.sort_with(alpha_comparator)
print ao.join(" ") # => 1 10 2

var ai = new Array[Int].with_items(2,1,10)
ai.sort_with(alpha_comparator)
# Static error: expected a Comparator[Int], got a Comparator[Object]
~~~

This PR implements the nice proposition of Etienne Gagnon to makes Comparator a non-generic class but use virtual types to control the type of compared elements.

It is clearly an improvement over the previous implementation:

* more expressive (++++)
* less code (+)
* simpler for the client (less generic stuff) (+)
* coherent with the `Comparable` hierarchy that also use virtual types (+)
* a little more complex for the lib (virtual type redefinition) (-)
* loss of information when things are typed with the interface `Comparator`, yielding to more potential covariance error at runtime (--)

While less type-safe than a full (and complex) contravariance solution, the proposer solution is still better in term of type-safety than dynamic languages and non-generic-non-virtual-type solution (eg. Java4):

* runtime errors are detected earlier than with erasure or with dynamic typing (fail fast)
* some errors are still detected statically:

~~~
var a = [1,10,2,3]
alpha_comparator.sort(a)
print a.join(" ") #=> 1 10 2 3
default_comparator.sort(a)
print a.join(" ") #=> 1 2 3 10

var b = [true, false]
alpha_comparator.sort(b)
print b.join(" ") # => false true
default_comparator.sort(b)
# Static type error: expected Array[Comparable], got Array[Bool]
~~~