March 20, 2007
Lionello Lunesu wrote:
> Tyler Knott wrote:
>> Lionello Lunesu Wrote:
>>> What's the use of "final" for variables? I'm saying "for variables" because for methods the benefit is only too clear.
>>>
>>
>> Because the "const" keyword is being repurposed for read-only references to mutable or non-mutable data, 
> 
> ...which I want, very much!
> 
>> we need a new keyword for non-mutable variables.
> 
> That's my question: do we actually need that? Examples are welcomed.
> 
>  > "final" fills that purpose nicely.  If the value of the variable is known at compile time, the compiler can constant-fold away the memory access to that variable for a small speed boost.  If the value is only determinable at runtime, that can still allow the compiler to make some optimizations that would not be possible with mutable variables.
> 
> This is the part I'm not sure about. As with C++'s "const", I don't think the compiler can conclude anything and therefor it can't optimize anything. A "final" variable is not constant.

final int x = 42;

Change that :o).


Andrei
March 20, 2007
Andrei Alexandrescu (See Website For Email) wrote:
>> This is the part I'm not sure about. As with C++'s "const", I don't think the compiler can conclude anything and therefor it can't optimize anything. A "final" variable is not constant.
> 
> final int x = 42;
> 
> Change that :o).
> 
> Andrei

How does this interact with CTFE for variables that are declared as const. With previous versions of the compiler, I know that it would try to constant-fold this code, resulting in an inlined constant from the result of the CTFE:

   const int abc = kaboom();

That code shouts out to me (and to the compiler) that the kaboom() method MUST be evaluated at compile-time. But this code is not nearly so clear:

   final int xyz = shabam();

Just because xyz can't be re-bound after its initial assignment doesn't necessarily mean that shabam() should be executed at compile-time. With the new const/final/invariant semantics, how will the compiler know when to perform constant-folding (or, I suppose, "final-folding") on functions?

--benji
March 20, 2007
Benji Smith wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>>> This is the part I'm not sure about. As with C++'s "const", I don't think the compiler can conclude anything and therefor it can't optimize anything. A "final" variable is not constant.
>>
>> final int x = 42;
>>
>> Change that :o).
>>
>> Andrei
> 
> How does this interact with CTFE for variables that are declared as const. With previous versions of the compiler, I know that it would try to constant-fold this code, resulting in an inlined constant from the result of the CTFE:
> 
>    const int abc = kaboom();
> 
> That code shouts out to me (and to the compiler) that the kaboom() method MUST be evaluated at compile-time. But this code is not nearly so clear:
> 
>    final int xyz = shabam();
> 
> Just because xyz can't be re-bound after its initial assignment doesn't necessarily mean that shabam() should be executed at compile-time. With the new const/final/invariant semantics, how will the compiler know when to perform constant-folding (or, I suppose, "final-folding") on functions?

Undecided at this time. At least "static final" will take care of that - you can't dynamically-initialize statics.

Andrei
March 20, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> Benji Smith wrote:
>> Andrei Alexandrescu (See Website For Email) wrote:
>>>> This is the part I'm not sure about. As with C++'s "const", I don't think the compiler can conclude anything and therefor it can't optimize anything. A "final" variable is not constant.
>>>
>>> final int x = 42;
>>>
>>> Change that :o).
>>>
>>> Andrei
>>
>> How does this interact with CTFE for variables that are declared as const. With previous versions of the compiler, I know that it would try to constant-fold this code, resulting in an inlined constant from the result of the CTFE:
>>
>>    const int abc = kaboom();
>>
>> That code shouts out to me (and to the compiler) that the kaboom() method MUST be evaluated at compile-time. But this code is not nearly so clear:
>>
>>    final int xyz = shabam();
>>
>> Just because xyz can't be re-bound after its initial assignment doesn't necessarily mean that shabam() should be executed at compile-time. With the new const/final/invariant semantics, how will the compiler know when to perform constant-folding (or, I suppose, "final-folding") on functions?
> 
> Undecided at this time. At least "static final" will take care of that - you can't dynamically-initialize statics.
> 
> Andrei

Damn. I always thought "static final" in Java was a sloppy kludge for what should have been "const".

--benji
March 20, 2007
Lionello Lunesu wrote:
> I understand, but what's the point of telling the compiler "I don't want to rebind this variable"? It doesn't seem like an optimization hint. Like telling "func(const int i)" in C++ doesn't actually do anything. You just type more.

Final is handy for a number of things:
1) For class members, it would indicate that a class is not mutable once it's constructed. Probably most classes are like this, and so it's a handy way to document it.
2) Andrei pointed out to me that one can often replace:
	auto x = initializer;
with:
	final x = initializer;
to indicate in a block of code that x will never be reassigned. This aids in understanding the code. It's a style I intend to adopt.
3) For cases like:
	const char[] s = "hello";
is it s that's not rebindable, or is the data that s is pointing to immutable? This never fails to confuse me (in C++), so I like to be able to say which it is in a clear manner.

> And if you later want to rebind 'i' you'll have to change the interface. Lose-lose?

Although final is specified in the interface, it is not part of the interface. It only affects the implementation of the interface. You'll be able to change it without affecting any users of the interface.
March 20, 2007
Walter Bright wrote:
> Lionello Lunesu wrote:
>> I understand, but what's the point of telling the compiler "I don't want to rebind this variable"? It doesn't seem like an optimization hint. Like telling "func(const int i)" in C++ doesn't actually do anything. You just type more.
> 
> Final is handy for a number of things:
> 1) For class members, it would indicate that a class is not mutable once it's constructed. Probably most classes are like this, and so it's a handy way to document it.
> 2) Andrei pointed out to me that one can often replace:
>     auto x = initializer;
> with:
>     final x = initializer;
> to indicate in a block of code that x will never be reassigned. This aids in understanding the code. It's a style I intend to adopt.

And the compiler will have an excellent opportunity to optimize the code (e.g. it can enregister "x" without fear). It's a win-win deal. Believe me. I'm not wearing a tie.

> 3) For cases like:
>     const char[] s = "hello";
> is it s that's not rebindable, or is the data that s is pointing to immutable? This never fails to confuse me (in C++), so I like to be able to say which it is in a clear manner.

What still needs to be decided here is whether we want to automatically make s final too when seen in a data definition. This is a hack for existing code's sake, and also because many people actually mean to make final const strings more often than just nonfinal const strings. Probably final can be inferred via simple flow analysis at low or no extra cost, which would please everyone.


Andrei
March 20, 2007
Benji Smith wrote:
> Damn. I always thought "static final" in Java was a sloppy kludge for what should have been "const".

It is. This is because Java lacks the notion of const for indirectly-referred data, which is the interesting case.

Andrei
March 20, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> final int x = 42;
> 
> Change that :o).

Not fair! You meant "const" :)

L.
March 20, 2007
Benji Smith wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>>> This is the part I'm not sure about. As with C++'s "const", I don't think the compiler can conclude anything and therefor it can't optimize anything. A "final" variable is not constant.
>>
>> final int x = 42;
>>
>> Change that :o).
>>
>> Andrei
> 
> How does this interact with CTFE for variables that are declared as const. With previous versions of the compiler, I know that it would try to constant-fold this code, resulting in an inlined constant from the result of the CTFE:
> 
>    const int abc = kaboom();
> 
> That code shouts out to me (and to the compiler) that the kaboom() method MUST be evaluated at compile-time. But this code is not nearly so clear:
> 
>    final int xyz = shabam();
> 
> Just because xyz can't be re-bound after its initial assignment doesn't necessarily mean that shabam() should be executed at compile-time. With the new const/final/invariant semantics, how will the compiler know when to perform constant-folding (or, I suppose, "final-folding") on functions?

const would still exist, right? So you'd just keep using "const int x = ...". The _only_ purpose of "final int y" is for code clarity, you don't have to scan a whole function to see what happens to that variable, since nothing will happen to it.

L.


L.
March 20, 2007
On Tue, 20 Mar 2007 16:52:14 +0100, Frits van Bommel wrote:

> Stewart Gordon wrote:
>> Tyler Knott Wrote:
>>> Lionello Lunesu Wrote:
>>>> What's the use of "final" for variables?  I'm saying "for variables" because for methods the benefit is only too clear.
>>> Because the "const" keyword is being repurposed for read-only references to mutable or non-mutable data, we need a new keyword for non-mutable variables.
>> <snip>
>> 
>> C++ manages with const for both, so why can't D?  What circumstance is there in which either keyword would be valid with different meanings?
> 
> If you apply "const" to a class reference, how would you determine which of {reference,object} the const applies to?
> 
> - If to the reference only, you can't express the constness of objects.
> - If to the object only, you can't express non-rebindability of the
> reference. (C++ doesn't have this problem, since the only references it
> has are implicitly final all by themselves)
> - If to both, you can only express constness of objects by
> simultaneously disallowing the reference to be rebound. Not nice.
> 
> I think that covers all cases (except 'neither', but that simply doesn't make any sense ;) ).

What happens with ...

   final const Foo f;
   invariant Foo f;

do either of these mean that both the reference and the object is not to be modified?

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Justice for David Hicks!"
21/03/2007 10:13:28 AM