digitalmars.D.learn - Why is there no range iteration with index by the language?
- Q. Schroll (26/26) Jun 09 2020 Is there any particular reason why std.range : enumerate is a
- H. S. Teoh (6/12) Jun 09 2020 [...]
- H. S. Teoh (7/17) Jun 09 2020 [...]
- Stefan Koch (4/7) Jun 09 2020 I don't think there is any particular reason. Other than that
- Seb (10/36) Jun 09 2020 It's a bit more complicated though as you need to avoid subtle
- Q. Schroll (6/11) Jun 09 2020 Okay, I can accept that. It's a poor decision, but well, it is
- Seb (5/16) Jun 09 2020 No, there's nothing "official" not public lists yet.
- jmh530 (7/10) Jun 10 2020 Chapel supports zippered iteration [1]. From the discussion here,
- Jesse Phillips (13/15) Jun 10 2020 Someone already mentioned dictionary.
- Steven Schveighoffer (9/15) Jun 10 2020 What is the use case for static foreach and enumerate?
- Dukc (8/15) Jun 10 2020 ```
Is there any particular reason why std.range : enumerate is a thing and foreach (i, e; range) { ... } doesn't work from the get-go? I wouldn't have such an issue with it if static foreach would work with enumerate just fine. As far as I can tell, foreach (e; range) { ... } is being lowered to for (auto _range = range; !_range.empty; _range.popFront) { auto e = _range.front; ... } So why cant DMD rewrite foreach (i, e; range) { ... } to for (auto _range = range, index = size_t(0); !_range.empty; _range.popFront, ++index) { size_t i = index; auto e = _range.front; ... } Doesn't seem like a big deal, does it? I'm asking because I suspect there's an odd reason I have no idea and I whish to be educated.
Jun 09 2020
On Tue, Jun 09, 2020 at 11:53:16PM +0000, Q. Schroll via Digitalmars-d-learn wrote:Is there any particular reason why std.range : enumerate is a thing and foreach (i, e; range) { ... } doesn't work from the get-go?[...] std.range.indexed is your friend. ;-) T -- Let's eat some disquits while we format the biskettes.
Jun 09 2020
On Tue, Jun 09, 2020 at 05:03:55PM -0700, H. S. Teoh via Digitalmars-d-learn wrote:On Tue, Jun 09, 2020 at 11:53:16PM +0000, Q. Schroll via Digitalmars-d-learn wrote:[...] Aaah, that function doesn't do what I thought it did. Sorry!! :-( What you want is std.range.enumerate. But you already knew that. T -- EMACS = Extremely Massive And Cumbersome SystemIs there any particular reason why std.range : enumerate is a thing and foreach (i, e; range) { ... } doesn't work from the get-go?[...] std.range.indexed is your friend. ;-)
Jun 09 2020
On Tuesday, 9 June 2020 at 23:53:16 UTC, Q. Schroll wrote:Is there any particular reason why std.range : enumerate is a thing and [...]I don't think there is any particular reason. Other than that might shadow an opApply. And C++ iterators didn't have it.
Jun 09 2020
On Tuesday, 9 June 2020 at 23:53:16 UTC, Q. Schroll wrote:Is there any particular reason why std.range : enumerate is a thing and foreach (i, e; range) { ... } doesn't work from the get-go? I wouldn't have such an issue with it if static foreach would work with enumerate just fine. As far as I can tell, foreach (e; range) { ... } is being lowered to for (auto _range = range; !_range.empty; _range.popFront) { auto e = _range.front; ... } So why cant DMD rewrite foreach (i, e; range) { ... } to for (auto _range = range, index = size_t(0); !_range.empty; _range.popFront, ++index) { size_t i = index; auto e = _range.front; ... } Doesn't seem like a big deal, does it? I'm asking because I suspect there's an odd reason I have no idea and I whish to be educated.It's a bit more complicated though as you need to avoid subtle breakage with ranges that return tuples that are auto-expanded like e.g. `foreach (k,v; myDict)`. So IIRC the main reason why D's foreach magic isn't doing this is that it was argued that this problem is not significant enough to be worth fixing as there's enumerate and "there's bigger fish to fry". Anyhow, I would be highly in favor of DMD doing this. It's one of those many things that I have on my list for D3 or a D fork.
Jun 09 2020
On Wednesday, 10 June 2020 at 00:53:30 UTC, Seb wrote:It's a bit more complicated though as you need to avoid subtle breakage with ranges that return tuples that are auto-expanded like e.g. `foreach (k,v; myDict)`.Okay, I can accept that. It's a poor decision, but well, it is what it is.Anyhow, I would be highly in favor of DMD doing this. It's one of those many things that I have on my list for D3 or a D fork.Is there any "official" or at least public list for D3 suggestions? Many people here talk about it recently...
Jun 09 2020
On Wednesday, 10 June 2020 at 01:35:32 UTC, Q. Schroll wrote:On Wednesday, 10 June 2020 at 00:53:30 UTC, Seb wrote:No, there's nothing "official" not public lists yet. However, there are two good related wiki pages: https://wiki.dlang.org/Language_issues https://wiki.dlang.org/Language_design_discussionsIt's a bit more complicated though as you need to avoid subtle breakage with ranges that return tuples that are auto-expanded like e.g. `foreach (k,v; myDict)`.Okay, I can accept that. It's a poor decision, but well, it is what it is.Anyhow, I would be highly in favor of DMD doing this. It's one of those many things that I have on my list for D3 or a D fork.Is there any "official" or at least public list for D3 suggestions? Many people here talk about it recently...
Jun 09 2020
On Wednesday, 10 June 2020 at 00:53:30 UTC, Seb wrote:[snip] Anyhow, I would be highly in favor of DMD doing this. It's one of those many things that I have on my list for D3 or a D fork.Chapel supports zippered iteration [1]. From the discussion here, it sounds very much like the implementation is similar to what D does with tuples. It probably would be pretty trivial with first class tuples. [1] https://chapel-lang.org/docs/language/spec/statements.html#zipper-iteration
Jun 10 2020
On Tuesday, 9 June 2020 at 23:53:16 UTC, Q. Schroll wrote:Is there any particular reason why std.range : enumerate is a thingSomeone already mentioned dictionary. Consider that most ranges don't actually have an index. In this case you aren't actually asking to add indexes, but a count of iteration. For those ranges which do have indexing, what if the range is iterating from a location in the middle. Now you have an iteration count but not the true index. `enumerate` allows for specifying a starting number but this still isn't sufficient since a filter could easily jump to any index. Now none of this may come as a surprise to you, but having an iteration counter and an array index using the same api does open the door for confusion.
Jun 10 2020
On 6/9/20 7:53 PM, Q. Schroll wrote:Is there any particular reason why std.range : enumerate is a thing and foreach (i, e; range) { ... } doesn't work from the get-go? I wouldn't have such an issue with it if static foreach would work with enumerate just fine.What is the use case for static foreach and enumerate? My biggest problem with enumerate is that you can't bind the tuple to parameters for something like map: arr.enumerate.map!((idx, val) => ...) doesn't work. Instead you have to do: arr.enumerate.map!((tup) => ...) And use tup[0] and tup[1]. -Steve
Jun 10 2020
On Wednesday, 10 June 2020 at 15:34:57 UTC, Steven Schveighoffer wrote:My biggest problem with enumerate is that you can't bind the tuple to parameters for something like map: arr.enumerate.map!((idx, val) => ...) doesn't work. Instead you have to do: arr.enumerate.map!((tup) => ...) And use tup[0] and tup[1]. -Steve``` alias tupArg(alias func) = x => func(x.expand); arr.enumerate.map!(tupArg!((idx, val) => ...)) ``` Somewhat heavy on syntax, but better than `tup[0]` or `tup[1]` IMO.
Jun 10 2020