Monday, April 9, 2018

Clearer Code with JDK 10 Local Variable Type Inference

One of the first fruits of Project Amber, Local-Variable Type Inference (JEP 286), has been delivered with JDK 10. JEP 286's "Summary" describes its purpose, "Enhance the Java Language to extend type inference to declarations of local variables with initializers." In conjunction with this release, Stuart Marks has published the March 2018 article "Style Guidelines for Local Variable Type Inference in Java."

In "Style Guidelines for Local Variable Type Inference in Java," Marks postulates four "Principles" that lead to seven "Guidelines" that help developers to apply var properly to "help improve good code, making it shorter and clearer without compromising understandability." The articulated guidelines attempt to strike a balance that brings benefits of less redundant code with the benefits of explicitly readable code. The article outlines cases where var should be used and where it shouldn't be used. In general var is best used when other naming conventions or other constructs in use provide significant detail about the local variable type that is only repeated with the explicit typing. On the other hand, there are cases where much information is lost if the explicit type is removed and in such cases, use of var is discouraged. Another typical case where use of local variable type inference might be preferred is when the explicit typing is difficult to read and is only used in an intermediate step. It may not be important to see the complex explicit type for that intermediate step.

I couldn't help but think about my earliest days working with Groovy while reading the document "Style Guidelines for Local Variable Type Inference in Java." Most of the literature I read sang the virtues of using Groovy's def keyword wherever possible to conserve keystrokes and make the Groovy code more concise. In an effort to appear to "speak Groovy" fluently, I embraced what I deemed to be "idiomatic Groovy." However, after several months of this, I realized that some uses of the def keyword significantly reduced the readability of my Groovy code when I returned to it months after writing it. I began to use personal guidelines similar to those espoused by Marks with Java's LVTI with my Groovy code.

I wasn't the only one who learned that mindless application of Groovy's handy def keyword could actually lead to less maintainable Groovy code. Benefits that can be gained from explicit typing in Groovy are discussed in the StackOverflow thread "Groovy: 'def' keyword vs concrete type." The book Programming Grails has a section called "'def' Considered Harmful" in its first chapter and Rob Hinds's post "Groovy: A Retrospective" states, "... typing is better - I still don't buy that typing def rather than the actual type is actually that much of a saving." The "official" Groovy Style Guide features a section "Optional typing advice" that talks about whether or not to use def. However, for the similar case to which Java LVTI applies (local variables), the advice is, "you're more free to decide when to type or not."

Like so many other Java APIs and language constructs, the best Java code will not be written to always use LVTI or to never use LVTI. Instead, as is so often the case in software development, the decision on whether to use LVTI or not to use LVTI depends on the context in which it would potentially be used. Reviewing the "Style Guidelines for Local Variable Type Inference in Java" document and trying out LVTI and reviewing others' code using LVTI are the best ways to build an intuitive sense for when to apply LVTI and when not to. The amber-dev mailing list thread starting with the message "LVTI Style Guide" provides significant more discussion surrounding this document on when to use and not use Java's Local Variable Type Inference. The blog post "Representing the Impractical and Impossible with JDK 10 'var'" demonstrates how to "declare variables with types that were erstwhile impractical or impossible to represent" using Local Variable Type Inference.

3 comments:

@DustinMarx said...

Nancy Jain's post Java 10: Let’s play with var uses jshell to demonstrate how var can be used and to demonstrate some of the limitations of Local Variable Type Inference (LVTI).

@DustinMarx said...

The Snyk blog has a recent post "Local Type Inference Cheat Sheet for Java 10 and beyond!" that features a downloadable PDF cheat sheet by Stuart Marks and Simon Maple.

@DustinMarx said...

Brian Goetz and Stuart Marks have posted "Java Local Variable Type Inference: Frequently Asked Questions."