```On 9/20/07, Rick DeNatale <rick.denatale / gmail.com> wrote:
> On 9/20/07, Xavier Noria <fxn / hashref.com> wrote:
> > On Sep 20, 2007, at 5:39 PM, Rick DeNatale wrote:
> >
> > > On 9/20/07, Xavier Noria <fxn / hashref.com> wrote:
> > >
> > >> On the other hand note that the definition of Range does not imply
> > >> the collection is finite, given suitables #<=> and #succ a range can
> > >> represent an enumeration of the rationals in [0, 1].
> > >
> > > True in theory, but, I wonder just how you would code succ so as to
> > > return the NEXT rational!?
> >
> > Of course that won't happen in practice, but since we were
> > speculating about a possible definition of length for ranges I
> > thought that comment was needed for the reply to be complete.
> >
> > The non-constructive argument goes like this (you say it is true so I
> > guess you already know this):
> >
> > Let f be a bijection between the rationals in the open interval (0,
> > 1) and N. Such a bijection exists because Q is numerable. For any f
> > (n) = q define q.succ to be f(n+1). For any given f(n) = q, f(m) = p
> > in (0, 1) define q <=> p iff n <=> m.
> >
> > I have seen explicit bijections between Q and N, I guess a
> > programmable .succ could be given.
> >
> > To complete the reasoning about the closed interval [0, 1], define 0
> > <=> q and q <=> 1 to be -1 for any q in (0, 1), and define 0.succ to
> > be f(0). 1.succ can be any arbitrary value, when you compute the
> > length iterating over a collection max.succ is not used anyway.
> >
> > I've written that off the top of my head but I think it is correct.
>
> You lost me, so what's the rational which is the successor to 1/3?

My last reply was a bit tongue in cheek.

Since rationals are densely ordered, it really doesn't make sense to
define a succ function since if a < b are both rationals there are an
infinite number of rationals c such that  a < c < b,

Getting back to the original thread though, it's actually not quite
true that ranges require the starting and ending elements to implement
succ, as long as you don't use methods which need them like each,
to_a etc.  If you don't need the enumerable aspects of a range then
you don't need to restrict the elements in that way.

(1.0..2.0).include?(1.5) # => true
1.0.methods.include?(:succ) # => false
(1.0..2.0).to_a # =>
# ~> -:3:in `each': can't iterate from Float (TypeError)
# ~> 	from -:3:in `to_a'
# ~> 	from -:3

class Foo
attr_accessor :value

def initialize(value)
@value = value
end

def <=>(another)
@value <=> another.value
end

def inspect
"Foo(#{value})"
end
end

foo_range = Foo.new(1)..Foo.new(10) # => Foo(1)..Foo(10)
foo_range.include?(Foo.new(5)) # => true
foo_range.to_a # =>
# ~> -:23:in `each': can't iterate from Foo (TypeError)
# ~> 	from -:23:in `to_a'
# ~> 	from -:23

So while it might make sense for SOME ranges to have a length, this is
not true in general.

And from a duck typing point of view note that ranges can be different
types of ducks depending on what they are being used for, and not all
ranges can be some of those types of ducks.

--
Rick DeNatale

My blog on Ruby