D const design rationale
Sean Kelly
sean at f4.ca
Sat Jun 23 08:43:43 PDT 2007
Daniel Keep wrote:
>
> Sean Kelly wrote:
>> Daniel Keep wrote:
>>> final int x; typeof(x) == int;
>>> const int y; typeof(y) == const int;
>>> final const int z; typeof(z) == final const int;
>> Hm. Just to clarify, we both agree that the value of a final integer
>> (ie. case 1 above) is effectively constant, correct?
>
> Indeed.
>
>>> "Wait; why is final part of the last type, but not the first?" And what
>>> does this mean if you want a class member with final-style binding, but
>>> (final const) type semantics?
>>>
>>> final (final const(int*)) foo;
>>>
>>> As opposed to
>>>
>>> final invariant(int*) foo;
>> Perhaps I'm missing something, but I would rewrite this as:
>>
>> final const int* foo;
>>
>> Thus foo cannot be reassigned once set and the data foo refers to may
>> not be changed through foo. This is a slightly weaker guarantee than:
>>
>> final invariant int* foo;
>>
>> Which says that the data foo refers to is immutable, but I am skeptical
>> that this guarantee actually matters much to users.
>>
>> Or am I completely misunderstanding? And why the parenthesis in the
>> second declaration?
>
> (When I wrote the below, I missed precisely what you were saying: the
> problem with writing it at "final const int*" is that you've got both
> final and const as a storage class; I assumed you were using them as a
> type constructor.)
>
> Ok, let's try this instead: in the current system, we have
>
> class Foo
> {
> final invariant(FunkyType) funky;
>
> this(bool superFunky)
> {
> if( superFunky )
> funky = cast(invariant) new FunkyType;
> else
> funky = some_global_invariant_funky;
> }
> }
>
> In this case, we have a final storage (so we can assign the value during
> the ctor), and an invariant(FunkyType) value type.
>
> Under your proposal, invariant is replaced with (final const); if we
> want the above, it'd become:
>
> final final const(FunkyType) funky;
Under my proposal, this would be:
final const FunkyType funky;
> But how does the compiler tell that second final is storage class or
> part of the type constructor? Remember, we could be dealing with a
> template that's just shoving "final" out the front of things, so we
> can't assume two finals ==> one is a type constructor. So we'd probably
> have to do this:
>
> final (final const(FunkyType)) funky;
Hm. I'm afraid I don't understand all this talk about type constructor
vs. storage class. What I get from the above is that:
final const FunkyType funky;
represents a fixed reference to an instance of FunkyType, which cannot
be changed through the reference.
> We can't use *just* "final const FunkyType funky" because then we'd have
> an "invariant" storage class: which means the initialiser would have to
> be a compile-time constant.
Why would it have to be an "invariant" storage class? It seems I'm
missing something fundamental here.
> Incidentally, the above is also probably
> equivalent to:
>
> final(final const(FunkyType)) funky;
>
> Which really doesn't make any sense anyway...
>>> I think the thing here is that you're shifting the complexity from
>>> invariant into final; instead of invariant meaning two different things
>>> with two very different appearances, you've got final meaning two
>>> slightly different things with almost identical looks.
>> I only see final meaning one thing: that the associated value may not be
>> reassigned. For concrete types like integers this is effectively the
>> same as const, but as Walter said, the integer would be addressable when
>> final but not when const. Perhaps this is the source of confusion?
>>
>
> Yes, but it *also* means "can assign to in a ctor".
Right. That's compatible with what I said. It can be assigned in a
ctor but not *reassigned* once assigned. Just like 'const' in D 1.0.
> Like Lars said, I do think that if there's a way to simplify or
> consolidate this, then we should take it. That said, I can see a use
> for each of the various cases the new system allows for, and I don't
> want to see any of them cut off in the name of "well *I'm* not going to
> use it, and I don't like that keyword, so it has to go!"[1]. :)
I agree.
Sean
More information about the Digitalmars-d
mailing list