This article aims to teach you about computing and programming in general “What is computing?” and “What are the important issues to consider when developing software?” also talk a little about the history of software development.
Computing means the broad discipline of computer technology: its composition, its uses (by individuals and organizations), the process of learning to think in terms of this technology and applying it to real situations. The software side of computing is emphasized, namely applications, programming and operating systems. The hardware side of computing is undeniably important, some hardware aspects are dealt with as part of the detail of networks, and machine code and execution speed are mentioned in the context of compiling and primitive instructions, respectively.
I did not call the article ‘Computer science’ or ‘Software Development’ or ‘Software Engineering’ as these names might have suggested too much theory, too little practical work, too much on how to program, or even a need for sophisticated mathematics. I felt that these terms omit or avoid important aspects that anyone who reads this article will come to appreciate.
One is that there is considerable uncertainty in many aspects of computing, there is no agreed right way to do things – creativity is undoubtedly involved, and experience counts when it comes to designing complex software systems.
Another important aspect is that communicating with and managing the people within computing is a challenge; understanding the language they use to communicate their requirements to each other or to a machine and how they safely and economically deploy and use computer technology is important.
3 Computer Programming
Computer programming (often shortened to programming, scripting, or coding) is the process of designing, writing, testing, debugging, and maintaining the source code of computer programs. This source code is written in one or more programming languages (such as C++, C#, Java, Python, Smalltalk, etc.). The purpose of programming is to create a set of instructions that computers use to perform specific operations or to exhibit desired behaviors. The process of writing source code often requires expertise in many different subjects, including knowledge of the application domain, specialized algorithms and formal logic.
Within software engineering, programming (the implementation) is regarded as one phase in a software development process.
There is an ongoing debate on the extent to which the writing of programs is an art form, a craft, or an engineering discipline. In general, good programming is considered to be the measured application of all three, with the goal of producing an efficient and evolvable software solution (the criteria for “efficient” and “evolvable” vary considerably). The discipline differs from many other technical professions in that programmers, in general, do not need to be licensed or pass any standardized (or governmentally regulated) certification tests in order to call themselves “programmers” or even “software engineers.” Because the discipline covers many areas, which may or may not include critical applications, it is debatable whether licensing is required for the profession as a whole. In most cases, the discipline is self-governed by the entities which require the programming, and sometimes very strict environments are defined (e.g. United States Air Force use of AdaCore and security clearance). However, representing oneself as a “Professional Software Engineer” without a license from an accredited institution is illegal in many parts of the world.
Another ongoing debate is the extent to which the programming language used in writing computer programs affects the form that the final program takes. This debate is analogous to that surrounding the Sapir–Whorf hypothesis in linguistics and cognitive science, which postulates that a particular spoken language’s nature influences the habitual thought of its speakers. Different language patterns yield different patterns of thought. This idea challenges the possibility of representing the world perfectly with language, because it acknowledges that the mechanisms of any language condition the thoughts of its speaker community.
4 Software, systems, components and applications
Now we move on to consider software, systems, components and applications. As part of your reading in this blog about C++ computing, you will use, examine and write software. It is the writing of the software that is the most important of these. In many ways, learning to write software is like learning a foreign language. Thus this blog starts with a discussion of some general ideas about the world of computing and object-oriented software. Then you will learn about the elementary constituents of the object-oriented language C++ and practice using a tool called C++ Builder “A development environment to write C++ programs”. Later I will try to formalize your practical experiences into some techniques for tackling problems.
We need first to consider what software is in general terms.
Can we define what this article means by ‘software’? What is a ‘program’? How do we define ‘application’? Can we think of software as being made up of components, like hardware of a computer? As should become apparent, we do not need to be precise about the term ‘software’, but we need at least to characterize software.
Arguably, items of software are the most complex artifacts humanity has produced.
Software is malleable; when running on a single microprocessor chip or a general-purpose computer it is effectively turning that chip or computer into another specialized computer. Hence, software can make a chip into a ‘washing machine controller computer’, or it can turn a PC into an ‘encyclopedia computer’.
When software is run on a large powerful mainframe, such as a computer that manipulates meteorological information, or on a tiny chip controlling the engine of a family car, it may be helpful to consider it’s functioning in terms of electrical signals. An engineer might occasionally view the running of software as the passing of such signals. The most primitive representation of software used when explaining how it is executed is as a sequence of zeros and ones, that is, binary digits or bits. In practice, few programmers need to think at the bit level.
Software may be stored on a disk. Although the software is held as magnetic patterns on a physical object (such as the floppy disk or the hard disk), the software itself is intangible. You cannot see or touch software. Software is essentially abstract in nature, and we need ways of describing and representing it so that humans can think about software and write about it. In other words we need languages. Some these languages, programming languages, need to be capable of translation into the bits which hardware can interpret like C++ does.
The concepts on which programming language are based fundamentally affect those languages and the ways in which we think of and write software.
I have spoken of software here only as it relates to a computer or a microcomputer chip. Software may be written for a particular chip or particular computer but that is not to say that what software is meant to do could not be done using another computer or different software. For example, a particular web browser cane be provided for different computers; the software is different at the bit level for each computer, but is probably the same software when not just linked to the hardware on which it executes; it is rare for software to execute on a computer without the mediation of an operating system.
Before we move to discuss systems we need to talk a little about programming history how it started and how it became very important in our lives.
Ancient cultures had no conception of computing beyond simple arithmetic. The only mechanical device that existed for numerical computation at the beginning of human history was the abacus, invented in Sumeria circa 2500 BC. Later, the Antikythera mechanism, invented sometime around 100 BC in ancient Greece, was the first mechanical calculator utilizing gears of various sizes and configuration to perform calculations, which tracked the metonic cycle still used in lunar-to-solar calendars, and which is consistent for calculating the dates of the Olympiads. The Kurdish medieval scientist Al-Jazari built programmable Automata in 1206 AD. One system employed in these devices was the use of pegs and cams placed into a wooden drum at specific locations, which would sequentially trigger levers that in turn operated percussion instruments. The output of this device was a small drummer playing various rhythms and drum patterns. The Jacquard Loom, which Joseph Marie Jacquard developed in 1801, uses a series of pasteboard cards with holes punched in them. The holes pattern represented the pattern that the loom had to follow in weaving cloth. The loom could produce entirely different weaves using different sets of cards. Charles Babbage adopted the use of punched cards around 1830 to control his Analytical Engine. The first computer program was written for the Analytical Engine by mathematician Ada Lovelace to calculate a sequence of Bernoulli numbers. The synthesis of numerical calculation, predetermined operation and output, along with a way to organize and input instructions in a manner relatively easy for humans to conceive and produce, led to the modern development of computer programming. Development of computer programming accelerated through the Industrial Revolution.
In the 1880s, Herman Hollerith invented the recording of data on a medium that could then be read by a machine. Prior uses of machine readable media, above, had been for lists of instructions (not data) to drive programmed machines such as Jacquard looms and mechanized musical instruments. “After some initial trials with paper tape, he settled on punched cards…” To process these punched cards, first known as “Hollerith cards” he invented the keypunch, sorter, and tabulator unit record machines. These inventions were the foundation of the data processing industry. In 1896 he founded the Tabulating Machine Company (which later became the core of IBM). The addition of a control panel (plugboard) to his 1906 Type I Tabulator allowed it to do different jobs without having to be physically rebuilt. By the late 1940s, there were several unit record calculators, such as the IBM 602 and IBM 604, whose control panels specified a sequence (list) of operations and thus were programmable machines.
The invention of the Von Neumann architecture allowed computer programs to be stored in computer memory. Early programs had to be painstakingly crafted using the instructions (elementary operations) of the particular machine, often in binary notation. Every model of computer would likely use different instructions (machine language) to do the same task. Later, assembly languages were developed that let the programmer specify each instruction in a text format, entering abbreviations for each operation code instead of a number and specifying addresses in symbolic form (e.g., ADD X, TOTAL). Entering a program in assembly language is usually more convenient, faster, and less prone to human error than using machine language, but because an assembly language is little more than a different notation for a machine language, any two machines with different instruction sets also have different assembly languages.
Some of the earliest computer programmers were women during World War II. According to Dr. Sadie Plant, programming is essentially feminine—not simply because women, from Ada Lovelace to Grace Hopper, were the first programmers, but because of the historical and theoretical ties between programming and what Freud called the quintessentially feminine invention of weaving, between female sexuality as mimicry and the mimicry grounding Turing’s vision of computers as universal machines. Women, Plant argues, have not merely had a minor part to play in the emergence of digital machines…Theirs is not a subsidiary role which needs to be rescued for posterity, a small supplement whose inclusion would set the existing records straight…Hardware, software, wetware-before their beginnings and beyond their ends, women have been the simulators, assemblers, and programmers of the digital machines.
In 1954, FORTRAN was invented; it was the first high level programming language to have a functional implementation, as opposed to just a design on paper. (A high-level language is, in very general terms, any programming language that allows the programmer to write programs in terms that are more abstract than assembly language instructions, i.e. at a level of abstraction “higher” than that of an assembly language.) It allowed programmers to specify calculations by entering a formula directly (e.g. Y = X*2 + 5*X + 9). The program text, or source, is converted into machine instructions using a special program called a compiler, which translates the FORTRAN program into machine language. In fact, the name FORTRAN stands for “Formula Translation”. Many other languages were developed, including some for commercial programming, such as COBOL. Programs were mostly still entered using punched cards or paper tape. (See computer programming in the punch card era). By the late 1960s, data storage devices and computer terminals became inexpensive enough that programs could be created by typing directly into the computers. Text editors were developed that allowed changes and corrections to be made much more easily than with punched cards. (Usually, an error in punching a card meant that the card had to be discarded and a new one punched to replace it.)
Let us now consider the meaning of ‘system’ – another word we have used liberally and with a variety of meanings. The apparent uncertainty about terms in the language of computing is not deliberated obfuscation. As the nature of computing changes, single words, acronyms or short phrases are used to indicate a whole range of ideas to do with some topic. It can take a long time to become comfortable about using the jargon of computing, and of object –oriented programming and networks in particular. Like learning any new language, it is important to try to use the jargon. Many terms have subtly different meaning depending on how they are used. For example, the word ‘system’ which is used to refer to the following:
- An operating system, as in ‘how do I configure my system to allow me to have more than twenty files open at the same time?’
- A computer system (a combination of hardware and software), as in ‘My system crashed four times last night. I cannot figure out whether it is a hardware problem or that software game I picked up from a magazine cover disk’.
- A software system (usually a large piece of software), as in ‘The patient monitoring system has eight subsystems, not including the part that checks that the others are functioning within normal operating parameters’.
- A human organizational system that may rely on a significant computing element, as in ‘The system we operate is pretty efficient and very flexible. We usually need only three clerks, and if the computers are down we can survive for a week’.
- One might, for example, consider Egypt’s Air traffic control system as a large human organizational system dependent on people using a continuously running computer system (which, if it failed to run, would cause inordinate problems for the air traffic controllers and the aircraft they ‘manage’).
For most of the time we use the term system to capture the idea of a large piece of software, as in (c) above. Such a system, as we shall see, is made up of many parts and has many ways of entering and leaving it. Occasionally, when talking about hardware or operating systems, we use the term in the sense (b) above – a computer system: that is, the combination of hardware and software (predominantly the operating system) providing the technological context for the software programs in which we are interested.
A crucial idea about the interpretation of the term ‘system’ in (c) is the extent to which it is like the human system of (d). A (software) system is concerned with some human enterprise. It is essentially meant to run for ever and has to respond to variety of events that may occur in an unpredictable order. For example, once a system has ‘taken over’ the management of a country’s railways, that system should run for ever, or at least until replaced by another one; if the system were to determine for itself when it had finished the ‘job’, the railways would not be able to operate.
The minutiae of learning to write small portions of software or of learning to use conferencing facilities can get in the way of seeing how the parts contribute to the whole. However, you have probably been a user of a large system, for example, an airline seat reservation system. An airline seat reservation system allows online enquiries and booking of airline seats from a vast world-wide network of travel agents (and perhaps booking from your own home if you have the appropriate connections to the systems). The system at the heart of the reservation system is intended to run for 24 hours a day, and to provide real-time access to a database which identifies the available seats on relevant flights. As a user of such a system you may not always be aware of the other uses which the airline companies (and the travel trade) make of the complete system (of which seat reservations are but a part of a multifunctional system). Clearly, seat reservation must be compatible with the availability and capacity of the aero planes and their movements around the world.
The internet is another system intended to run for ever. It exhibits further characteristics of systems. It has no starting point and no end point in the sense that you can connect to the internet from anywhere in the world. There is no central control of the internet, and this has two important consequences. First, there are ethical issues to do with the content of what is accessible on the internet; and, second, the lack of central control means that a provider of services on the internet has only to conform to the protocols of the internet to be able to add to, and hence change, the system.
4.3 Software components
All the complex systems we create, whether or not they involve computers, need to be organized in such a way that human mind can deal with them. This inevitably means viewing the system in terms of constituent components and imposing some structure on these components. Throughout the history of software development there has been an active search for useful structuring techniques and appropriate languages for defining components. The object-oriented approach is one of the most powerful to emerge.
In the same way that designers in other areas can make use of standard components, there is the hope that a similar situation is emerging in software development which will make the writing of reliable software easier. To try to envisage what software components might be, let us think about why software is so called by comparing it with hardware. The hardware components of a computer are the electronic and electromechanical manufactured components. They are tangible: you can touch them and pick them up.
By comparison, software components are abstract, not tangible. At the level we want to consider them, software components are effectively sentences of a language, which directly or indirectly cause hardware components to interpret the software in order to make a computer system do what we want. As far as we are concerned, we cannot change hardware to get a computer system to do what we want; but we can change the software.
How should we imagine one of those sentences, those components of software? One approach is to think of software as simulating (modeling) the part of the real world with which we are concerned. If we need a system to help manage patients in hospital, our software will in some sense have to represent part of the world of hospital, our software will in some sense have to represent part of the world of hospital administration. The software components we might need are those that deal with modeling patients, doctors, nurses, wards, and so on. Since the system would be a computerized one, we should also need software components which are software building blocks corresponding to such computing features as windows, menus and buttons and network connections.
Since the word has many connotations, we shall use software as general term for software components; the term can refer to a single component, to a collection of integrated interdependent components and collections of more or less unrelated components.
In this article my approach is to think of software components in a special way, to think of them as what we call objects. Ideally, we should like to be able to take these standard components ‘off the shelf’ when we design and write such systems; object technology holds out some promise of this ideal.
We can characterize the program as meaning a collection of integrated, interdependent software components which have been put together for some specific purpose. For example, one (very simple) program might display the numbers 1 to 10 on your computer screen in quick succession. Another might play the first few bars of Beethoven’s fifth symphony through your computer’s speakers. This notion of ‘program’ assumes a pattern of input-process-output; this is, the software is the program has a starting point at which it takes some input, it then performs whatever computation is needed, and it has an end point at which output is given and the software ceases to run. This contrasts with how we view systems.
With a notion of software as components, we can talk about the ‘software industry’s being that part of a commercial enterprise whose business is the production and sale of software and software related services. Mostly this software consists of programs and systems, but a part of the industry is moving to the production of generally useful software components and highly specialized software components.
The use of components in developing software is important. Although component-based construction of programs has long been accepted in principle, it has only fairly recently becomes a practical proposition. It is interesting to compare the software industry and the automotive industry. To start with, cars were unique, hand-crafted artefacts. However, with the introduction of production lines, cars are now designed in the knowledge that many of the required components already exist; when new components have to be designed, they are designed with aim of reusing them. Until the early 1990s the software industry was more like the early car manufacturing industry – components were (more or less) designed for a particular program. More recently, standard software components have been produced in a similar fashion to car components. This is not to say that software can be assembled on a production line; rather, carefully crafted software can be built from standard components.
The concept of software components has led to the possibility of replaceable parts of programs – not just for replacing faulty components with correct versions, but for replacing limited components with more flexible ones. For example, imagine a component of word processor, say, one that allows the word processor to manipulate documents. If the relevant component were only to accept documents of less than 6000 characters (a couple of pages’ worth), but you wanted the word processor to be useful for writing a book, it would be essential to replace the original limited component with one that accepted, say, 2,400,000 characters.
Application software (or just application) may be either programs or systems, but the important thing about applications is that they are software applied to human problems.
Earlier we likened objects to virtual computers each doing some job of work in a computer system. Similarly we can liken applications to virtual computers each with a special operating system. For example, when you use a word processor you turn your general-purpose computer into a computer that knows only about documents and the commands that are relevant to them. And when you use a web browser you turn your personal computer into one that spans the world. A web browser knows about the web and how to display the documents that reside there. As a computer user, you start up these different computing environments, have more than one running at the same time and switch between environments.
Think about the situation where you start up a word processor, and then, without exiting from it, you start up a web browser. Each application is a virtual computer with its own set of commands, or the same commands with slightly different meanings. For example, the commands Open and Save have different meanings in a word processor and a web browser.
Software is written using a programming language, and pieces of text in such a language are often called source code or just code. The programming language used in this blog I called C++, and you (the reader) will spend a considerable amount of time learning to program in C++because it accurately embodies object-oriented ideas. Actually C++ is based on the programming language “C” but with classes.
One of the main benefits of the object-oriented approach to software is that object-oriented software can provide a model of the area (or application domain or problem domain) for which it was designed. We have already mentioned how, for example, a hospital patient management system has in some sense to model that part of the hospital world with which it is concerned; in this case the domain is hospital administration and the model is the software concerned with it.
In this article you have been considering a manifesto for the blog. Some of this has been about the ideas and themes of the blog; more importantly, a view of modern computing has been outlined.
The blog is not just about theoretical (and sometimes controversial) issues. It also takes a practical view, so discussions about what software is or is not are not just philosophical. This blog seeks to develop an understanding of how various C++ applications using “C++ Builder” are designed and constructed.
A language “C++” for describing computing and software has evolved to capture the concepts in these subjects. Ultimately software executes on hardware; software delivers instructions to hardware. In this blog I am mainly interested in software systems and applications developed using “C++ Builder”.
Applications that are made up of integrated software components. In object technology, the software components are called objects. We will get introduced to some of them in later articles on this blog. We also discussed that useful models of applications can be devised by considering the software as interacting components – as software objects sending messages to each other.