On interfaces and backward compatibility - Part 1 of 2

The Ship of Theseus

As told in an old Greek myth, Theseus defeated the Minotaur and escaped from Crete in his ship, thus rescuing the children from his motherland. To commemorate this great feat, the people from Athens preserved the ship through the centuries, replacing its wooden planks and poles as they decayed. There eventually came a time when all the original pieces were gone, and so the story is cited as a classical thought experiment: was this the same ship as the original one if every piece had been replaced, or did this constitute a novel entity altogether?

Portion of the François Vase depicting one of Theseus’s trips [1].

Interfaces: where do I plug this in?

In the most generical way, we can think of an interface as simply a ‘point of interaction between entities’, whether physical or logical. What do we mean by entity? A person, a mechanical or electrical system, a web server, a tool, a source of energy: so pretty much anything you can think of as separate agents or pieces of a system.

Even though the term adoption was heavily influenced by computer technology -you might first associate it with a ‘user interface’ in a web page, or application-, the truth is that we can find examples of interfaces pretty much everywhere in day to day life: a door can be thought of as an interface between rooms, a doorknob an interface between a person and a door, a sign an interface between the road infrastructure and your eyes, a contract an interface between two businesses, an RJ-45 socket an interface between your internet router and your computer (or is it two interfaces, one on each end of the Ethernet cable?). An interface can even be invisible: just think of your cell phone connecting to a tower.

We can also think of nested interfaces, since what’s considered an interface for a level of abstraction can be a whole system on its own for another. For instance, you can say a headphone is an interface between your ears and a sound system; and you can also take apart a headphone -especially a modern Bluetooth one-, and see that it holds itself a myriad of smaller entities that connect between each other: a battery and a charging port to the mainboard, a wireless and memory chips to the main microcontroller, a sound amplifier to the earphone coils.

In the engineering world we use interfaces explicitly to design products and systems, and the main reason to do so is to compartmentalize, i.e. to delimit responsibilities or scope. For instance, a socket on a wall does not care about what you plug into it, as long as the appliance and the socket “agree” on a set of rules: same voltage, same connector, same limit on power consumption.

The emphasis on rules cannot be overstated: a sensible interface is expected to define a detailed and stable set of rules. This might as well be considered a contract between two parties. For users of technology, for instance, this means you know beforehand what kind of device you can plug into your USB port. For engineers, this means we can design larger systems and divide up the work into pieces to be developed by separate people, and expect things to work when everything is integrated. Although this does not always happen (either because the understanding of the rules had a mismatch between groups, or because the interface itself was ill-defined from the start, or even changed along the way), having agreed-upon points of communication between subsystems allow the work to be done in parallel and areas of expertise to be clearly separated.

As a junior engineer, the jobs I was assigned were naturally small-ish modules (e.g. build an OTU scrambler for 256-bit data width). As years went by and my work started to become more abstract and encompass larger areas within systems, I started to appreciate the times I was given smaller, well-defined tasks, because I realized how hard it is to do that without interfaces falling apart along the way (this is very important since changes in interfaces along the development of a product become very costly, very fast).

It became obvious that an important aspect of designing a system consists of clearly defining external and internal interfaces for all or most of its layers. This sometimes happens way before the development of its constituent parts even starts, and it ends up imposing very hard constraints on the shape of every such layer of the system. It’s sort of like those experiments we did as kids, where we’d put a sheet of paper on top of a magnet and then scatter iron filings all over the page, to see them fall into place according to the underlying magnetic fields. You might think of the sheet as a truly blank slate, but that’s not really the case. It also reminds me of a certain mythical ship...

Diagram of a Intel Stratix 10 System-on-Chip device depicting a myriad of interfaces connecting the different subsystems [2].

Backward compatibility

Large systems can have a huge number of external interfaces, and an even larger number of internal ones (these interfaces even tend to mimic the communicational structure of the company building it -something referred to as Conway’s law- but that’s a topic for another day).

And so, what sometimes happens is that the evolution of the different pieces of a product (be it a software system, railway infrastructure, an integrated circuit, particle accelerator, or a lithography machine) is not time-aligned among teams. This is, version 1 of the system might contain version 1 of subsystems A, B, and C; version 2 of the system might contain version 2 of subsystems A and C, but still maintain version 1 of subsystem B; and so on and so forth. And when this happens, the only way to keep coherence within the system is by keeping the interfaces stable.

But when new features must be introduced, new interfaces appear even though not every side is ready to use them (another generic example: tier A of the product introduces version 2 of every subsystem, but tier B is still in the market and only uses version 2 for subsystem B, and version 1 for everything else). This imposes that certain subsystems must maintain compatibility with older and newer versions of their counterparts (i.e. support more than one interface, or interface version). This might be much more relatable when we talk about external interfaces: imagine a newer video game console supporting both last and previous generation games, or a WiFi 6 router supporting older devices that only go up to WiFi 4.

This concept is called backward compatibility (although I much prefer the Spanish word, which literally translates to Retrocompatibility), and it appears for a number of reasons:

  • Different timelines in internal development, such as the previous examples.
  • Market needs, such as contracts with clients who have bought previous versions of our equipment.
  • Gradual adoption of newer technology in consumers.
  • Cost or availability of replacement parts.

This struck me as a very interesting engineering challenge when a dear communications technologies professor told us to about the following example: FM broadcasting was conceived in the 1930s as a monaural radio system that offered higher quality audio when compared to classical AM communication. By the 1950s, when it was already fairly established and several commercial operators were present across the US and Europe, many companies started proposing methods to improve FM and introduce stereo channels. The largest constraint, though, was that such methods must not break compatibility with existing receivers, which until the date only supported mono audio.The methodology proposed simultaneously by Zenith and General Electric, and later on accepted by the American FCC, is as follows: turn the mono channel, which spanned from 30 Hz to 15 kHz of the radio bandwidth, into the sum of the left and right stereo channels (L+R), and add a difference signal in a higher part of the spectrum, around the 38 kHz mark (L-R). Hence, mono receivers wouldn’t be able to tell the difference and would just play the L+R signal, while newer stereo receivers would need to decode both channels and route their sum to the left channel (L+R+L-R = 2L), and their difference to the right channel (L+R-(L-R) = L+R-L+R = 2R). Quite elegant, I think.

Diagram of the frequency spectrum (one-sided) occupation of an FM radio channel. RDS is a much newer digital data channel added to transmit text data along the audio, such as what’s playing or news snippets [3].

Written by Leandro Echevarría

If you need further information, contact us: info@emtech.com.ar