www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - enumerated iteration to struct

reply Fra Mecca <me francescomecca.eu> writes:
I don't know if this post belongs to the learn section, but I'll 
try anyway.

I am using the std.path.pathSplitter function that returns a 
PathSplitter function exposing ranges primitive.

I have some question that could be generalized to other structs 
that expose range primitives.

1. Why can't I write foreach(i, el; 
pathSplitter("foor/bar").enumerate)  ?
2. Supposing I want to fix this problem, what do I add to the 
struct? opApply?
3. Why doesn't ranges infer the iteration method at compile time 
so that I don't need to write enumerate?
Feb 06
parent reply Fra Mecca <me francescomecca.eu> writes:
On Wednesday, 7 February 2018 at 01:10:34 UTC, Fra Mecca wrote:
 I don't know if this post belongs to the learn section, but 
 I'll try anyway.

 I am using the std.path.pathSplitter function that returns a 
 PathSplitter function exposing ranges primitive.

 I have some question that could be generalized to other structs 
 that expose range primitives.

 1. Why can't I write foreach(i, el; 
 pathSplitter("foor/bar").enumerate)  ?
 2. Supposing I want to fix this problem, what do I add to the 
 struct? opApply?
There was a stupid stupid error on my part because I wasn't import the range module.
 3. Why doesn't ranges infer the iteration method at compile 
 time so that I don't need to write enumerate?
This question is still valid. I think it would be saner to write foreach(idx, el; paths) instead of foreach(idx, el; paths.enumerate)
Feb 06
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, February 07, 2018 01:21:16 Fra Mecca via Digitalmars-d-learn 
wrote:
 On Wednesday, 7 February 2018 at 01:10:34 UTC, Fra Mecca wrote:
 I don't know if this post belongs to the learn section, but
 I'll try anyway.

 I am using the std.path.pathSplitter function that returns a
 PathSplitter function exposing ranges primitive.

 I have some question that could be generalized to other structs
 that expose range primitives.

 1. Why can't I write foreach(i, el;
 pathSplitter("foor/bar").enumerate)  ?
 2. Supposing I want to fix this problem, what do I add to the
 struct? opApply?
There was a stupid stupid error on my part because I wasn't import the range module.
 3. Why doesn't ranges infer the iteration method at compile
 time so that I don't need to write enumerate?
This question is still valid. I think it would be saner to write foreach(idx, el; paths) instead of foreach(idx, el; paths.enumerate)
Perhaps, but foreach does not support that. foreach(e; range) { ... } is lowered to something like for(auto __range = range; !__range.empty; __range.popFront()) { auto e = __range.front; ... } In order to support indices, it would need to also add a size_t that it incremented as it iterated the range, and the language doesn't support that. It would be useful in many cases, and it would make sense for many ranges, but it arguably doesn't make sense for others. In particular, it would pose a problem for infinite ranges, and it's been argued before that for stuff like AAs where you're not really dealing with a linear list, it doesn't make sense (though that's debatable, since the range itself is linear even if it doesn't relate to indices into anything). Ultimately, it's one of those things where it was trivial to solve with a library solution, so it wasn't added to the language. I don't know what the odds would be of a DIP which adds it to the language being accepted, but I suspect that it would be rejected on the grounds that it's already solved with a library solution. Over time, Walter and Andrei have increasingly favored library solutions over language solutions when a library solution will do the job, though certainly sometimes it's debatable as to whether a language solution would be better. - Jonathan M Davis
Feb 06
parent Seb <seb wilzba.ch> writes:
On Wednesday, 7 February 2018 at 01:45:27 UTC, Jonathan M Davis 
wrote:
 Perhaps, but foreach does not support that.

 foreach(e; range)
 {
     ...
 }

 is lowered to something like

 for(auto __range = range; !__range.empty; __range.popFront())
 {
     auto e = __range.front;
     ...
 }
Fun fact: an actual lowering from the compiler: Result __r39 = iota(2).opSlice(); for (; !__r39.empty(); __r39.popFront()) { int a = __r39.front(); } https://run.dlang.io/is/QihjQi (sorry for being slightly off-topic, but it's always interesting for me to check whether our assumptions for of the inner-workings of the compiler are true ...)
Feb 06