Thread overview
[Spec mistake] Is the `for` loop missing semicolon in the D Lang specification?
Aug 09, 2023
BoQsc
Aug 09, 2023
Quirin Schroll
Aug 09, 2023
jmh530
Aug 09, 2023
matheus
Aug 09, 2023
Paul Backus
Aug 10, 2023
Patrick Schluter
August 09, 2023

https://dlang.org/spec/statement.html#for-statement

Imgur1

Testing on DMD

I tried to test the for loop without the first semicolon.
It seems that two semicolons are required: compiler produces error.

import std;
void main()
{
    for (int i = 0 i < 10; i++)
        writeln("Hello D");
}

https://run.dlang.io/is/Pk0wbh

Imgur2

Conclusion

I'm confused. Do I not understand something in the specification or is it missing a semicolon?

August 09, 2023

On Wednesday, 9 August 2023 at 11:00:55 UTC, BoQsc wrote:

>

I'm confused. Do I not understand something in the specification or is it missing a semicolon?

NoScopeNonEmptyStatement Contains a semicolon.

-Steve

August 09, 2023

On Wednesday, 9 August 2023 at 11:00:55 UTC, BoQsc wrote:

>

[…]
I'm confused. Do I not understand something in the specification or is it missing a semicolon?

From the perspective of the parser, the semicolon is part of the initialization if it’s a simple one. The initialization can be more complex, though, formed by a braced sequence of statements, where the closing brace suffices to indicate the end of the initialization statement. This is valid D code:

void main()
{
    import std.stdio;
    for ({ int x = 1; double d = 3.14; } x < 10; ++x, d *= 10)
    {
        writeln(x, " ", d);
    }
}

Notice that the closing brace before x < 10 has no semicolon following it, and if you place on there, it won’t compile. I’m not saying you should write code like that.

August 09, 2023

On Wednesday, 9 August 2023 at 13:01:37 UTC, Quirin Schroll wrote:

>

On Wednesday, 9 August 2023 at 11:00:55 UTC, BoQsc wrote:

>

[...]

From the perspective of the parser, the semicolon is part of the initialization if it’s a simple one. The initialization can be more complex, though, formed by a braced sequence of statements, where the closing brace suffices to indicate the end of the initialization statement. This is valid D code:

void main()
{
    import std.stdio;
    for ({ int x = 1; double d = 3.14; } x < 10; ++x, d *= 10)
    {
        writeln(x, " ", d);
    }
}

Notice that the closing brace before x < 10 has no semicolon following it, and if you place on there, it won’t compile. I’m not saying you should write code like that.

That's news to me!

August 09, 2023
On Wednesday, 9 August 2023 at 13:01:37 UTC, Quirin Schroll wrote:
> On Wednesday, 9 August 2023 at 11:00:55 UTC, BoQsc wrote:
> ...
> ```d
> void main()
> {
>     import std.stdio;
>     for ({ int x = 1; double d = 3.14; } x < 10; ++x, d *= 10)
>     {
>         writeln(x, " ", d);
>     }
> }
> ```
> Notice that the closing brace before `x < 10` has no semicolon following it, and if you place on there, it won’t compile. I’m not saying you should write code like that.

I wonder if this is a different case or a "bug" in the parser:

>     for ({ int x = 1; double d = 3.14; } x < 10; ++x, d *= 10)

There is no ";" after } but there is after d = 3.14;

Or maybe {} is treated different in this case, like a block and there is an implicitly ";" being evaluated?

Matheus.
August 09, 2023
On Wednesday, 9 August 2023 at 13:59:54 UTC, matheus wrote:
> Or maybe {} is treated different in this case, like a block and there is an implicitly ";" being evaluated?

Yes, the {} is treated like a block statement, so it doesn't require a semicolon. Compare:


    import std.stdio;

    void main()
    {
        {
            writeln("Hello");
        } // <-- no semicolon
        writeln("World");
    }
August 10, 2023

On Wednesday, 9 August 2023 at 13:01:37 UTC, Quirin Schroll wrote:

>

On Wednesday, 9 August 2023 at 11:00:55 UTC, BoQsc wrote:

>

[…]
I'm confused. Do I not understand something in the specification or is it missing a semicolon?

From the perspective of the parser, the semicolon is part of the initialization if it’s a simple one. The initialization can be more complex, though, formed by a braced sequence of statements, where the closing brace suffices to indicate the end of the initialization statement. This is valid D code:

void main()
{
    import std.stdio;
    for ({ int x = 1; double d = 3.14; } x < 10; ++x, d *= 10)
    {
        writeln(x, " ", d);
    }
}

Notice that the closing brace before x < 10 has no semicolon following it, and if you place on there, it won’t compile. I’m not saying you should write code like that.

Cool. That one I miss a lot in my C programs. It's not rare to have more than one loop variable of differing types. In C I have to declare one in front of the for loop, which is annoying as the scope of the variable is not the real one I would like.
These are the small things I love so much in D.