New operators opStaticIndex and friends

Q. Schroll qs.il.paperinik at gmail.com
Tue May 14 19:10:05 UTC 2019


On Tuesday, 14 May 2019 at 18:13:18 UTC, Ahmet Sait wrote:
> On Tuesday, 14 May 2019 at 15:49:51 UTC, Q. Schroll wrote:
>> I whish, D has these operators:
>>
>> opStaticIndex
>> opStaticIndexAssign
>> opStaticIndexOpAssign
>> opStaticSlice
>
> I think this is solving the wrong problem.

Maybe. I'll try to clarify what problem is being solved.

Current state of D: Let seq be some AliasSeq. Indexing it looks 
like this:

     auto value = seq[i];

Here, the compiler must evaluate `i` at compile-time (cf. H. S. 
Teoh's link) to even get the type of value correctly.

Let arr be some slice (aka. "dynamic array"), e.g. a value of 
int[]. Indexing it looks like this:

     auto value = arr[i];

Wow, they look identically, but mean completely different things! 
What an incident.

You can make the latter work in your custom type (notably 
random-access ranges) by providing opIndex and companions.

However, you cannot provide the former functionality for your 
custom type. The suggested operators would solve that without 
interrupting the rest of the language.

> If compiler provided means to check whether a parameter is 
> known at compile time easily & consistently these would not be 
> necessary at all

What kind of parameter? A template parameter is known at 
compile-time by definition and a function (run-time) parameter by 
definition is not. The new operators won't change that.

> Of course, talk is cheap and actually implementing such new 
> __traits is rather compilcated.

This is no kind of __traits. I don't think the problem could be 
solved nicely with such __traits if it existed.

The alternative were a parameter *storage class*:

     T opIndex(static size_t i); // alternative to opStaticIndex
     T opIndex(       size_t i);

An illustrative example:

     void format(static string fmt, ...); //1
     void format(       string fmt, ...); //2

You'd have both overloads. //1 is viable, when the first 
parameter can be evaluated at compile-time. It could check at 
compile-time if the arguments' types match the format. //2 is 
always viable, but //1 is considered a better match for a 
compile-time format string. The `static` storage class would make 
the parameter semantically equivalent to a template parameter 
inside the `format` function. Outside, it would be called using 
the same syntax, i.e.

     string s1 = format("The %s-th component", i); // calls //1
     string s2 = format(readln(), i); // calls //2

You basically could overload on the compile-time availableness of 
parameters. There is no __traits to be involved. Even without 
compiler knowledge, I strongly believe that this is more 
complicated, apart from being a major change of the language.


More information about the Digitalmars-d mailing list