digitalmars.D.learn - Is there any reason to use non-ref foreach?
- Dukc (25/25) Aug 31 2018 For me, it seems that for generality you should always add ref
- bauss (28/54) Aug 31 2018 It makes sense in your simplified examples, but in practice it
- James Blachly (3/6) Aug 31 2018 I assume a benefit could be observed if you are copying a large
- Dukc (8/11) Aug 31 2018 I think you misunderstood. I wasn't trying to optimize, I was
- Andrea Fontana (3/5) Sep 03 2018 One good reason:
- Dukc (8/13) Sep 04 2018 I am almost sure it will stay how it is, because of the sheer
- Andrea Fontana (3/18) Sep 04 2018 Waiting for this to be merged:
- Dukc (4/6) Sep 04 2018 Well, it seems Andrei has already approved the concept. well,
For me, it seems that for generality you should always add ref into foreach loop variable. The reason is this: import std.experimental.all; struct NoCopies { disable this(this); int payload; } void main() { auto range = new NoCopies[20]; foreach(const ref el; range) el.payload.writeln; } Without ref qualifier in el, this won't work because it would make a copy. Unlike ref as a function argument, it does not enforce refness: import std.experimental.all; void main() { auto range = iota(20).map!(x => x + 2); foreach(const ref el; range) el.writeln; } This compiles, even though range elements are rvalues. This seems to imply, for me, that for generality one should always use ref in foreach loop variables. If the vairable has to be guarded against changes, it should const ref, not unqualified. But considering unqualified is the default, I am probably missing something here. Performance?
Aug 31 2018
On Friday, 31 August 2018 at 09:59:20 UTC, Dukc wrote:For me, it seems that for generality you should always add ref into foreach loop variable. The reason is this: import std.experimental.all; struct NoCopies { disable this(this); int payload; } void main() { auto range = new NoCopies[20]; foreach(const ref el; range) el.payload.writeln; } Without ref qualifier in el, this won't work because it would make a copy. Unlike ref as a function argument, it does not enforce refness: import std.experimental.all; void main() { auto range = iota(20).map!(x => x + 2); foreach(const ref el; range) el.writeln; } This compiles, even though range elements are rvalues. This seems to imply, for me, that for generality one should always use ref in foreach loop variables. If the vairable has to be guarded against changes, it should const ref, not unqualified. But considering unqualified is the default, I am probably missing something here. Performance?It makes sense in your simplified examples, but in practice it doesn't, because it will depend on each situation, what type of data you're enumerating etc. And I bet you there are some gotchas using just ref. In reality you're micro-optimizing something that doesn't require it. Remember that basically the difference is this. foreach (i; values) { ... } for (int _ = 0; _ < values; _++) { auto i = values[_]; ... } VS foreach (ref i; values) { ... } for (int _ = 0; _ < values; _++) { auto i = &values[_]; ... } So basically ... Instead of copying the value, you're just copying the address. I can't see the benefit other than added complexity.
Aug 31 2018
On Friday, 31 August 2018 at 12:52:17 UTC, bauss wrote:So basically ... Instead of copying the value, you're just copying the address. I can't see the benefit other than added complexity.I assume a benefit could be observed if you are copying a large struct instead of an int.
Aug 31 2018
On Friday, 31 August 2018 at 12:52:17 UTC, bauss wrote:In reality you're micro-optimizing something that doesn't require it.I think you misunderstood. I wasn't trying to optimize, I was looking for a general way to iterate.I can't see the benefit other than added complexity.I just explained it. Iterating by ref works with elements that have postblits disabled, iterating by value doesn't. I was wondering that if iterating by ref is the most general way to iterate, why it isn't the default? Is there some big implication in using it?
Aug 31 2018
On Friday, 31 August 2018 at 09:59:20 UTC, Dukc wrote:For me, it seems that for generality you should always add ref into foreach loop variable. The reason is this:One good reason: https://forum.dlang.org/thread/dlhrrgvzmhladnphidei forum.dlang.org
Sep 03 2018
On Monday, 3 September 2018 at 13:34:36 UTC, Andrea Fontana wrote:On Friday, 31 August 2018 at 09:59:20 UTC, Dukc wrote:I am almost sure it will stay how it is, because of the sheer amount of breakage changing that would cause. I still agree that in princliple, the general way to iterate should be something else (auto ref?). But as with autodecoding, the present way is already in too wide use to be worth changing. But I think we need an official line to confirm whether one can use that without risking a deprectation.For me, it seems that for generality you should always add ref into foreach loop variable. The reason is this:One good reason: https://forum.dlang.org/thread/dlhrrgvzmhladnphidei forum.dlang.org
Sep 04 2018
On Tuesday, 4 September 2018 at 07:06:43 UTC, Dukc wrote:On Monday, 3 September 2018 at 13:34:36 UTC, Andrea Fontana wrote:Waiting for this to be merged: https://github.com/dlang/dmd/pull/8437On Friday, 31 August 2018 at 09:59:20 UTC, Dukc wrote:I am almost sure it will stay how it is, because of the sheer amount of breakage changing that would cause. I still agree that in princliple, the general way to iterate should be something else (auto ref?). But as with autodecoding, the present way is already in too wide use to be worth changing. But I think we need an official line to confirm whether one can use that without risking a deprectation.For me, it seems that for generality you should always add ref into foreach loop variable. The reason is this:One good reason: https://forum.dlang.org/thread/dlhrrgvzmhladnphidei forum.dlang.org
Sep 04 2018
On Tuesday, 4 September 2018 at 08:17:14 UTC, Andrea Fontana wrote:Waiting for this to be merged: https://github.com/dlang/dmd/pull/8437Well, it seems Andrei has already approved the concept. well, THAT is a good reason to avoid this paradigm. Thanks for the info.
Sep 04 2018