hacks on opApply

Steven Schveighoffer schveiguy at gmail.com
Thu Aug 28 00:49:24 UTC 2025


On Wednesday, 27 August 2025 at 20:34:22 UTC, monkyyy wrote:
> spec doesn't define this behavior as far as I can tell
>
> ```d
> import std;
> auto loop(){
> 	struct foreach_{
> 		int opApply(int delegate(int i) dg){
> 			dg(0).writeln;//1
> 			dg(1).writeln;//2
> 			dg(2).writeln;//3
> 			return 3;
> 	}}
> 	return foreach_();
> }
> unittest{
> 	a: while(true){
> 	b: foreach(i;loop()){
> 		if(i==0){break;}
> 		if(i==1){break b;}
> 		if(i==2){break a;}
> }}}
> ```
>
> rn I believe you could pretty reasonably overload the behavior 
> of break in a crafted opApply to make a 2d iteration
>
> it should be possible to modify ref indexs and other stateful 
> things that are tricky with pure ranges
>
> slight errors produce infinite loops tho and this is like the 
> 3rd opApply ive ever written, no idea on stable patterns

For a valid `opApply` you need to continue looping as long as the 
delegate returns 0.

If the delegate returns something other than 0, then you have to 
return that value from `opApply`. If you don't, the behavior is 
not defined. Even what the different values do is not defined or 
specified.

If you reach the end of your data that you are looping, and the 
final delegate call returned 0, then you return 0.

How you loop is defined by you. So calling the delegate in 
different ways is OK, but continuing on a non-zero value is not 
valid.

Relevant spec information (see paragraph 5):

https://dlang.org/spec/statement.html#foreach_over_struct_and_classes

-Steve


More information about the Digitalmars-d mailing list