skip to content

Linter. Sometimes It Hurts.

By Vlad Zams.   

coding

I would like to have small things unified. E. g. consistently having no space before colon character when assigning a type: to have class WebShopActivityLESE: Base() instead of class WebShopActivityLESE : Base()

But I would not like any automated tool to define how linebreaks and tab-like spaces should be organized in my code. Since those things are not purely about the visual aspect of the code, but also about how the thought behind it was organized. What I’m saying is that line breaks and tabulation can affect what we notice first and what we notice later on. I want to preserve this hand-crafted structure to let guide the reader’s attention. Or at least to increase the chance that the attention will be guided as it was intended by the author.

And depending on the problem that any particular function solves, the variance in the placement of line breaks and spaces may help to highlight something or move sth away from the primary focus.

Here is an example:

// hand-made alignment, no linter
Thread(Runnable { synchronized(threadsSyncLock) {
  while (!isUpdateComplete) { 
    try {
      threadsSyncLock.wait()
    } catch (e: InterruptedException) { 
          logInfo("onPurchasePlansRequestFailed") 
      e.printStackTrace()
    }
  }}
  loadingIndicator?.dismiss()
}).start()

line 1: few technical details are folded into one line: Thread(Runnable { synchronized(_threadsSyncLock) {

These are technical in a sense that they don’t contribute to the main idea of what the code inside that function does. The “meat” code starts on the next line and reads like “while not isUpdateCompleted try to wait for _threadsSyncLock or, if not succeeded, stop execution with an error. If still relevant, dismiss loadingIndicator.”

line 6: The extra spaces at the beginning of the line with logInfo... is not a typo, it’s done on purpose. Most of the time logging statements are not part of the “business” logic (the “meat code”), we are not interested in putting our eyes on that each time we’re trying to understand what function is primarily doing.

As soon as I learn the way to configure a particular linter so it handles the small things like a space before colon character but does not touch certain more significant things like some line breaks and tabulation, I utilize it.

Btw, quite a bizarre circumstance: none of the startups I worked with used a linter in the codebase I inherited. And some of them had 5-10 years old code. At the end of the day, there are much more important things to care about especially before hitting the first product/market fit.

… I almost forgot. See the linted version of the code mentioned above. Which one do you like more?

// with linter
Thread(
  Runnable { 
    synchronized(threadsSyncLock) {
      while (!isUpdateComplete) {
        try {
          threadsSyncLock.wait()
        } catch (e: InterruptedException) { 
              logInfo("onPurchasePlansRequestFailed") 
          e.printStackTrace()
        }
      }
    }
    loadingIndicator?.dismiss()
  }
).start()