Extended Type Design.

Andrei Alexandrescu (See Website For Email) SeeWebsiteForEmail at erdani.org
Fri Mar 16 10:55:14 PDT 2007


Derek Parnell wrote:
> On Fri, 16 Mar 2007 02:25:24 -0700, Andrei Alexandrescu (See Website For
> Email) wrote:
> 
>> Derek Parnell wrote:
>>>>> int a;
>>>>> const! int* p = &a; // error! cannot convert int* to const! int*
>>>>> final int b = 42;
>>>>> const! int* p1 = &b; // yah, b is truly immutable
>>>>> const! int* p2 = new const! int; // yah
>>> I'm not sure about that last one. Does this mean that p2 points to an int
>>> that cannot change and p2 itself can no longer be changed? And what is the
>>> value in the int that p2 points to?
>> Good point. 
> 
> <G> But you didn't answer my question? What is the value of the int to
> which p2 is pointing?

The default value of int, which is zero.

>> There is a little exception here. 
> 
> Oh no ... alarms start to sound when I see 'exceptions'. Is it not possible
> to eliminate this exception?

I would love to. It is only for the sake of compatibility with existing 
code.

>> People expect that when 
>> they write:
>>
>> const char[] str = "Hi!";
>>
>> they can't modify str nor its characters. So they expect str to be final 
>> as well. We then arrange that if const appears in a data definition, 
>> that data is automatically made final as well. So the above is 
>> equivalent to:
>>
>> final const char[] str = "Hi!";
> 
> Are you saying "People expect that when they write ... and so that's what
> we are going to have D do for them."?

I was just trying to minimize the amount of broken code. Also, we need 
to figure what to do about this:

const int capacity = 80;

In this context const makes no sense because int does not contain 
pointers. The above should be:

final int capacity = 80;

> Let's see if I got this ...
> 
>   const char[] str = "Hi!";  // Neither 'str' nor it contents can
>                              // be changed.
>   final const char[] str2 = "Hi again"; // Means the same as above syntax.

Correct.

>   const char*  chr = "Hi!";  // 'chr' can be changed but the chars
>                              // it points to cannot be changed.

Correct. The pointer can be made to point anywhere, but it's looking, no 
touching.

>   final const char*  chr2 = "Hi!";  // 'chr2' can be not be changed
>                                // and neither can its chars.

Yes.

> I hope I got this wrong because that is a easy bug maker.

How would the bugs be introduced?

>> If you don't want str to be final, do this:
>>
>> const(char[]) str = "Hi!";
> 
> You have got to be kidding! This is starting to get unreadable again. As a
> simple person, if I didn't want something to be 'final', I wouldn't use the
> 'final' keyword.

The problem is that many simple persons have different simple needs.

The parens actually help readability a lot when compared to C++ because 
you don't need to put several const's for complex types.

> But you are saying that if I don't want 'final', I not
> only have to avoid using 'final', I also have to put some of the phrase
> (and I know I'll never remember which parts) in parenthesis. But wait ...
> there's more. If I do want it to be 'final' all I have to do is not use the
> 'final' keyword.  Am I getting this right?
> 
> Is it not possible to make reading code simple?

An intuition that I see reasonable is that const by default engulfs 
everything to its right:

const char[] str = "Hi!"; // same as const(char[] str) = "Hi!";

When it engulfs the symbol, it makes it immutable, hence final. So by 
putting the parens you limit const's power.

But I'd be glad to drop this exception. I'm not sure what Walter and 
people who'll have to modify their code would say though.

>>> Hmmmm... does "const char[] X" mean that X.ptr can change, X.length can
>>> never change and the data pointed to by X.ptr can never change? Or is "can
>>> never" too strong? Is it more that code within the scope of the declaration
>>> is not allowed to change those things?
>> See the exception above. 
> 
> The EXCEPTION (alarms still ringing)  seems to be saying that 'const char[]
> X' means that X.ptr, X.length and the data in X's RAM cannot be changed.

I am hearing it. :o)

>> But now consider a function:
>>
>> void say(const char[] data)
>> {
>>    ...
>> }
>>
>> The bits of data are a private copy of say, so they can be changed 
>> discretionarily (if that's a word). But the bits pointed to by data do 
>> not belong to say, so they can't be written.
>>
>> If say wants to be fancy, it can look like this:
>>
>> void say(final const char[] data)
>> {
>>    ...
>> }
> 
> That didn't help. I'm even more confused now. Can I try? ...
> 
>   void say (const char[] data)
>   {
>      data[0] = 'a'; // Allowed but not passed back to caller.
>      data = "ABC";  // Not allowed.
>   }

Now, you got it backwards: data's contents belong to the caller, and 
data's pointer belongs to the callee.

>> Then data can't be even rebound. The "final" being a storage class, it 
>> doesn't appear in the function signature (e.g., in the interface file).
> 
> Hmmmm ... won't that cause problems for library writers who provide a
> library and ".di" files?

No.


Andrei



More information about the Digitalmars-d mailing list