.. and ... aren't operators, maybe they should be?

Discussion in 'Ruby' started by Logan Capaldo, May 5, 2005.

  1. I was just wondering if maybe the range construction syntax could be
    implemented as a set of operators?

    ie

    class Object
    def ..(other)
    Range.new(self, other)
    end
    def ...(other)
    Range.new(self, other, true)
    end
    end

    This wouldn't implement the parser much (I don't think any way) and
    it could be useful for things like
    defining inifinite lazy lists, or other ranges with weird natures

    ie

    class InfRange
    attr_reader :first
    def take(n)
    i = self.first
    1.upto(n) { yield(i); i = i.succ }
    end
    def initialize(n)
    @first = n
    end
    end

    class Fixnum
    def ..(other)
    if other.nil?
    InfRange.new(self)
    else
    Range.new(self, other)
    end
    end
    def ...(other)
    if other.nil?
    InfRange.new(self)
    else
    Range.new(self, other, true)
    end
    end
    end

    (1..inf).take(5) do |x|
    p x
    end

    Ok thats a pretty silly example, but lets say succ was more
    complicated than just self + 1

    Eh maybe I'm crazy and this is useless. Just seems to be in line with
    << and + etc. being changeable.
    Logan Capaldo, May 5, 2005
    #1
    1. Advertising

  2. On 5/5/05, Logan Capaldo <> wrote:
    > I was just wondering if maybe the range construction syntax could be
    > implemented as a set of operators?
    >
    > ie
    >
    > class Object
    > def ..(other)
    > Range.new(self, other)
    > end
    > def ...(other)
    > Range.new(self, other, true)
    > end
    > end
    >
    > This wouldn't implement the parser much (I don't think any way) and
    > it could be useful for things like
    > defining inifinite lazy lists, or other ranges with weird natures
    >
    > ie
    >
    > class InfRange
    > attr_reader :first
    > def take(n)
    > i = self.first
    > 1.upto(n) { yield(i); i = i.succ }
    > end
    > def initialize(n)
    > @first = n
    > end
    > end
    >
    > class Fixnum
    > def ..(other)
    > if other.nil?
    > InfRange.new(self)
    > else
    > Range.new(self, other)
    > end
    > end
    > def ...(other)
    > if other.nil?
    > InfRange.new(self)
    > else
    > Range.new(self, other, true)
    > end
    > end
    > end
    >
    > (1..inf).take(5) do |x|
    > p x
    > end
    >
    > Ok thats a pretty silly example, but lets say succ was more
    > complicated than just self + 1
    >
    > Eh maybe I'm crazy and this is useless. Just seems to be in line with
    > << and + etc. being changeable.
    >


    Nobody likes this idea? Or is it just so dumb its not worthy of a response? ;)
    Logan Capaldo, May 6, 2005
    #2
    1. Advertising

  3. Logan Capaldo

    Hal Fulton Guest

    Logan Capaldo wrote:
    >
    > Nobody likes this idea? Or is it just so dumb its not worthy of a response? ;)
    >


    Heh... so far I've never felt a need for these to
    be operators.

    I don't *think* it's a dumb idea. But is it worth
    the trouble of implementing?


    Hal
    Hal Fulton, May 6, 2005
    #3
  4. Logan Capaldo

    Markus Guest

    On Fri, 2005-05-06 at 14:08, Hal Fulton wrote:
    > Logan Capaldo wrote:
    > >
    > > Nobody likes this idea? Or is it just so dumb its not worthy of a response? ;)
    > >

    >
    > Heh... so far I've never felt a need for these to
    > be operators.
    >
    > I don't *think* it's a dumb idea. But is it worth
    > the trouble of implementing?


    Re-re-implementing. There were (IIRC) at least two working versions
    floating around, and a bunch of other "spaceship" forms that were
    discussed and may well have been implemented using the "user defined
    operators" parser patch.

    --MarkusQ
    Markus, May 6, 2005
    #4
  5. Logan Capaldo

    Markus Guest

    On Fri, 2005-05-06 at 13:51, Logan Capaldo wrote:
    > On 5/5/05, Logan Capaldo <> wrote:
    > > I was just wondering if maybe the range construction syntax could be
    > > implemented as a set of operators?
    > >


    > Nobody likes this idea? Or is it just so dumb its not worthy of a response? ;)


    I think the problem is that it was talked to death about six or eight
    months ago, in one of the longest counter-examples to Goodwin's law I've
    ever seen. If the topic interests you, check the archives for a bunch
    of different insights into people's thinking.

    --MarkusQ
    Markus, May 6, 2005
    #5
  6. Hi,

    Am Freitag, 06. Mai 2005, 07:22:09 +0900 schrieb Logan Capaldo:
    > I was just wondering if maybe the range construction syntax could be
    > implemented as a set of operators?
    >
    > ...


    > This wouldn't implement the parser much (I don't think any way) and
    > it could be useful for things like
    > defining inifinite lazy lists, or other ranges with weird natures
    >
    > ...
    >
    > (1..inf).take(5) do |x|
    > p x


    Say `inf = 1/0.0', that works.

    > Ok thats a pretty silly example, but lets say succ was more
    > complicated than just self + 1
    >
    > Eh maybe I'm crazy and this is useless. Just seems to be in line with
    > << and + etc. being changeable.


    You may redefine a classes `<=>' operator and its `succ'
    method before you use its instances as range limits.

    The compare operator is needed for initialization of the
    range and for the `include?' test. The `succ' method is used for
    `to_a' and `each'.

    Here is another infinity implementation:

    class InfClass
    def initialize ; @s = +1 ; end
    def negate ; @s = -@s ; self ; end
    def -@ ; dup.negate ; end
    def <=> oth ; @s ; end
    include Comparable
    end

    class String
    alias oldcmp <=>
    def <=> oth
    oldcmp( oth) || -(oth <=> self)
    end
    end

    Inf = InfClass.new
    puts Inf < "x"
    puts "x"..Inf
    puts -Inf.."x"

    This is not a very good example as `succ' doesn't make very
    much sense for an infinity value.

    Bertram


    --
    Bertram Scharpf
    Stuttgart, Deutschland/Germany
    http://www.bertram-scharpf.de
    Bertram Scharpf, May 6, 2005
    #6
  7. "Logan Capaldo" <> schrieb im Newsbeitrag
    news:...
    > On 5/5/05, Logan Capaldo <> wrote:
    >> I was just wondering if maybe the range construction syntax could be
    >> implemented as a set of operators?
    >>
    >> ie
    >>
    >> class Object
    >> def ..(other)
    >> Range.new(self, other)
    >> end
    >> def ...(other)
    >> Range.new(self, other, true)
    >> end
    >> end
    >>
    >> This wouldn't implement the parser much (I don't think any way) and
    >> it could be useful for things like
    >> defining inifinite lazy lists, or other ranges with weird natures
    >>
    >> ie
    >>
    >> class InfRange
    >> attr_reader :first
    >> def take(n)
    >> i = self.first
    >> 1.upto(n) { yield(i); i = i.succ }
    >> end
    >> def initialize(n)
    >> @first = n
    >> end
    >> end
    >>
    >> class Fixnum
    >> def ..(other)
    >> if other.nil?
    >> InfRange.new(self)
    >> else
    >> Range.new(self, other)
    >> end
    >> end
    >> def ...(other)
    >> if other.nil?
    >> InfRange.new(self)
    >> else
    >> Range.new(self, other, true)
    >> end
    >> end
    >> end
    >>
    >> (1..inf).take(5) do |x|
    >> p x
    >> end
    >>
    >> Ok thats a pretty silly example, but lets say succ was more
    >> complicated than just self + 1
    >>
    >> Eh maybe I'm crazy and this is useless. Just seems to be in line with
    >> << and + etc. being changeable.
    >>

    >
    > Nobody likes this idea? Or is it just so dumb its not worthy of a
    > response? ;)


    I didn't see you first posting - maybe it was lost somewhere along the way
    and that's why nobody reacted.

    First I thought, this is a good idea. Here are some caveats / remarks:

    If you redefine Fixnum#... (assuming it was an ordinary operator) in order
    to create a custom range with "1...3" then you will see a lot strange
    behavior of existing code. In fact it might do more harm than good.

    Ok, to avoid that, you would need to define YourSpecialClass#... - but if
    you need a new class anyway, you can as well just define a new Range type
    and use its constructor like "SpecialRange.new(1, 3)" or "SpecialRange[1,
    3]". Or you define Array#to_special so you can do "for i in [1,
    3].to_special". You can even define Range#to_special that does the job, so
    you can do "for i in (1...3).to_special". All these are not much typing
    overhead but show better that you're doing weired things...

    As illustration:

    class SomeRange
    include Enumerable

    def self.[](a,b) self.new a, b end

    def initialize(a,b) @a, @b = a, b end

    def each
    i = @a

    until i == @b
    yield i
    i = i.succ
    end

    self
    end
    end

    >> for n in SomeRange.new(1, 3)
    >> puts n
    >> end

    1
    2
    => #<SomeRange:0x10188670 @b=3, @a=1>
    >> for n in SomeRange[1, 3]
    >> puts n
    >> end

    1
    2
    => #<SomeRange:0x10183648 @b=3, @a=1>
    >>


    Not that bad, ain't it?

    Kind regards

    robert
    Robert Klemme, May 6, 2005
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Guest
    Replies:
    5
    Views:
    612
  2. Ville Vainio
    Replies:
    11
    Views:
    606
    Hamish Lawson
    Aug 10, 2004
  3. Dave Rudolf
    Replies:
    1
    Views:
    300
    Kai-Uwe Bux
    May 17, 2006
  4. Replies:
    4
    Views:
    2,637
  5. botp
    Replies:
    6
    Views:
    208
    Joel VanderWerf
    Oct 5, 2010
Loading...

Share This Page