PROPOSAL: 'final' without explicit type (update)

Reinier Zwitserloot reinier at zwitserloot.com
Tue Mar 31 08:28:12 PDT 2009


Tim:

This isn't the first time I've read about inferring types, and this  
isn't the first time I've seen 'final' used for it.

It's -not- just to avoid a new keyword. It's quite specifically  
because auto-typing should only be done for final variables. The  
problem is this:

List<String> list = new ArrayList<String>();

The LHS type is not the same as the RHS type. Virtually all java  
programmers would agree the above is superior to:

ArrayList<String> list = new ArrayList<String>();

for two reasons:

  1. You will not be able to assign another type of list to this thing  
later.

  2. You will not be calling arraylist-specific methods (which there  
are none, but let's argue for a moment that there are), eventhough the  
intent is for 'list' to perhaps hold some other non-ArrayList list, and

And yet, with type inference, you'll get ArrayList<String> on the LHS,  
and not List<String>.


Both of those reasons become moot, or almost moot, if the variable is  
final:

  1. It's final. You can't assign anything to it, so no problem here,  
and

  2. Because you can't assign anything else, calling arraylist- 
specific stuff is less of an issue. The issue doesn't go away entirely  
(and this is in fact the only reasonable complaint against the final- 
without-explicit-type proposal that I can think of) but it becomes  
much less important. It is further mediated by the idea that java  
allows you to operate on expressions and not just variables, and  
expression do quite auto-infer (and are in essence final, you can't re- 
assign the value of an expression, of course!), so there's precedent,  
which is always a good thing for language changes.

In other words:

(new LinkedList()).push("Hello!");

is perfectly legal, and yet it has the exact same problem that,  
supposedly, a (final!) implicit variable type would have: If you were  
intending to change that linkedlist for an arraylist later, than  
'push' was not a method you were supposed to call on it.

As the above example clearly shows: It's a problem, but not exactly a  
backbreaking one. We've been dealing with it for years.



FWIW, I'm -strongly- in favour of implicit typing for final local  
method variables, and opposed to extending this for non-finals, not  
just because its hard to come up with a syntax for it, due to there  
being no readily available keywords or operators to do it with. :=  
comes to mind, but that's about it.

NB2: If you want to push forward with this proposal anyway, I strongly  
suggest you rewrite it to this, which would be far more backwards  
compatible:

foo := expression;

instead of:

auto foo = expression;


  --Reinier Zwitserloot



On Mar 31, 2009, at 15:43, Tim Lebedkov wrote:

> Hello Marek,
>
> my proposal (http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001055.html 
> )
> is very similar to yours (it just uses 'auto' instead of 'final').
>
> Does yours declare variables as final (I mean here 'constant') only
> because you try to avoid introducing a new keyword? Or is there
> another motivation?
>
> Tim
>
> On Tue, Mar 31, 2009 at 8:40 AM, Marek Kozieł  
> <develop4lasu at gmail.com> wrote:
>> W dniu 31 marca 2009 03:06 użytkownik Gabriel Belingueres
>> <belingueres at gmail.com> napisał:
>>>
>>> Why?
>>> final a = 1; // static type is int
>>> final b = new Integer(6); // static type is Integer
>>>
>>> If this is confusing for someone:
>>> final c = 1 + new Integer(7);
>>>
>>> then declare it as usual.
>>>
>>
>> I just think that in this form solution will be easier to use.
>>
>>
>>> Assuming that getLocalization() returns a Localization, then the  
>>> whole
>>> point is that you don't need the cast; otherwise this feature is of
>>> doubtful utility. The variable type is known at compile type to be a
>>> Localization.
>>
>> "o is Object" for any reason, if it would be Localization then  
>> problem
>> would not exists.
>>
>>> OTOH, if the getLocalization() returns an Object, then
>>> final o = (Localization) some.getBoo().getLocalization();
>>> might throw a ClassCastException at runtime, which is a pity because
>>> this is a new feature.
>>> If you want to risk to receive a ClassCastException, then declare  
>>> it as usual:
>>> final Localization o =  (Localization)  
>>> some.getBoo().getLocalization();
>>
>> What for if we already casted it ?
>>
>>>
>>> IMHO, type casts should be forbidden, or at least discouraged.
>>
>> I can agree a little.
>>
>> --
>> Pozdrowionka. / Regards.
>> Lasu aka Marek Kozieł
>>
>> http://lasu2string.blogspot.com/
>>
>>
>




More information about the coin-dev mailing list