Jump to page: 1 2
Thread overview
Why is there no range iteration with index by the language?
Jun 09, 2020
Q. Schroll
Jun 10, 2020
H. S. Teoh
Jun 10, 2020
H. S. Teoh
Jun 10, 2020
Stefan Koch
Jun 10, 2020
Seb
Jun 10, 2020
Q. Schroll
Jun 10, 2020
Seb
Jun 10, 2020
jmh530
Jun 10, 2020
Jesse Phillips
Jun 10, 2020
Dukc
June 09, 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.
June 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.
June 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:
> > 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. ;-)
[...]

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 System
June 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 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.
June 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 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.
June 10, 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...
June 10, 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:
>> 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...

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_discussions

June 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 thing

Someone 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.
June 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
June 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.
« First   ‹ Prev
1 2