The Code Diarist

A diary about code

Code Within Code: List of Mysteries

April 26, 2025

How much should my code depend on other people’s code?

This question comes up early and often when writing code for microcontrollers.

Suppose I want to connect a gas sensor to a device that will alert me when it sniffs gas? Whatever sensor I might choose, someone, somewhere, will have written a library of code designed to make it easy. I might use such a hypothetical library this way in my code:

  /* bring the library into my project */
  #include <gas_sensor_library.h>
  
  /* access procedures in the library by their names */
  gas_sensor.begin();
	    

The notable point here is that the library can contain all of the code required to communicate with the sensor and to interpret the data it provides. The library could do all of the technically challenging things behind the scenes while “exposing” to a code writer like me just one, usable instruction: for example, to get the current gas level.

  gasConcentration = gas_sensor.gasLevel();
		

Alternatively, the sensing device could be interactive. Suppose it were capable of taking certain actions depending on instructions it receives from my program. Perhaps it could signal an alarm if the gas level exceeds some amount. The library could provide a procedure for setting things up inside the device. All that I might see is a name by which to call the procedure and to designate an amount of gas at which to activate the alarm.

  gas_sensor.setAlarmAboveGasLevel(3000);
		

When I use the library, I do not need to know how such an instruction actually gets carried out. I just need to know that the instruction exists, and what result to expect when my code executes the instruction.

A library such as the example given here is called a dependency of my code. Literally, the success of my code depends upon it. I must depend on the people who wrote the code in the library to have made it reliable and to keep it that way. Code within code; what could go wrong?

Plenty. Especially in the open-source world, where I do most of my work with code.

Open-source libraries abound for popular devices such as the various kinds of Arduino circuit boards. Typically, they were written a long time ago by volunteers. Also typically, those volunteers in turn made liberal use of other libraries written even longer ago by other volunteers. Code within code within code within code...

Consider the new-version problem. It is not unusual for some nice person to mess up a lot of other people's code by coming in to “help” with maintaining a older library. They change how some some instruction works and then bang! that dependency becomes incompatible with other people's projects all over the world that were built in reliance upon upon a now-obsolete, prior version of that library.

There are many more ways that a dependency can go wrong. We have, for example, the multiple-library puzzle. There may be many different libraries available for that gas sensor of ours, written by different people, some better than others, some perhaps deficient in one way or another. Which one to choose? The flip side of that scenario is the deleted-dependency situation, where someone who made a useful library available for a long time no longer does.

For such reasons, I often write my own code, even when a reputable library has already ‘solved’ whatever I happen to be working on. Surely I will at first make mistakes that could be avoided with the library. Yet I can learn from my mistakes and so hope to get better at writing code. And when I finally get it right, I can believe that no one will mess up my code by changing a library it would otherwise have depended upon.

Reasonable people can disagree on the advantages and disadvantages of writing one's own code compared to using reputable libraries when available. I will bow to the conclusion that code-within-code is often the better way to go in most situations. There is one place where I would disagree, however. Writing one's own wins the prize when learning is the goal.

The learning angle is actually important to me. I grumble that we who encourage children to engage with code by messing around with Arduinos approach the children's learning superficially. We want the kids to enjoy the experience. We think, Golly, they might have fun playing with that gas sensor doohickey.

So we show them how easily it attaches to an Arduino and how to download a ready-made library of code for it. Hey kids, look! You’ve Got Gas! Cue the golf-applause from the school board and the Facebook followers.

What do they learn? They learn to reach no farther than the nearest code library. We teach them short-cuts that actually avoid learning. We teach them to perform magic tricks with libraries instead of asking them to read — and to understand — what is written in those libraries.

We teach them dependency.

Hiding the implementation inside a library can actually retard progress. I recently experienced several days of delays with a gas sensor because an important fact about the blessed thing was embedded in a line of code inside a library. The fact was the sensor had been designed in such a way that it could not work with the microcontroller my project would be using.

After digging a clue to that fact out of the library, we were able to confirm it by consulting other reference materials. The project is suspended temporarily while we wait for a different type of sensor to arrive.

Code is not magic; it is method, directed to a purpose. When using a library, study it to learn how its code works. Then study that to learn how devices such as the gas sensor work. I want more than merely to mumble a mouthful of mystical incantations from some prepackaged procedures for performing pretty tricks.

We increase interest and decrease fear in the world around us when we know better how the things we use do what they do for us.