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