<div dir="ltr">Following up on this thread, I published (to the best of my ability) the result of the work with the students.<br><br><a href="https://mccue.dev/pages/8-13-23-java-compiler-error-messages">https://mccue.dev/pages/8-13-23-java-compiler-error-messages</a><br><br>(I know I haven't really responded to Maurizio's points about the inference and parsing errors, the thrust of what I wrote and the prototype we made is "we at least need a box to put the solutions into", if that makes sense.)<br><br><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Feb 7, 2023 at 8:57 PM Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com">maurizio.cimadamore@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

  
  <div>
    <p>Hi,<br>
      there are two classes of errors that are hard. The first, as your
      example demonstrates, has to do with parser errors. When parsing
      it is hard to recover from errors. Javac tries to do its best, but
      if you are parsing a production, and you find a token that is
      unexpected for that production, it is not clear what should happen
      next. I mean, an error should be reported - but what then? Javac
      tries to figure out where to start parsing again - in some cases
      this can be done with some success (e.g. finding the matching
      closing brace, parens, etc.). In other cases it's harder, and it
      can lead to pathological situations such as the ones you describe.
      Some of these issues might be made worse by actual bugs (so it is
      possible that in the case of "expected class" there's an actual
      issue with javac - would be nice to have a reproducer).</p>
    <p>The other class of errors that are hard are errors related to
      overload resolution and inference. The problem there is that the
      error has to cover so much ground (too much). When you have an
      overload resolution failure, you can, at least in the general
      case, have many overload candidates, each of which fails for a
      different reason (which might be interesting or not). If there's
      inference, the reason as to why a candidate is not applicable
      might be obscure (e.g. incompatible bounds on an inference
      variable), and if you have nested or chained generic method calls,
      things tend to explode pretty quickly, so when your typical stream
      chain fails to type it's hard to understand exactly what needs to
      be fixed - often because the error typicall shows up in the wrong
      place. For instance, you might get an error message when you call
      `toList()` on a stream and assign it to a `List<String>` -
      but the real problem is that the type of the stream is not
      `Stream<String>` as you expect: something sent inference
      down the wrong path in an earlier call in the method chain, which
      caused the stream type to become `Stream<Object>`.</p>
    <p>These things can (and should!) be improved, but there's a limit
      on how much you can improve things when working with the command
      line interface. For instance, when diagnosing inference issues
      inside an IDE, I find myself hoovering on each component of the
      call chain, or try to use auto-complete after each subexpression,
      to have a rough idea of what the type might be at that point. Even
      doing that is not always possible: methods that are generic in
      their return type can be "influenced" by their surrounding
      context, so breaking up a method chain can sometimes result in
      changes to how a subexpression is typed. So... it's an hard
      problem - and the limited visual aids a terminal offer, combined
      with the lack of interaction makes these issues particularly
      pesky. Other langauges have explored the idea of a type debugger
      [1] - although I don't know what's the state of these initiatives.<br>
    </p>
    <p>Cheers<br>
      Maurizio<br>
    </p>
    <p>[1] - <a href="https://infoscience.epfl.ch/record/179877?ln=en" target="_blank">https://infoscience.epfl.ch/record/179877?ln=en</a><br>
    </p>
    <p><br>
    </p>
    <p><br>
    </p>
    <div>On 04/02/2023 03:48, Ethan McCue wrote:<br>
    </div>
    <blockquote type="cite">1.
      The error messages that the student got were not helpful for them
      seeing their error. I don't have their original code so I can't
      dive in to why and say "ah, we could obviously make this case
      better", but I choose to believe there was some way to not vomit "<span style="font-family:monospace">class, interface, enum, or record
        expected" </span><font face="arial, sans-serif">nine times.</font></blockquote>
  </div>

</blockquote></div>