digitalmars.D - CT foreaches
- monkyyy (40/40) Aug 01 ```d
- Nick Treleaven (8/48) Aug 01 You're using runtime foreach here. It's only expanded at
- monkyyy (13/27) Aug 01 No, `foreach(alias` is functionally undocumented (dip 1010 is not
- Nick Treleaven (11/38) Aug 01 Thanks, fix:
- Quirin Schroll (4/16) Aug 01 Making non-static `foreach (enum x; l .. u)` an error would be
- Timon Gehr (7/24) Aug 01 For reference:
- Timon Gehr (16/53) Aug 01 These behave like lined out in Proposal 1 of DIP 1010.
```d import std; void foo(int i:0)()=>"foo".writeln; void foo(int i:1)()=>"bar".writeln; void foo(int i:2)()=>"foobar".writeln; void main(){ foreach(i,alias b; AliasSeq!("foo","bar")){ pragma(msg, b.stringof); break; } pragma(msg,"---"); foreach(i,enum b; AliasSeq!("foo","bar")){ pragma(msg, b.stringof); break; } pragma(msg,"---"); static foreach(i;0..3){ pragma(msg, i.stringof); //break; //the scope error } pragma(msg,"---"); foreach(enum i;0..3){// ERROR ISNT CT. ISNT AN ENUM pragma(msg, i.stringof); //foo!i; //doesnt compile break; } } ``` Theres bugs and unintended features here :D ; alias foreach is undocumented even in the template book; the dip 1010 code block that *may* be why this behavior exists doesnt actaully work, the docs were wrong a week ago etc. etc. currently I believe: a) static makes it a block, makes enum or alias infered b) enum or alias of aliasSeq, whoever made thought there be an upgrade to fully generalize the syntax c) the dip 1010 section was ambiguous if it was real causing enum to be ignored anyone got any code blocks?
Aug 01
On Friday, 1 August 2025 at 13:51:43 UTC, monkyyy wrote:```d import std; void foo(int i:0)()=>"foo".writeln; void foo(int i:1)()=>"bar".writeln; void foo(int i:2)()=>"foobar".writeln; void main(){ foreach(i,alias b; AliasSeq!("foo","bar")){ pragma(msg, b.stringof); break; } pragma(msg,"---"); foreach(i,enum b; AliasSeq!("foo","bar")){ pragma(msg, b.stringof); break; } pragma(msg,"---"); static foreach(i;0..3){ pragma(msg, i.stringof); //break; //the scope error }Up to here is all as expected, right?pragma(msg,"---"); foreach(enum i;0..3){// ERROR ISNT CT. ISNT AN ENUM pragma(msg, i.stringof); //foo!i; //doesnt compileYou're using runtime foreach here. It's only expanded at compile-time when the aggregate is a sequence - as the spec says. The confusing thing is that enum there is silently ignored. I think we could add an error for that.break; } } ``` Theres bugs and unintended features here :D ; alias foreach is undocumented even in the template book;That hasn't been updated in 8 years.the dip 1010 code block that *may* be why this behavior exists doesnt actaully work, the docs were wrong a week ago etc. etc. currently I believe: a) static makes it a block, makes enum or alias infered b) enum or alias of aliasSeq, whoever made thought there be an upgrade to fully generalize the syntaxNot sure what you mean for (b).c) the dip 1010 section was ambiguous if it was real causing enum to be ignored anyone got any code blocks?
Aug 01
On Friday, 1 August 2025 at 15:15:35 UTC, Nick Treleaven wrote:Up to here is all as expected, right?No, `foreach(alias` is functionally undocumented (dip 1010 is not exactly common reading material for current year, and if you did read it, it would have errors or misunderstanding for what eventually happened) and extremely rare`foreach(enum i;0..3){` is directly from the dip 1010 its unclear from the responce if it was accepted or rejectedpragma(msg,"---"); foreach(enum i;0..3){// ERROR ISNT CT. ISNT AN ENUM pragma(msg, i.stringof); //foo!i; //doesnt compileYou're using runtime foreach here. It's only expanded at compile-time when the aggregate is a sequence - as the spec says.dip 1010 was optimistic about near term upgrades to static foreach; static break and continue ---b) enum or alias of aliasSeq, whoever made thought there be an upgrade to fully generalize the syntaxNot sure what you mean for (b).The confusing thing is that enum there is silently ignored. I think we could add an error for that.That would be a breaking change now, most code swapped from runtime to ct should continue working tho, better to just implement it
Aug 01
On Friday, 1 August 2025 at 15:47:47 UTC, monkyyy wrote:On Friday, 1 August 2025 at 15:15:35 UTC, Nick Treleaven wrote:Thanks, fix: https://github.com/dlang/dlang.org/pull/4279Up to here is all as expected, right?No, `foreach(alias` is functionally undocumentedThat's under the 'Limitations of this DIP / possible future improvements' section: https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1010.md#allowing-alias-and-enum-on-regular-foreach-loop-variables`foreach(enum i;0..3){` is directly from the dip 1010 itspragma(msg,"---"); foreach(enum i;0..3){// ERROR ISNT CT. ISNT AN ENUM pragma(msg, i.stringof); //foo!i; //doesnt compileYou're using runtime foreach here. It's only expanded at compile-time when the aggregate is a sequence - as the spec says.unclear from the responce if it was accepted or rejectedThat DIP says 'Status: Accepted' at the top.Not really, no one should have used enum/alias with a non-static ForeachRangeStatement because (as you pointed out), it wasn't in the spec. If they did use it, they'd probably realize that those storage classes had no effect.dip 1010 was optimistic about near term upgrades to static foreach; static break and continue ---b) enum or alias of aliasSeq, whoever made thought there be an upgrade to fully generalize the syntaxNot sure what you mean for (b).The confusing thing is that enum there is silently ignored. I think we could add an error for that.That would be a breaking change now, most code swapped from runtime to ct should continue working tho, better to just implement it
Aug 01
On Friday, 1 August 2025 at 16:45:04 UTC, Nick Treleaven wrote:On Friday, 1 August 2025 at 15:47:47 UTC, monkyyy wrote:Making non-static `foreach (enum x; l .. u)` an error would be fairly easy. It’s just a parser issue. The error message could say: Use `static foreach`. I’ll have a go on this.On Friday, 1 August 2025 at 15:15:35 UTC, Nick Treleaven wrote:Not really, no one should have used enum/alias with a non-static ForeachRangeStatement because (as you pointed out), it wasn't in the spec. If they did use it, they'd probably realize that those storage classes had no effect.The confusing thing is that enum there is silently ignored. I think we could add an error for that.That would be a breaking change now, most code swapped from runtime to ct should continue working tho, better to just implement it
Aug 01
On 8/1/25 20:06, Quirin Schroll wrote:On Friday, 1 August 2025 at 16:45:04 UTC, Nick Treleaven wrote:For reference: https://github.com/dlang/dmd/issues/21630 https://github.com/dlang/dmd/pull/21631 https://github.com/dlang/dmd/pull/21633 My PR is currently blocked on a weird CI failure, not sure where it is coming from.On Friday, 1 August 2025 at 15:47:47 UTC, monkyyy wrote:Making non-static `foreach (enum x; l .. u)` an error would be fairly easy. It’s just a parser issue. The error message could say: Use `static foreach`. I’ll have a go on this.On Friday, 1 August 2025 at 15:15:35 UTC, Nick Treleaven wrote:Not really, no one should have used enum/alias with a non-static ForeachRangeStatement because (as you pointed out), it wasn't in the spec. If they did use it, they'd probably realize that those storage classes had no effect.The confusing thing is that enum there is silently ignored. I think we could add an error for that.That would be a breaking change now, most code swapped from runtime to ct should continue working tho, better to just implement it
Aug 01
On 8/1/25 15:51, monkyyy wrote:```d import std; void foo(int i:0)()=>"foo".writeln; void foo(int i:1)()=>"bar".writeln; void foo(int i:2)()=>"foobar".writeln; void main(){ foreach(i,alias b; AliasSeq!("foo","bar")){ pragma(msg, b.stringof); break; } pragma(msg,"---"); foreach(i,enum b; AliasSeq!("foo","bar")){ pragma(msg, b.stringof); break; }These behave like lined out in Proposal 1 of DIP 1010. Code snippets from the DIP: ```d foreach (enum v; AliasSeq!(x,y,z)) { ... } ``` ```d foreach (alias v; AliasSeq!(x,y,z)) { } ``` https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1010.md#proposal-1-allow-enum-and-alias-variables-for-unrolled-foreach-statementspragma(msg,"---"); static foreach(i;0..3){ pragma(msg, i.stringof); //break; //the scope error } pragma(msg,"---");This is just a standard `static foreach`.foreach(enum i;0..3){// ERROR ISNT CT. ISNT AN ENUM pragma(msg, i.stringof); //foo!i; //doesnt compile break; } } ``` ...This one is a bug, quote from DIP1010:Currently, it is an error to use alias or enum on a regular foreach loop: ```d foreach (enum i; 0 .. 3){ ... } // error ``` It has been suggested that this should instead unroll the loop, suchthat it becomes equivalent to:```d foreach (enum i; AliasSeq!(0,1,2)) { ... } ```https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1010.md#allowing-alias-and-enum-on-regular-foreach-loop-variables https://github.com/dlang/dmd/issues/21630 https://github.com/dlang/dmd/pull/21631
Aug 01