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 http://talklikeaduck.denhaven2.com/