The in operator (along with other things) is designed poorly.

Ruby The Roobster michaeleverestc79 at gmail.com
Tue May 31 00:16:46 UTC 2022


# The in operator is designed poorly.

Don't get me wrong, I know that nothing is perfect, and that 
making a programming language is hard, and that there will be 
less-than-optimal features.  However, here are several such 
features that made me find annoying work-arounds. and they will 
be mentioned here.

## The in operator being a pointer.

Operators that can yield an expression evaluable at compile-time 
should not return a type who's value can only be known at run 
time.  The in operator returns a pointer, resulting in the 
following not working:

```d
import std.stdio;

void main()
{
     static if(0 in [0: 0]) //This expression should be true.
     {
         writeln(typeof(0 in [0: 0]).stringof);
     }
}
```

This code fails to compile, because the in operator returns a 
pointer, who's value cannot be known at compile time.  Note that 
the code will compile if you replace the expression being 
evaluated with 1 in [0: 0], because it evaluates to null.  Due to 
this poor design,  to get the code to compile you have to do the 
following:

```d
//This program prints int* to stdout.
import std.stdio;

void main()
{
     static foreach(k; [0: 0])
     {
         static if(k == 0)
         {
             writeln(typeof(0 in [0: 0]).stringof);
         }
     }
}
```

## Operator overloads not being retrieved by 
__traits(getOverloads, ... , ... ).

This is the other annoying feature that I encountered today.  
Take the following code:

```d
class C
{
     this(int m)
     {
         this.m = m;
     }
     public C opBinary(string op)(C rhs)
     {
         mixin("return new C(this.m " ~ op ~ " rhs.m);");
     }
     int m;
}

void main()
{
     import std.stdio;
     writeln(__traits(getMember, C, "opBinaryRight")); //false
     writeln(__traits(getOverloads, C, "opBinary")); //You would 
expect the output to be "(C(string op)(C rhs))".  Instead what is 
printed is ().
}
```

In other words, you can determine whether an operator is 
overloaded, but you cannot get the total list of overloads of 
that operator.  What if you need to know if there is a shared 
version?  Too bad, you're going to have to use __traits(compiles) 
to figure it out (though admittedly, it IS easier to use 
__traits(compiles) to figure this out, it still makes no sense 
that __traits(getOverloads) doesn't work on operator overloads 
while everything else does.)


More information about the Digitalmars-d mailing list