Improving readability of type/casting error messages
cowwoc
cowwoc at bbs.darktech.org
Fri Dec 5 05:09:16 UTC 2014
Sorry for the repeated follow-up emails but I just discovered something
else. In the aforementioned compiler error what was really going on was
that the lambda was returning Promise<Optional<Object>> instead of
Optional<Object>. This is important to note because in actuality, we
should be telling the user:
Invoked thenApply(Function<A, B>) with B = Optional<GetPostalCode>
but function returned Promise<Optional<GetPostalCode>>.
I think it is much more likely that the user will need to change a
lambda's return type than to change the return type of the Function
being implemented. As such, I think the above message is probably the
clearest of all.
(Notice that it took me over 5 minutes to figure out what was actually
going on in my own code, and I've been dealing with these error messages
for months now)
Gili
On 05/12/2014 12:10 AM, cowwoc wrote:
> The "simplified" message I quoted below was technically incorrect, but
> hopefully you still got my point. Instead of "expected B to extend
> Object" it should have read "expected B to extend Promise<? extends
> Object>"
>
> The point is, let's do all the variable substitution on behalf of the
> user in the summary. Instead of Promise<U#2> the user should be seeing
> Promise<? extends Object>.
>
> I would still keep the technical breakdown below (with all that
> wonderful U#2 stuff) but the summary should do all the mental
> gymnastics on behalf of the user.
>
> Gili
>
> On 05/12/2014 12:02 AM, cowwoc wrote:
>> Jon,
>>
>> There has to be a way to improve this. Look at this error:
>>
>> The type of <U>thenApply(Function<? super T,? extends U>) is erroneous
>> where U,T are type-variables:
>> U extends Object declared in method <U>thenApply(Function<? super
>> T,? extends U>)
>> T extends Object declared in class Promise
>>
>> incompatible types: inference variable U#1 has incompatible bounds
>> equality constraints: Optional<GetPostalCode>
>> lower bounds: Promise<U#2>
>> where U#1,T,U#2 are type-variables:
>> U#1 extends Object declared in method <U#1>thenApply(Function<?
>> super T,? extends U#1>)
>> T extends Object declared in class Promise
>> U#2 extends Object declared in method <U#2>completed(Executor,U#2)
>>
>> The existing first line is kind of useless. All it says is "you used
>> the wrong type in <method signature>. To find out more, read through
>> the highly-technical breakdown below".
>>
>> Couldn't we replace it with this?
>>
>> "Invoked thenApply(Function<A, B>) with B =
>> Optional<GetPostalCode> but expected B to extend Object"
>>
>> I don't need you to tell me the method signature in the summary line
>> (I can read through the technical breakdown for that). Instead, you
>> should focus on describing the actual vs expected values using as
>> simple wording as possible. Is that possible?
>>
>> Gili
>>
>> On 04/12/2014 9:24 PM, Jonathan Gibbons [via OpenJDK] wrote:
>>> Gili,
>>>
>>> I am sorry you feel the error messages have gotten less readable over
>>> time, because we have put a significant amount of effort into improving
>>> the messages.
>>>
>>> It is certainly the case that the type system has gotten a lot more
>>> complex over the past few releases, and in some of the more complex
>>> cases, it is indeed hard to create readable messages . In particular,
>>> although you can interpret a series of phrases to mean
>>>
>>> "this::addProperty returns void but thenApply() expects it to return
>>> a type
>>> that extends Object"
>>>
>>> that sort of transformation is almost impossible within javac,
>>> especially given that we need to be able to localize the message for
>>> the
>>> supported non-English locales.
>>>
>>> The current design goal for the messages is to have the message begin
>>> with a short 1-line summary, followed by the code in question, to give
>>> some context, followed by any additional details the compiler is
>>> able to
>>> provide.
>>>
>>> That being said, there may well be specific instances where messages
>>> can
>>> be improved, and we welcome input when you find specific messages that
>>> are unclear.
>>>
>>> -- Jon
>>>
>>> On 12/04/2014 06:05 PM, cowwoc wrote:
>>>
>>> > Hi,
>>> >
>>> > With the addition of lambdas in Java8, I'm running into generics
>>> error
>>> > messages more frequently than ever before and the messages have
>>> gotten less
>>> > and less readable over time.
>>> >
>>> > I'll start by discussing a seemingly benign error message:
>>> >
>>> > incompatible types: bad return type in lambda expression
>>> > Promise<Optional<GetPostalCode>> cannot be converted to
>>> Optional
>>> >
>>> > for this code:
>>> >
>>> > Promise<Optional<GetPostalCode>> result = current.map(child ->
>>> > {
>>> > // do something
>>> > return Optional.empty();
>>> > }).orElseGet(() ->
>>> > {
>>> > return getPostalCode();
>>> > });
>>> > return result;
>>> >
>>> > The line triggering the error is: "return getPostalCode()"
>>> >
>>> > Here's my problem:
>>> >
>>> > 1. getPostalCode() returns "Promise<Optional<GetPostalCode>>"
>>> > 2. "result" is of the same type.
>>> > 3. Looking at this code, it's not obvious why the compiler is
>>> trying to cast
>>> > the output to "Optional"
>>> >
>>> > I've run across this kind of problem very often. The problem I am
>>> referring
>>> > to is not the specific error message but rather the fact that
>>> you're forcing
>>> > developers to reverse engineer the compiler in their head to
>>> figure out what
>>> > is going wrong.
>>> >
>>> > Instead of forcing developers to do figure out why the compiler is
>>> > attempting a seemingly wrong cast, couldn't the error message
>>> explain it
>>> > explicitly? I don't mind passing extra command-line parameters
>>> into the
>>> > compiler to get more verbose explanations, so long as this is
>>> possible.
>>> >
>>> > The second kind of error I am running into is:
>>> >
>>> > method thenApply in class Promise<T> cannot be applied to given
>>> types;
>>> > required: Function<? super PostProperty,? extends U>
>>> > found: this::addProperty
>>> > reason: cannot infer type-variable(s) U
>>> > (argument mismatch; bad return type in method reference
>>> > void cannot be converted to U)
>>> > where U,T are type-variables:
>>> > U extends Object declared in method <U>thenApply(Function<?
>>> super T,?
>>> > extends U>)
>>> > T extends Object declared in class Promise
>>> >
>>> > I don't know about you, but (as a human being) I find this message
>>> very hard
>>> > to read. It sounds as if the message was written for computers to
>>> parse, not
>>> > people. What the compiler is actually trying to say is that
>>> > "this::addProperty returns void but thenApply() expects it to
>>> return a type
>>> > that extends Object".
>>> >
>>> > Is it possible for someone to investigate improving these messages?
>>> >
>>> > Thank you,
>>> > Gili
>>> >
>>> >
>>> >
>>> > --
>>> > View this message in context:
>>> http://openjdk.5641.n7.nabble.com/Improving-readability-of-type-casting-error-messages-tp209424.html
>>> > Sent from the OpenJDK Compiler Development mailing list archive at
>>> Nabble.com.
>>>
>>>
>>>
>>> ------------------------------------------------------------------------
>>> If you reply to this email, your message will be added to the
>>> discussion below:
>>> http://openjdk.5641.n7.nabble.com/Improving-readability-of-type-casting-error-messages-tp209424p209427.html
>>>
>>> To unsubscribe from Improving readability of type/casting error
>>> messages, click here
>>> <http://openjdk.5641.n7.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=209424&code=Y293d29jQGJicy5kYXJrdGVjaC5vcmd8MjA5NDI0fDE1NzQzMjEyNDc=>.
>>> NAML
>>> <http://openjdk.5641.n7.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>>>
>>
>
--
View this message in context: http://openjdk.5641.n7.nabble.com/Improving-readability-of-type-casting-error-messages-tp209424p209440.html
Sent from the OpenJDK Compiler Development mailing list archive at Nabble.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20141204/81a0550e/attachment-0001.html>
More information about the compiler-dev
mailing list