What To Do About the Red Squiggles?

NOTE: This document assumes you know what Types, Subroutines, and Variables are. Here's a refresher on Programming in Java


Java is a precise language. Just like English, Java has rules for how it's structures can be related and where to place punctuation marks. But unlike a human who speaks English, Java requires that your code conform to it's rules exactly. Java can not guess what you really mean when you misspell a variable or forget to add the right parentheses. These kinds of grammatical mistakes are called syntax errors, which Replit displays like so:

Note the red squiggly line underneath the text ReadLetter. Syntax errors are always shown using a red underline and must be resolved before you can run your program. Contrast this to runtime errors which happen when Java can understand your code perfectly well, but you gave the computer incorrect instructions.

So how do we fix these syntax errors? Let's start by looking at the two ways of finding out what the problem is.

You can hover the mouse over the red underlined text:

Or run the program and see it fail in the panel on the right:

Sometimes these error messages are helpful, sometimes they're not. Usually they can provide a clue for where to go looking, though they're often cryptic and more confusing than they're worth. In this case, Java is trying to tell us that it cannot find a symbol that corresponds to ReadLetter.

Next, let's look at the position of the error. Notice that the red squiggle is only under the text ReadLetter, and not under anything else in the line. This isn't always perfectly accurate, sometimes incorrect code can look correct for a while before breaking. Most of the time, the squiggle will be at the incorrect code or just after it.

And finally, we have to consider the purpose of the broken code. Java can't help us here, it has no idea what we're doing. The whole purpose of writing the code is to explain to Java what we want it to do. As programmers, we know that the text Zystem.ReadLetter is supposed to be calling a subroutine, and putting the result of that subroutine in the input variable. (did you not know that Zystem.ReadLetter is a subroutine? Review these materials)

So let's review our clues:

Now this is the hard part, you have to think about these clues, their relationship, and put the pieces together. The first two clues tell you what you have and the last clue tells you what you're trying to do. At this point, I usually look up the correct syntax on google or through refrence materials. Can you think of how to fix this error? Try it and come back.

Done? Results not what you expected? Let's dig in.

In this case, the solution is that the Java compiler thought you where asking for a class field (another name for variable, which is why Java uses the term 'Symbol') and couldn't find one, while what we meant to say was "call this subroutine." The solution is to add a '(' and a ')' to the end of the line, before the semicolon, to turn this from a field access to a subroutine call:

Success! We fixed the cannot be resolved to a field error! And drat! A new error! This is a common occurence when dealing with Syntax errors. Each time we fix an error it reveals new, higher-level problems with our code that Java couldn't catch until it knew exactly what we where trying to say. The solution is simple: keep collecting clues and solving problems until Java stops complaining. Let's look at the error message again, this time in the console on the right to practice reading the other way:

And let's go through our clues:

Again, this is the hard part, we have to do some creative thinking and problem solving. Java is telling us that there's a type mismatch between the variable and the subroutine call, so we either have to change our variable's type, or change the Zystem.ReadLetter() call. Can you think of how you would change either of these to fix the error?

Let's go through both kinds of solutions.

First, changing the type of our variable. Java told us that char cannot be converted to String. In the context of our code's purpose, that means that Zystem.ReadLetter() is giving us a char, but we're trying to put that into a variable that's expecting a String. Let's change what type the variable input is expecting to char:

Success! No syntax errors, and we can continue on programming with a char input.

But what if we needed that String? What if our input is more complicated than a single character? If we look at the Zystem documentation, there's another subroutine in there that gives us a String: Zystem.ReadWord(). I'll leave you to read the description of Zystem.ReadWord() in our documentation on your own time. It's good practice to know exactly what is happening when calling subroutines so there aren't any surprises later. If we change our code to use this new subroutine:

Success again! No syntax errors, and we can continue programming with a String input.

Top Down Design, knowing the purpose of each line of code and how it relates to the next, is the only way to determine which of these solutions is better. They're both valid Java code, but usually only one is best for your specific use case. This is why the compiler's errors are so cryptic and confusing, it can't do TDD and has no idea what you're trying to do. It can only tell you that, whatever you where doing, you did it wrong.

So to recap, here's how you fix syntax errors:

And that's it. Good luck, and always remember to ask a friend or a mentor for help if you get stuck on one of these steps :)

P.S. Replit can be slow and a little buggy. The red squiggles don't always show up immediately (or at all) when I've used Replit. The Java Compiler on the right will always tell you exactly what's wrong, and you should trust it's judgement implicitly. But it can be a little harder to read than the red squiggles.To be a productive programmer, you need to understand how to read both kinds of errors.

- Mikayla Maki

First Draft 2022 April 13