paint-brush
Thoughts on cyclomatic complexity in Golang's worldby@DiegoZoracKy
5,369 reads
5,369 reads

Thoughts on cyclomatic complexity in Golang's world

by Diego ZoracKyApril 12th, 2018
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Cyclomatic complexity can be helpful in keeping us away from writing complex code that can be more error prone, more complex to be tested and harder to reason about. I would give a special attention for the latter one as it implies in low readability and high maintenance costs. For example, an if/else statement is commonly used as:

Coin Mentioned

Mention Thumbnail
featured image - Thoughts on cyclomatic complexity in Golang's world
Diego ZoracKy HackerNoon profile picture

Cyclomatic complexity can be helpful in keeping us away from writing complex code that can be more error prone, more complex to be tested and harder to reason about. I would give a special attention for the latter one as it implies in low readability and high maintenance costs. For example, an if/else statement is commonly used as:


if THIS thendo some logic in order to return THAT


if THAT thendo some logic in order to return THIS




if SOMETHINGELSE thendo some logic in order to return THAT and THISelsedo some logic in order to return THIS and THAT

Usually each block contains some logic in order to do something. Naturally each piece of logic requires attention as one must understand what a block is doing, what is its purpose and if the expected result is what is being produced. Now imagine a single function with twenty conditional statements, where each one produces a single different result, and you have to explain (and remember) what are all the values that this function returns and under which conditions. Probably you already got the point.

However, note that cyclomatic complexity doesn’t try to determine how complex each path contained in a control flow graph is. It doesn’t try to understand each block of your program’s architecture, instead, it focus on how most of the programs are written and assumes that all cases are equal. In order to be helpful it assumes that all execution path contains a specific and unique piece of logic, as most of the time, it is the case. I have been thinking about that point since I started programming in Go. Following the error handling pattern we use in Golang, check this other example:



THIS, ERR := fnGetThis()if ERR thenreturn error



THAT, ERR := fnGetThat()if ERR thenreturn error



SOMETHINGELSE, ERR := fnGetSomethingElse()if ERR thenreturn error



WHATEVER, ERR := fnGetWhatever()if ERR thenreturn error

do some logic in order to produce the expected result using THIS, THAT, SOMETHINGELSE and WHATEVER

It seems to me that none of the if statements that only return an error, and has no extra logic, can be error prone, nor is difficult to reason about, nor makes it harder to explain the purpose of that whole block. It does one thing, once everything it needs works.

Maybe a better cyclomatic complexity analysis would be presented if we could choose to discard the cases where returning an error is the only thing that is done, and nothing else. As the real complexity to generate those errors is not written there, but instead, in the functions that are being called.

I would like to hear more thoughts on this subject as my goal here is to discuss about it. So, feel free to leave a comment 😉.