On Wed, 29 Sep 2010 15:16:28 -0400, Jonathan M Davis <jmdavisp...@gmx.com> wrote:

On Wednesday, September 29, 2010 11:54:30 Steven Schveighoffer wrote:
I think it may have to be more than just const:

class C(T)
{
    static T globalval;
}

class A {}
class B : A {}

void foo(C!B c)
{
   const(C!A) c2 = c;
   c2.globalval = new A;
}

If the entire class is marked as pure (with pure defined as weak purity a
la Don's idea) that might work as setting globalval would be illegal.

Ah. Once you get beyond arrays, you have the issue of the container type itself being different. Hmmm. For C#, you might be okay since they're all technically the same type anyway (and would share any globals), but for D, the two types could have absolutes nothing in common with one another. All class variables would be by definition local to each instantiation, so no const would not be
enough.

But worse still, consider this: With templates, you could have a container type which used completely different implementations depending on the type(s) you use
to instantiate it.

Excellent point. If this *were* a feature we wanted, the compiler would have to make that determination (I think it could be done, but I'm not sure of all the nuances).

It could use an array for ints, a hash table for floats, and a
red-black tree for everything else.

Wait, the types have to be bit-for-bit compatible, or it doesn't work. You can't cast floats to ints without reinterpreting the data.

I don't even think you could do classes to interfaces, because you need to do a translation.

In such a case, would would it even _mean_
to try and assign one container type to another? Sure, if they're classes, and they share the same API, you may be able to get it to work thanks to the fact
that you're dealing with references.

No, even with that, you brought it up earlier -- class C could say:

static if(is(T == A))
   void anotherfunction() {}

and then the vtable for C!B is different than C!A, even though the vtable for B is compatible with the vtable for A.

There has to be some way for the compiler to determine this, but again, only if this feature makes sense to implement.

But for structs? Forget it. Just because
the types Array!int and Array!float are instantiated from the same template
doesn't mean that they have anything in common other than the base name.

For floats and ints, yes. But this doesn't even matter, because it has to be bit-for-bit compatible. There's no way you could case S!int to S!float without having to translate everything.

Something like Array!int to Array!(const int) would be feasible.

The
only way that you can even consider having containers be effectively in an inheritance hiercharcy because their elements are in an inheritence hiearchy is if the containers are classes. And since it looks like most - if not all -
containers in Phobos are going to be structs

All containers in dcollections are classes ;)

it quickly becomes a moot point
for anything but arrays. With arrays, you could do it with just constness, I think. But for other container types? It _might_ be feasible with classes if you could somehow restrict access to all of their class variables and non-pure,
static member functions, but it_won't work for structs.

I think it can be done, but it may require really strict rules, and those rules may not be assertable without some new syntax.

For example, one place where this can be extremely useful is tail-const. If S!(T) implicitly casts to S!(const(T)), then we can implement tail-const in the library (though I'd prefer a compiler solution).

-Steve

Reply via email to