extending foreach for keyed ranges and other usage of datastructures

Nick Treleaven nick at geany.org
Thu May 16 12:16:46 UTC 2024


On Wednesday, 15 May 2024 at 20:27:12 UTC, monkyyy wrote:
> extend the api of foreach to allow for 
> `foreach(key,value;data)` for user data types,

You can already have multiple variables using `opApply`, or for a 
range where front returns a tuple.

https://dlang.org/spec/statement.html#front-seq

For the front tuple case, it doesn't support `ref value` well.

> 2. if the data is a keyd range but the foreach header has a 
> key; define key to be range.key and value to be range.front; 
> handle ref if possible

> ### keyd range example code
>
> ```d
> struct strangecounter{
>   int front;
>   int last;
>   void popFront(){front++;}
>   int key()=>front*front;
>   bool empty()=> last>=front;
> }
> foreach(k,v;strangecounter(0,10)){
>   writeln(k,":",v);//0:0, 1:1, 4:2,9:3.....
> }
> ```
>
> `foreach(ref k,v;strangecounter(0,10))` would fail to compile, 
> some complaint about lvalues or suggesting the user to define a 
> `torange!("ref",void)`
> `foreach(k,ref v;strangecounter(0,10))` would compile

`ref k` could work if `key()` is an lvalue, although I'm not sure 
if there are any data types where that makes sense.
`ref v` can work if `front` is an lvalue, otherwise it should be 
an error.

> `foreach(v;strangecounter(0,10))` would compile (using keys are 
> optional)

It may be less efficient for certain ranges to track what the 
current key is when the foreach statement doesn't need it. Also 
when iterating the range and the user doesn't need `.key`.




More information about the dip.ideas mailing list