Am Tue, 14 Jan 2014 19:07:33 +1000 schrieb Manu <turkey...@gmail.com>:
> On 14 January 2014 19:04, Manu <turkey...@gmail.com> wrote: > > > On 14 January 2014 18:36, Jakob Ovrum <jakobov...@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