Features vs. Requirements - Introduction

❝... on the difference between a feature and a requirement.❞

It is not always as easy to make a distinction between a feature of a (library) implementation and the requirement of its users. They are not perfect counterparts. There is a gray area in between the implementation of a library and the use of it, partly caused by the desire to provide a complete, full-featured library implementation. This series is about making the distinction between the two for a number of different but closely related aspects of programming: thread-safety, (non)blocking I/O and memory usage. I am hoping to paint you a picture of where to draw this line in a number of different cases.

With the introduction of multi-processing, the ability to run multiple processes at the same time, and the use of computers primarily through a graphical user interface, it has become increasingly necessary to run multiple pieces of code simultaneously. For example, you would not want your computer to be frozen for the entire time that it takes to install a program, or to render a movie. We expect programs to run in parallel, such that we do not have to wait for one program to finish before the next can run. Even more, we expect a single program to do processing and at the same time to respond to our mouse clicks. Like a virus scanner that is scanning your PC, while at the same time you expect to receive updates on progress and findings. These are cases where you need to construct your program in such a way that it works with multiple processes or threads, at least one of which is at the beck and call of the user, and others that do the actual work.

I/O operations are an infamous source of delays. Whether data is read from a storage unit or a network interface, I/O causes delays in processing. Blocking I/O is more convenient to implement, while non-blocking I/O gives the developer control over the delays.

Similarly with buffering and memory usage, we expect a library to make use of all the memory it needs to perform its function. In the general case we would not want trade in every last byte of used memory for CPU cycles. However, we should not trade in more than is strictly required for its operation, especially in the age of Big Data and data flow networks.

This series is a way to explore the various aspects and properties of decisions that need to be made in software development. Decisions that typically are trade offs for performance, simplicity, understandability, determinism, support and the likes. Some solutions are better supported by language constructs and/or its standard library, even though different solutions are available.

In the following articles of this series we go into a number of different cases.

This post is part of the Features vs Requirements series.
Other posts in this series: