
Have you ever noticed that a computer program never does exactly what you want? Oh, it will process your data for you, and produce results that you can use, or it will move those files from here to here, but may move ones that you didn’t want moving or leave ones that you did want to move. But it won’t do exactly what you want, first time with no hassles.
Of course you can make it work for you, make it do what you want more accurately, but you have to work harder to make it do so, and programs are supposed to make things easier, right? Take this very editor that I am using to compose this post. I thought the bold words above as I wrote, but I needed to perform an action to make them come out bold and another to ensure that the text after the bold words didn’t also come out bold.
Of course this is a very minor consideration and if I were to find a program that changed the font to bold for one word and then stopped, I’d probably find it irksome to bold two words in succession. Also, I’d bet the house that there would be something that the first program did automatically or easily that would be difficult to achieve using the second program.
Those who are not programmers seem to have an ambivalent attitude to programs. On the one hand, if they are using a program and they can’t get it to work, they blame themselves. “I must be doing something wrong!” comes the impassioned plea. So the technophile in the household has to interpret what helpful statement “It doesn’t work!” really means and what how the program expects in the way of input. Problem fixed. Until the next time.
On the other hand, the non-programmer will accept it without question when the hero/heroine of the film briefly types something at the computer and the world is saved! Hooray! The sentient virus destroying humanity is defeated! Hooray again!
However these issues with programs are not bugs. The program is not doing something wrong. The issue is with our expectations of how things ought to work. It may well be that the program is designed to do things differently to those expectations, either because the programmer assumes that the way that he codes it is the way that people will expect things to work.
If the programmer gets a lot of issues with a particular feature of his program, he may decide to change it to fit more closely with the expectations of the users, and then send out an update. It is likely that he will then get a lot of issues from those people who have been using the program for a while and have come to expect it to behave the old way. The programmer can never win.
I’ve done quite a bit of programming over the years, thankfully mostly for myself. Every program that is written these days usually fits into what might be called an ecosystem. There are programs to gather data, programs to crunch data, and programs to display the results, but there are many programs to perform each of these three tasks.

For example, the results may be printed on a printer, either as a table of data, or as graph or pie chart, or in these days of 3-D printing, a physical object, or it may be displayed on a screen, or in any other way where the recipient can interrelate with it.
Data input may typed in, drawn in on a graphical input device, or it may be collected by some means or other from sensors or other devices. Your heartbeat may be collected from a number of sensors on your skin, read by a machine and be printed off on a roll or paper, while at the same time being displayed on a local screen. It may also be sent off to some remote location where specialists may peruse it.

In the middle, between input and output comes the processing or crunching of the data. This is what most people think of when they think of computer processing. Somewhat unfairly the input and output processes are relegated to only secondary interest. This is, however, what a program or system is written to do. Even so, input and output processes may be complex.
Data may be processed in several different ways in between input and output, and by several different programs. There are layers within layers. For example a program that takes advantage of a database uses many layers. The program which the programmer is writing will no doubt call programs (called APIs or interfaces) within the environment that he is working in which start the process of communicating with the database.

The API puts the programmers request into a form that the database expects and sends it to another process, not usually part of the programmer’s chosen system, which exists only to connect the programmer’s program (and any other similar programs) to the database.
At the database end the receiving part of the database system receives the request and passes it to the main database program, which checks it and executes it. During the execution process the database program makes calls to system programs which perform any necessary retrieval or writing of the data to the system’s file system, via the system’s hardware interface with the storage system.
I’ve collapsed many layers in the explanation above. The main point is that the programmer’s program is the tip of the iceberg, and there are many layers which are called into action during the execution of the program. To complicate things further, the system that the programmer uses to perform his work is also a program and has its own layers on top of layers.
This explains why programs don’t ever do exactly what you want. The programmer has to use utility programs which, while flexible can’t do everything. The utility programs are also flexible, but are interfacing with other programs, which while flexible also can’t do everything. And so on.
The more flexible a program is, the bigger it is, as it has be programmed to enable the flexibility. So, this forces constraints on it, which impose constraints on the programmer, whose program therefore imposes constraints on the user of the program. And those constraints are why the program can’t do exactly what you want, but usually, it’s close enough that the program is useful to the end user. Most of the time.
