foreach thoughts

Marco Leise Marco.Leise at gmx.de
Wed Jan 15 11:56:35 PST 2014


Am Tue, 14 Jan 2014 19:07:33 +1000
schrieb Manu <turkeyman at gmail.com>:

> On 14 January 2014 19:04, Manu <turkeyman at gmail.com> wrote:
> 
> > On 14 January 2014 18:36, Jakob Ovrum <jakobovrum at gmail.com> wrote:
> >
> >> On Tuesday, 14 January 2014 at 08:23:05 UTC, Manu wrote:
> >>
> >>> 1. A termination condition (ie, while)
> >>>
> >>> foreach(t; things) iterates each thing, but it's common in traditional
> >>> for
> >>> loops to have an && in the second 'while' term, to add an additional
> >>> termination condition.
> >>> for(i=0; i<things.length && things[i].someCondition; ++i)
> >>>
> >>> Or with foreach:
> >>> foreach(i, t; things)
> >>> {
> >>>   if(t.someCondition)
> >>>     break;
> >>>   ...
> >>> }
> >>>
> >>
> >> foreach(t; things.until!(t => t.someCondition))
> >> {
> >> }
> >>
> >> Unfortunately foreach over a range does not automatically support an
> >> index loop variable. We could add something like std.range.enumerate to
> >> support this, but I think it's a common enough requirement that a language
> >> amendment is warranted (there are some subtleties involved in implementing
> >> it though - specifically when combined with automatic tuple expansion).
> >>
> >>
> >>  2. A filter
> >>>
> >>> The other thing is the ability to skip uninteresting elements. This is
> >>> typically performed with the first line of the loop testing a condition,
> >>> and then continue:
> >>> foreach(i, t; things)
> >>> {
> >>>   if(!t.isInteresting)
> >>>     continue;
> >>>   ...
> >>> }
> >>>
> >>
> >> foreach(t; things.filter!(t => t.isInteresting))
> >> {
> >> }
> >>
> >> Ditto about the index loop variable.
> >>
> >>
> >>  I've tried to approach the problem with std.algorithm, but I find the
> >>> std.algorithm statement to be much more noisy and usually longer when the
> >>> loops are sufficiently simple (as they usually are in my case, which is
> >>> why
> >>> the trivial conditions are so distracting by contrast).
> >>>
> >>
> >> The two examples above look a *lot* cleaner and less noisy (declarative!)
> >> to me than the imperative approach using if-break or if-continue.
> >
> >
> > /agree completely.
> > This is nice, I didn't think of writing statements like that :)
> > That's precisely the sort of suggestion I was hoping for. I'll continue
> > like this.
> >
> 
> Can anyone comment on the codegen when using these statements? Is it
> identical to my reference 'if' statement?
> Liberal use of loops like this will probably obliterate unoptimised
> performance... :/
 
For a moment, I thought the performance crew lost you. :)
D's foreach is awesome. Remember this benchmark?
http://togototo.wordpress.com/2013/08/23/benchmarks-round-two-parallel-go-rust-d-scala-and-nimrod/
The top entry's performance is due to how well LDC2 optimized
the foreach, otherwise the code is quite the same as the C++
version.

-- 
Marco



More information about the Digitalmars-d mailing list