Concise method body + type inference ?

Remi Forax forax at univ-mlv.fr
Wed Oct 3 21:36:26 UTC 2018


I wonder if the concise method body proposal should not be extended to add parameters types/return type inference in case of overriding methods.

The idea is that in case of a method overriding a method or implementing an abstract method the return type and the type parameters are optional like with a lambda.
  
Syntactically, if the signature of a method is inferred, a method starts with an identifier (the method name), followed by the name of the parameters enclosed in parenthesis.

By example,
  class Task implement Runnable {
    private int result;

    run() -> result = Calculation.calculate();  // inferred as "void run()"
  }

or with an anonymous class

  class Range implements Iterable<Integer> {
    final int start;
    final int end;
    ...

    iterator() -> new Iterator<>() {  // inferred as "Iterator<Integer> iterator()"
      int index = start;

      hashNext() -> index < end;      // inferred as "boolean hasNext()"
   
      next() {                        // inferred as "Integer next()"
        if (!hashNext()) { 
          throw new NoSuchElementException();
        }
        return index++;
      }
    };
  }

obviously it also works with the public method of Objects

  class Author {
    private final String name;

    public Author(String name) {
      this.name = Objects.requiresNonNull(name);
    }

    toString() -> name.toString();

    hashCode() -> name.hashCode();

    equals(o) -> (o instanceof Author author)? name.equals(author.name): false;
  }

The nice thing with this proposal is that it avoid "the all or nothing" of the lambda syntax,
i.e. either you have a functional interface and you have a nice concise syntax or you have an interface with more than one abtract methods and it becomes verbose.
Inferring the parameter types of the overriding methods provide an intermediary syntax.

1) lambda: Runnable runnable = () -> ...;
2) var iterator = new Iterator<String>() {
     public boolean hasNext() -> ...;
     ...
   };

this proposal is the 1.5 syntax:
  var iterator = new Iterator<String>() {
     hasNext() -> ...;
     ...
   };

Like with lambdas, i do not think that supporting parameterized methods is a good idea.

If there are several overloads, the parameter types can not be inferred apart if only the return type is different, in that case, the compiler choose the most specific if one exists. 

Should the visibility modifiers be specified or not is an open question ? I think they not should be because i rarely use inheritance, so overriding a package visible method is not something i do frequently. So no modifier means, the modifier is inferred and not the modifier is the package visibility.

regards,
Rémi







More information about the amber-spec-experts mailing list