New operators opStaticIndex and friends

Q. Schroll qs.il.paperinik at gmail.com
Tue May 14 15:49:51 UTC 2019


I whish, D has these operators:

opStaticIndex
opStaticIndexAssign
opStaticIndexOpAssign
opStaticSlice

When used, they look the same way as opIndex and friends, but the 
stuff between [ and ] would be bound to template parameters 
(instead of runtime parameters) and be known at compile time. 
Basically, this allows to implement static indexing the same way 
it is possible for an AliasSeq.

Furthermore, it is possible to have static and dynamic indexing 
next to each other. This is supported by static-size arrays (e.g. 
int[3]) only: https://run.dlang.io/is/99g01e

Implementing e.g. tuple-like structures, it would be valuable to 
have both. Dynamic indexing would only be present (design by 
introspection) if the contents support it.

   struct S
   {
     enum int opStaticIndex(int index) = index + 1;
     int opIndex(int index) { return index + 1; }

     enum size_t[2] opStaticSlice(size_t i, size_t j) = [ i, j ];

     void opStaticIndexAssign(int index)(int value);
     void opStaticIndexAssign(int i, int j)(int value);
     void opStaticIndexAssign(size_t[2] slice)(int value);
     void opStaticIndexOpAssign(string op, int index)(int value);
   }

   S s;
   int i = s[0]; // rewrites to s.opStaticIndex!(0), as 0 can be 
used for the template parameter
   int j = s[i]; // rewrites to s.opIndex(i), as i cannot be read 
at compile-time

The "Static" variants would be preferred when determining which 
one to lower to.

s[0] = 1; // rewrites to s.opStaticIndexAssign!(0)(1)
s[0, 2] = 1; // rewrites to s.opStaticIndexAssign!(0, 2)(1)
s[0 .. 2] = 1; // rewrites to 
s.opStaticIndexAssign!(s.opStaticSlice!(0, 2))(1)
s[0] += 1; // rewrites to s.opStaticIndexOpAssign!("+", 0)(1)
s[0, 2] += 1; // rewrites to s.opStaticIndexOpAssign!("+", 0, 
2)(1)

Currently, there is no way to implement custom compile-time 
indexing. Only using alias-this to an AliasSeq can do something, 
but is very limited. The alias-this is shadowed by any presence 
of opIndex.

An alternative would be a `static` or `enum` storage class for 
function runtime parameters that only bind to values known at 
compile-time.
These have been proposed years ago and would not only solve this 
but also format!"fmt" vs. format(fmt) and friends.

I have no knowledge about the DMD implementation, but I'd 
intuitively expect that new operator rewrites would be much less 
work to implement.

Do you want it? Do you see problems? Should I clarify something? 
Is it worth writing a DIP?


More information about the Digitalmars-d mailing list