Nil Comparable

T

Trans

Does anyone see anything problematic about this?

class NilClass

include Comparable

def <=>(x)
x.nil? ? 0 : -1
end

def succ; nil; end

end

It seems benign enough, and can be used to represent "always before".
For instance, in Rake there is a class called EarlyTime: "EarlyTime is
a fake timestamp that occurs before any other time value." And that's
all that it does. If NilClass were comparable per the above then
EarlyTime would not be needed.

T.
 
A

ara.t.howard

Does anyone see anything problematic about this?

class NilClass

include Comparable

def <=>(x)
x.nil? ? 0 : -1
end

def succ; nil; end

end

It seems benign enough, and can be used to represent "always before".
For instance, in Rake there is a class called EarlyTime: "EarlyTime is
a fake timestamp that occurs before any other time value." And that's
all that it does. If NilClass were comparable per the above then
EarlyTime would not be needed.

it could mask errors like

[42, nil].sort

depending on the order of comparison it may or may not work since we might get

42.send '<=>', nil

or

nil.send '<=>', 42

so it's a bit different in that it's weakly typed where as the EarlyTime class
is strongly typed - it'll only compare with other times

still - it __is__ handy. if you search the archives i've suggeted that
-Infinity and Infinity have these kinds of properties wrst numerics a few
times.

cheers.

-a
 
R

Ronnie

Does anyone see anything problematic about this?

class NilClass

include Comparable

def <=>(x)
x.nil? ? 0 : -1
end

def succ; nil; end

end

It seems benign enough, and can be used to represent "always before".
For instance, in Rake there is a class called EarlyTime: "EarlyTime is
a fake timestamp that occurs before any other time value." And that's
all that it does. If NilClass were comparable per the above then
EarlyTime would not be needed.

it could mask errors like

[42, nil].sort

depending on the order of comparison it may or may not work since we
might get

42.send '<=>', nil

or

nil.send '<=>', 42

so it's a bit different in that it's weakly typed where as the
EarlyTime class
is strongly typed - it'll only compare with other times

still - it __is__ handy. if you search the archives i've suggeted that
-Infinity and Infinity have these kinds of properties wrst numerics a few
times.

cheers.

-a
The Facets library includes all of the above-mentioned features of
usefulness.
http://facets.rubyforge.org/
There are a lot of other extensions to the Ruby core in it, and they can
mostly be included in small chunks, so they are easy to use.
I hope this helps!

Thus spake the monkey
 
T

Trans

it could mask errors like
[42, nil].sort
depending on the order of comparison it may or may not work since we
might get
42.send '<=>', nil

nil.send '<=>', 42
so it's a bit different in that it's weakly typed where as the
EarlyTime class
is strongly typed - it'll only compare with other times
still - it __is__ handy. if you search the archives i've suggeted that
-Infinity and Infinity have these kinds of properties wrst numerics a few
times.

-a

The Facets library includes all of the above-mentioned features of
usefulness.http://facets.rubyforge.org/
There are a lot of other extensions to the Ruby core in it, and they can
mostly be included in small chunks, so they are easy to use.
I hope this helps!


He he... The code I listed actually came right from Facets :)

Much thanks though!

T.
 
R

Robert Dober

Does anyone see anything problematic about this?

class NilClass

include Comparable

def <=>(x)
x.nil? ? 0 : -1
end

def succ; nil; end

end

It seems benign enough, and can be used to represent "always before".
For instance, in Rake there is a class called EarlyTime: "EarlyTime is
a fake timestamp that occurs before any other time value." And that's
all that it does. If NilClass were comparable per the above then
EarlyTime would not be needed.

it could mask errors like

[42, nil].sort

depending on the order of comparison it may or may not work since we
might get

42.send '<=>', nil

or

nil.send '<=>', 42

so it's a bit different in that it's weakly typed where as the
EarlyTime class
is strongly typed - it'll only compare with other times

still - it __is__ handy. if you search the archives i've suggeted that
-Infinity and Infinity have these kinds of properties wrst numerics a few
times.

cheers.

-a
The Facets library includes all of the above-mentioned features of
usefulness.
http://facets.rubyforge.org/
There are a lot of other extensions to the Ruby core in it, and they can
mostly be included in small chunks, so they are easy to use.
I hope this helps!
Well I guess Tom knows about Facets Ronnie :)
http://rubyforge.org/projects/facets/
as you might know this link :).
Thus spake the monkey
It must be quite rewarding though to get pointed to your own project I
would love that ;)

Cheers
Robert
 
T

Trans

It must be quite rewarding though to get pointed to your own project I
would love that ;)

Yes, and rather surprising at the same time. I'm not sure what to make
of it actually.

T.
 
R

Robert Dober

Yes, and rather surprising at the same time. I'm not sure what to make
of it actually.

T.
As a matter of fact it is remarkable how you use the list as a tool to
improve the code and ideas of facets ...
Poor Ronnie got caught by your humble attitude, but it was funny - in
a nice way.

Personally for what it is worth:
I avoid his kind of trickery with core classes when I think my code
might become an API and I use it freely in applications (e.g. DSLs).
Now I am really not studied enough to tell you: DONT, but that would
be my advice if I were forced to give one.
This aligns pretty well with recent posts and the point of view from
learned gurus like David or Ara, I still might fail to see the whole
picture of course.

Cheers
Robert
 
T

Trans

Does anyone see anything problematic about this?
class NilClass
include Comparable
def <=>(x)
x.nil? ? 0 : -1
end
def succ; nil; end

It seems benign enough, and can be used to represent "always before".
For instance, in Rake there is a class called EarlyTime: "EarlyTime is
a fake timestamp that occurs before any other time value." And that's
all that it does. If NilClass were comparable per the above then
EarlyTime would not be needed.

it could mask errors like

[42, nil].sort

depending on the order of comparison it may or may not work since we might get

42.send '<=>', nil

or

nil.send '<=>', 42

so it's a bit different in that it's weakly typed where as the EarlyTime class
is strongly typed - it'll only compare with other times

still - it __is__ handy. if you search the archives i've suggeted that
-Infinity and Infinity have these kinds of properties wrst numerics a few
times.

Infinity and _Infinity would be a better fit, I agree. But is it
possible for them to always be lesser or greater no matter if they are
the receiver or argument of a comparison? That's doesn't seem to fit
well with OOP design. And it's not very practical to add this
constraint to ever definition of <=> in every class. Although maybe
<=> could be defined in Kernel with the constraints and super could be
called to get that functionality. Eg.

module Kernel
def <=>(other)
return 1 if -Infinity == other
return -1 if Infinity == other
0
end
end

then

class Integer
def <=>(other)
if (c = super) != 0 then return c
...

T.
 
R

Robert Dober

Does anyone see anything problematic about this?
class NilClass
include Comparable
def <=>(x)
x.nil? ? 0 : -1
end
def succ; nil; end

It seems benign enough, and can be used to represent "always before".
For instance, in Rake there is a class called EarlyTime: "EarlyTime is
a fake timestamp that occurs before any other time value." And that's
all that it does. If NilClass were comparable per the above then
EarlyTime would not be needed.

it could mask errors like

[42, nil].sort

depending on the order of comparison it may or may not work since we might get

42.send '<=>', nil

or

nil.send '<=>', 42

so it's a bit different in that it's weakly typed where as the EarlyTime class
is strongly typed - it'll only compare with other times

still - it __is__ handy. if you search the archives i've suggeted that
-Infinity and Infinity have these kinds of properties wrst numerics a few
times.

Infinity and _Infinity would be a better fit, I agree. But is it
possible for them to always be lesser or greater no matter if they are
the receiver or argument of a comparison? That's doesn't seem to fit
well with OOP design. And it's not very practical to add this
constraint to ever definition of <=> in every class. Although maybe
<=> could be defined in Kernel with the constraints and super could be
called to get that functionality. Eg.

module Kernel
def <=>(other)
return 1 if -Infinity == other
return -1 if Infinity == other
0
end
end
Will that be good enough? People will often write their # said:
then

class Integer
def <=>(other)
if (c = super) != 0 then return c
...

T.
I really hate not having more time and/or knowledge.
I had talked about this twice on the list but the second time (the
peak of the iceberg) I never found the time to elaborate.

I am very unhappy with the <=> paradigm for Comparable I really prefer
the Less Pattern (no idea why it has that name, maybe I recall
incorrectly) should be LessEqual.
Tom I guess you are familiar with it - I have posted this before, sorry

module Comparable
# relies on #<= only
def < other; self <= other && ! other <= self end
def > other; other <= self && ! self <= other end
def >= other; other <= self end
def == other; other <= self && self <= other end
def != other; ! self == other; end
end

At first sight there are two major advantages, we can use it for half
orders where neither x <= y nor y <= x hold !
And more important in your context the module Comparable enforces the
symmetry of the #<= method, it does not show up later when you are
sorting.

Performance of course is a catastrophe :(

Cheers
Robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top