http://d.puremagic.com/issues/show_bug.cgi?id=4085
Summary: Steps toward a static foreach Product: D Version: future Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: nob...@puremagic.com ReportedBy: bearophile_h...@eml.cc --- Comment #0 from bearophile_h...@eml.cc 2010-04-12 18:30:59 PDT --- A "static foreach" can be useful to statically unroll loops (both on a small numerical range, or for example on items of an array/matrix known at compile time, this can significantly improve the performance of some code), to define many switch cases in a compact way, to reduce code duplication using string mixins, and so on. It can be useful both inside and outside function bodies. Currently the foreach on tuples is static, but the new D programmer can ignore this, and a quick inspection of D code doesn't tell if a foreach is static or runtime. Generally in D code it's important to always be able to visually tell apart static statements (like static if, static assert) from their runtime variants. At the moment it's possible to use a limited form of static foreach on a numeric range, using a helper template like (similar Range can be defined with one and three input arguments): template Range(int start, int stop) { static if (stop <= start) alias Tuple!() Range; else alias Tuple!(Range!(start, stop-1), stop-1) Range; } But Range generates many templates, works only inside functions, and visually the code that uses Range!() is not visually distinct from the runtime foreach. Andrei has commented: > static foreach was part of the plan until recently, but Walter > encountered severe implementation difficulties so we had to abandon it. > I agree that it's odd that the same statement iterates at compile-time > or run-time depending on the iterated type. I'd like Walter to explain why it's hard to implement, maybe some other programmer can find a way to implement it. Even if a static foreach can't be fully implemented, there are other intermediate solutions. Even a partially implemented static foreach is an improvement over the current situation. There are various levels of implementation of static foreach, more and more complete, each one of them is better than the last one: 1) Just require the prefix keyword "static" before "foreach" when the foreach is done on a tuple. This doesn't change the semantics of the current D programs, but helps who will read the D code to visually tell apart the static case from the runtime case. I think this is not too much hard to implement. 2) The compiler can translate (lower) code like "static foreach (i; 10 .. 20)" into something like that "static foreach (i; Range!(10, 20))", using a Range template defined automatically (this static foreach on a range can be used only inside functions). 3) The same as point (2), but the compiler can avoid instantiating all those templates. This can reduce memory used during compilation and speed up the compilation a little. 4) The same as (3) but it can work on arrays too known at compile time too. The compiler can convert arrays known at compile time into tuples, and then iterate on a numerical range as long as the array, and pick items from the tuple usign an index. (This is already doable now, with a recursive template that converts an array known at compile time into a tuple). 5) Like (4) but the compiler can optimize better, avoiding the conversion from the array known at compile time into a tuple (as the precedent levels, this static foreach can be used only inside functions). 6) This is the full static foreach, that can be used outside the body of any function too. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------