Generic const - a non-functional view
Steven Schveighoffer
schveiguy at yahoo.com
Wed Jun 25 10:05:08 PDT 2008
"Jason House" wrote
> Steven Schveighoffer Wrote:
>
>> "Jason House" wrote
>> > A lot of times, when I think about tail const/mixed const/mutable/...,
>> > I
>> > start thinking about arrays.
>> > AKA:
>> > T[] vs. array!(T)
>> > const(T)[] vs. array!(const(T)) vs. const!(element)(array!(T))
>
> I probably should have stated that arrays have special status in D. As
> built in containers, they have support for for tail const while other
> objects don't have that luxury. I implicitly measure the quality of a
> const proposal by how it can implement an alternate to arrays without the
> syntactic sugar arrays provide.
Ah, I now understand what you meant. Yes, it can be done, just like you
say.
const alias element;
class array(T){
typedef element(T) elem;
elem[] contents; // same as elem contents[] I think
}
the tag is not in itself const. It is a noop when not selected for
const/invariant.
So array!(T) becomes:
{
typedef T elem;
elem[] contents;
}
And const!(element)(array!(T)) becomes:
{
typedef const(T) elem;
elem[] contents; // which is now const(T)[]
}
>> or const!(element)(T)[]
>>
>> or
>>
>> alias const!(element) eleconst;
>>
>> eleconst(T)[]
>
> What's the difference between const!(element)(T)[] and const(T)[]? I
> believe this is more a misunderstanding of what I was driving at.
Yes, I misunderstood you. const!(element)(T)[] and const(T)[] are different
depending on what T is. If T is a struct:
struct T
{
element int x;
int y;
}
Then const(T) yields:
{
const int x;
const int y;
}
and const!(element)(T) yields:
{
const int x;
int y;
}
> Consider this template:
>
> class array(T){
> typedef element T elem;
> elem contents[];
> }
>
> Maybe I got the syntax wrong, but the basic idea is that T and element are
> really the same kind of thing. array!(const T) and
> const!(element)(array!(T)) are different types. Should they be? I don't
> think so. There's still something buried in a tail const scheme that
> still needs to get fleshed out, somehow...
Tail const is much more possible with the const scheme I outlined. Your
example is not really relevant because the entire set of members is marked
by a tag. This is no different than today's const.
Basically, as a simple rough explanation, what I propose allows you to
direct const to apply only to certain pieces of a struct or class, instead
of always affecting the whole thing. Tail const is possible because you can
tag only the 'pointed to' data and const-ify only that part.
Another aspect is this:
array!(T) and array!(const T) are not implicitly castable, because they are
two separate types. e.g.:
array!(T) t = new array!(T)(5); // array of 5 Ts
const(array!(T)) t2 = t; // ok, t2 is the same type, but with a const
modifier.
array!(const T) t3 = t; // error, incompatible types
const!(element)(array!(T)) t4 = t; // ok, because t4 is the same type, but
with a const modifier.
-Steve
More information about the Digitalmars-d
mailing list