Extended Type Design.

Bruno Medeiros brunodomedeiros+spam at com.gmail
Mon Mar 19 09:02:49 PDT 2007


Derek Parnell wrote:
> On Sat, 17 Mar 2007 21:33:16 -0700, Walter Bright wrote:
> 
>> Derek Parnell wrote:
>>>> final
>>>  This applies only to assignments to Write-Once RAM locations. This can be
>>> done by either the compiler or at run time depending on the amount of
>>> knowledge the compiler has about the location's usage.
>> No. This applies to rebinding of a name:
>> 	final x = 3;
>> 	x = 4;		// error, x is final
>> i.e. final applies to the declared name, not the type.
>>
>>>> const
>>>  This is applied to declarations to prevent code in the same scope as the
>>> declaration from being able to modify the item being declared.
>> No. This means that it is a readonly view of data - other views of the 
>> same data may change it.
>> 	char[] s = "hello".dup;
>> 	const char[] t = s;
>> 	t[0] = 'j';	// error, const char[] is a readonly view
>> 	s[0] = 'j';	// ok
>> 	writefln(t);	// prints "jello"
>> 	t = s[1..2];	// ok, as t is not final
>> Note that const applies to the type, not the name.
>>
>>>> invariant
>>>  This is applied to declarations to prevent code in the same application as
>>> the declaration from being able to modify the item being declared.
>> Almost right. It isn't the declaration, but the *type* that is 
>> invariant. Invariant applies to the type, not the name.
>>
>>> As you can see, I'm confused as to how the qualifier effects which code is
>>> allowed to change which items. Even more so when it comes to reference
>>> items ... 'cos I'm not sure how to use these qualifiers to specify whether
>>> the reference and/or the data being referenced can be changed, and by whom.
>> 'final' is a storage class, like 'static'. It doesn't apply to the type 
>> of the symbol, only the symbol itself.
>> 'const' and 'invariant' apply to the type of the symbol, not the symbol.
> 
> I'm sure its just a terminology problem I'm having, but I still can't
> understand what you are trying to tell me. I'm sorry I'm so thick!
> 

It's likely the following:
By "It doesn't apply to the type of the symbol, only the symbol itself." 
it means it applies to the immediate-value, and by "apply to the type of 
the symbol, not the symbol" it means it applies to the referenced-data, 
where:

"immediate-value" means the value that is changed on assignments, which 
in primitives is the primitive value, and on references is the pointer 
(memory location).
"referenced-data" is the data obtained through references (i.e., data 
pointed to)

IMO I think that terminology is faulty, since, for starters, one can 
have an expression that is not assignable (like the return value of 
functions), which is the same as being 'final', yet there is no 
associated symbol. The same applies to saying 'final' "applies to 
rebinding of a name", like in the example below:

> 
> Walter said:
>> No. This applies to rebinding of a name:
>> 	final x = 3;
>> 	x = 4;		// error, x is final
>> i.e. final applies to the declared name, not the type.
> 
> Now by 'binding' I assume you mean 'having the compiler associate a value
> with a symbol'.
> 
> So "final x = 3" is sort of equivalent to C's "#define x (3)", but in D
> there are scope and data-type implications. 
> 

The differences are that the 'final' variable exists at runtime (unlike 
#define) and as such the initializer doesn't have to be a constant, and 
the var can be referenced.

> I expect that in D we will also be able to do ...
> 
>   final double z = 4.288392;
> 
> but what about things like ...
> 
>   int y = 3;
>   final x = y;
>   final q = someFunc();
> 

Yes.

> And is ...
> 
>     final s = "qwerty";
>     char[] t = s;
> 
> identical to ...
> 
>     char[] t = "qwerty".dup;
> 

No, I don't think so, why would it be?

> 
> I presume this would fail at compile time ...
> 
>     void XYZZY(inout char[] x) { . . . }
>     . . .
>     final s = "qwerty";
>     XYZZY(s);
> 
> 

Yup.

> *****
> Okay, now let's revisit 'const'.
> 
> I said ...
>>>  This is applied to declarations to prevent code in the same scope as the
>>> declaration from being able to modify the item being declared.
> 
> And you said ...
>> No. This means that it is a readonly view of data - other views of the 
>> same data may change it.
>> 	char[] s = "hello".dup;
>> 	const char[] t = s;
>> 	t[0] = 'j';	// error, const char[] is a readonly view
>> 	s[0] = 'j';	// ok
>> 	writefln(t);	// prints "jello"
>> 	t = s[1..2];	// ok, as t is not final
>> Note that const applies to the type, not the name.
> 
> Apart from the last sentence, which still confuses the hell out of me, I
> think we almost are saying the same thing.
> 
> Using your example code, I was saying that the declaration "const char[] t"
> means that you can't change 't' (i.e. t.ptr and t.length cannot be altered)
> but you can change the data that t.ptr points to.  

That's what 'final' does (i.e. "t.ptr and t.length cannot be altered").

>However, I see by your
> explanation that I got this the wrong way around. I now read you saying
> that 'const char[] t' means that program can change t.ptr and/or t.length
> but it cannot use 't' to change the data it points to. I said nothing about
> getting to the data via another symbol. Also, I see that you are saying
> "final const char[] t" means that neither 't' nor its data can be altered.
> 
> Is there any difference between "final const char[] t" and "const final
> char[] t"?
>

Nope.

> Is "const int x = 4" and "final int x = 4" mean the same thing (not a
> reference type this time)? 
> 

I suspect no, since 'const' for primitives is either ignored or not 
allowed, but I'm not sure what Andrei is planning it to be.

> Would "final const x = 5" compile? Would it mean anything different from
> just 'final' or just 'const'?
> 

Same as above, dunno.

> It would seem that 'const' is primarily used to protect referenced data
> rather than the reference itself. Is that right?
> 

Yup.

> And now to 'invariant' ...
> 

For what I got 'invariant' means the data doesn't change at all, like 
compile time constants, or ROM data. But I didn't understand if it 
applies to the "immediate-value" only (like 'final'), or transitively to 
the referenced data too (like 'const'). Clarify?

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D



More information about the Digitalmars-d mailing list