Manifold is a Java compiler plugin, its features include Metaprogramming, Properties, Extension Methods, Operator Overloading, Templates, a Preprocessor, and more.
Provide auto functionality for local vars, fields, and method return types.
Rationale: Although Java 10+ provides var to infer the type of local variables, it can't be applied to fields and methods. Additionally, var is not available in Java 8, which is where much Java dev still happens, particularly with Android. Thus, the proposed auto functionality fills in these gaps while not interfering with existing functionality.
Local variable example
public void post(String stuff) {
auto list = new ArrayList<>();
list.add(stuff);
post(list);
}
Auto field and method example
public class Employee {
private auto contacts = new ConcurrentHashMap<String, Contact<Person>>();
...
public auto findContact(String key) {
return contact.get(key);
}
}
In some cases it is vital to infer the return type of a method so that a generated type may be conveyed to the call-site. One such case involves separate feature requests for type-safe multiple return values and, more generally, tuple expressions.
Tuples example
auto record = (material: "Basalt", weight: "5296.8", departs: LocalDate.from(2022, 5, 6), origin: "Mexico");
auto date = record.departs;
Multiple return values
public auto getBoundaries() {
int min = findMin();
int max = findMax();
return min, max;
}
...
auto bounds = getBoundaries();
int min = bounds.min;
int max = bounds.max;
Limitations
There are a few limitations, at least in the first draft of the feature.
LUB method return type
Used as a method return type, auto poses a challenge in terms of reflecting a complete type. Return type inference must take into account methods having multiple return statements where return expressions may have different, but related types. Specifically, a "least upper bound" (LUB) algorithm must be applied to properly capture the type. Such a type may result in an intersection type reflecting all the common interfaces between the varying return expression types. Although the Java compiler provides limited support for such types, the JVM does not; intersection types are not supported in method signatures. As a compromise the algorithm will use heuristics in an attempt to infer the most relevant type from the intersection of types e.g., CharSequence wins over Serializable.
Head recursion
An auto return type supports tail recursion, but not head recursion. This is because return type analysis visits method call sites in a top-down fashion. If a recursive auto call precedes the first non-recursive return statement (head recursion), the method's type can't be inferred. Note, this is a first-draft limitation that will likely be remedied in a future revision.
Concerns
Careless use of auto with non-private fields and methods can lead to an overexposed API. For instance, exposing an ArrayList<String> as opposed to List<String> may be an unintentional consequence of using auto. However, considering the bulk of fields in most applications are private, perhaps having auto vs. not is a reasonable trade-off. Similarly, method return type inference via auto should be used judiciously for public APIs.
Proposal
Provide
auto
functionality for local vars, fields, and method return types.Rationale: Although Java 10+ provides
var
to infer the type of local variables, it can't be applied to fields and methods. Additionally,var
is not available in Java 8, which is where much Java dev still happens, particularly with Android. Thus, the proposedauto
functionality fills in these gaps while not interfering with existing functionality.Local variable example
Auto field and method example
In some cases it is vital to infer the return type of a method so that a generated type may be conveyed to the call-site. One such case involves separate feature requests for type-safe multiple return values and, more generally, tuple expressions.
Tuples example
Multiple return values
Limitations
There are a few limitations, at least in the first draft of the feature.
LUB method return type
Used as a method return type,
auto
poses a challenge in terms of reflecting a complete type. Return type inference must take into account methods having multiple return statements where return expressions may have different, but related types. Specifically, a "least upper bound" (LUB) algorithm must be applied to properly capture the type. Such a type may result in an intersection type reflecting all the common interfaces between the varying return expression types. Although the Java compiler provides limited support for such types, the JVM does not; intersection types are not supported in method signatures. As a compromise the algorithm will use heuristics in an attempt to infer the most relevant type from the intersection of types e.g.,CharSequence
wins overSerializable
.Head recursion
An
auto
return type supports tail recursion, but not head recursion. This is because return type analysis visits method call sites in a top-down fashion. If a recursive auto call precedes the first non-recursive return statement (head recursion), the method's type can't be inferred. Note, this is a first-draft limitation that will likely be remedied in a future revision.Concerns
Careless use of
auto
with non-private fields and methods can lead to an overexposed API. For instance, exposing anArrayList<String>
as opposed toList<String>
may be an unintentional consequence of usingauto
. However, considering the bulk of fields in most applications are private, perhaps havingauto
vs. not is a reasonable trade-off. Similarly, method return type inference viaauto
should be used judiciously for public APIs.