Home > Uncategorized > Future-Proof Your Programming Skills

Future-Proof Your Programming Skills

October 7, 2023

If you started with Java when it was the ‘new kid’, and then moved into Node-JS, Rust or Python, you come to know that the language you are using today may not be the one you are using in two or three years. Structured programming, objects, encapsulation, open-source frameworks and packages are common features of all modern platforms. So, when we migrate to a new environment – we expect to find these familiar constructs along with a new twist.

Read on, and you will see how developing your logical thinking skills is actually your core competency.

As we all come “up to speed” in a new development environment, we reach for familiar job aids the first two or three weeks. A good code editor will “grammar check” your code and helpfully fill in key reserved words.  Syntax cheat sheets and code examples will get you rapidly oriented to syntax in your new language.

In quick references, you will find the hundred or so built-in functions that do the usual type conversions, string and numeric manipulations and so on. Are they implemented “SQL” style, or are they called as an object’s method? Is code structure defined with keywords beginning and ending code blocks, or does indentation create structure? Can I create a data type and assign it values, or am I limited to traditional data types? How does it handle JSON or XML? Where are the database APIs?

None of these “quick start” tools will help you to debug one of the most common logic mistakes in programming. The order in which code is executed matters, and you must learn how to control it.

The Beginner Debugging Challenge

When we read code, the default assumption is that code is executed in the order presented, and this is often true. Beginner mistakes include such things as attempting arithmetic on an undefined variable and missing code dependencies. Language nuance does matter a bit here. Do we declare a variable or object before using it, or is it implicitly declared and typed on first use?

The Intermediate Debugging Challenge

In many languages code is not always executed in the order presented. The simplest example is a nested and not so obvious break from a loop or a function. A more complex example is the “callback function”, a bit of code that is triggered upon the completion of another code.

The next debugging challenge in the intermediate category is event handling code – code that is triggered by a change to system state. In the cloud it could be code that is triggered when a file is added to a directory. In integration with real-world sensors and devices it could be code that is triggered by light, movement, a magnetic sensor, and so on.

The most challenging entry in this category is concurrency and “race condition” issues. When the language and platforms permit parallel execution of code, one routine may complete too soon, and “turn out the lights and put out the cat” before another routine has completed its work.   Or, two or more routines may compete for a shared resource and “gridlock” the application so that no routine can proceed.

Even non-procedural tools like SQL are vulnerable to concurrency logic issues. SQL logic grows into scripts. Scripts become stored procedures. Stored procedures become multiple “cron” jobs that are released into systems on independent schedules. Suddenly, completion order, and race conditions are again in play, and must be sorted out.

The Advanced Debugging Challenge

Here is a little true story that illustrate an advanced issue of logic and order of execution:

There once was a very big bank who had to reload customer accounts from backup. One most recent and tiny transaction, a few pennies of a bank change was not reloaded into several customer accounts. All other historical transactions were recovered, and IT was satisfied that all ending balances were correct.

A very conscientious customer had kept, printed and filed every monthly statement from the bank for years. It was satisfying for them to see each ending balance transferred to the next month, all transactions present and accounted for, and a new correct ending balance drawn from the beginning balance and the monthly activity.

WHOOPS! The online new month’s balance now suddenly does not agree with the last printed statement’s ending balance!

And, the online system has new and different beginning and ending balances the previous month and the next previous month, and so on.

There was no explanation. No transaction was present that accounted for the missing few pennies and no obvious reason why all online records by month were now retroactively different from the printed and saved monthly statements!

What do you think happened?

Perhaps a programmer thought and built the on-line system like this:

IF New Balance = Old Balance plus Transaction data,
THEN Old Balance = New Balance minus Transaction data.

It is a common mistake to think we can cleverly and always recreate past state of a database or system. That is most likely the error in logic for the banking programmer. Bank ledgers are uni-directional. Calculations always proceed from closed accounting periods to closed accounting periods. Here, it is not just the order in which code is executed, it is the order in which data is handled for correct and auditable results.

Conclusion

Banking systems must retain the past state of customer accounts, and not ‘reverse-engineer” past ending balances. The same is true for many business processes where programming must take and retain snapshots of the “current state” of the operation.  

The solution to these and other kinds of logic issues will not be found in a programming language quick reference. They come from experience and a willingness to think and understand more about what you are asking the system to do, in addition to how you ask the language to do it.

Comments are closed.