New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should we have an operator for expressing ranges as start/length #99
Comments
PS: How about exclusive spans? |
An example why this would be useful:
Using
...though you could write it a bit shorter using the operators proposed by #88. |
Well, a totally different approach occurs to me, that ties in with the proposal for comprehensions in #82. Instead of loops:
This is clearly more flexible, and no more verbose than comprehensions:
Again, more flexible, and no more verbose than subranges:
Well, this is obviously a lot more verbose, but it's also waay more powerful. Basically this:
would be more or less a shortcut way of writing:
I'm kinda liking this concept! |
Note that we could likely even support an abbreviation for the very common case of
That winds up even cleaner and less verbose that |
Tako points out that step size is a problem with this syntax. (Currently we can write
But that's clearly a little unnatural. |
of course |
Well, actually not so much. Here's a solution:
Clearly not as clean as:
but then I have very rarely used step sizes in Java, and this kind of thing is going to be even way less common in Ceylon where you simply don't iterate over array (i.e. sequence or |
Or:
But I also rarely need this. A question concerning subranges: does |
So I'm convinced step sizes and reverse ranges, etc, are not an issue. Here's my reasons:
Most of all, I simply adore the immediate readability of:
That's the opposite of cryptic. |
That's a good question. When I characterized it as an abbreviation for a comprehension, that's not precisely right because the thing about the But the way I'm now trying to conceptualize
According to the functionality proposed by #82, this means that this operation can be called like this:
which we would then let you abbreviate to:
Does that make sense? |
If I understand it correctly, this means that in most cases Apart from that: a readable syntax that fits well into the language and can replace both |
I think it could be perfectly efficient. I'm not going to go off and eagerly allocate an array under the covers. At most I'm going to create some sort of iterator. |
P.S. I would not cry very much if we simply dropped the |
Sounds good. Something I still don't understand is the following...
Any of the indices can be out of range, so wouldn't that make
without sacrificing efficiency, especially considering that indexed access is potentially slow for |
I don't like the Also anything with My favorite proposals are still As for the original "start/length" question, what about
This is not a problem if you don't guarantee that the length of the subrange is the same as the number of indices supplied. That way you can skip bad indices. |
Not sure what you mean. Couldn't you just write "
Sure, but then you can't return anything that satisfies I think the |
I'm saying that your suggestion is preferred over |
But the JVM doesn't have unsigned integers, so this is never possible. |
Yes, but the resulting range will be I don't know what the intended use case for the inclusive range construct is, but I wouldn't expect it to be the default. Especially after reading Djikstra's Why numbering should start at zero. So I would expect Also, I believe having a way to define a range by (start, end) and by (start, length) will only serve to confuse newbies, since they are equivalent in the most common case (start == 0). |
Djikstra's little argument is interesting, but to me ultimately unconvincing, and, frankly, seems to come close to assuming its conclusion in its premises. A much better approach, I think, is to ask what in practice we generally get as inputs when we construct a range. My experience is that it's almost always the case that we receive either:
I find the case of an exclusive endpoint to be something that simply doesn't naturally occur very often. Now, the advantage of a "Djikstra span" is that both of the above can be re-expressed using addition (and no subtraction) in terms of an inclusive start and exclusive end, so if you're hung up on trying to find a single best way to write a range, that's a reasonable compromise. But we don't have to accept that there should be exactly one way to write down a range. If there's more than one way, then we can make both 1 and 2 expressible directly, without even the use of addition. http://groups.google.com/group/ceylon-dev/msg/c7b6e7a38e21d3b8?hl=en |
An inclusive range on both ends does seem to to be the standard in functional languages, so maybe it really is more common. I concede that I often find myself iterating on a list and splitting it in consecutive segments, so with inclusive ranges I would need to subtract 1 from the end to ensure that they don't overlap. I would also need subtraction if I were to use
Actually that's what I'm trying to argue, that having more than one way to write a range will only lead to confusion. To quote Djikstra:
Ruby actually has both |
That's possible, but to me it doesn't seem likely. I might be wrong.
I definitely don't want to get into an argument with Djikstra, especially since he's much smarter than me and sadly not here to defend himself, but I don't find second-hand reports about experience with a 30-year-old language very convincing. Remember that back in those days almost every usage of the range construct was for iterating an array. That's exactly the opposite situation from Ceylon, where we never use ranges for iterating collections! FTR, Mesa used the notation |
I would have liked to link to a more recent report, but I couldn't find any. The only language I saw that offers both inclusive and exclusive ranges is Ruby, and the exclusive variant seems a bit unpopular there.
I would say it's also the other way around: you never use ranges for iterating collections in Ceylon because it only has inclusive ranges, and inclusive ranges are never appropriate for working with collections! And it's not just about iterating collections: even splitting a range in two is more awkward with inclusive ranges. |
For the record, one way to rescue the current
The
I think this is probably a competitive alternative to the |
Another idea to make the mathematics-style syntax more palatable. I think we could probably eliminate the need for the Then you would be able to write comprehensions like:
And subranges like:
I'm not sure if that's better or worse. But it does address the complaint about verbosity. |
It would be much easier if we just turn In general I do want to vote to keep this syntax, regardless if you want to implement the math-style syntax or not. This is really nice syntax, easy to understand and most people love it when you show it to them. The math-style could be used for more advanced situations if you want. |
One way to define the step size, which I've seen used in other language is to use the syntax: |
Very true. The Actually, the mathematical syntax could even allow backward iteration in a straight-forward way: if And for custom step sizes I can easily do without syntactic sugar. |
@gavinking |
Tom, There's no SegmentOp; |
@chochos there is! The typechecker lets me can say this
to create the sequence |
oooooooh that's another thing entirely... but shouldn't that be a |
It's a |
since this is not in the spec yet... what types does this operator accept? only Integers, or Ordinals in general? |
Gavin: I believe this is your cue to update the spec ;) |
Lhs is Ordinal and rhs is integer atm, but I don't think that works, which I'll explain after I've eaten... |
That's what I was afraid of... so to get the end of the Range you have to calculate the Range end by looping rhs times incrementing the lhs... |
@chochos We actually already mentioned a solution to this problem a few months ago: |
Right... but it hasn't been added yet and I don't know if it will. Meanwhile, calculating the end of the Range with the loop works; and having that method in Ordinal that returns another Ordinal at a certain distance will just be implemented with the same loop. |
The idea is the same as with the A loop is not ok because we don't know how many iterations it will have, so it can too easily result in a almost-endless loop. |
The problem I was thinking of was this:
Presumably the result should be All this is for the JVM, of course. Maybe reconsidering ceylon/ceylon.language#50 (i.e. detecting the overflow and throwing) would help. |
Corrected: I meant |
'can use |
It would be ok with me if |
I agree that detecting overflow in general too inefficient. I admit I hadn't considered building knowledge of |
I guess you're right. So apparently the only easy solution is to let the method in |
I think the problem stems from trying to use a
And compare it with the Java equivalent:
In Java it's left to the programmer to worry (or not) about what happens if |
@gavinking what do you think we should do for this problem with overflow? |
Reopening to get @gavinking's attention and opinion about this overflow problem. |
@tombentley if you have a new related problem, please open a new issue for it. I don't want to discuss it here. |
@tombentley P.S. That would be an issue for |
We have the syntax
start..end
for expressing inclusive ranges (what I've been calling "spans"). This makes an appearance in two different operators, for example:In this thread:
http://groups.google.com/group/ceylon-dev/browse_thread/thread/82daa1e0750f133a?hl=en
The idea of having an operator for expressing ranges by start and length (what I've been calling "segments") came up. The syntax I like the most would be a
:
, but I think that..:
or../
could also potentially work.Now,
:
is a potentially very useful symbol, so I'm a little loathe to "waste" it on something non-critical like this. So a different possibility would be something like..:
or../
.Anyway, this is not going to be for M1, it's just an idea that is out there to see if it would be popular with other folks.
The text was updated successfully, but these errors were encountered: