March 18, 2007
Walter Bright wrote:
> Derek Parnell wrote:
[snip]
>>> 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.

By the way, "invariant" is a lifesaver. Everybody and their sister in the coffee shop liked it at the first sight. The girl at the counter asked for kris' email :o).

Yes, "invariant" is essentially a synonym to "constant", but here are two simple mnemonic devices to remember which is which:

a) "const" is shorter because it's used more often;

b) "const" is similar to C++'s homonym.

Easier to remember than perl's $|.


Andrei
March 18, 2007
Andrei Alexandrescu (See Website For Email) Wrote:

> Walter Bright wrote:
> > Derek Parnell wrote:
> [snip]
> >>> 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.
> 
> By the way, "invariant" is a lifesaver. Everybody and their sister in the coffee shop liked it at the first sight. The girl at the counter asked for kris' email :o).
> 
> Yes, "invariant" is essentially a synonym to "constant", but here are two simple mnemonic devices to remember which is which:
> 
> a) "const" is shorter because it's used more often;
> 
> b) "const" is similar to C++'s homonym.
> 
> Easier to remember than perl's $|.
> 
> 
> Andrei

Another option I'd like to have at least considered is the finding of a character that can be used to denote const. Adding various constnesses to all the code could easily add a whole lot of typing to the task of getting things done in D.

Could we find a unicode character that wouldn't be too much trouble for editors to insert ? Might mean that D starts to require unicode source - but is that such a bad thing ?

Are there any ascii characters that can be found that wont confuse the parser ? - like how the use of ! works for templates

Alex
March 18, 2007
Alex Burton wrote:
> Andrei Alexandrescu (See Website For Email) Wrote:
> 
>> Walter Bright wrote:
>>> Derek Parnell wrote:
>> [snip]
>>>>> 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.
>> By the way, "invariant" is a lifesaver. Everybody and their sister in the coffee shop liked it at the first sight. The girl at the counter asked for kris' email :o).
>>
>> Yes, "invariant" is essentially a synonym to "constant", but here are two simple mnemonic devices to remember which is which:
>>
>> a) "const" is shorter because it's used more often;
>>
>> b) "const" is similar to C++'s homonym.
>>
>> Easier to remember than perl's $|.
>>
>>
>> Andrei
> 
> Another option I'd like to have at least considered is the finding of a character that can be used to denote const.
> Adding various constnesses to all the code could easily add a whole lot of typing to the task of getting things done in D.
> 
> Could we find a unicode character that wouldn't be too much trouble for editors to insert ? Might mean that D starts to require unicode source - but is that such a bad thing ?
> 
> Are there any ascii characters that can be found that wont confuse the parser ? - like how the use of ! works for templates

Type inference will reduce the need for littering code with "const" a great deal (when compared to today's C++ code, at least). You just write:

auto var = expression;

and the const will propagate. Initial experience will show whether this is enough.


Andrei
March 18, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> Alex Burton wrote:
>> Andrei Alexandrescu (See Website For Email) Wrote:
>>
>>> Walter Bright wrote:
>>>> Derek Parnell wrote:
>>> [snip]
>>>>>> 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.
>>> By the way, "invariant" is a lifesaver. Everybody and their sister in the coffee shop liked it at the first sight. The girl at the counter asked for kris' email :o).
>>>
>>> Yes, "invariant" is essentially a synonym to "constant", but here are two simple mnemonic devices to remember which is which:
>>>
>>> a) "const" is shorter because it's used more often;
>>>
>>> b) "const" is similar to C++'s homonym.
>>>
>>> Easier to remember than perl's $|.
>>>
>>>
>>> Andrei
>>
>> Another option I'd like to have at least considered is the finding of a character that can be used to denote const.
>> Adding various constnesses to all the code could easily add a whole lot of typing to the task of getting things done in D.
>>
>> Could we find a unicode character that wouldn't be too much trouble for editors to insert ? Might mean that D starts to require unicode source - but is that such a bad thing ?
>>
>> Are there any ascii characters that can be found that wont confuse the parser ? - like how the use of ! works for templates
> 
> Type inference will reduce the need for littering code with "const" a great deal (when compared to today's C++ code, at least). You just write:
> 
> auto var = expression;
> 
> and the const will propagate. Initial experience will show whether this is enough.

What about the ability to deduce only parts of a type?

Declaring types is also a kind of documentation / assertion that can help maintainers of the code later.   I might want to specify const and let the type be deduced, or I might want to specify the type I'm expecting and let const be deduced.

Maybe declaration followed by is-test will be necessary for those cases.  If they aren't too common I guess that's ok.  But I would hate to see
   auto var = expression;
   assert(is(non_const_typeof(var)==Something));
become a standard idiom.

... how will one do that is() check for base type sans type constructors?

--bb
March 18, 2007
Bill Baxter wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>> Alex Burton wrote:
>>> Andrei Alexandrescu (See Website For Email) Wrote:
>>>
>>>> Walter Bright wrote:
>>>>> Derek Parnell wrote:
>>>> [snip]
>>>>>>> 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.
>>>> By the way, "invariant" is a lifesaver. Everybody and their sister in the coffee shop liked it at the first sight. The girl at the counter asked for kris' email :o).
>>>>
>>>> Yes, "invariant" is essentially a synonym to "constant", but here are two simple mnemonic devices to remember which is which:
>>>>
>>>> a) "const" is shorter because it's used more often;
>>>>
>>>> b) "const" is similar to C++'s homonym.
>>>>
>>>> Easier to remember than perl's $|.
>>>>
>>>>
>>>> Andrei
>>>
>>> Another option I'd like to have at least considered is the finding of a character that can be used to denote const.
>>> Adding various constnesses to all the code could easily add a whole lot of typing to the task of getting things done in D.
>>>
>>> Could we find a unicode character that wouldn't be too much trouble for editors to insert ? Might mean that D starts to require unicode source - but is that such a bad thing ?
>>>
>>> Are there any ascii characters that can be found that wont confuse the parser ? - like how the use of ! works for templates
>>
>> Type inference will reduce the need for littering code with "const" a great deal (when compared to today's C++ code, at least). You just write:
>>
>> auto var = expression;
>>
>> and the const will propagate. Initial experience will show whether this is enough.
> 
> What about the ability to deduce only parts of a type?
> 
> Declaring types is also a kind of documentation / assertion that can help maintainers of the code later.   I might want to specify const and let the type be deduced, or I might want to specify the type I'm expecting and let const be deduced.
> 
> Maybe declaration followed by is-test will be necessary for those cases.  If they aren't too common I guess that's ok.  But I would hate to see
>    auto var = expression;
>    assert(is(non_const_typeof(var)==Something));
> become a standard idiom.
> 
> ... how will one do that is() check for base type sans type constructors?

assert(is(const typeof(var) == typeof(var)));

Only time will show whether this will be needed frequently. I don't think so: in general var will engender an error upon first mutation, which is close to its definition.

Andrei
March 19, 2007
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!

To me the word 'type' refers to the data type associated with a symbol - like 'int', 'float', 'char[]' , etc... So when you say "'const' and 'invariant' apply to the type" it sounds like you are saying that 'const' prevents a symbol from changing types - which doesn't make sense to me. In D, a symbol can never change types once it has been declared.

So, I'm now wondering if by "type" you are actually meaning the data represented by the symbol and not its data-type. However that doesn't quite make sense either because that's what I was saying but you disagreed with me!?

Please bear with me. Oh, and anyone else can chime in to help make it clear to me too, please.

Let's take 'final' again.

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.

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();

And is ...

    final s = "qwerty";
    char[] t = s;

identical to ...

    char[] t = "qwerty".dup;


I presume this would fail at compile time ...

    void XYZZY(inout char[] x) { . . . }
    . . .
    final s = "qwerty";
    XYZZY(s);


*****
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.  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"?

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

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

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


Will this be allowed ...

   void XYZZY(const char[] s)
   {
      char[] t;
      t = s;   // fails here?
      t[0] = 'a';
   }

*****
And now to 'invariant' ...

You said ...
> It isn't the declaration, but the *type* that is invariant. Invariant applies to the type, not the name.

I have no idea what you mean by that statement! I still can't see that data-types can change. But maybe you mean data rather than data-type, but then isn't that what 'const' is doing? And I'm sure you *do not* mean that somehow you can rename symbols during compilation!? So I can't see what is "invariant" - as in - what is "not changing".

If I code "invariant char[] t", ...
  (A) are changes to t.ptr/t.length prevented?

  (B) are changes to the data that 't' points to prevented?

How is 'invariant' different from 'final'?

How is 'invariant' different from 'const'?

How is 'invariant' different from 'final const'?


Is combining 'invariant' with 'final' and/or 'const' meaningful? If so, how?

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Justice for David Hicks!"
19/03/2007 11:55:33 AM
March 19, 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!
> 
> To me the word 'type' refers to the data type associated with a symbol - like 'int', 'float', 'char[]' , etc... So when you say "'const' and 'invariant' apply to the type" it sounds like you are saying that 'const' prevents a symbol from changing types - which doesn't make sense to me. In D, a symbol can never change types once it has been declared.

It's just saying that "T" and "const T" are different types (unless T was already const); they have different permitted operations.

I'd have to say that I find Walter's ideas on const/final
to be rather... distinctive... and we've debated terminology
at some length but with no resolution.  It's his language,
he can use terms as he wishes.  It may impede communication.
This may be a case of "final" being a thing that Walter likes
to think of as a storage class rather than a type modifier
(though in a more general sense storage classes are just a
special/restricted case of type modifiers).

"final", I think, is a workaround for handling types
that are accessed through automatically-dereferenced
GC'd pointers in D.  The auto-deref property hides the
actual type of those pointers from us, so we can't const-
qualify them; we just end up adding const to the type to
which they point.  C++ doesn't work this way, and so
const does everything that final does and more in C++.
It's just different.  If you want indirection via a
reference/pointer, C++ makes you say so, but gives you
the chance to apply type modifiers to that pointer.  D
does it invisibly, but then requires extra syntax to be
able to stop the name being rebindable.

-- James

March 19, 2007
On Sun, 18 Mar 2007 20:46:58 -0700, James Dennett wrote:

Walter says
>> "'const' and 'invariant' apply to the type"

> It's just saying that "T" and "const T" are different types (unless T was already const); they have different permitted operations.

Oh?! Is that all. That is easy to understand, but it does not help me understand how Walter sees it or 'invariant' being used.

So "int", "const int" and "invariant int" are all different types and as such have in-built rules concerning implicit conversions etc...That's fine. I can understand that. But what then are the built-rules? Are the rules different for POD, Objects, and Arrays?

> I'd have to say that I find Walter's ideas on const/final to be rather... distinctive... and we've debated terminology at some length but with no resolution.  It's his language, he can use terms as he wishes.  It may impede communication.

I'm fine with that too. Sure, its Walter (and Andrei's) language and that can make up syntax and keywords as they see fit. I only hope that they get some good documentation experts to help people like me understand it.

> This may be a case of "final" being a thing that Walter likes to think of as a storage class rather than a type modifier (though in a more general sense storage classes are just a special/restricted case of type modifiers).
> 
> "final", I think, is a workaround for handling types
> that are accessed through automatically-dereferenced
> GC'd pointers in D.  The auto-deref property hides the
> actual type of those pointers from us, so we can't const-
> qualify them; we just end up adding const to the type to
> which they point.  C++ doesn't work this way, and so
> const does everything that final does and more in C++.
> It's just different.  If you want indirection via a
> reference/pointer, C++ makes you say so, but gives you
> the chance to apply type modifiers to that pointer.  D
> does it invisibly, but then requires extra syntax to be
> able to stop the name being rebindable.

Interesting ... but what does all that sound like in English <G>

I don't really know C++ all that well so I don't quite get the comparisons. Can anyone explain this without referring to other programming languages, please? Just common everyday English would be nice - oh, but with example <G>.

But let's see if I can translate it first ...

"storage class" means how something's value is stored in RAM. Which could be in the data space or as immediate literals in the code space. Thus 'final' is a description of how the compiler sees the value stored in the program. One rule is that it is impossible for any code to alter the value associated (bound) a 'final' symbol. For all practical purposes, from the compiler's point of view, the symbol *is* the value. When applied to reference types, the symbol's value is the reference and not that which is being referenced.


-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Justice for David Hicks!"
19/03/2007 3:24:59 PM
March 19, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> Bill Baxter wrote:
>> Andrei Alexandrescu (See Website For Email) wrote:
>>> Alex Burton wrote:
>>>> Andrei Alexandrescu (See Website For Email) Wrote:
>>>>
>>>>> Walter Bright wrote:
>>>>>> Derek Parnell wrote:
>>>>> [snip]
>>>>>>>> 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.
>>>>> By the way, "invariant" is a lifesaver. Everybody and their sister in the coffee shop liked it at the first sight. The girl at the counter asked for kris' email :o).
>>>>>
>>>>> Yes, "invariant" is essentially a synonym to "constant", but here are two simple mnemonic devices to remember which is which:
>>>>>
>>>>> a) "const" is shorter because it's used more often;
>>>>>
>>>>> b) "const" is similar to C++'s homonym.
>>>>>
>>>>> Easier to remember than perl's $|.
>>>>>
>>>>>
>>>>> Andrei
>>>>
>>>> Another option I'd like to have at least considered is the finding of a character that can be used to denote const.
>>>> Adding various constnesses to all the code could easily add a whole lot of typing to the task of getting things done in D.
>>>>
>>>> Could we find a unicode character that wouldn't be too much trouble for editors to insert ? Might mean that D starts to require unicode source - but is that such a bad thing ?
>>>>
>>>> Are there any ascii characters that can be found that wont confuse the parser ? - like how the use of ! works for templates
>>>
>>> Type inference will reduce the need for littering code with "const" a great deal (when compared to today's C++ code, at least). You just write:
>>>
>>> auto var = expression;
>>>
>>> and the const will propagate. Initial experience will show whether this is enough.
>>
>> What about the ability to deduce only parts of a type?
>>
>> Declaring types is also a kind of documentation / assertion that can help maintainers of the code later.   I might want to specify const and let the type be deduced, or I might want to specify the type I'm expecting and let const be deduced.
>>
>> Maybe declaration followed by is-test will be necessary for those cases.  If they aren't too common I guess that's ok.  But I would hate to see
>>    auto var = expression;
>>    assert(is(non_const_typeof(var)==Something));
>> become a standard idiom.
>>
>> ... how will one do that is() check for base type sans type constructors?
> 
> assert(is(const typeof(var) == typeof(var)));
> 
> Only time will show whether this will be needed frequently. I don't think so: in general var will engender an error upon first mutation, which is close to its definition.
> 
> Andrei

Why not just
  const auto var = expression;
?

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
March 19, 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