Issue #5534 has been reported by Alexey Muranov. ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange http://redmine.ruby-lang.org/issues/5534 Author: Alexey Muranov Status: Open Priority: Normal Assignee: Category: core Target version: I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
[ruby-trunk - Feature #5534][Open] Redefine Range class and introduce RelativeNumeric and RelativeRa
on 2011-11-01 12:04
on 2011-11-01 22:45
Issue #5534 has been updated by Alexey Muranov. By the way, i do not understand the use of ranges in conditional expressions in loops, and do not know how to be consistent about it: http://snippets.dzone.com/posts/show/11251 http://www.ruby-doc.org/docs/ProgrammingRuby/html/... ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange http://redmine.ruby-lang.org/issues/5534 Author: Alexey Muranov Status: Open Priority: Normal Assignee: Category: core Target version: I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
on 2011-11-06 09:27
Issue #5534 has been updated by Thomas Sawyer. What is the point of all this? I mean the equality thing is somewhat interesting but how is it really useful? And why does it have any bearing at all on slicing arrays? Really I for one can't make much sense of what you are proposing. ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange http://redmine.ruby-lang.org/issues/5534 Author: Alexey Muranov Status: Open Priority: Normal Assignee: Category: core Target version: I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
on 2011-11-06 11:29
Issue #5534 has been updated by Alexey Muranov. I was not precise, i meant not equality, but *identity* --- that there be only one empty range: Range::EMPTY_SET. Like this: (2..1) # => Range::EMPTY_SET This way it would be clear what a range is --- just an infinite set of a certain form, with methods to work with it. I am in favor of reducing the number of internal attributes of class instances when possible and simplifying their definitions. In my opinion, this should help to understand what a program is doing, to avoid side effects, to write specifications (and hence to maintain existing behavior in future versions), and to settle more easily on desire behavior for new methods. Mathematically, ranges (2..1) et (3..0) are equal --- both empty, but Ruby remembers their "bounds" and treats them differently. If my proposed definition of Range is accepted, the questions like the one discussed in #4541 will simply not arise: since the ranges (4..1) and (3..1) will be identical, [1,2,3][3..1] and [1,2,3][4..1] will be giving identical results, whatever the result is. I propose to view the "memory" of bounds of an empty range as an artifact of implementation of Range , which should not be used for operations like a[1..-2] . My more general view point is the following: i think it will help to settle on some kind of standards for the language if reasonable relations between different methods are enforced. It is already done in cases where one method uses another, for example Comparable#> , Comparable#< , etc., use #<=> : a < b if and only if (a <=> b) == -1 I think it would be helpful for understanding the language and coming up with some kind of standards or best practice guidelines if similar relations were imposed between methods that cannot be defined in terms of one another simply because of computer limitations (not being able to loop over infinitely many objects). For example, require in specifications that (unless overridden in a subclass) for two ranges x and y , x == y must be true if and only if x.include?(z) == y.include?(z) is true for every possible object z. ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange http://redmine.ruby-lang.org/issues/5534 Author: Alexey Muranov Status: Open Priority: Normal Assignee: Category: core Target version: I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
on 2011-11-06 16:39
Issue #5534 has been updated by Thomas Sawyer. "This way it would be clear what a range is --- just an infinite set of a certain form, with methods to work with it." How is that a Range at all? A Range is only "infinite" if one of the sentinels is infinite. "Mathematically, ranges (2..1) et (3..0) are equal --- both empty, but Ruby remembers their "bounds" and treats them differently." How is a Range to work without remembering the bounds? If anything I wish Ruby would understand "counting down" ranges. Currently `(3..1).to_a` returns `[]`. "x == y must be true if and only if x.include?(z) == y.include?(z) is true for every possible object z." For better or worse, Range serves a double (perhaps triple) purpose, e.g. it can serve as interval or it can serve as a way to define a sequential set. So the meaning of #== might not be considered that same in these cases. So Range was given a general definition that works for who it is designed --based on the range bounds. To do as you suggest would, I thing require separating Range into Interval and Sequence classes, so to speak, where you definition of #== is more fitting a Sequence, albeit one might still argument that the order of sequence should be significant too. ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange http://redmine.ruby-lang.org/issues/5534 Author: Alexey Muranov Status: Open Priority: Normal Assignee: Category: core Target version: I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
on 2011-11-06 16:42
Issue #5534 has been updated by Thomas Sawyer. "This way it would be clear what a range is --- just an infinite set of a certain form, with methods to work with it." How is that a Range at all? A Range is only "infinite" if one of the sentinels is infinite. "Mathematically, ranges (2..1) et (3..0) are equal --- both empty, but Ruby remembers their "bounds" and treats them differently." How is a Range to work without remembering the bounds? If anything I wish Ruby would understand "counting down" ranges. Currently `(3..1).to_a` returns `[]`. "x == y must be true if and only if x.include?(z) == y.include?(z) is true for every possible object z." For better or worse, Range serves a double (perhaps triple) purpose, e.g. it can serve as interval or it can serve as a way to define a sequential set. So the meaning of #== might not be considered that same in these cases. So Range was given a general definition that works for who it is designed --based on the range bounds. To do as you suggest would, I thing require separating Range into Interval and Sequence classes, so to speak, where you definition of #== is more fitting a Sequence, albeit one might still argument that the order of sequence should be significant too. ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange http://redmine.ruby-lang.org/issues/5534 Author: Alexey Muranov Status: Open Priority: Normal Assignee: Category: core Target version: I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
on 2011-11-06 17:16
Issue #5534 has been updated by Alexey Muranov. Thomas Sawyer wrote: > "This way it would be clear what a range is --- just an infinite set of a certain form, with methods to work with it." > > How is that a Range at all? A Range is only "infinite" if one of the sentinels is infinite. There are infinitely many numbers, even if you only count rationals, in the range (1..2) > "Mathematically, ranges (2..1) et (3..0) are equal --- both empty, but Ruby remembers their "bounds" and treats them differently." > > How is a Range to work without remembering the bounds? It has to remember its bounds to work unless it is empty. If it is empty, and if my proposal to view it as a set is accepted, then it has no bounds (the empty set has no bounds), and methods should work like this: (2..1).begin # => nil (2..1).end # => nil (2..1) # => Range::EMPTY_SET > If anything I wish Ruby would understand "counting down" ranges. Currently `(3..1).to_a` returns `[]`. What you suggest here is similar to another alternative which i would accept too, but which i didn't mention because it looked to me even father from the current definition of Range: to allow "oriented" ranges. If ranges are oriented, than 3..1 is the same as 1..3, but with negative orientation. In that case one should get (1..3).include?(2) # => true (3..1).include?(2) # => true Then 3..1 is not empty, and can be used to slice an array like this: [1,2,3,4][3..1] # => [4,3,2] > "x == y must be true if and only if x.include?(z) == y.include?(z) is true for every possible object z." > > For better or worse, Range serves a double (perhaps triple) purpose, e.g. it can serve as interval or it can serve as a way to define a sequential set. So the meaning of #== might not be considered that same in these cases. So Range was given a general definition that works for who it is designed --based on the range bounds. To do as you suggest would, I thing require separating Range into Interval and Sequence classes, so to speak, where you definition of #== is more fitting a Sequence, albeit one might still argument that the order of sequence should be significant too. Can you be more precise here please? Depending on the context and the goal, it can be "good" or "bad" that the same class serves "double or triple purpose". Which purposes a range viewed as (possibly oriented) interval cannot serve, other than slicing an array with a[1..-1] ? ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange http://redmine.ruby-lang.org/issues/5534 Author: Alexey Muranov Status: Open Priority: Normal Assignee: Category: core Target version: I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
on 2011-11-06 17:35
Issue #5534 has been updated by Thomas Sawyer. "There are infinitely many numbers, even if you only count rationals, in the range (1..2)" Ah, okay. See, I think that's a good case in point. I was thinking of range as a sequence, while you were thinking of it an interval. Well, I think the only good thing about the multi-purpose Range is that we only need one literal notation, ie. `x..y`. Otherwise I think it would probably be better to have a separate Interval class, if only for the fact that Range, unlike an actual interval, can't exclude the starting sentinel. But other methods would likely vary too, as some of your comments make clear, such as #==. In addition there are a lot of short-cuts taken when dealing with Ranges. If for instance we create an EvenInt class as subclass of Integer that could only represent even integers. Then... r = (EvenInt[2]...EvenInt[4]) This range will not actually behave as we expect in all cases. r.to_a #=> [2,4] [0,1,2,3,4][r] #=> [2,3,4] r.include?(3) #=> true ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange http://redmine.ruby-lang.org/issues/5534 Author: Alexey Muranov Status: Open Priority: Normal Assignee: Category: core Target version: I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
on 2011-11-06 17:37
Issue #5534 has been updated by Thomas Sawyer. "There are infinitely many numbers, even if you only count rationals, in the range (1..2)" Ah, okay. See, I think that's a good case in point. I was thinking of range as a sequence, while you were thinking of it an interval. Well, I think the only good thing about the multi-purpose Range is that we only need one literal notation, ie. `x..y`. Otherwise I think it would probably be better to have a separate Interval class, if only for the fact that Range, unlike an actual interval, can't exclude the starting sentinel. But other methods would likely vary too, as some of your comments make clear, such as #==. In addition there are a lot of short-cuts taken when dealing with Ranges. If for instance we create an EvenInt class as subclass of Integer that could only represent even integers. Then... <pre> r = (EvenInt[2]...EvenInt[4]) </pre> This range will not actually behave as we expect in all cases. <pre> r.to_a #=> [2,4] [0,1,2,3,4][r] #=> [2,3,4] r.include?(3) #=> true </pre> ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange http://redmine.ruby-lang.org/issues/5534 Author: Alexey Muranov Status: Open Priority: Normal Assignee: Category: core Target version: I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
on 2011-11-06 17:39
Issue #5534 has been updated by Thomas Sawyer.
"There are infinitely many numbers, even if you only count rationals, in
the range (1..2)"
Ah, okay. See, I think that's a good case in point. I was thinking of
range as a sequence, while you were thinking of it an interval.
Well, I think the only good thing about the multi-purpose Range is that
we only need one literal notation, ie. `x..y`. Otherwise I think it
would probably be better to have a separate Interval class, if only for
the fact that Range, unlike an actual interval, can't exclude the
starting sentinel. But other methods would likely vary too, as some of
your comments make clear, such as #==.
In addition there are a lot of short-cuts taken when dealing with
Ranges. If for instance we create an EvenInt class as subclass of
Integer that could only represent even integers. Then...
r = (EvenInt[2]...EvenInt[4])
This range will not actually behave as we expect in all cases.
r.to_a #=> [2,4]
[0,1,2,3,4][r] #=> [2,3,4]
r.include?(3) #=> true
----------------------------------------
Feature #5534: Redefine Range class and introduce RelativeNumeric and
RelativeRange
http://redmine.ruby-lang.org/issues/5534
Author: Alexey Muranov
Status: Open
Priority: Normal
Assignee:
Category: core
Target version:
I started by commenting on Feature #4541, but ended up with proposing a
new feature myself.
I suggest to redefine the behavior of Range class so that all empty
ranges be equal:
(2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # =>
true
In other fords, ranges `r1` and `r2` should be equal if and only if
`r1.include?` and `r2.include?` give identical results for all inputs.
(Why is it not `includes?` by the way?) Thus Range would simply be a
way to store certain infinite sets.
This change will result in not being able to slice an array `a` from
beginning and from the end simultaneously with `a[1..-2]`. To resolve
this, i propose to introduce `RelativeNumeric` and `RelativeRange`
classes.
Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is
an arbitrary symbol. For example:
3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom
One can define shortcuts `#from_bottom` for `#from(:bottom)` and
`#from_top` for `#from_top`.
A `RelativeRange` is a range with relative bounds. If bounds of a
relative range r are relative to the same anchor and the range is seen
to be empty, it should be equal to *the* empty relative range with this
anchor. For example:
(3.from(:center)..2.from(:center)) ==
(0.from(:center)...0.from(:center)) # => true
Now, to do what is currently done by `a[1..-2]`, one can redefine
`Array#slice` to use instead:
a[1.from_bottom..(-1).from_top]
What do you think?
on 2011-11-06 17:40
Issue #5534 has been updated by Thomas Sawyer. ADMIN! There is bad bug in the redmine interface that deletes the message if one tries to use the edit feature. I had to resubmit this post four times to get it show up again. ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange http://redmine.ruby-lang.org/issues/5534 Author: Alexey Muranov Status: Open Priority: Normal Assignee: Category: core Target version: I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
on 2011-11-11 11:52
Issue #5534 has been updated by Alexey Muranov.
I have just discovered that there is Range#cover? method which works
how i would expect Range#include? to work. I would have preferred
that these two behaved identically and that there were only one of them.
Having the both looks to me like a way to cover up inconsistencies
between different meaning and uses of Range.
I think that Rang#to_a has to accept an argument to tell it which
elements of the range to use. The same when converting a range to an
Enumerator with Range#each. Maybe the Enumerable module can provide
some tools to create objects like "all_integers", "all_even_integers",
"all_words_in_capital_letters_A_to_Z". Maybe even constants
Enumerable::INTEGERS, Enumerable::EVEN_INTEGERS,
Enumerable::WORDS_IN_CAPITAL_LETTERS_A_TO_Z would be good enough to
begin with:
(1..6).to_a(Enumerable::INTEGERS) # => [1, 2, 3, 4, 5, 6]
(1..6).to_a(Enumerable::EVEN_INTEGERS) # => [2, 4, 6]
I understand better now the difficulties in defining a range as
something other than a pair of bounds: whether ("X".."AB") is empty
depends on the order (lex or deglex).
I can think of one possible solution: allow to specify the order in
cases where more than one exists. Probably an order should be an
object which knows its own properties, but in simple cases, to start
with, it can be a symbol. The use would be like this:
Range.new("A", "AB", exclusive=false, order=:lex).include?("X") # =>
false
Range.new("A", "AB", exclusive=false, order=:deglex).include?("X") # =>
true
Range.new("A", "C", exclusive=false,
order=:lex).to_a("Enumerable::WORDS_IN_CAPITAL_LETTERS_A_TO_Z") # =>
InfniteArrayError: ["A", "AA", "AAA", ...]
Range.new("A", "C", exclusive=false,
order=:deglex).to_a("Enumerable::WORDS_IN_CAPITAL_LETTERS_A_TO_Z") # =>
["A", "B", "C"]
These are very rough ideas.
----------------------------------------
Feature #5534: Redefine Range class and introduce RelativeNumeric and
RelativeRange
http://redmine.ruby-lang.org/issues/5534
Author: Alexey Muranov
Status: Open
Priority: Normal
Assignee:
Category: core
Target version:
I started by commenting on Feature #4541, but ended up with proposing a
new feature myself.
I suggest to redefine the behavior of Range class so that all empty
ranges be equal:
(2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # =>
true
In other fords, ranges `r1` and `r2` should be equal if and only if
`r1.include?` and `r2.include?` give identical results for all inputs.
(Why is it not `includes?` by the way?) Thus Range would simply be a
way to store certain infinite sets.
This change will result in not being able to slice an array `a` from
beginning and from the end simultaneously with `a[1..-2]`. To resolve
this, i propose to introduce `RelativeNumeric` and `RelativeRange`
classes.
Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is
an arbitrary symbol. For example:
3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom
One can define shortcuts `#from_bottom` for `#from(:bottom)` and
`#from_top` for `#from_top`.
A `RelativeRange` is a range with relative bounds. If bounds of a
relative range r are relative to the same anchor and the range is seen
to be empty, it should be equal to *the* empty relative range with this
anchor. For example:
(3.from(:center)..2.from(:center)) ==
(0.from(:center)...0.from(:center)) # => true
Now, to do what is currently done by `a[1..-2]`, one can redefine
`Array#slice` to use instead:
a[1.from_bottom..(-1).from_top]
What do you think?
on 2012-03-18 14:36
Issue #5534 has been updated by alexeymuranov (Alexey Muranov).
More of my crazy ideas. Wouldn't it be nice to be able to write:
a, b = 0.5, 10.5
(a..b).each(Integer) do { |n| puts n }
----------------------------------------
Feature #5534: Redefine Range class and introduce RelativeNumeric and
RelativeRange
https://bugs.ruby-lang.org/issues/5534#change-24916
Author: alexeymuranov (Alexey Muranov)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version:
I started by commenting on Feature #4541, but ended up with proposing a
new feature myself.
I suggest to redefine the behavior of Range class so that all empty
ranges be equal:
(2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # =>
true
In other fords, ranges `r1` and `r2` should be equal if and only if
`r1.include?` and `r2.include?` give identical results for all inputs.
(Why is it not `includes?` by the way?) Thus Range would simply be a
way to store certain infinite sets.
This change will result in not being able to slice an array `a` from
beginning and from the end simultaneously with `a[1..-2]`. To resolve
this, i propose to introduce `RelativeNumeric` and `RelativeRange`
classes.
Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is
an arbitrary symbol. For example:
3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom
One can define shortcuts `#from_bottom` for `#from(:bottom)` and
`#from_top` for `#from_top`.
A `RelativeRange` is a range with relative bounds. If bounds of a
relative range r are relative to the same anchor and the range is seen
to be empty, it should be equal to *the* empty relative range with this
anchor. For example:
(3.from(:center)..2.from(:center)) ==
(0.from(:center)...0.from(:center)) # => true
Now, to do what is currently done by `a[1..-2]`, one can redefine
`Array#slice` to use instead:
a[1.from_bottom..(-1).from_top]
What do you think?
[ruby-trunk - Feature #5534][Assigned] Redefine Range class and introduce RelativeNumeric and Relati
on 2012-03-27 15:55
Issue #5534 has been updated by mame (Yusuke Endoh). Status changed from Open to Assigned Assignee set to matz (Yukihiro Matsumoto) ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange https://bugs.ruby-lang.org/issues/5534#change-25244 Author: alexeymuranov (Alexey Muranov) Status: Assigned Priority: Normal Assignee: matz (Yukihiro Matsumoto) Category: core Target version: I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
on 2012-11-28 15:31
Issue #5534 has been updated by alexeymuranov (Alexey Muranov).
=begin
I propose to cancel the second part of my proposal: about
(({RelativeNumeric})) and
(({RelativeRange})). When i look back at it now, it looks quite crazy
and not
particularly useful.
However, i still would like to see the behavior of (({Range})) changed,
as in the
first part of the proposal. In other words, i would like (({Range}))
become a ((*lazy
ordered set*)), infinite or finite.
I think i proposed (({RelativeNumeric})) simply because i didn't dare to
propose
to deprecate the usage like
b = a[1..-2]
for an array (({a})) without proposing some similarly looking
replacement.
Now i've decided i would prefer this usage be deprecated.
How about a new method (({Array#trim(fixnum, fixnum)})) to write
b = a.trim(1,1)
instead of
b = a[1..-2]
? (I can start a new Feature Request if a discussion is necessary.)
It looks strange to have to convert a pair of numbers ((*m*)) and
((*n*)) into a range
(({m..(-1-n}))) to simply ask an array to remove ((*m*)) elements from
the beginning and
((*n*)) elements from the end. If you think about what the range
(({m..(-1-n)})) actually ((*is*)), then the syntax (({a[m..(-1-n)]}))
looks plain weird :).
=end
----------------------------------------
Feature #5534: Redefine Range class and introduce RelativeNumeric and
RelativeRange
https://bugs.ruby-lang.org/issues/5534#change-34085
Author: alexeymuranov (Alexey Muranov)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor
I started by commenting on Feature #4541, but ended up with proposing a
new feature myself.
I suggest to redefine the behavior of Range class so that all empty
ranges be equal:
(2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # =>
true
In other fords, ranges `r1` and `r2` should be equal if and only if
`r1.include?` and `r2.include?` give identical results for all inputs.
(Why is it not `includes?` by the way?) Thus Range would simply be a
way to store certain infinite sets.
This change will result in not being able to slice an array `a` from
beginning and from the end simultaneously with `a[1..-2]`. To resolve
this, i propose to introduce `RelativeNumeric` and `RelativeRange`
classes.
Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is
an arbitrary symbol. For example:
3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom
One can define shortcuts `#from_bottom` for `#from(:bottom)` and
`#from_top` for `#from_top`.
A `RelativeRange` is a range with relative bounds. If bounds of a
relative range r are relative to the same anchor and the range is seen
to be empty, it should be equal to *the* empty relative range with this
anchor. For example:
(3.from(:center)..2.from(:center)) ==
(0.from(:center)...0.from(:center)) # => true
Now, to do what is currently done by `a[1..-2]`, one can redefine
`Array#slice` to use instead:
a[1.from_bottom..(-1).from_top]
What do you think?
on 2012-12-11 17:26
Issue #5534 has been updated by alexeymuranov (Alexey Muranov). I propose to close this my Feature Request, as i have opened a new one that replaces it: #7545, see also #7546. ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange https://bugs.ruby-lang.org/issues/5534#change-34623 Author: alexeymuranov (Alexey Muranov) Status: Assigned Priority: Normal Assignee: matz (Yukihiro Matsumoto) Category: core Target version: next minor I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
[ruby-trunk - Feature #5534][Rejected] Redefine Range class and introduce RelativeNumeric and Relati
on 2012-12-11 17:46
Issue #5534 has been updated by drbrain (Eric Hodel). Status changed from Assigned to Rejected ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange https://bugs.ruby-lang.org/issues/5534#change-34626 Author: alexeymuranov (Alexey Muranov) Status: Rejected Priority: Normal Assignee: matz (Yukihiro Matsumoto) Category: core Target version: next minor I started by commenting on Feature #4541, but ended up with proposing a new feature myself. I suggest to redefine the behavior of Range class so that all empty ranges be equal: (2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true In other fords, ranges `r1` and `r2` should be equal if and only if `r1.include?` and `r2.include?` give identical results for all inputs. (Why is it not `includes?` by the way?) Thus Range would simply be a way to store certain infinite sets. This change will result in not being able to slice an array `a` from beginning and from the end simultaneously with `a[1..-2]`. To resolve this, i propose to introduce `RelativeNumeric` and `RelativeRange` classes. Each `RelativeNumeric` would be a `Numeric` with an "anchor", which is an arbitrary symbol. For example: 3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom One can define shortcuts `#from_bottom` for `#from(:bottom)` and `#from_top` for `#from_top`. A `RelativeRange` is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to *the* empty relative range with this anchor. For example: (3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true Now, to do what is currently done by `a[1..-2]`, one can redefine `Array#slice` to use instead: a[1.from_bottom..(-1).from_top] What do you think?
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.