extending foreach for keyed ranges and other usage of datastructures

monkyyy crazymonkyyy at gmail.com
Thu May 16 16:07:07 UTC 2024


On Thursday, 16 May 2024 at 12:16:46 UTC, Nick Treleaven wrote:
> 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.

which only work with 1 configuration and doesnt provide the 
explicit "implicit casting" options; its a single function 
iteration api when ranges being a 3 function api is just clearly 
superior

>
> 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.
>

I meant those as specif results of the code above it, that key 
isnt a ref function

ref keys mutating the range is a rabbit hole that while I 
support, I can easily use work arounds and it would scare the 
very people who feel that foreach(int i...) is somehow an 
"implict" cast and that should have been deprecated

>> `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`.

I want keys in ranges in general if theres some major reason to 
not have keys you could have two different "range starters" much 
like trees having depthfirst or breathefirst ranges (I cant 
imagine it being that slow, either your poking an int or 
forwarding the hashmap keys outward)


More information about the dip.ideas mailing list