New operators opStaticIndex and friends

Q. Schroll qs.il.paperinik at gmail.com
Sat May 18 01:23:51 UTC 2019


On Friday, 17 May 2019 at 19:52:53 UTC, Exil wrote:
> On Friday, 17 May 2019 at 17:41:26 UTC, Q. Schroll wrote:
>> On Thursday, 16 May 2019 at 22:26:34 UTC, Exil wrote:
>>> This doesn't help with the explanation, what special syntax? 
>>> Maybe an example that works with opStaticIndex and that 
>>> wouldn't work with opIndex would help. Otherwise I still 
>>> don't see a problem.
>>
>> Simple answer is: You cannot overload opIndex aliasing a data 
>> member and opIndex being a function. If it is a function 
>> somewhere, it *must* always be a function in that aggregate 
>> (struct/union/class/interface).
>
> That's what template specialization is exactly for. Exactly how 
> it can be used:

Do you really mean specialization? I'm asking as you don't use it 
in your following example. Maybe you mean instantiation? I just 
want to make sure we're talking about the same thing.

> struct A {
>
>     template opIndex(int i) {
>         static if (i == 0) alias opIndex = member1;
>         else alias opIndex = member2;
>     }
>
>     int member1;
>     double member2;
>
>
>     int opIndex(int a, int b) { return 0; }
>
>     int opIndex(T...)(T a) { return 1; }
>
> }
>
> void main() {
> 	A a;
>
>     a[0,0];
>     a[0];
>
>     a.opIndex!0 = 10;   // a[0] = 10
>     a.opIndex!1 = 10.1; // a[1] = 10.1
>
>     writeln(a.member1, a.member2);
> }

I'm sorry, but I don't get what you want to show me. I strongly 
believe that you have a point somewhere and I'm just not seeing 
it. I've just tried out that code piece and it worked to my 
surprise.

I honestly think now, it's actually possible. The question 
remaining is: Is it really better or rather too complicated?

In the current form of the DIP, if you'd use a type as index, 
it'd compile. I'll change that, because that's not how it's meant 
to be.

I find it really difficult to say if widening the abilities of 
opIndex to opStaticIndex can be done. There are so many corner 
cases. That's mainly why I proposed a new compiler-recognized 
name: It's the safe option.

In the current state of D, opIndex must be callable to trigger 
the rewrite; being present as member is insufficient. As a simple 
example, if you use std.typecons.Tuple with a member namend 
"opIndex" of type int, you still can do everything you'd expect 
from a tuple with reasonable field names. Notably, it doesn't 
invalidate static indexing. But make "opIndex" of type `int 
delegate(/*whatever you like*/)`, and the Tuple is unusable: 
https://run.dlang.io/is/BuiT2a
It's somewhat artificial and not a reason for the DIP. Sure, 
naming a member "opStaticIndex" would break the tuple, too.

>> It is more flexible not having a name clash. It's easier to 
>> learn and reason about, too. To me, it has literally no 
>> benefit using opIndex for static indexing.
>>
>> Part of a working example: https://run.dlang.io/is/274pNN
>
> So what if you have 2 parameters, one is a runtime value and 
> the other is a compile time value? Would it be a compile error 
> then? But then you can implement opIndex and opStaticIndex, so 
> you can use two runtime values and two compile time values but 
> if for some reason you need one, instead you will need some 
> hacky work around to get it to work:
>
>     arr[ 0, someRunTimeIndex() ] = 10; // error mixing 
> compile-time and run-time
>
>     int i = 0;
>     arr[ i, someRunTimeIndex() ] = 10; // ok

To use a template, you need *all* arguments at compile-time. 
Otherwise it's lowered to a run-time indexing operation no matter 
how many arguments are present at compile-time.

The first call (// error mixing) is not a problem. The fact that 
some values could be used as a template parameter is irrelevant. 
The question is: Does the template instantiation work? And the 
answer is no. That's where double indexing, e.g. tup[0][1] versus 
tup[0,1] makes a real difference. If you really need mixing sorts 
of arguments, that's the way I'd do it.

Mixing is not an error. Mixing is just run-time.


More information about the Digitalmars-d mailing list