The pragmatic programmer | Insights, and thoughts part 5

Kevin Da Silva
5 min readOct 7, 2021

--

Hello reader, as you probably noticed by the previous episodes this one is a brand new episode on the series about the insights I got from reading the book the pragmatic programmer, but if you arrived here now don't worry you can always read the previous episodes, nice to see you here and let's get started.

Debug

Photo by Timothy Dykes on Unsplash

One of the duties and one of most painful parts of being a programmer debugging by prints or by cool debuggers on IDE is almost never an easy task, especially when we are dealing with a bug that is hidden so deep on the rules of the system that can change its behavior and not get easily detected

The author's advice on this case is first of all:

Dont panic

and:

Try to find the cause before fixing symptons

When we are dealing with a tricky bug normally our instinctive behavior is to attack the symptoms in order to find the root cause of the problem, but sometimes we should give a step back, and be more analytical into finding the cause of the problem instead of running like crazy fixing symptoms that are being chained one after the other.

Rubber duck

Saying the problem out loud is an incredible way to solve the problem because it in some way triggers some subconscious part of the brain that start making connections about what was said with a solution, the authors recommend if you don't have colleagues available to do pair programming, that you find a rubber duck and try to explain the problem out loud to the rubber duck.

Find Bugs Once

Photo by Immo Wegmann on Unsplash

Now that you got some debug techniques its time to make sure a similar bug will never occur again, when the bug is solved immediately add a test case to make sure a less experienced developer will not change the piece of code that solved the bug triggering a recursion of the same bug. With a test case created whenever any developer made a change on the solution of the bug the test will break and the developer will be able to know about the bug before it gets into production. And also it makes delivery of a more safe and concise system to the users because I make sure that a reported bug will never occur anymore as well as saving your team from hours of debugging.

Exceptions

As I totally agree the authors mention that your source code should not have a lot o try-catch blocks everywhere on the code because of its GOTO flavor that pollutes the readability of the code and that's true, the authors recommend you to add specific parts of your source code to add exception handling and only for the essential parts of your program instead of applying it as a way to handle everything everywhere.

A solution I really appreciate to do exception handling in a beautiful way is the “either” data type that is very popular in functional languages. The “either” data type consists of two types like a boolean(true or false) but as Left and Right, whenever I got a successful computation it returns a successful computation wrapped inside a Right and whenever I get an error I wrap a log of the error on a Left type.

Example of either type as exception handling in haskell:

-- eithers being used to create a safe division function
safeDiv v 0 = Left "cant divide by zero error"
safeDiv v d = Right(v / d)
-- real world example using the try function that returns an either from our computationupdateComment (pipe, dbName) commentId content = do
updatedComments <- try (access pipe master dbName (updateCommentsOperation commentId content)) :: IO (Either SomeException ())
case updatedComments of
Left ex -> print $ show ex
Right _ -> print "Success"

In my opinion, eithers are the most beautiful, expressive, readable, and idiomatic way of exception handling and it can be easily portable to imperative languages and it would be nice to see it being used more outside the functional programming world.

Assumptions

As programmers, we normally make a lot of assumptions that may seem right but are not proven to be like:

“this system will only be used in this country why locate it?”

Because of globalization, your company can be bought by a multinational and if you don't have a located system from the beginning you will have to rush to achieve it in a matter of weeks before the deal is made.

“This system will not be used for more than 30 years
so two digit dates will do just fine”

The bug of the millennium showed us that some systems will be kept in use for more than that, have you heard about COBOL and mainframes before? If yes your project can be the next mainframe and lasts for centuries.

“A minute will always be 60 seconds”

Except if it is a leap second(61 or 62 seconds)

“Months will never have less than 28 days”

Except if in order to change the calendar format we need to face another month of 19 days or less

When building a system, if we cant prove it will not occur at any part of the time we need to be conscious about how it may impact the system in the future and also conscious about how to plan to recover from it in order to not get surprised by non so obvious assumptions.

Photo by Jennifer Martin on Unsplash

So here we are to what I think will be the last episode of this series on the book “The pragmatic programmer”, I still have some insights I haven't mentioned, that could make another episode, but I think we covered enough already, and I also want to left some insights for you if you are planning to read the book at some moment.

--

--

Kevin Da Silva
Kevin Da Silva

Written by Kevin Da Silva

I'm a back-end developer, functional programming lover, fascinated by computer science and languages. From the south part of Brazil to the world

No responses yet