digitalmars.D.learn - Double bracket "{{" for scoping static foreach is no longer part of D
- data pulverizer (12/12) Dec 22 2021 Hi All,
- rikki cattermole (34/34) Dec 22 2021 Seems to be working just fine as of 2.098.
- ag0aep6g (35/56) Dec 22 2021 In this context, `{ ... }` is not the same as `() { ... }`.
- data pulverizer (30/45) Dec 22 2021 I see, It looks like I remembered incorrectly about using `{{` in
- Adam D Ruppe (43/47) Dec 22 2021 None of these things have anything to do with each other.
- data pulverizer (3/8) Dec 22 2021 Just seen this. Thanks - I should have been more patient.
- Era Scarecrow (8/17) Dec 26 2021 I thought the {{ }} was mostly related to static if, namely that
Hi All, I noticed that the double bracket `{{` for scoping `static foreach` is no longer part of D and it looks like it has been replaced with https://dlang.org/changelog/2.098.0.html#AliasAssign. Could someone confirm this with a link to the DIP and any other tools that we should be using (I guess it's now more reliance on CTFE)? I tend to avoid CTFE for small amounts of meta-programming since it is resolved at "soft compile time" and being cautious by nature I tend to rely more on templates. The change is not a big deal, I just didn't see any news about it. Many thanks
Dec 22 2021
Seems to be working just fine as of 2.098. ```d import std; void main() { static foreach(Foo; ["Abc", "def"]) {{ string str = Foo; writeln("Hello D ", str, __VERSION__); }} } ``` ``` Hello D Abc2098 Hello D def2098 ``` Anyway, AliasAssign has nothing to do with this. This "trick" creates a closure aka ``() { ... }``. Thats all its doing. From the AST dump: ``` import object; import std; void main() { { string str = "Abc"; writeln("Hello D ", str, 2098L); } { string str = "def"; writeln("Hello D ", str, 2098L); } return 0; } ```
Dec 22 2021
On 22.12.21 17:01, rikki cattermole wrote:Anyway, AliasAssign has nothing to do with this. This "trick" creates a closure aka ``() { ... }``. Thats all its doing. From the AST dump: ``` import object; import std; void main() { { string str = "Abc"; writeln("Hello D ", str, 2098L); } { string str = "def"; writeln("Hello D ", str, 2098L); } return 0; } ```In this context, `{ ... }` is not the same as `() { ... }`. Also, `() { ... }` is not a closure, and does not necessarily involve a closure. Just a scope: ---- import std.stdio; void main() { { string str = "Abc"; writeln("Hello D ", str, 2098L); } } ---- An immediately called function literal: ---- import std.stdio; void main() { () { string str = "Abc"; writeln("Hello D ", str, 2098L); } (); } ---- Returning a closure: ---- import std.stdio; void main() { f("Abc")(); } auto f(string str) { return { writeln("Hello D ", str, 2098L); }; } ----
Dec 22 2021
On Wednesday, 22 December 2021 at 16:01:49 UTC, rikki cattermole wrote:Seems to be working just fine as of 2.098. ```d import std; void main() { static foreach(Foo; ["Abc", "def"]) {{ string str = Foo; writeln("Hello D ", str, __VERSION__); }} } ``` ``` Hello D Abc2098 Hello D def2098 ```I see, It looks like I remembered incorrectly about using `{{` in templates! It seems that it doesn't work in templates or in "global" (outside main), so for instance neither this ``` // compiled with -o- flag static foreach(Foo; ["Abc", "def"]) {{ enum str = Foo; pragma(msg, "Hello D ", str, __VERSION__); }} ``` nor this ``` template Demo() { static foreach(Foo; ["Abc", "def"]) {{ enum str = Foo; pragma(msg, "Demo: Hello D ", str, __VERSION__); }} enum Demo = null; } void main() { Demo!() } ``` will run. It gives an error `Error: declaration expected, not {`.
Dec 22 2021
On Wednesday, 22 December 2021 at 15:57:29 UTC, data pulverizer wrote:I noticed that the double bracket `{{` for scoping `static foreach` is no longer part of D and it looks like it has been replaced with https://dlang.org/changelog/2.098.0.html#AliasAssignNone of these things have anything to do with each other. static foreach is a loop over some compile time value. It is special because it can be used outside a function as well as inside it. static foreach's body has optional {}. Its body can contain whatever the context of the static foreach itself is allowed to contain. Meaning if it is inside a function, it can have all the things inside that functions can have. This happens to include the nested scope statement, {}. If it is outside a function, it can only use things that are legal outside a function, so no nested scope, no expressions; just other declarations. So OUTSIDE a function, static foreach() {{ }} is illegal because a plain {} is illegal outside a function. But INSIDE a function, static foreach() {{ }} is legal, but it isn't magic about static foreach - it is just a body with its optional {} present as well as a scope statement inside. void test() { int a; { // this is a scope statement int b; } // a still exists here as a local var, but b's lifetime ended with the preceding }. static foreach(...) stuff; // the {} are optional and i left htem out static foreach(...) { stuff; // same as above but now i put in the optional {} } // now the double {} is actually: static foreach(...) { // optional body {} present { // and this is actually one of those scope statements from above int b; } } } The alias assign is completely different, that's unrelated to either of those features. It is about overwriting one declaration with another if you haven't accessed it yet, giving the illusion of mutation in a compile time alias value.
Dec 22 2021
On Wednesday, 22 December 2021 at 16:10:42 UTC, Adam D Ruppe wrote:So OUTSIDE a function, static foreach() {{ }} is illegal because a plain {} is illegal outside a function. But INSIDE a function, static foreach() {{ }} is legal, but it isn't magic about static foreach - it is just a body with its optional {} present as well as a scope statement inside.Just seen this. Thanks - I should have been more patient.
Dec 22 2021
On Wednesday, 22 December 2021 at 16:30:06 UTC, data pulverizer wrote:On Wednesday, 22 December 2021 at 16:10:42 UTC, Adam D Ruppe wrote:I thought the {{ }} was mostly related to static if, namely that when you do static if, the block contents is added in scope; So if you needed a scope you'd do the second bracket as the outer/first one is stripped out. I need to once again re-familiarize myself more with D. It's been too long.So OUTSIDE a function, static foreach() {{ }} is illegal because a plain {} is illegal outside a function. But INSIDE a function, static foreach() {{ }} is legal, but it isn't magic about static foreach - it is just a body with its optional {} present as well as a scope statement inside.Just seen this. Thanks - I should have been more patient.
Dec 26 2021