JDK-4459053 : Type inference for variable declarations
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 1.3.0
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 2001-05-15
  • Updated: 2018-03-02
  • Resolved: 2001-05-24
Related Reports
Relates :  
Description

Name: bsC130419			Date: 05/15/2001


Currently the Java Language Specification (JLS) requires you to specify the type
of a variable when the variable is declared.  This is often annoying, especially
in combination with casts.  For example, to iterate over a map:

    Map map = getSomeMap();
    Iterator iter = map.entrySet().iterator();
    while (iter.hasNext()) {
        Map.Entry entry = (Map.Entry) iter.next();
        MyTableValue value = (MyTableValue) entry.getValue();
        ...;
    }

Here the variable declarations of 'entry' and 'value' need to specify the type
twice.  A simple extension to the JLS would be to be able to introduce variables
without specifying the type.  For example:

    let map = getSomeMap();
    let iter = map.entrySet().iterator();
    while (iter.hasNext()) {
        let entry = (Map.Entry) iter.next();
        let value = (MyTableValue) entry.getValue();
        ...;
    }

This makes the code easier to read, type, and change due to less duplication of
information.  A variable declared using the 'let' construct will take its type
from the initializer value expression.

Implementation effort is minimal.  I've finished a basic implementation of this
in my copy of the Jikes compiler in less than 4 hours (without any prior
knowledge of the Jikes source code).  No changes are necessary to the JVM, the
.class file format, or the Java APIs.

Restrictions:
1) A variable introduced using the let statement _must_ have an initializer
   statement so its type can be determined.
2) A variable introduced using the let statement _cannot_ have an array
   initializer as determining the type for array initializers is difficult.

Options:
1) Instead of introducing a new keyword 'let' reuse the 'final' keyword.  This
   slightly changes the semantics (the variable is final) but avoids having to
   introduce a keyword.
2) Allow 'let' to be used in expressions:
   
   public int surfaceArea(int x1, int y1, int x2, int y2) {
       return let dx = x2 - x1,
                  dy = y2 - y1,
              in  dx * dy;
   }

   This uses an additional keyword 'in'.  'dx' and 'dy' are only visible inside
   the expression.  Instead of 'in' the 'do' keyword could be reused.
3) Allow 'let' to be used as part of a member declaration in an interface or
   class.

Note: My implementation follows the restrictions and does not implement any of
the options.

Other RFEs:

Generics (JSR-014) looks like they would reduce the need for 'let'.  Consider
the following example:

    Map<String, Integer> map = getSomeMap();
    Iterator<Map<String, Integer>.Entry> iter = map.entrySet().iterator();
    while (iter.hasNext()) {
        Map<String, Integer>.Entry entry = iter.next();
        ...;
    }

Very wordy indeed!  At least no casts were necessary.  Compare this with the
'let' version:

    let map = getSomeMap();
    let iter = map.entrySet().iterator();
    while (iter.hasNext()) {
        let entry = iter.next();
        ...;
    }

No casts and no complex type declarations.  The code is still fully type-checked
by the compiler without bothering the programmer with the need for type
declarations.
(Review ID: 124038) 
======================================================================

Comments
WORK AROUND Name: bsC130419 Date: 05/15/2001 Declare the type for each variable (wordy and annoying). ======================================================================
11-06-2004

PUBLIC COMMENTS Type declarations for variables provide a valuable form of documentation and a cross check that helps catch errors.
10-06-2004

EVALUATION This is a well reasoned and logical RFE (that's rare enough that I feel the need to call it out). However, I don't expect us to follow this path in Java for the following reason: The submitter's claim is that the type information in a standard Java variable declaration is redundant. This may be true from the compiler's perspective, but often it will not be true from the programmer's perspective. Consider: Map m = getMap(); Humans benefit from the redundancy of the type declaration in two ways. First, the redundant type serves as valuable documentation - readers do not have to search for the declaration of getMap() to find out what type it returns. Second, the redundancy allows the programmer to declare the intended type, and thereby benefit from a cross check performed by the compiler. While I personally find the use of let attractive, the drawbacks above are enough to reject it. Add the "un-java-like" feel of this and the complications of adding a keyword, and it's clearly a non-starter. gilad.bracha@eng 2001-05-23
23-05-2001