Is old style compile-time foreach redundant?

H. S. Teoh hsteoh at quickfur.ath.cx
Tue Jan 9 16:35:40 UTC 2018


On Tue, Jan 09, 2018 at 10:57:03AM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote:
> On 1/8/18 9:27 AM, H. S. Teoh wrote:
> > On Sun, Jan 07, 2018 at 10:39:19PM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote:
> > > On 1/6/18 6:25 PM, Ali Çehreli wrote:
> > > > Is 'static foreach' sufficient for all needs or is there any
> > > > value for regular foreach over compile-time sequences?
> > > 
> > > If you use continues or breaks, then you need to switch to gotos
> > > if using static foreach, as it does not support them directly.
> > [...]
> > 
> > Are you sure?  I was under te impression that it does support
> > continues and breaks -- but only if they are labelled, because of a
> > syntactic ambiguity otherwise.
> 
> I thought it only worked for constructs outside the static foreach
> (like switch).
> 
> testing...
> 
> Nope, doesn't work.

Grrr... I thought it did, but you're right, attempting to break the
static foreach with a label gets this compile error:

-----
test.d(7): Error: enclosing label FE for break not found
-----


> The ambiguity is that if you have a breakable or continuable construct
> outside a static foreach (e.g. switch), then you may believe that the
> break statement is affecting the foreach (in fact, that is how
> tuple-foreach works), but you are actually affecting the outer
> construct.

Yes, that's the ambiguity I was referring to. :-)


> The extra requirement is to help you realize the implication. It may
> be removed in the future.

I vaguely remember Timon mentioning something about implementing static
break / static continue, and somehow I thought the labelled break /
labelled continue was supposed to be it. Or at least, they are stand-ins
until static break/continue are implemented.  Is that no longer on the
table?


> I may have been misleading when I made my first comment. What I mean
> is that you *can't* break or continue a static foreach, even with
> labels. However, you *can* do it to a standard foreach over a tuple.
> This may be one reason you want to use a tuple-foreach over a static
> foreach.
[...]

Actually, that's wrong too. Tuple-foreach does not interpret
break/continue either. Here's a proof:

	alias Seq(A...) = A;
	foreach (i; Seq!(0, 1, 2, 3)) {
		static if (i==2)
			break;
		static assert(i < 3); // will fail on the 4th iteration
	}

What actually happens is that all iterations are unrolled, then the
unreachable iterations are elided by the optimizer during codegen. The
foreach itself is not affected by break/continue at all.


T

-- 
Дерево держится корнями, а человек - друзьями.


More information about the Digitalmars-d-learn mailing list