Is alias equality inconsistent?

Timon Gehr timon.gehr at gmx.ch
Sat May 14 03:44:35 PDT 2011


> On 2011-05-13 17:28, Timon Gehr wrote:
> > > The only value of is and static arrays that I can think of is if you can
> > > use them to verify whether a dynamic array refers to a particular static
> > > array. Other than that, what value do they add? If you're checking for
> > > equality, then use ==. That one use case may make it useful to allow for
> > > is in comparing static and dynamic arrays, but other than that, I don't
> > > really see what is gives you when comparing static arrays.
> > >
> > > - Jonathan M Davis
> >
> > is on static arrays compares ptr and length too. So it is different from
> > ==.
>
> And of what value is that? == should already doing that before checking for
> equality on each of the elements, because if the ptr and length are identical,
> then there's no point checking the elements for equality. So, is doesn't add
> any benefit there, unless == is poorly implemented for static arrays.

== currently checks length but not ptr for both static and dynamic arrays.

>
> Static arrays are value types, not reference types, so checking whether two of
> them refer to the same array makes no sense. Checking whether a dynamic array
> refers to a static array makes sense, but checking whether two static arrays
> are the same array does not. And since == should shortcut when comparing a
> static array to itself (heck, the compiler should be able to optimize the
> check out entirely and replace it with true), I don't see how using is on two
> static arrays does anything for you at all.
>
> - Jonathan M Davis

Ah, thats what you are referring to. Yes, 'is' on two static arrays can be
resolved entirely on compile time.
And disallowing 'is' for static arrays is actually one check more in the compiler,
so the compiler gets slightly more complicated. This works against D's goals ;).
Apart from that, saying that dynamic arrays are reference types and ergo 'is'
makes sense is somewhat incomplete, because they are actually value types
(structs) with some reference-like behavior:

//does not change its argument
void foo(int[] a){
    a.length=3*a.length;
    a[0]=10029;
}
//this does (but it cannot take a static array)
void foo(ref int[] a){
    a.length=3*a.length;
    a[0]=10029;
}

It is not beautiful but practical... Same goes for some reference-like behavior of
static arrays. You can think of static arrays as being the same as dynamic arrays
except that they define a postblit operator and cannot be resized. You can also
think of them as being structs that embed all the data and define opBinary("is").
The current semantics of static arrays allow both interpretations if you do not
want to get too low level.


What about static array references by the way? With ref arguments static and
dynamic arrays even have similar semantics (except that you cannot change the
length of a static array).

But ref arguments are a different beast. 'is' does not work as may be expected by
some:

bool bar(ref int a, ref int b){
    return a is b;
}

void main(){
    int x=0,y=1;
    assert(!bar(x,y));
    x=1;
    assert(bar(x,y));
}

Again, if you understand that value types are similar to immutable references, it
makes sense. But I think that this behavior could as well be changed.


Besides: consider a little analogy:

if(x==y){..} //fine.
if(x==1){..} //fine.
if(2==y){..} //fine.
if(2==1){..} //there for completeness

Just because you do not want to write 2==1 so often, do you want to remove it from
the language? And then you would remove x==1 and 2==y too?


I think what D is doing now feels right and consistent.

Timon


More information about the Digitalmars-d mailing list