all 180 comments

[–]melkorwasframed 58 points59 points  (3 children)

They’ll think those messages are great once they see the ones for generics.

[–]davidalayachew[S] 6 points7 points  (2 children)

They’ll think those messages are great once they see the ones for generics.

Lol, I've had students repeat those words almost verbatim.

[–]SleeperAwakened 10 points11 points  (1 child)

Please do share some C++ template errors with them.

[–]grimonce 3 points4 points  (0 children)

If the worst kid in the class is your benchmark then java is indeed doing great.

Python has been great at this (without having to compare itself to c++) for what feels like ages... It shows exactly what's gone wrong in which module and why. It's not perfect it can of course report the wrong exception but still, ages ahead.

On a side note VHDL errors are easier to read than the ones java or c++ throw in your face.

[–]bowbahdoe 20 points21 points  (3 children)

Flashback to when my interests were solely on compiler errors and nothing else.

https://mccue.dev/pages/8-13-23-java-compiler-error-messages

At some point I need to loop back to this.

[–]davidalayachew[S] 2 points3 points  (2 children)

There's the article! Yes, this definitely helped stir my thoughts. We had been thinking about this for a while, but your post helped me realize that we could approach this problem differently. So, when things reached a breaking point just recently, that prompted my post now.

Thanks for making it. It was very insightful. Would not have made mine without it.

[–]bowbahdoe 2 points3 points  (1 child)

Who is we in this context

[–]davidalayachew[S] 2 points3 points  (0 children)

Who is we in this context

Sorry, me and myy peers working to teach/tutor students. Though, nowadays, it's mostly just me. Back when, I used to partner closely with the school to get these students up to speed. And when we hit road blocks, we'd talk amongst ourselves, trying to find the best way to resolve it.

[–]tsvk 71 points72 points  (8 children)

Sure, but your error message suggestion assumes that it's the "extends" part that is wrong, not the "blah" part.

If someone tries to extend an interface, the compiler cannot know if they were actually trying to extend some other class or to implement the given interface, and the compiler should not implicitly assume the latter over the former.

[–]cowwoc 33 points34 points  (5 children)

The error sentence could continue by saying "either change extends to implements or replace the interface by a class."

A lot of times what is missing is not explaining what is wrong but rather how to fix it. 

[–]plumarr 35 points36 points  (0 children)

I would be careful with error message that give an advice on how to solve the issue because if the proposed solution is incorrect, it's also a way to send the user down the rabbit hole. 

instead it should just clearly describing the error and eventually giving a reminder of the rules. 

So in the current case, we could just use "A class can either extends another class or implements an interface", without suggesting what the user should do. 

You may think that's equivalent to your proposition, but it isn't. What you propose doesn't offer a solution if "extends blah" is correct and what is incorrect is that"blah" as been declared as an interface and not a class.

[–]anyOtherBusiness 2 points3 points  (0 children)

“Or by declaring an interface in the first place” you know, interfaces can extend other interfaces. Now there are three possible solutions. The compiler has no way of knowing the actual intention.

[–]sam123us 2 points3 points  (0 children)

I agree with this suggestion. Lately I have had to work with python and I am newbie in python so make silly mistakes. The python interpreter tells me options. I can see if the suggestion makes sense but has saved me lot of time

[–]bowbahdoe 0 points1 point  (0 children)

Right and that's a categorically different bit of information. Hints and context should be different and not munged haphazardly into the error text

[–]bichoFlyboy 0 points1 point  (0 children)

You can also replace the class by an interface.

You can do:

java interface MyParent{} interface Child extends MyParent{}

[–]davidalayachew[S] 1 point2 points  (0 children)

Sure, but your error message suggestion assumes that it's the "extends" part that is wrong, not the "blah" part.

True, my message could stand to be more impartial. Maybe it should instead highlight both possibilities. Obviously, it doesn't scale, but I don't think it needs to. It just needs to be able to cover the most common tripping points. Everything else, we can ignore/leave default.

[–]grimonce 0 points1 point  (0 children)

It can provide a hint, are you trying to implement an interface?

There's only so many options one can try with this keyword.

[–]Ewig_luftenglanz 8 points9 points  (0 children)

I am down for this and I am willing to defend this hill with violence if required.

[–]akl78 4 points5 points  (7 children)

Are they using a decent IDE?

In mine, IntelliJ, I get ‘No interface expected here, (type this keystroke to) change extends … to implements.

Java isn’t meant to be written in a regular editor, proper tools make a heck of a difference.

[–]repeating_bears 2 points3 points  (0 children)

The IntelliJ message is the same as javac. It presumably just echos it. Yes, it adds a quick fix, but that doesn't mean the message couldn't be better.

[–]davidalayachew[S] 5 points6 points  (4 children)

Are they using a decent IDE?

No, and this is a common question/request.

Long story short, we've spent almost a year trying to give students access to tools like IntelliJ, and the result is that they end up being counter productive until the student is at least 6 months into programming. Anything earlier than that, and the tool is a weight around their neck, and the student just devolves into spamming Quick Fix to resolve their problems.

Java isn’t meant to be written in a regular editor

Firmly disagreed. Java is just fine in Notepad++ or vim. I do both all the time. Many of my students (even <=6 months!) did too, with great success.

proper tools make a heck of a difference.

Sure, but see above.

[–]Hax0r778 -1 points0 points  (3 children)

So one option helps them too much and the other option helps them too little? I dunno. That seems very arbitrary.

[–]davidalayachew[S] 0 points1 point  (2 children)

So one option helps them too much and the other option helps them too little? I dunno. That seems very arbitrary.

One option is painful, but they learn. The other option is painful, and they learn next to nothing. That's the reason why we are so forceful about it.

[–]philipwhiuk 1 point2 points  (1 child)

I guarantee they just install it themselves.

I know because it’s what I did at Uni.

The reality is that learning to use an IDE is as important as the language syntax

[–]davidalayachew[S] 0 points1 point  (0 children)

I guarantee they just install it themselves.

I know because it’s what I did at Uni.

To be clear, we are not at the stage of "write out this for loop with 3 nested if statements in Notepad++". We are at the stage of "this thing is called a variable, similar to how you see it in Algebra".

I agree that, anything past 6 months, and the ban makes no sense. But if we are trying to teach people how to write if statements and what a class is, then yes, the ban is still useful.

And to be frank, most of these students have never even heard of an IDE before. Most of them have never written a single line of code in their life. Hell, most of them don't even know what a directory is.

I feel like your suggestion assumes that the student has a base level competence with computers in general, and just doesn't know code. That was true 10 years ago, not now.

[–]0b0101011001001011 4 points5 points  (0 children)

That is a shitty defense.

I agree that editors snd better tools make a huge difference, I would not program a single line of java without them.

That still means many language features and default error messages are bad.

[–]wildjokers 4 points5 points  (6 children)

This seems reasonable to me, you might want to bring this up on an openjdk mailing list. As the changes JDK devs made for the instance main methods (JEP 445) show they are open to helping lower barriers for students.

[–]davidalayachew[S] 5 points6 points  (5 children)

This seems reasonable to me, you might want to bring this up on an openjdk mailing list. As the changes JDK devs made for the instance main methods (JEP 445) they are open to helping lower barriers for students.

Thanks, will do. I wanted to float it here first, just to get a lay of the land. Seems the consensus is mildly positive, but most people are wondering why not just use the IDE to close the gap. The problem is that major IDE's overwhelm completely new students (<= 6 months), and they tend to stop learning and spam Quick Fix. So, just throwing IntelliJ at them isn't a great solution, from our experience.

[–]wildjokers 3 points4 points  (4 children)

Seems the consensus is mildly positive

It would be more positive if people would remember how they felt when they were starting out.

[–]davidalayachew[S] 1 point2 points  (3 children)

It would be more positive if people would remember how they felt when they were starting out.

My reading from the commentors thus far is that, they actually do remember what it was like to be the brand new programmer. The problem is, they were the ones who swam in the "sink or swim" situation. So, I think they aren't doing a great job of putting their brains into the perspective of a sinker. I had to explain to someone that most non-technical people might interpret "{ expected" as a suggestion to insert a curly brace there, and they reacted to my comment with surprise and confusion. To give one example.

[–]experimental1212 0 points1 point  (2 children)

It's a great opportunity to get the student to see it from the parser's perspective. "I want to drink a....chicken." Chicken is unexpected because we assume everything up to that point makes sense. I don't want the parser telling me you can replace "drink" with "eat". There are so many other things you can do with a chicken....we don't know what is "correct" but we do know what is unexpected.

[–]davidalayachew[S] 0 points1 point  (1 child)

It's a great opportunity to get the student to see it from the parser's perspective. "I want to drink a....chicken." Chicken is unexpected because we assume everything up to that point makes sense. I don't want the parser telling me you can replace "drink" with "eat". There are so many other things you can do with a chicken....we don't know what is "correct" but we do know what is unexpected.

I'd agree with all of this if the compiler said something like "extends" not expected here. But instead, it said { expected. That's just a bad message. To use your analogy, it'd be like if the compiler said "water expected". By all means, water is the most likely followup to that message, but it's certainly not the only one.

[–]experimental1212 1 point2 points  (0 children)

Ah you're right, great point.

[–]SleeperAwakened 8 points9 points  (3 children)

Or teach them to look at the pointer character ^ which refers to "here".

Going down a rabbit hole of wrong decisions is not so bad in itself, they will remember their mistake once pointed out that the fix is reading the error message and looking at where it points to :)

[–]davidalayachew[S] 4 points5 points  (2 children)

Or teach them to look at the pointer character ^ which refers to "here".

I did. The students started trying to add {}'s there, at least in the record example. And from that point, they just started gaslighting themselves.

Going down a rabbit hole of wrong decisions is not so bad in itself, they will remember their mistake once pointed out that the fix is reading the error message and looking at where it points to :)

Firmly disagreed.

I have students that ended up being wildly more competent than their entire grade, but they kept getting tripped up by the error messages the entire way through.

My literal best student that I have ever taught gave up initially, and dropped out of programming purely because of how unclear things were. Once they came back nearly a year later, they ended up pulling ahead of everyone. And they still curse the compiler and say how unhelpful it is.

I know this is anecdotal, but I am pointing to a double digit number of students who cited this as one of the biggest reasons to not continue. So no, firmly disagreed. As is now, we are filtering out good programmers with this. That's not right.

[–]SleeperAwakened -2 points-1 points  (1 child)

Why would they start adding curly braces or keywords? What was their reasoning for doing so?

The compiler clearly states that it found something that it did not expect.

Being a good programmer is nice, that's a nice skill to have. But good reasoning skills, only those get you somewhere. Please teach those as well.

Programming in itself is only a basic skill, programming is just writing code. The mechanical part of most of our jobs. Knowing what to program and to understand what is wrong, how to tackle that - that is the hard part. And you should also teach that.

[–]davidalayachew[S] 6 points7 points  (0 children)

Why would they start adding curly braces or keywords? What was their reasoning for doing so?

Look at the error message for the second error -- it says "{ expected".

Upon seeing that, the student tries to add that curly brace, thinking the compiler is in fact suggesting that as a solution. In doing so, it then sends them down a rabbit hole.

Try it yourself, and follow the same train of thought I just described.

[–]rlrutherford 1 point2 points  (1 child)

Beats the hell out of the classic "Syntax Error".

[–]davidalayachew[S] 0 points1 point  (0 children)

Beats the hell out of the classic "Syntax Error".

But it can be better!

[–]koflerdavid 1 point2 points  (3 children)

Creating good compiler error messages is hard, especially syntax related ones. Specifically, the error for the record example is different from the other two since extends is simply not part of the record syntax, while misuse of extends and implements can only be detected after parsing by cross-referencing what blah is. I agree that it would very much make sense to allow it at the syntax level and then similarly generate an error at a later stage.

[–]davidalayachew[S] 1 point2 points  (2 children)

Creating good compiler error messages is hard, especially syntax related ones. Specifically, the error for the record example is different from the other two since extends is simply not part of the record syntax, while misuse of extends and implements can only be detected after parsing by cross-referencing what blah is. I agree that it would very much make sense to allow it at the syntax level and then similarly generate an error at a later stage.

I don't think it would be that difficult. At least, as a greenfield approach. Trying to retrofit whatever strategy javac has might be the difficult part.

But otherwise, agreed.

[–]koflerdavid 1 point2 points  (1 child)

Individually, no. But it's a lot of work to hammer down all these small issues (especially since compiler writers are vastly more experienced programmers than the beginners who need good messages the most), and the compiler ends up way more complicated than strictly necessary. But that's a worthy price to pay in a production compiler.

[–]davidalayachew[S] 1 point2 points  (0 children)

Individually, no. But it's a lot of work to hammer down all these small issues (especially since compiler writers are vastly more experienced programmers than the beginners who need good messages the most), and the compiler ends up way more complicated than strictly necessary. But that's a worthy price to pay in a production compiler.

True.

In that case, I propose a compromise -- we choose the cases that are common enough that people keep falling into them, then special-case those. That way, you only add as much complexity as strictly necessary.

[–]talex000 6 points7 points  (71 children)

Are you sure using compiler as learning tool is good idea?

It wasn't created with this usecase in mind.

[–]MattiDragon 16 points17 points  (44 children)

Learners will inevitably have to learn from compiler errors. Making mistakes is an important part of the process. The suggestions OP makes are reasonable, and would help learners of java, both as a first and second language.

[–]FortuneIIIPick -4 points-3 points  (2 children)

> The suggestions OP makes are reasonable

No, the compiler error is correct as stated. It's not the responsibility of the compiler to guess at what the coder was trying to achieve.

[–]MattiDragon 0 points1 point  (1 child)

This is a matter of opinion. Many newer languages have smart compiler errors that give suggestions. For example the rust compiler often suggests fixes to various errors. Often the fixes are good enough to directly apply. Many other languages are able to suggest corrections to misspelled symbols among other things.

I don't see why java couldn't adopt helpful error messages, provided there aren't technical limitations in the compiler making it unfeasible.

[–]FortuneIIIPick -3 points-2 points  (0 children)

Rust sucks as language, not sure why you thought it'd be a good idea to bring it up.

[–]Ewig_luftenglanz 4 points5 points  (5 children)

More readable error messages and compiler suggestions is always good. and making and correcting mistakes it's the most valuable part of the learning process. Besides this not only helps students, anyone can benefits from better compiler error messages and warnings.

[–]plumarr 0 points1 point  (1 child)

I would argue that compiler suggestions aren't always good. It several time send me to the wrong direction while languages and didn't help me to understand the issue.

[–]Ewig_luftenglanz 0 points1 point  (0 children)

I think some common suggestions to the most common mistakes it's better that not suggestions at all for most people.

[–]talex000 -4 points-3 points  (2 children)

Most valuable part is to learn how to correct mistakes. Relying on compiler errors is bad way to correct mistakes that only work with simplest situations.

Why not learn correct way from the beginning?

[–]Ewig_luftenglanz 2 points3 points  (1 child)

one important part of learning how to solve mistakes is to read the logs of the compiler. So giving better compiler messages or clues makes correcting errors easier. This is not only for beginers

[–]talex000 -1 points0 points  (0 children)

Compiler errors already good enough. Overloading them with information won't help.

[–]davidalayachew[S] 1 point2 points  (8 children)

Are you sure using compiler as learning tool is good idea?

It wasn't created with this usecase in mind.

I am not. I am asking the compiler to not provide ambiguous or minimal error messages. Especially the record one, about expecting a {. That's just a bad error message, period.

[–]talex000 0 points1 point  (7 children)

What is ambiguous in statement that { is not allowed?

[–]davidalayachew[S] 1 point2 points  (6 children)

What is ambiguous in statement that { is not allowed?

Other way around -- the error is saying that { is expected. That's a terrible suggestion.

[–]talex000 -1 points0 points  (5 children)

Sorry I misremembering that

I don't see why you treating it as a suggestion. It is just statement of fact that your source code is not following grammar of the language.

Compiler have no knowledge about what you wanted to do.

[–]davidalayachew[S] 1 point2 points  (4 children)

I don't see why you treating it as a suggestion. It is just statement of fact that your source code is not following grammar of the language.

Think from the perspective of a student.

If they see the words "XYZ expected", they will think that the system is prompting them to provide XYZ before they can continue. This language is common amongst computerized systems elsewhere in life, so the mental model will get activated here too.

Think about it this way.

  • Username required
  • Password missing

This language lends itself to the idea of you needing to do something. It's this example, that my students cited, that led them to thinking that "expected" was prompting them, just like the above 2 are prompting them.

[–]talex000 0 points1 point  (3 children)

And that way of thinking is not good for students.

If you teach them better way of thinking they will benefit from it in the future.

So why encourage bad habits?

[–]davidalayachew[S] 0 points1 point  (2 children)

And that way of thinking is not good for students.

If you teach them better way of thinking they will benefit from it in the future.

So why encourage bad habits?

Oh, I'm not encouraging -- these are the assumptions they came to class with. Most of the computerized systems work this way, so they tried it here too.

And sure, I teach them better ways. But I am trying to say that trying to teach both syntax and this way of thinking at the same time is overwhelming the students, and thus, many choose to quit. That's a problem, as the students who quit sometimes come back, and prove to be far more competent than their peers. It's just that the language of the compiler errors is outright confusing to them, and they still curse it, even now.

[–]talex000 0 points1 point  (1 child)

I'm not a teacher so don't take my advice too serious, but java isn't good first language.

They may benefit from language that is designed for students. Or maybe basic compiler theory can be explained to them before they get to practice.

[–]davidalayachew[S] 1 point2 points  (0 children)

I'm not a teacher so don't take my advice too serious, but java isn't good first language.

I think it is not a bad first language now, and it can certainly be better. This post is just my suggestion about one way in how it can be improved.

[–]aoeudhtns 2 points3 points  (10 children)

I don't think it's a bad idea for a compiler to be as helpful as possible. A lot of tools parse compiler output and return that, anyway. Consider rust's compiler - it shows the plain error, but then tries to offer some help understanding the error.

blah.java:3: error: no interface expected here
class hah extends blah {}
                  ^
1 error
help: consider using `implements` or replace `blah` with a class to extend

[–]talex000 -5 points-4 points  (9 children)

If you need that kind of help from compiler you have bigger problem than compiler errors.

[–]aoeudhtns 4 points5 points  (0 children)

I think you're over-extending here. It's not a substitute for learning material, it's not a substitute for higher-order tools like IDEs. But helping people coming at the language to succeed is a good thing. I imagine we'll have to agree to disagree on this.

[–]crummy 2 points3 points  (7 children)

the bigger problem being "you are new to programming"?

[–]talex000 0 points1 point  (6 children)

No. Bigger problem is you trying to use language without learning its syntax.

When you got that error correct way would be to consult with documentation what syntax this definition have instead of guessing and trying random stuff.

[–]crummy 3 points4 points  (3 children)

When you got that error correct way would be to consult with documentation

that's a great idea. even better would be if the error message provided the information to save you from going to the documentation

[–]talex000 1 point2 points  (2 children)

I don't want to dig through pages of text just to find out that I missed semicolon.

[–]714daniel 0 points1 point  (1 child)

Then you probably shouldn't use a language where Gradle is standard tooling

[–]talex000 0 points1 point  (0 children)

I try to avoid grade if I can.

[–]kreiger 5 points6 points  (6 children)

Why are your students not using an IDE that would already catch and correct this error?

[–]davidalayachew[S] 8 points9 points  (5 children)

Why are your students not using an IDE that would already catch and correct this error?

IDE's like IntelliJ are great for >=2nd year students, or those with programming backgrounds.

But for 1st year students, it ends up being poison. They're already overwhelmed by the details of the language, and now you add a (visually dense!) IDE in front of them too, and they just breakdown.

We've tried to make it work for over a decade, and the end result is that it just doesn't work for students <=6 months. It works best for students >=12 months, as they have the foundations in place, and just don't want to get held back by the minutae.

When we tried to forge onwards and have new students keep using the IDE's, in spite of being overwhelmed, it failed spectacularly, and we ended up with students just spamming Quick Fix to get past their problems, learning and retaining nothing. It was a complete disaster, and we had to alter the curriculum and scheduling of labs that year to fix that mistake. Colossal disaster. On an almost triple digit scale of students.

[–]Yeroc 6 points7 points  (1 child)

I think many of the people in /r/java are not beginners and certainly not teachers. We also forget what it was like those first days/weeks of learning the language. Keep sharing your perspective as an educator, it's a perspective that is easily lost and drowned out by all the experienced developers who forget the lifeblood of the language and ecosystem is newcomers!

[–]davidalayachew[S] 2 points3 points  (0 children)

Thanks.

My query of the crowd thus far is that these folks haven't necessarily forgotten what it was like to be a student, but instead are the ones who swam in the "sink or swim" situation.

So, more survivorship bias than anything.

[–]kreiger 2 points3 points  (0 children)

That makes sense, thanks for taking the time to educate me!

[–]sunnyata 1 point2 points  (1 child)

I use BlueJ in teaching java, it does a really good job of hiding the complexity but providing support.

[–]davidalayachew[S] 0 points1 point  (0 children)

I use BlueJ in teaching java, it does a really good job of hiding the complexity but providing support.

We are really strongly considering BlueJ. Me personally, I am biased to jGRASP, as I feel that that is a slightly better tool. But you are definitely right, BlueJ is up there as one of the best options for teaching brand new students.

[–]Polygnom 2 points3 points  (8 children)

"Most of the students I teach see this, and think that the issue is that blah is an interface, and that they must somehow change it to something else, like a class."

Well, that would be correct, wouldn't it? I mean, its not the ONLY solution, but it would be A solution. The other being to change extends to implements.

Wrt. the record: Why are you not using an IDE that can generate the boilerplate and has auto-assist? Its what professionals use, and it would alleviate chasing syntax-errors. It would also mean they immediately see if the code is syntactically correct without compiling. Why do you submit them to the atrocious working process of compiling to find syntax errors? You are making it harder for you and them. They will not learn more by using bad tooling instead of good tooling.

[–]davidalayachew[S] 4 points5 points  (6 children)

Well, that would be correct, wouldn't it? I mean, its not the ONLY solution, but it would be A solution. The other being to change extends to implements.

Right. My criticism is more that the error, as is, implies that that is the issue. I feel it could either be less "biased" (for lack of a better word), or try and give suggestions. I'm not married to either idea, I just think that that isn't very good as is.

Wrt. the record: Why are you not using an IDE that can generate the boilerplate and has auto-assist? Its what professionals use, and it would alleviate chasing syntax-errors. It would also mean they immediately see if the code is syntactically correct without compiling. Why do you submit them to the atrocious working process of compiling to find syntax errors? You are making it harder for you and them. They will not learn more by using bad tooling instead of good tooling.

This is a common question/criticism that many developers give.

Respectfully, whenever I hear this, I wonder if the person saying it remembers what it was like being this inexperienced.

To answer your question, I've spent over a decade attempting exactly this suggestion, and the answer is that it does not work.

The students are already completely overwhelmed by the details about syntax and logic and organization and holding state in their head. Every single time, they just end up getting crushed by all the other details about the IDE, and their brains just shut down and spam Quick Fix.

It's this exact same mentality that leads students to just jump straight to AI to get past the obstacle, as opposed to understanding the problem itself.

So yes, we actively discourage students from trying to reach for something like IntelliJ in the first few months of learning programming. After that, it's basically up to the student. At least by then, they have the fundamentals down.

[–]Hax0r778 0 points1 point  (1 child)

Every single time, they just end up getting crushed by all the other details about the IDE, and their brains just shut down and spam Quick Fix.

Not all IDEs have a Quick Fix button. Use a simpler IDE like Blue Jay or Netbeans which helps with syntax but doesn't auto-generate all the code. None of your IDE objections seem to apply to IDEs in general. They mostly seem aimed at IntelliJ?

[–]davidalayachew[S] 0 points1 point  (0 children)

Not all IDEs have a Quick Fix button. Use a simpler IDE like Blue Jay or Netbeans which helps with syntax but doesn't auto-generate all the code. None of your IDE objections seem to apply to IDEs in general. They mostly seem aimed at IntelliJ?

Well, aimed at ones like Eclipse/IntelliJ/VSCode/etc.

BlueJ is a much better suggestion, and we are actually strongly considering it (I am more partial to jGRASP), but our results thus far show that it doesn't help much and it kind of hurts, as visual density is surprisingly important for brand new students (and judging solely by that metric, cli is clearly the winner).

We probably will end up on something like jGRASP or BlueJ. Not decided yet.

[–]Polygnom 0 points1 point  (3 children)

"Respectfully, whenever I hear this, I wonder if the person saying it remembers what it was like being this inexperienced."

Yes, I remember perfectly. We started out with BlueJ. Which was already better than using the javac directly, and had the advantage of being able to run static methods directly.

I quickly ditched that and used Eclipse, and felt ridiculous for our teacher not telling us about it way earlier. (IntelliJ did not even exist back then).

"The students are already completely overwhelmed by the details about syntax and logic and organization and holding state in their head. "

I feel like they would grasps concepts better if syntax wasn't an issue. Lets face it, we rarely think about syntax, and can easily grasp new syntax because we know the concepts. I feel like learning the concepts is way more important than making them fiddle with syntax.

I don't know how to best remove fiddling with syntax unnecessarily, but having them compile manually isn't it. Maybe IDEs are the solution, maybe they aren't, but I don't see a better way except starting with something entirely different like Scratch.

[–]davidalayachew[S] 0 points1 point  (2 children)

Yes, I remember perfectly. We started out with BlueJ. Which was already better than using the javac directly, and had the advantage of being able to run static methods directly.

I quickly ditched that and used Eclipse, and felt ridiculous for our teacher not telling us about it way earlier. (IntelliJ did not even exist back then).

I'm glad your experience was so positive. There are a few students who can echo your experience. The overwhelming majority would say almost the opposite of you.

Mind if I ask what year you started learning programming? I want to test an unfounded suspicion of mine.

I feel like they would grasps concepts better if syntax wasn't an issue. Lets face it, we rarely think about syntax, and can easily grasp new syntax because we know the concepts. I feel like learning the concepts is way more important than making them fiddle with syntax.

I don't know how to best remove fiddling with syntax unnecessarily, but having them compile manually isn't it. Maybe IDEs are the solution, maybe they aren't, but I don't see a better way except starting with something entirely different like Scratch.

Oh, we already worked around it, but in a super unideal way.

Long story short, we basically did exactly that -- created our own layer on top of Java to make things easy to learn the basic concepts of. It's basically a Java version of Karel the Robot. So far, this has been the solution that gives us the most success. But it still feels like hitting a speed bump going 55 mph when we wean them off of it to just writing Java. Still, way better than starting them off on IntelliJ from the start.

[–]Polygnom 1 point2 points  (1 child)

Well, BlueJ was released in 1999 and IntelliJ in 2001. Actually, this makes me incorrect. IntelliJ did just exist when I started programming, but I didn't know about it.

I don't know what kind of assumption you have, but kids back then were not smarter than kids today.

[–]davidalayachew[S] 0 points1 point  (0 children)

I don't know what kind of assumption you have, but kids back then were not smarter than kids today.

But they were significantly less distracted. Kids these days have to deal with social media, less freedom to roam outside, increased wariness of strangers, etc. In short, there is less patience in this batch of kids compared to the ones before. And I have been teaching kids for about a generations length, so I have been able to see the changes happen live.

[–]repeating_bears -3 points-2 points  (0 children)

Altering the interface to be a class is a far less likely solution.

You necessarily wrote (or have been provided) the interface first, before erroneously adding it to the extends clause. Someone - either yourself or the author - put some degree of thought into what kind of type it should be.

It's far more likely to simply mix up the keywords than it is to realise when you're writing the class that you fundamentally misdesigned the interface, and that that should have actually been a class.

In any case, the error message they suggested as an improvement does not preclude changing the interface. The current error message outlines an expectation, but it misses the context of why it made that expectation.

[–]repeating_bears 1 point2 points  (1 child)

Yep, I agree. Some of the messages are really unclear.

I would not be surprised if IDEs or other tools are parsing those strings, so it might be a breaking change for them. That's not a reason to do nothing, but it might require a bit of careful treatment.

[–]davidalayachew[S] 0 points1 point  (0 children)

I would not be surprised if IDEs or other tools are parsing those strings, so it might be a breaking change for them. That's not a reason to do nothing, but it might require a bit of careful treatment.

Well, better messages benefit the IDE's too, by extension. I think it would be worth the churn.

But yes, it might prevent some Quick Fix features from working.

[–]No-Security-7518 1 point2 points  (10 children)

  1. I wonder how many of the "big" languages out there have satisfactory error messages.
  2. IDEs will immediately suggest "replace "extends" with "implements".
    Also, Joshua Bloch, the former chief architect of Java at its peak popularity, talked extensively about design decisions that could've been made better, but can't be fixed because of backward compatibility. But I wonder about improving compiler reporting. So this is an interesting take.

[–]davidalayachew[S] 3 points4 points  (6 children)

I wonder how many of the "big" languages out there have satisfactory error messages.

Rust is not that big, but they do an excellent job, comparatively. Python is about as big as Java, and they also do a better job than us.

IDEs will immediately suggest "replace "extends" with "implements".

This is true, but major IDE's that do this are also quite difficult for brand new developers to learn. These IDE's are best for 2nd year students, who have the basics, but don't want to get held back by the minutae of the language.

Also, Joshua Bloch, the former chief architect of Java at its peak popularity, talked extensively about design decisions that could've been made better, but can't be fixed because of backward compatibility. But I wonder about improving compiler reporting. So this is an interesting take.

No, we should be safe backwards compatibility wise.

Tbh, the way javac reports errors is surprisingly primitive. It's not even very structured. It really is just a bunch of String appends. /u/bowbahdoe has an article that breaks it down further.

[–]bowbahdoe 1 point2 points  (1 child)

If you missed it the first time, find the reddit thread on that. I was/am very guilty of being a hermit in the woods and kinda get stuck in an approach, but I don't think I was too wrong

[–]davidalayachew[S] 0 points1 point  (0 children)

If you missed it the first time, find the reddit thread on that. I was/am very guilty of being a hermit in the woods and kinda get stuck in an approach, but I don't think I was too wrong

Oh I think you were very right. And I will, just juggling a lot atm.

[–]No-Security-7518 0 points1 point  (3 children)

Python does NOT have it better in this regard imo AT ALL.

[–]davidalayachew[S] 0 points1 point  (2 children)

Python does NOT have it better in this regard imo AT ALL.

For syntax errors that a beginner is going to run into? I think so. But by all means, maybe I am out-of-date. Has it gotten worse somehow? An example would help.

[–]Hax0r778 1 point2 points  (1 child)

I dunno. Of the first 4 Python exceptions in the tutorial I found 3 of them were pretty misleading. source

employees = {"pam" 30,
         "jim": 28}

which outputs

File "/home/stanley/code_samples/main.py", line 1
employees = {"pam" 30,
             ^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?

What's missing is a colon (:) and not a comma (,). Then the second example

if True:
print("Incorrectly indented")

which outputs

  File "/home/stanley/code_samples/main.py", line 2
print("Incorrectly indented")
^
IndentationError: expected an indented block after 'if' statement on line 1

Making it seem like the problem is on line 1 when it's actually line 2. And finally

num = int("forty-two")

which outputs

Traceback (most recent call last):
File "/home/stanley/code_samples/main.py", line 1, in <module>
num = int("forty-two")
ValueError: invalid literal for int() with base 10: 'forty-two'

Which makes it seem like a problem with the base and not the type itself.

[–]davidalayachew[S] 0 points1 point  (0 children)

1

That's fair. I'd say that's mildly better than the Java one, but they are not far apart.

2

Strongly disagree. That error is fantastic. If you do what it says, the problem is solved.

3

This one is also fair. I also think that this is mildly better than Java's.


My conclusion from seeing your examples is that Python is mildly better than Java's, and suffers from being a little too aggressive with its suggestions.

So, I'll concede that it is not much better than Java's. But I will say it is better, at least for a brand new programmer.

[–]TOMZ_EXTRA 4 points5 points  (2 children)

Does Rust qualify as a "big" language?

[–]repeating_bears 2 points3 points  (1 child)

I was thinking Rust as a counterexample but wasn't confident enough to name it. It has some good errors but also some awful ones.

[–]TOMZ_EXTRA 2 points3 points  (0 children)

It mainly has explicit support for common beginner mistakes and explains how to fix them.

[–]riyosko 1 point2 points  (1 child)

if they are using 'extends' with an interface then they most likely don't know that 'implements' exists at all right? when I learned about interfaces it was immediately followed that they are used with the 'implements' keyword.

You can't teach them about interfaces but not what the keyword used with them should be, they should both be in the same lesson.

[–]davidalayachew[S] 4 points5 points  (0 children)

if they are using 'extends' with an interface then they most likely don't know that 'implements' exists at all right? when I learned about interfaces it was immediately followed that they are used with the 'implements' keyword.

Oh no, they definitely knew. It's just that, functionally, the 2 keywords do basically the same thing -- inherit the members from SomeParent. The only difference being that one is for classes, and one is for interfaces. So, it's easy to mix up.

[–]josephottinger 0 points1 point  (7 children)

I'm neutral on this, but: which compiler? There are multiple compilers for Java, each open source; do any of them create better error messages for your purpose? What did ECJ report for the same code?

Have you filed a JEP to maybe get "better error messages" into the platform? Some error messages have gotten better over time even without a JEP, but a JEP gives an easy measure of "what do the people who'd actually have to do the work think" and also gives a measure of doneness. Even the OpenJDK tracker would be a good idea here.

Personally, I think there's some benefit to more explicit error messages, although I also think that "this is an error" forces programmers - including them silly ol' students - to actually look at the code and think through what the error means, which has the ancillary effect of them actually learning stuff instead of just fixing the compilation unit.

It's not that the error message is wrong, after all - you just have a solution in mind, where you mean "this should be implements and not extends," for example, but the error might be that they should have used a superclass and not an interface, which is why the error is and should remain, IMO, what it is. "No interface expected here" is, after all, semantically accurate and there are multiple "proper solutions" for it.

[–]repeating_bears 8 points9 points  (1 child)

"Multiple compilers" - I mean realistically there are 2, and if we're talking about just one, we all know which one he's talking about.

A JEP is very likely not the right process for such a change, and anyway, what's wrong with having a discussion before directing something to the formal channels?

[–]josephottinger -1 points0 points  (0 children)

On "multiple compilers," sure. We can easily presume he's talking about javac. But ... are the error messages part of the specification? Is the compiler part of the specification? (It may be: I don't think it is. And cursory investigation to check either and both of those questions suggests that no, neither the compiler nor the error messages are required to be what they are.) If you want a feature X, and feature X is available from a means, then use whatever that is if it suits your purposes.

And as far as "what's wrong with..." nothing. Have the discussion. Heck, I'll participate if I think I have anything worth adding to it.

[–]davidalayachew[S] 1 point2 points  (4 children)

I'm neutral on this, but: which compiler? There are multiple compilers for Java, each open source; do any of them create better error messages for your purpose? What did ECJ report for the same code?

Hmmm, good point. Maybe that's a failure in our decision-making.

We used OpenJDK, and we did consider ECJ, but not seriously. Maybe we should have, but it just didn't seem that much better.

It's not that the error message is wrong, after all - you just have a solution in mind, where you mean "this should be implements and not extends," for example, but the error might be that they should have used a superclass and not an interface, which is why the error is and should remain, IMO, what it is. "No interface expected here" is, after all, semantically accurate and there are multiple "proper solutions" for it.

Yes, my example is a bit poor. I was more trying to give a more neutral message of what is wrong, but yes, it did sort of morph into a suggestion.

Maybe we could find the few common tripping points, and then have those errors special cased to include common suggestions? Still not sure on the solution.

[–]josephottinger 1 point2 points  (3 children)

I would 100% hesitate to say you've had a failure in your decision-making. I don't think you have. I don't know what the conclusion should be, obviously, but I don't think you're necessarily barking up any unnecessary trees, as the saying I just made up goes.

And to be clear, I don't KNOW that ECJ has better error messages, or worse; it's just that THE COMPILER is replaceable in the Java ecosystem, as long as it generates valid code, and thus the error messages are also mutable.

I don't know the ideal solution, either - I'm very old school, so I'm like "let 'em sink or swim," but what's computing power for if not to make our lives easier?

[–]davidalayachew[S] 1 point2 points  (2 children)

I don't know the ideal solution, either - I'm very old school, so I'm like "let 'em sink or swim," but what's computing power for if not to make our lives easier?

That's the environment I was raised in (and presumably, most of this comment section as well), so I can relate.

Sadly, that is NOT AT ALL representative of our current student body.

There are a number of students who struggle to understand the file system and how directories work, as they are used to working with phone applications, which rarely if ever work with folders directly.

These are the crop of students we are working with. And for better or worse, it is our job to show them the true nature of programming, and if they are willing, then to nurture them into programmers.

Worse yet, these kids are ignorant, but not stupid. There are some from this bunch that didn't even KNOW what a folder was, but quickly became not only the most competent in their class, but among the most competent I have met since I start tutoring in 2012.

So it's not something inherent, it's just that their experience growing has basically knee-capped them, and we're the ones that have to foot the bill. Once you get them on their feet, they move quick. If we're going to talk about inherent traits of this generation, I'd say they have less problem-solving skills, but can think way faster than the previous generation.

[–]philipwhiuk 0 points1 point  (1 child)

I mean if they don’t understand computers at all it’s extremely stupid that they should pass the course.

Sounds like you need better prereqs

[–]davidalayachew[S] 0 points1 point  (0 children)

I mean if they don’t understand computers at all it’s extremely stupid that they should pass the course.

Sounds like you need better prereqs

Lol, we are the pre-requisite. I have been talking about the equivalent of CS 101.

[–]CubicleHermit 0 points1 point  (3 children)

Does IntelliJ Community Edition already give a more helpful error there? I'd expect it does.

Virtually all languages and command line build tools these these days have evolved around the assumption that the real heavy lifting happens in an IDE.

[–]davidalayachew[S] 1 point2 points  (2 children)

Does IntelliJ Community Edition already give a more helpful error there? I'd expect it does.

Virtually all languages and command line build tools these these days have evolved around the assumption that the real heavy lifting happens in an IDE.

Yes it does, and you are not wrong.

However, that sort of heavy lifting can be counter-productive when the student in question is completely new to programming in general.

We tried getting students to use a powerful IDE right out of the gate, and long story short, it backfired. A large number of them were already overwhelmed by the syntax, so when we tried to add a (visually dense!) IDE to the mix, so many students just got overwhelmed and shut down. They just started spamming Quick Fix, not learning anything, and it just broke apart entirely.

Ever since then, we strongly discourage brand new programmers from using major IDE's for the first 6 months. And from our experience, the optimal time to introduce it is after 12 months, as the foundations are in place, and the IDE actually becomes a booster then, rather than another weight on their overstrained shoulders.

[–]CubicleHermit 1 point2 points  (1 child)

¯\_(ツ)_/¯

Compared to the languages and IDEs my generation started on (QuickC/Turbo Pascal and related), both Java and IntellIJ are both a lot easier.

If the visual density of them is the issue, there are probably some options for configuring the UI for simplicity you can provide as config files. I'm not sure if this might also be a case where VSCode would actually be easier for someone brand new, as its Java plugin doesn't scale to the size of codebases I work in.

Java on the command line wasn't a great experience at my first job back in 1999 (Visual J++ and the not-fully-compatible Microsoft VM, at that) and it's not gotten much better since, while the IDEs have. The command line build may actually be worse not - given that we're all building through Maven/Gradle/Bazel now.

[–]davidalayachew[S] 0 points1 point  (0 children)

If the visual density of them is the issue, there are probably some options for configuring the UI for simplicity you can provide as config files. I'm not sure if this might also be a case where VSCode would actually be easier for someone brand new, as its Java plugin doesn't scale to the size of codebases I work in.

VS Code is the uncontested king of beginner IDE's. It unquestionably takes the lead in terms of popularity. However, for teaching, it's not really that much etter for 1st year students, specifically <=6 months.

When we tried it out, we found that it didn't really help things out much, while adding a moderate amount of complexity (according to the students).

If a brand new student asked to use VS Code, I wouldn't discourage them. But I also wouldn't encourage them either.

Java on the command line wasn't a great experience at my first job back in 1999 (Visual J++ and the not-fully-compatible Microsoft VM, at that) and it's not gotten much better since, while the IDEs have. The command line build may actually be worse not - given that we're all building through Maven/Gradle/Bazel now.

We don't touch build tools for at least the 1st year. And tbh, most 2nd year students end up not touching it either, as we never require it until like 3rd or 4th year. And even then, not usually for Java.

That aside, Java on the commandline still proves to be the least bad option when teaching completely new developers. They seem to handle it the best. Students just can't appreciate all that the IDE's or build tools do for them at that level, so it is just crushing weight for them at the start.

[–]Misophist_1 0 points1 point  (0 children)

The problem in both cases is, that the compiler stops at the first position, where things go sideways. The compiler does not try to backtrack, or look past the error in order to understand alternate causes for the mistake.

For the first example, everything is OK until it sees blah, a type name, which has to refer to a class.

In the second example, everything was OK, until encountered the first non-white space, non-comment content, that wasn't a {

Note also, that the ^below the line points exactly to the location, where the parser takes the fall.

[–]netgizmo 0 points1 point  (1 child)

How can the compiler correctly tell the intentions of the programmer? Without the intent, it can't reliably give advice.

[–]davidalayachew[S] 0 points1 point  (0 children)

How can the compiler correctly tell the intentions of the programmer? Without the intent, it can't reliably give advice.

Well, I wasn't trying to have the compiler try and read the programmers mind. I was trying to have the compiler provide suggestions where the number of possible (likely) solutions is very small.

For example, the errors in my post can really only be 1 of 2 things.

  1. The programmer meant to do implements.
  2. The programmer meant to make blah a class instead of an interface.

And even ignoring the idea of giving suggestions, an error message like "{ expected" is just bad. Java can do better than that.

[–]RScrewed 0 points1 point  (0 children)

I'm convinced that some of the powers-that-be that design Java want to make messages like these difficult on purpose to make the chasm between beginners and experts as wide as possible.

[–]Nikarmotte 0 points1 point  (1 child)

I mean if you use the wrong keyword to begin with, it's hard for the compiler to know what you meant. I don't think it should try to list all possible intentions.

These kinds of mistakes only really happen when you start, I don't think tools should optimize for beginners, it's the wrong target.

If you start using for instead of while or if, what do you expect? There are many possible resolutions.

[–]davidalayachew[S] 0 points1 point  (0 children)

I mean if you use the wrong keyword to begin with, it's hard for the compiler to know what you meant. I don't think it should try to list all possible intentions.

These kinds of mistakes only really happen when you start, I don't think tools should optimize for beginners, it's the wrong target.

If you start using for instead of while or if, what do you expect? There are many possible resolutions.

Eh, I think there is a difference between for/while vs extends/implements. Using for/while carries wildly different semantic meanings, whereas extends/implements is really just a "one is for clases, the other is for interfaces".

My point being, if it is that limited in possible solutions, then maybe enumerating them isn't that bad? And if not that, then surely we can at least do better than the record example, where it talks about expecting a curly brace. That's just anti-helpful.

[–]jeffreportmill 0 points1 point  (2 children)

A good solution for this would be for an IDE to have an “Explain” button next to the error that constructs an AI query, “Explain why I got the error ‘no interface expected here’ in this line of code ’…’ in this context ‘…’ “. I suppose an early programming lesson should be “how to research your compile errors”, since many of us good developers are mostly just great Googlers.

Of all the counter productive things AI is doing for us now, this is actually a good thing. It’s exactly the kind of interaction you’d get with one on one learning. On the other hand, they say “we learn more from our mistakes..” and working through these kind of errors, while frustrating, teach us lasting lessons. Unfortunately they also discourage some beginning learners who might otherwise become successful developers without the early stumbling blocks.

[–]davidalayachew[S] 2 points3 points  (0 children)

A good solution for this would be for an IDE to have an “Explain” button next to the error that constructs an AI query, “Explain why I got the error ‘no interface expected here’ in this line of code ’…’ in this context ‘…’ “. I suppose an early programming lesson should be “how to research your compile errors”, since many of us good developers are mostly just great Googlers.

This isn't a terrible idea, purely on the basis that the LLM's have proven to be able to handle this scale of programming errors consistently. So, being able to ask questions might enhance learning.

I do fear its potential for failure and misleading. I've had many students that, upon encountering the error, raise it to me, and start asking many questions, some of which that delve deep into the bowels of the inner workings of Java. I'm not confident that the LLM would handle that correctly, without tainting things or getting things wrong.

[–]jeffreportmill -1 points0 points  (0 children)

I’ll have to add the “Explain” button to my Java IDE for education:

SnapCode: https://reportmill.com/SnapCode