Reader Mail Bag -- Local Type Inference (original) (raw)
Brian Goetz brian.goetz at oracle.com
Thu Mar 24 19:44:13 UTC 2016
- Previous message: Local variable type inference survey -- round 1 results, and round 2 survey
- Next message: Reader Mail Bag -- Local Type Inference (JEP 286)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
(Please do not respond directly to this mail; if you want to respond, please use the follow-up survey.)
The first survey is closed, and we received ~2500 entries, with over 400 providing long-form comments and questions. I'll try to answer some of the the constructive questions here, which I've divided into groups by topic. I've answered the mostly non-subjective questions here; I'll cover the more subjective ones in a separate mail. (Also see the earlier "Reader Mail Bag" response, which answers some of the early-arriving questions.)
"How does it work"
Q: How does mutability/finality work in "var only"?
In all of the alternatives, effective-finality analysis applies to local variables declared with 'var'. In the alternatives that also include val/let, these are treated as explicitly final, but the existence of val/let doesn't mean that we don't do effectively-final analysis on variables declared with 'var'.
Q: Are 'val' and 'final var' equivalent?
Yes, val/let would be equivalent to 'final var'.
Q: Will this break existing programs that use 'var' or 'val' as field or method names?
No.
Q: Will this break existing programs that use 'var' or 'val' as a class or interface name?
Yes. We've explored how to provide a means to save these classes, at the cost of additional complexity, but the return-on-complexity didn't seem to be there.
Q: Does 'let' mean 'immutable'?
It means 'final'.
Q: Are these dynamically typed?
No! This is not dynamic typing; it is allowing the compiler to determine the static type for you, rather than making you provide it explicitly. Once the compiler chooses a type (which is based entirely on the type of the initializer expression), it is as if you had provided that type explicitly.
Q: How does this interact with existing type inference, such as for diamond constructors, generic methods, or lambda formals in the initializer expression?
For inference variables in the initializer expression, if they can be
inferred from type information in the initializer expression itself,
then the expression is compatible with using 'var' on the declaration.
On the other hand, if they cannot be inferred without a target type, and
no target type is provided, then inference will fail, and the compiler
will issue an error message.
Q: What is the type of an anonymous class creation expression?
For an anonymous class creation expression, we infer the base type. So for example, in:
var foo = new Foo() { ... }
we would infer 'Foo' for the type of 'foo'.
Q: How does it work with variables that don't have initializers.
It doesn't; this is an error.
Q: Can I mix explicit and implicit types?
Yes.
Tooling Impact
Q: Does this affect the runtime or classfile?
No.
Q: Will this affect runtime performance?
No.
Q: Will this affect compiler performance?
In any realistic case, no. (Even with a manifest type, the compiler still has to synthesize the type of the initializer, and perform a subtyping check against the manifest type.)
Q: Does this affect Javadoc?
No; local variables do not appear in Javadoc.
Q: Can we have Javac modify the code and insert the type?
IDEs will certainly do this for you. Javac doesn't modify code in-place, but we are considering enhancing features of javac like -printSource to expand inferred types (and not just for locals, but also for generic methods, diamond constructors, and lambda formals), as a debugging aid.
Q: Can we have a compiler warning that detects the use of 'var'?
This seems better handled by style-checking tools like CheckStyle.
Q: Will it require targeting the latest class file?
There are no classfile changes mandated by this feature.
Feature Scope
Q: Why not allow it on fields or method returns?
Because these are part of the interface of your class, and these appear in classfiles (which could then cause silent compatibility issues if implementation changes cause the inferred type to change.) Locals cannot be accessed outside of the declaring scope; their types are pure implementation details.
Q: OK, what about private fields or method returns? They aren't accessible from other classes.
We could choose to include these; this would be a tradeoff of greater complexity (more complex set of rules for when 'var' is allowed, would mean broadening the accessibility of a member becomes potentially not a source-compatible change) for greater applicability. We're inclined to keep it simple.
Q: Why not allow diamond on the LHS?
This is a viable feature, and has pros and cons. This helps for generic types, but doesn't help at all for long type names (AbstractBeanProviderFactory).
Q: How does it interact with subsequent uses?
As proposed, we infer the type of the local purely from the initializer
type; thereafter, the type is fixed as if it were explicitly provided.
Alternately, we could instead have chosen to infer it from all
assignments; this might well result in inferring weaker types (like
Object). The choice to use the initializer only is a tradeoff; we gain
greater simplicity and stability, at the cost of being able to infer
types for more locals. (Because other assignments might be far away
from the declaration, using all assignments could easily generate
confusing action-at-a-distance errors.)
- Previous message: Local variable type inference survey -- round 1 results, and round 2 survey
- Next message: Reader Mail Bag -- Local Type Inference (JEP 286)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the platform-jep-discuss mailing list