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

L

Logan Capaldo

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.
 
L

Logan Capaldo

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? ;)
 
H

Hal Fulton

Logan said:
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
 
M

Markus

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
 
M

Markus

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
 
B

Bertram Scharpf

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
 
R

Robert Klemme

Logan Capaldo said:
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
1
2
=> # said:
for n in SomeRange[1, 3]
puts n
end
1
2

Not that bad, ain't it?

Kind regards

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

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top