Range class is one I use a lot, having first-class range literals is handy all over the place.
Every once in a while I wish for better semantics on the class, though. As it stands, Range acts as just a data-holder, for the start, end, and exclusive fields. Sometimes that's good, but sometimes you want a range to know something about the concept it represents. Here's 4 apis that I think Range should have:
min / max
Should return the min (max) of the elements in the range. Equivalent to range.toList.min.
last
Don't know about name confusion with end, but occasionally you need to get the final element in a range; would be nice not to have to use
Having first and last would seem meaningful, but of course first would be completely redundant.
equiv (or equivalent)
I guess I can understand equals being like it is, but it seems like a real weird thing that 0..2 != 0..<3 ; I would think that equals should act like it does with lists: they're equal if their elements all match. At least there ought to be a method for that.
All these (to me at least) seem like they ought to have the same semantics as List; but without creating the list, of course.
DanielFathSat 17 Oct 2009
I must ask what is the difference between max and last?
Max returns the largest element which unless I'm misinterpreting is the last element in the range?
I'm kind of weirded out by the fact that equals doesn't do that already. All in all I like your first and last suggestion except that I suggest making equals return true for 0..2 == 0..<3 and making a function called same return false for 0..2 == 0..<3 (since their boundaries aren't same).
However if there are plans to introduce some kind of joker or special characters into the range I could see this kind of reasoning being a problem.
KevinKelleySat 17 Oct 2009
what is the difference between max and last?
Difference is with descending ranges: if the range is ascending, last == max; if descending, last == min.
As for the rest - seems cleaner and more useful to use toList and have the full List API at your disposal. Its a few extra chars, but you can already do all that with List:
Difference is with descending ranges: if the range is ascending, last == max; if descending, last == min.
My bad.
0..2 != 0..<3 I agree that should evaluate to true.
Hmm this seems like a big gotcha. I assume many new comers would expect equals works on the range content and not the range itself. So you could produce something that compares content like equalsContent to prevent some boiler plate code. Though it is not much of a hassle.
KevinKelleySat 17 Oct 2009
but you can already do all that with List:
What bothers me about that is the time-complexity: creating a list almost has to be O(N) in the size of the range, while calculating those (min,max,last) values can be done in O(K) (just a very few machine instructions).
alexlamslSat 17 Oct 2009
What bothers me about that is the time-complexity: creating a list almost has to be O(N) in the size of the range
We can have Range extends List, or have Range.toList returns a synthetic List. Either way, the O(N) cost would be avoided.
alexlamslSat 17 Oct 2009
And whilst we are on the topic, it might be useful to have Range applicable to any Type that implements increment and decrement.
Range being a sub-type of List would seem pretty natural IMHO, as places where I would supply a List would fit Range equally well.
On a slightly unrelated note - a[list] would seem a strange but wonderful generalisation over a[range].
brianSun 18 Oct 2009
I added isEmpty, min, max, first, last with the exact semantics of calling toList and then calling the respective method (without the overhead of building up the list).
A lazy/generator list would be cool and something I'd like to consider in the future (just not right now).
I don't really like another equals method.
KevinKelleySun 18 Oct 2009
I added ...
Cool, those seem good and proper.
Any further thoughts on equals? Adding another equals is probably <em>wrong. Is there a reason to keep the current range.equals as it is?
I guess for Range there's various possible meanings for equality.
=== - same object
equals - same object behavior (equal fields in a const obj)
min/max equal - range covers same values
first/last equal - same values, in same order
I'd probably vote for having the last one as the meaning of equals, but it's not as important with the new methods.
If Fan had a mechanism for memoizing construction of const objects that are side-effect-free, then === and current meaning of equals would conflate to both meaning identity. As is, maybe there's reason for keeping them separate?
brianSun 18 Oct 2009
I think the current definition of equals is correct:
start..end != start..<end
In some uses of range you might say that you can normalize the exclusive end, but that isn't true in all cases. For example, in all our uses of ranges for slice operations, the notion of exclusive and inclusive is quite important.
Plus, I think for anything that serializes as a string, equality should hold true for toStr and fromStr (which is another case where the exclusive flag is semantically significant).
KevinKelley Sat 17 Oct 2009
Range class is one I use a lot, having first-class range literals is handy all over the place.
Every once in a while I wish for better semantics on the class, though. As it stands, Range acts as just a data-holder, for the start, end, and exclusive fields. Sometimes that's good, but sometimes you want a range to know something about the concept it represents. Here's 4 apis that I think Range should have:
min / max
Should return the min (max) of the elements in the range. Equivalent to range.toList.min.
last
Don't know about name confusion with
end
, but occasionally you need to get the final element in a range; would be nice not to have to useHaving
first
andlast
would seem meaningful, but of course first would be completely redundant.equiv (or equivalent)
I guess I can understand equals being like it is, but it seems like a real weird thing that
0..2 != 0..<3
; I would think thatequals
should act like it does with lists: they're equal if their elements all match. At least there ought to be a method for that.All these (to me at least) seem like they ought to have the same semantics as List; but without creating the list, of course.
DanielFath Sat 17 Oct 2009
I must ask what is the difference between
max
andlast
?Max returns the largest element which unless I'm misinterpreting is the last element in the range?
I'm kind of weirded out by the fact that
equals
doesn't do that already. All in all I like your first and last suggestion except that I suggest makingequals
returntrue
for0..2 == 0..<3
and making a function calledsame
return false for0..2 == 0..<3
(since their boundaries aren't same).However if there are plans to introduce some kind of joker or special characters into the range I could see this kind of reasoning being a problem.
KevinKelley Sat 17 Oct 2009
Difference is with descending ranges: if the range is ascending,
last == max
; if descending,last == min
.andy Sat 17 Oct 2009
I agree that should evaluate to
true
.As for the rest - seems cleaner and more useful to use
toList
and have the full List API at your disposal. Its a few extra chars, but you can already do all that with List:DanielFath Sat 17 Oct 2009
My bad.
Hmm this seems like a big gotcha. I assume many new comers would expect
equals
works on the range content and not the range itself. So you could produce something that compares content likeequalsContent
to prevent some boiler plate code. Though it is not much of a hassle.KevinKelley Sat 17 Oct 2009
What bothers me about that is the time-complexity: creating a list almost has to be O(N) in the size of the range, while calculating those (min,max,last) values can be done in O(K) (just a very few machine instructions).
alexlamsl Sat 17 Oct 2009
We can have
Range
extendsList
, or haveRange.toList
returns a syntheticList
. Either way, the O(N) cost would be avoided.alexlamsl Sat 17 Oct 2009
And whilst we are on the topic, it might be useful to have
Range
applicable to any Type that implementsincrement
anddecrement
.Range
being a sub-type ofList
would seem pretty natural IMHO, as places where I would supply aList
would fitRange
equally well.On a slightly unrelated note -
a[list]
would seem a strange but wonderful generalisation overa[range]
.brian Sun 18 Oct 2009
I added isEmpty, min, max, first, last with the exact semantics of calling toList and then calling the respective method (without the overhead of building up the list).
changeset
A lazy/generator list would be cool and something I'd like to consider in the future (just not right now).
I don't really like another equals method.
KevinKelley Sun 18 Oct 2009
Cool, those seem good and proper.
Any further thoughts on
equals
? Adding another equals is probably <em>wrong. Is there a reason to keep the current range.equals as it is?I guess for Range there's various possible meanings for equality.
===
- same objectequals
- same object behavior (equal fields in a const obj)I'd probably vote for having the last one as the meaning of
equals
, but it's not as important with the new methods.If Fan had a mechanism for memoizing construction of const objects that are side-effect-free, then
===
and current meaning ofequals
would conflate to both meaning identity. As is, maybe there's reason for keeping them separate?brian Sun 18 Oct 2009
I think the current definition of equals is correct:
In some uses of range you might say that you can normalize the exclusive end, but that isn't true in all cases. For example, in all our uses of ranges for slice operations, the notion of exclusive and inclusive is quite important.
Plus, I think for anything that serializes as a string, equality should hold true for
toStr
andfromStr
(which is another case where the exclusive flag is semantically significant).