Awashing machine can only wash your clothes. A
vacuum is great if all you need to do is suck dirt from your rug.
A plane can whizz you round the world, which is pretty
amazing, but that's all it can do for you. A
computer, on the other hand, is a wonderful general-purpose machine
that can do all kinds of things from
forecasting the weather to calculating your tax return. What
makes it so different? A computer is really two things in one: an
electronic number-cruncher, built out of bits like
transistors and memory chips, and a series of instructions that tells the electronic bits what do do. The machine is called the hardware; the
instructions that operate the machine are called its software
(sometimes they're also called programs, code, or apps). What
exactly is software and how does it work? Let's take a closer look!
Imagine if your computer could do only one thing.
If all it could do were basic arithmetic, it would be, quite simply,
a calculator. You couldn't send emails with it, write essays, play
chess, or do anything else.
Thankfully, your computer is so much more: it's like a personal
servant you can instruct to do whatever you want. The instructions
you give a computer are called its program—and software is
really just another name for that. Give your
computer some new instructions and you can make it do
something completely different. When you install apps on your smartphone, you are reprogramming the computer inside it to do a different job. If you know how to
write programs yourself (which is called coding), you can make
your own apps and get your computer to do anything you can imagine,
from editing photos to playing Angry Birds.
Photo: Computer architecture: You can think of a computer as a series of layers, with the hardware at the bottom, then the BIOS, then the operating system, and finally the applications on top.
A typical computer, like the one in the laptop or
smartphone you're using right now, has several main types of software
inside it. Imagine them stacked on top of one another (as the picture shows here),
or maybe like the layers of an onion, with the computer's electronic hardware at the
core. At the lowest level is something called the BIOS
(basic input/output system), which is a relatively simple bit of
software (technically known as firmware), written
into a computer's processor, that boots (starts up) a
computer from cold. (On newer computers, there's an
equivalent piece of software called the Unified Extensible Firmware Interface, UEFI.)
The BIOS loads another piece of software called the operating system, which
carries out more sophisticated jobs, from operating the touchscreen (in a phone) to spinning
the hard drive and keeping the processor cool. The BIOS and operating system are examples
of what's called system software, because they work directly with
the computer's hardware—the computer system, if you like.
On top of the operating system, at the next level, are what we call
application programs (sometimes shortened to
applications), which are things like word-processing programs and web
browsers running on desktop PCs and laptops, and all the different
apps you install on smartphones. Applications
use the operating system to control the hardware—and you can run
applications on top of applications. For example, your web browser
(an application running on your operating system) can run
If you use your computer graphics program to do the same thing, over
and over again, like resizing and rotating photos and saving them in
a different format, you can write a little program called a macro that will repeat
these processes for you so you don't have to type
and click your mouse the same way each time.
Or maybe you've added extra features to your web browser with "extensions,"
which are add-on applications that run on top of the browser.
What's so good about this layered approach? It means people who write applications
don't have to come up with all the code for controlling the computer's most basic functions—things
like writing information to the hard drive or figuring out
how the mouse is moving; all that's done by the operating
system. So any make or model of computer that can run a certain operating system should run applications
written for that operating system in more or less the same way. Before operating systems were invented,
programs written for one make of a computer often wouldn't run on another one, even if it was
fairly similar and the code was written in exactly the same language.
Writing software—the magic of coding
How do you go about writing a computer program?
Although apps have many different purposes, they all have one thing
in common: they're designed to do a certain job or, you might say,
solve a specific problem or problems. So the first step in writing a
program is to define what those problems are and how best to tackle them.
Defining the problem
If you were writing a computer program to edit
photos taken with an old-fashioned film camera, you might have
a whole series of problems to solve: how to convert the photos
into a digital format, how to edit them
in various ways (change the brightness or contrast, or apply
filters of varies kinds) to make them better, and how to save them in
different sizes, formats, and so on. Each of these is really
a separate problem, and some
of them might involve more than one problem (how to save files in PNG
format is a different problem to saving them as JPG).
Sometimes, analysing how a computer could solve an
everyday problem is so complex that it's considered
a completely separate job from the business of writing the
final code. For example, if you were running a big, old-fashioned
main-street store with no computerization of any kind and you
suddenly decided you wanted to sell your products online
through ecommerce, that would
mean a wholesale rethinking of how you do your business. In the
computer world, thinking
about problems in this general, "high-level" way can be a
distinct job called systems analysis (or system analysis). But
it can also be done by programmers themselves—and here, we'll
simply regard it as the first stage of ordinary programming.
Artwork: Complex problems: Computerizing a business with e-commerce
involves carefully defining a whole series of problems, from running a website to managing stock
inventory, taking payments, and organizing shipments. Each of these might involve using a completely separate computer program, which will need to work with all the other programs the business uses.
Once you've figured out what the various
problems are, you need to figure out how you can solve each one,
within the limitations of what a computer can do, using a logical series of clearly defined steps
called an algorithm. Programmers often figure out their
algorithms by drawing flowcharts,
which are easy-to-follow diagrams with boxes and arrows that start from the top of a
page and work downwards, branching off in different ways according to
decisions made on the way. Another method is to use pseudo-code,
which is a series of logical statements, written in plain English or
a cross between English and a simple
programming language, that set out the process
that will eventually be transformed into a computer program.
Each separate statement of pseudo-code (or an actual program) is
called a line (so
programmers typically talk about writing "lines of code").
Your clothes washing machine probably has a one-chip computer (microprocessor) inside it,
soldered onto an electronic circuit board
that controls its motors, water heater, pump, and so on, and
it uses connected sensors
to measure things like the
water level and water temperature.
Unlike the program in a
computer, the one that operates
a washing machine is
fixed—it cannot be changed—so
this particular type of
computer can't be programmed to do anything else.
A pseudo-code algorithm for washing clothes might start off something like I've written
below, and I've drawn a small part of the flowchart to go with it (covering just steps
7,8, and 9):
Lock the door.
Read the washing temperature and program
number from the operating dials.
Open water inlet.
Test water level.
If water is at the level needed for this program,
close water inlet otherwise return to step 4.
If current water temperature is less than water
temperature needed for this program, switch on water heater.
Test water temperature.
If current water temperature is less than desired
water temperature, return to step 7.
If water heater is switched on, switch it off.
Set timer for wash duration
according to the selected program number.
Rotate drum 10 times clockwise.
Rotate drum 10 times anticlockwise.
and so on.
Notice how each of these steps is well defined and has a clear beginning and ending.
It's either a clearly
defined job to do or a test
of some kind ("if this… do that…") with a clear outcome
that steers the program one way or another. There
are no open-ended questions, like the ones you might get in an essay
("Did did the end of World War I contribute to the beginning of
World War II? Discuss.") or vague operations ("Heat the water
until it feels about right"). Everything is unambiguous.
Not all algorithms have to be devised from scratch: many computer programs do
the same sorts of things, and bits of them are often built
from algorithms other people have devised in the past. Searching and sorting are two very
common things that many programs have to do—and
there are standard ways of doing those that progammers can draw on.
For example, a binary search (sometimes called a "binary chop") is a way of finding an item in a sorted list by
repeatedly dividing it in half, while a bubble sort is a way of
sorting a list into order by testing and swapping items as you move
through, multiple times. Hashing (turning a variable piece of data into a smaller, compressed, fixed
format) is another common problem. There are plenty of standard algorithms for searching,
sorting, and hashing—so you don't need to invent your own (unless
you really want to).
Artwork: A simple binary search. Suppose you want to see if a list of 16, presorted items contains the value 477. Divide the list in half and check the middle value: 212. It's less than 477, so we need to look in the other half of the list. Now keep dividing the list in half and inspecting the middle value until you find (or don't find) the item you're looking for. We reach "477" after a handful of these binary chops, which saves having to work through the list an item at a time, which usually takes a lot longer. The longer the list, the more time you save by searching this way.
Artwork: A simple bubble sort. Suppose you have a list of numbers you want to put in numeric order. Work through the list and, each time you come to a pair of numbers that are out of order, swap them around. if you carry out any swaps, you will need to work through the list again. Keep working through the list until there are no more numbers to swap—and it will then be in order.
Once you've defined your problem and figured out your problem-solving algorithms,
you can set about turning them into actual programs that your computer can implement. For that,
you'll need to know one or more computer languages. People
talk to one another in various languages, most of which are
structured in similar ways according to the rules we
call grammar. If you've written some pseudo-code, you
probably wrote it in a language like English, but it won't be any
good to a computer. That's because computers speak their own
language, not ours. Generally speaking, computer languages are more
formally structured than ordinary languages. Their "grammar" is usually called "syntax"
(meaning how you structure and write your lines of code)—and it really matters; a missing comma or bracket or a stray dollar sign of slash is more than enough to bring a computer program to a halt.
High-level languages and low-level languages
At their most basic, computers "talk"
in binary: everything a computer does can, ultimately, be translated
into long series of zeros and ones. But it's impossible for
people to think like that—our
brains don't work that way—so we
have to write programs in what are called high-level languages instead.
These then have to be translated into something that a computer can
understand. Typically that means a program has to be compiled
(translated, all in one go, into computer-speak in a one-time process—the
way a book is transformed into another language by a human translator) or
interpreted (where the instructions you give the computer are turned into computer-speak one at a time—the
way an interpreter converts someone's sentences into a foreign
Screenshot: BASIC used to be the most popular high-level, interpreted language running on
home computers. Today, home geeks are more likely to program in Python.
If you're writing code these days, you'll typically use a high-level language like C++,
an older high-level language like BASIC, FORTRAN, or COBOL. These use
English words like "IF", "DO", "WHILE", and so on, strung
together to make logical statements. In between high-level languages and raw
binary there are low-level languages called assembly
language (assembler) or machine-code, which relate much more closely
to how the computer itself works. In
machine code, there are typically only a couple of dozen, very basic
instructions, and they do simple things like moving numbers in and
out of registers (memory storage "boxes"), adding one to
(incrementing) registers, jumping from one line of code to another, and so on.
Why use low-level languages when high-level ones are so much easier to understand?
Simply because low-level languages are easier for computers to understand, so
they typically run much, much faster. Talking to a computer to a machine code is
like talking to a French person in French. Talking to a computer in an interpreted, high-level
language is like talking to a French person who speaks very poor English:
they have to translate everything you say into French before they can understand
and act on it—so it takes a lot longer.
There are a few other kinds of languages you'll come across in computing,
known as markup languages, that don't qualify as programming languages. The
best-known examples are HTML (which is used to describe the structure and formatting of web pages),
SGML (which is often used for formatting printed documents), and XML (for
structuring various kinds of computer data). The HTML used to write web pages is often
called "code," but it isn't the same kind as in a programming language: bracketed
items like <H1>, <P>, and <IMG> just
"tag" different bits of your page as headings, body text, images,
or whatever so a web browser can figure out what everything means and how to display it correctly.
a programming language that runs in a web browser that can add
interactive features to web pages or make them run as applications.)
Artwork: HTML is the "code" that makes web pages like this display correctly, but it's not a programming language.
How do programs actually work?
Whatever problems it's helping you to solve, a computer program is obviously limited
to working in certain ways and it draws on four basic things that all
computers do, all the time: input, processing, storage, and output.
If it's a program that edits photos, its input
is the photos you give it (scanned, perhaps, or fed in directly from
another piece of software, such as an email program). The
processing it does might include adjusting the brightness, color, or size of your photos. The
output is the photos in their new form—displayed on your screen, perhaps, or
shuffled off to your laser printer. And all these different steps involve storing the photos in either their original or modified form.
Whatever problems they're solving, most of what computer programs do is essentially
mathematical. If you look at a few lines of a typical program, whatever language
it's written in, it will usually involve storing and playing around
with numbers using what is essentially algebra. Editing
a digital photo involves changing the numeric values of each
pixel—increasing the values to make the pixel brighter or
decreasing them to make it darker. So you might have lines of code
that load each pixel value, increase its value by a set amount, store
the value, and then load the next pixel until you reach the end. This
sort of problem solving by numerical processing explains why
computers were, historically, often referred to as "number
crunchers." If you look again at my little example of assembly language,
you can see how just how loading, incrementing, and storing pixel values
A word-processing program (like the one I'm using to write this article) doesn't
look particularly mathematical as you sit at your computer and type.
But how are the letters you type stored in your machine? Each letter
is assigned a numeric value, so a word or sentence is really a series
of numbers. When you cut some text out of one paragraph and paste it into a different one, you're
really slicing a chunk of numbers from a long list and moving them
higher up (or lower down the list). Suppose
you have a column of words and you sort it into alphabetical order.
How does that work? If you remember that each letter is really a
number, it's easy to imagine the computer sorting the numbers that
represent those letters (using a bubble sort or some other standard sorting algorithm).
Learning to program
If you want to learn to program for yourself, there are lots of simple ways to
start. For younger children, a simple picture-based language called
Scratch is a fun and easy way to get going. It involves writing simple programs that tell
stories in pictures, using simple, English-like words, written on blocks,
that can be moved about and slotted into place. For everyone else, Python is
possibly the best high-level language to start with. It's clear,
simple, relatively intuitive, and still very powerful. Back in the 1970s
and 1980s, when home computers first became popular, most people
would have started their programming careers with a simple,
English-like language called BASIC; today, Python is generally
considered a better starting point—and
a better launching pad for learning about more complex languages in
Screenshot: Scratch is a simple programming language that involves clicking blocks of code together to make simple cartoons and tell stories. The code I've put together on the left animates the little cat on the right.
A brief history of software and programming
Artwork: Charles Babbage (1791–1871) designed the world's first programmable, mechanical computer. Picture from The Illustrated London News, 1871, courtesy of US Library of Congress.
1725: French Textile worker
Basile Bouchon invents
a loom that can be "programmed" in advance using a long paper
tape punched with holes. His ideas are later improved by
Jacques de Vaucanson, a pioneer of early automated "robots" called automata.
1804: Building on the work of Bouchon and
Vaucanson, Joseph-Marie Jacquard perfects
his textile weaving loom, which can be "programmed" with
punched cards. Jacquard's loom is a milestone in computing history,
because it shows how machines can be programmed to do the same thing
over and over again.
1830s: Inspired by Jacquard's work, English
mathematican Charles Babbage and his assistant, Ada Countess of
Lovelace, develop the first programmable, mechanical computer.
Lovelace imagines how it could
"weave algebraic patterns just as the Jacquard loom weaves
flowers and leaves."
1940s: German computer pioneer
conceives one of the first high-level programming languages,
1949: John Mauchly, an American computer
scientist, develops Short Code, another early high-level language. Similar
languages are later developed in Britain at the universities of Manchester, Cambridge, and London during
the early 1950s.
1954: IBM's John Backus invents the FORTRAN
scientific programming language. It remains popular until the 1980s.
1950s: Grace Murray Hopper develops a high-level, English-like language called
that ultimately leads to the development of COBOL, the most popular
business computer language in the late 20th century, in
1958: John Wilder Tukey, an American
mathematician, is believed to have coined the use of the word
"software" (meaning computer program) in a paper called "The
Teaching of Concrete Mathematics" (although this has
1964: BASIC is invented by John G. Kemeny and
Thomas E. Kurtz at Dartmouth College. (The
original version of BASIC is sometimes referred to as
Dartmouth BASIC for this reason.)
1969: Charles Goldfarb develops GML (Generalized
Markup Language), one of the first data-storage languages, as a way
of defining how text will
be printed. A more general (but much more complex) version,
called SGML, follows in 1974.
~1970: C is developed and evolves into C++ in the
1987: Larry Wall invents Perl, a high-level
interpreted language, initially to help with processing large text
files and reports.
1989: Tim Berners-Lee conceives HTML, a simple markup language, as a way of "tagging" the structure of a web
page to indicate things like paragraphs and headings. With HTTP, a
structured way of sending HTML and other files between a browser and
server, it forms the foundation of the World Wide Web.
that run inside a web browser.
2003: Scratch, the introductory visual programming
language, is developed at the MIT Media Lab.
A special 1984 issue of Scientific American carried some great conceptual articles about different aspects of computer software by pioneering figures from the field, which, although decades old, are still worth reading today:
Please do NOT copy our articles onto blogs and other websites
Articles from this website are registered at the US Copyright Office. Copying or otherwise using registered works without permission, removing this or other copyright notices, and/or infringing related rights could make you liable to severe civil or criminal penalties.