Jump to page: 1 2 3
Thread overview
"for" statement issue
Oct 21, 2016
Stefan Koch
Oct 21, 2016
RazvanN
Oct 21, 2016
Stefan Koch
Oct 21, 2016
Adam D. Ruppe
Oct 21, 2016
Stefan Koch
Oct 21, 2016
Temtaime
Oct 21, 2016
mogu
Oct 21, 2016
mogu
Oct 22, 2016
Nick Treleaven
Oct 22, 2016
ag0aep6g
Oct 23, 2016
Nick Treleaven
Oct 22, 2016
Timon Gehr
Oct 22, 2016
Marc Schütz
Oct 21, 2016
Kagamin
Oct 21, 2016
Kagamin
Oct 21, 2016
Vladimir Panteleev
Oct 21, 2016
Vladimir Panteleev
October 21, 2016
I got a question about what happens with this code:

int j;
for({j=2; int d = 3; } j+d<7; {j++; d++;}) {
}

My first instinct was that that won't compile but it surprisingly does. And it loops forever.

So the grammar according to https://dlang.org/spec/grammar.html#ForStatement is:

ForStatement:
    for ( Initialize Testopt ; Incrementopt ) ScopeStatement

Initialize:
    ;
    NoScopeNonEmptyStatement

NoScopeNonEmptyStatement:
    NonEmptyStatement
    BlockStatement

NonEmptyStatement goes over a bunch of odd places such as case statement and default statement. And then BlockStatement is the matched case:

BlockStatement:
    { }
    { StatementList }

So it seems we have another case in which "{" "}" do not introduce a scope. Fine. The real problem is with the increment part, which is an expression. The code { j++; d++; } is... a lambda expression that never gets used, which completes a very confusing sample.

What would be a good solution to forbid certain constructs in the increment part of a for statement?


Thanks,

Andrei
October 21, 2016
On Friday, 21 October 2016 at 12:34:58 UTC, Andrei Alexandrescu wrote:
> I got a question about what happens with this code:
>
> int j;
> for({j=2; int d = 3; } j+d<7; {j++; d++;}) {
> }
>
> [...]
We could restrict the initialze part to assignments only. But I am unsure of the implications.
How did you find this case?
October 21, 2016
On Friday, 21 October 2016 at 12:34:58 UTC, Andrei Alexandrescu wrote:
> I got a question about what happens with this code:
>
> int j;
> for({j=2; int d = 3; } j+d<7; {j++; d++;}) {
> }
>
> My first instinct was that that won't compile but it surprisingly does. And it loops forever.
>
> So the grammar according to https://dlang.org/spec/grammar.html#ForStatement is:
>
> ForStatement:
>     for ( Initialize Testopt ; Incrementopt ) ScopeStatement
>
> Initialize:
>     ;
>     NoScopeNonEmptyStatement
>
> NoScopeNonEmptyStatement:
>     NonEmptyStatement
>     BlockStatement
>
> NonEmptyStatement goes over a bunch of odd places such as case statement and default statement. And then BlockStatement is the matched case:
>
> BlockStatement:
>     { }
>     { StatementList }
>
> So it seems we have another case in which "{" "}" do not introduce a scope. Fine. The real problem is with the increment part, which is an expression. The code { j++; d++; } is... a lambda expression that never gets used, which completes a very confusing sample.
>
> What would be a good solution to forbid certain constructs in the increment part of a for statement?
>
>
> Thanks,
>
> Andrei

I am the one who raised the question. I am n00b when it comes to D language (I just started reading about it a couple of days ago) and I tried the above mentioned code expecting that either the variables j and d get incremented accordingly or at least
I would get a compilation error. Instead, the program compiles and when run it sticks
into an infinite loop. I haven't read anything about lambda functions in D, but the
current outcome is very confusing for a beginner like myself.

Thanks,
RazvanN
October 21, 2016
On Friday, 21 October 2016 at 13:18:19 UTC, RazvanN wrote:
> On Friday, 21 October 2016 at 12:34:58 UTC, Andrei Alexandrescu wrote:
>> [...]
>
> I am the one who raised the question. I am n00b when it comes to D language (I just started reading about it a couple of days ago) and I tried the above mentioned code expecting that either the variables j and d get incremented accordingly or at least
> I would get a compilation error. Instead, the program compiles and when run it sticks
> into an infinite loop. I haven't read anything about lambda functions in D, but the
> current outcome is very confusing for a beginner like myself.
>
> Thanks,
> RazvanN
Ah.
It does create a lambda?
Hmm that should not happen.

I agree this is confusing and unwanted.
Please feel free to post this to bugzilla.

I will take a look next month. If nobody resolves it before then.


October 21, 2016
On Friday, 21 October 2016 at 13:33:26 UTC, Stefan Koch wrote:
> It does create a lambda?
> Hmm that should not happen.

Eh, that's exactly what the language rules say should happen, and it actually does make sense to me... you might even want to use an immediately-called lambda to group several statements together into one expression.

Though I have become convinced recently that we should deprecate the `{ lambdas }` in favor of `() { lambdas }`. This is the same mistake as `() => {xxx}` that we see a bunch of newbies make. If the syntax was changed to require the empty parens for the args, `() {}`, people would be a lot less likely to mess this up... and the rest of us don't seriously lose anything, adding `()` is easy enough if they aren't already there.

I think deprecating `{ lambda }` is really the way to go. It'd fix this as well at that other FAQ at pretty low cost.
October 21, 2016
On Friday, 21 October 2016 at 13:42:49 UTC, Adam D. Ruppe wrote:
> On Friday, 21 October 2016 at 13:33:26 UTC, Stefan Koch wrote:
>> It does create a lambda?
>> Hmm that should not happen.
>
> I think deprecating `{ lambda }` is really the way to go. It'd fix this as well at that other FAQ at pretty low cost.

Yes lets make it happen!
{ } has too many meanings.
Lets deprecate this one.


October 21, 2016
On Friday, 21 October 2016 at 13:42:49 UTC, Adam D. Ruppe wrote:
> On Friday, 21 October 2016 at 13:33:26 UTC, Stefan Koch wrote:
>> [...]
>
> Eh, that's exactly what the language rules say should happen, and it actually does make sense to me... you might even want to use an immediately-called lambda to group several statements together into one expression.
>
> [...]

Please, no.
It's fully clear that { stmts } createa a lambda, just () is ommited.

foo({ code; }); is always OK and we shouldn't deprecate it.
October 21, 2016
On 10/21/16 8:34 AM, Andrei Alexandrescu wrote:
> I got a question about what happens with this code:
>
> int j;
> for({j=2; int d = 3; } j+d<7; {j++; d++;}) {
> }
>
> My first instinct was that that won't compile but it surprisingly does.
> And it loops forever.
>
> So the grammar according to
> https://dlang.org/spec/grammar.html#ForStatement is:
>
> ForStatement:
>     for ( Initialize Testopt ; Incrementopt ) ScopeStatement
>
> Initialize:
>     ;
>     NoScopeNonEmptyStatement
>
> NoScopeNonEmptyStatement:
>     NonEmptyStatement
>     BlockStatement
>
> NonEmptyStatement goes over a bunch of odd places such as case statement
> and default statement. And then BlockStatement is the matched case:
>
> BlockStatement:
>     { }
>     { StatementList }
>
> So it seems we have another case in which "{" "}" do not introduce a
> scope. Fine. The real problem is with the increment part, which is an
> expression. The code { j++; d++; } is... a lambda expression that never
> gets used, which completes a very confusing sample.
>
> What would be a good solution to forbid certain constructs in the
> increment part of a for statement?

How about in general forbidding lambda statements that aren't called or used anywhere?

-Steve
October 21, 2016
On 10/21/16 10:12 AM, Temtaime wrote:
> On Friday, 21 October 2016 at 13:42:49 UTC, Adam D. Ruppe wrote:
>> On Friday, 21 October 2016 at 13:33:26 UTC, Stefan Koch wrote:
>>> [...]
>>
>> Eh, that's exactly what the language rules say should happen, and it
>> actually does make sense to me... you might even want to use an
>> immediately-called lambda to group several statements together into
>> one expression.
>>
>> [...]
>
> Please, no.
> It's fully clear that { stmts } createa a lambda, just () is ommited.

No, it's not.

{ int x; x = 2; }

Is not a lambda. It's a scope.

So the meaning changes based on where it's used. I totally agree that we should remove that feature.

-Steve
October 21, 2016
On Friday, 21 October 2016 at 14:16:26 UTC, Steven Schveighoffer wrote:
> How about in general forbidding lambda statements that aren't called or used anywhere?

How?

int main()
{
	int a;
	auto b = ()=>{a++;};
	b();
	assert(a==1);
	return 0;
}
« First   ‹ Prev
1 2 3