Syntax Error #2: print it like a boss

This month's newsletter talks about the little lights on your screen and how sometimes their pattern is all wrong (and how to figure out why!)

In northern Europe, where I come from, March is the month when the nature slowly starts to wake up from the long winter slumber and extra joy and hope fills my heart. And this spring, a new issue of Syntax Error just appeared on your inbox or RSS reader!

If you like this one, why not share it with a friend? A direct link to this post online is

The lights are all wrong!

Three-panel xkcd comic. Two people are standing next to a computer, having a discussion. Panel 1: "You know this metal rectangle full of little lights?" "Yeah". Panel 2: "I spend most of my life pressing buttons to make the pattern of lights change however I want." "Sounds good". Panel 3: "But today, the pattern of lights is all wrong!" "Oh god! Try pressing more buttons" "It's not helping!"

I hope that the lights are in the right pattern for you this Friday. For those days when they are not, continue reading and learn something new!

Thanks everyone who reached out after the first issue, it really makes me happy to hear back from people reading these newsletter issues.

Last year, I wrote a blog post bit provocatively titled print is your best debug tool. I had been doing talks about debugging in a few conferences and meetups and those led to a lot of discussions with developers with varying opinions on the topic.

In your language, it may come in dressed as console.log, print, println, printf, Console.WriteLine, echo or some other form – regardless of its form, we're talking about the same concept: printing something on the screen.

Obviously, not everyone agrees with using print statements. In my blog post, I wrote

I've heard from few sources that some senior developers have been teaching juniors to avoid printing. I can only guess it comes from the dislike of print statements ending up in production but it's unfortunate if the side effect is that new developers skip printing altogether, even when it's hugely beneficial.

For me, the reason why print is the best tool is not that it's the most powerful or most complex tool available. It's exactly for the opposite reason: because it's so simple.

The main benefits of print are that 1) it only takes a few seconds to add to your code and 2) it's easy to read from the output. You add it, you run your app and you keep an eye on whatever console your application prints to.

Not having to set up anything means you can debug any legacy software in pretty much anywhere.

I'm not claiming that print would be all powerful either. It does have some shortcomings. Mainly, it requires you to run the entire software or script every time you want to see a different output. Comparing that to a more sophisticated debugging tool that lets you halt the execution, you might have to do dozens of more runs and it can get cumbersome.

So treat print as your best friend in debugging and then advance to other tools when it hits its limits.

Geoffrey Litt also wrote about this topic in his newsletter couple of years ago.

Stack trace of the Month

This month, we're looking at Elm, a language that claims to be a delightful language for reliable web applications. I haven't actually done more than a tutorial with Elm myself but I used to work with a few brilliant engineers and fantastic human beings who were really into Elm and I trust them.

One thing that I do know about Elm is its delightful error messages. This modified example comes from Elm's example collection with a mistake I baked in.

update : Msg -> Model -> Model
update msg model =
  case msg of
    Increment =>
      model + 1

    Decrement ->
      model - 1
1.1 Update function

If we try to run this update method as part of our web app, we see this error:

I am partway through parsing a `case` expression, but I got stuck here:
46|   case msg of
47|     Increment =>
I was expecting to see an arrow next.

Note: Sometimes I get confused by indentation, so try to make your `case` look something like this:

    case maybeWidth of
      Just width ->
        width + 200

      Nothing ->

Notice the indentation! Patterns are aligned with each other. Same indentation. The expressions after each arrow are all indented a bit more than the patterns. That is important!
1.2 Error message from running #1.1

Just look at that error! It's amazing. It's not a cryptic message written for a computer but a helpful story written for humans. I know not everybody likes that, some people prefer very minified and technical error messages but I'm a strong believer that error messages like these make a language more approachable.

With this error, it doesn't feel like the computer is pointing fingers or shouting angrily at me. It shows were it tripped up, what it expected to see(!) and also gives a bit of extra advice on the best practices of writing case statements.

And even if you have never seen or written a single line of Elm in your life, you can probably figure out what you need to do. That's powerful messaging!

We first learn that Elm is expecting an arrow (which we kinda provide with =>) and then shows an example of what the code should look like in case statements so we can see that we actually need to use a thin arrow (->).

Evan Czaplicki, the creator of Elm, explained the reasoning and process behind these error messages in this blog post from 2015, Compiler Errors for Humans:

Folks who prefer dynamically-typed languages are generally of the opinion that working with compiler error messages sucks. Now before anyone goes into a tired treatise about the virtues and benefits of types, think about the actual concern here. A lot of compiler error messages actually do suck. Some of them suck quite a lot. What happens when we accept that there is a problem here and try to do better?

It's definitely a worthy read for any software developer who'll ever need to deal with a case where something goes wrong - no matter if you're building a compiler or a user-facing SaaS product.

Speaking of Elm and printing, I find Elm's Debug.log quite nicely designed. It does what other print calls do but in addition, it returns the value it was passed so it can be sprinkled in as an expression as displayed in the docs:

1 + log "number" 1        -- equals 2, logs "number: 1"
length (log "start" [])   -- equals 0, logs "start: []"

Another design decision I like about it is that you pass in two arguments: the first one is a string label and the second one the value you want to print out. While it doesn't force you to write good log statements, it hopefully at least nudges you towards that direction.

Debugging in Elm by Elm Radio

There was a great episode Debugging in Elm in the Elm Radio podcast. Jeroen and Dillen discussed both generic things like assumptions, rubber ducks, taking a break and so on.

Whether you are working with Elm or not, I recommend giving it a listen. I found a lot of the things they discussed applicable to any language and it's always great to get new ideas from technologies outside your day-to-day tools.

My favorite new pick from the episode was The SSCCE (Short, Self Contained, Correct (Compilable), Example). I have previously been linking to this Stack Overflow post about Minimal, Reproducible Examples but I do like the SSCCE a bit more. Creating those examples is very good when asking questions from other people, be it in forums, chat rooms, your colleagues or your duck.

Story time

If you have debugging stories or examples you want to share to the Syntax Error community, please reach out via and we might share your story!

This month's story comes from Jesse Skinner's blog post titled Debugging a slow web app. I saw it pop up in Mastodon and my RSS feed and I really enjoyed it for how practical and detailed the story is.

I got an email today from one of my clients, letting me know that one of his web apps was down. He said he was getting an error and asked me to take a look.

The story starts as they often do: something's wrong in the production but nobody knows what. That's how most of the good debugging stories begin.

Still, I knew these API requests were hanging on something. I went back to the code and looked at the API endpoints in question, and all they did was make a database query. At this point I was pretty sure it was database-related somehow.

Jesse then goes on to explain his approach to identifying the cause: check out the site, confirm the problem exists, check dev tools to identify the route that is failing, checking server health and eventually narrowing it down to being an issue in the code that calls the database.

I wondered if I was missing something. Calling SHOW PROCESSLIST shows a summary of queries, but it cuts them off. A quick DuckDuckGo search later, and I found out you can call SHOW FULL PROCESSLIST to see the entire query.

It was then that I discovered what the problem was. The query was written exclusively using LIKE statements instead of =.

This was also a case where it would have been really hard to replicate on local development environment as Jesse explains in the blog post which makes it even more important to make sure you pinpoint the source of the issue before you start attempting to make changes to fix it.

I was surprised the problem actually was in the code base itself. It made sense to me, this isn't the kind of problem that would have shown up locally, or even when the site first launched. It would have grown slowly as the table size grew, and apparently only became a major issue once the table had over 750k records in it.

Head over to Jesse's blog post to read the whole story and the learnings of this debugging!

Syntax Error is created with love by Juhis. If you liked it, why not share it with a friend? Or if you have any feedback or just want to say hi, hit reply. I'm always happy to hear from my readers and learn about what you do and how you debug your issues.

Subscribe to Syntax Error

Sign up now to get access to the library of members-only issues.
Jamie Larson