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