After half a century or so of computer programming, we have learned
that modularization is a cornerstone of software development.
Modularization, in this context, means that we divide a big problem
into several smaller problems. Then we write a number of programs or
program parts, each of them solving one of those small problems.
It is usually easier to jump one foot high ten times, than it is to
jump ten feet high in one jump. In the same way, it is usually easier
to write ten small programs, and then integrate them to a complete
system, than it is to write the entire system at once. (Ok, we may
expect some objections against that analogy. But the idea is the same
in both cases, and it works in practice: small programs are almost
always easier to write than big ones.)
The small programs or program parts are usually called "modules".
Here, the term "module" is used in this general sense, but you should
make a mental note that in Pike, the term module usually refers
to a very specific kind of module, the plug-in modules of Pike.
For modularization to work well, we need something that is called
information hiding or encapsulation. This means that we
hide the internal structure of each module, so the rest of the system
doesn't need to worry about it. Think of it this way:
If we build a locomotive in modules, we want to build one module at
a time, and then bolt them together. If the cogwheels and stuff inside
those modules are sticking out, outside the modules, the cogwheels in
one module will jam the cogwheels in another module. The result is
that the modularization doesn't work: even if we have divided the
locomotive into modules, we still have to think about the cogwheels in
all the other modules when we design the cogwheels in this module.
It is the same way with programs. The modules have lots of stuff
inside: variables, loops, data structures. All of that should be
hidden inside the module. Some programmers believe they should be so
well hidden that it is impossible to look at them. Others feel that it
is enough that you don't have to look at them. Remember: the
cogwheels shouldn't be sticking out.
Obviously, we can't hide all the information. The modules
must interact in some way, for example by sending data to each other.
The (few) things that are visible on the surface of a module, for
others to see and use, is sometimes called its interface.
So how do we modularize a program? Which parts should we divide it
into? One way is to look at what it does. You divide the thing it does
into small things, and you divide those small things into even smaller
An even better way is to look at the data that the program
works with: simple things like integers and strings, and more complex
things that often reflect real-world objects: persons, aircraft,
courses at a university. Each such thing, like that person over there,
is called an object, and each type of thing, like
"person", is called a class. As you may have guessed, this is
the basis of object-oriented programming.
The class describes the things, and not only what we know about
them, but also what we can do with them. For example, a person may
have a name and a birthdate, but a person can also eat, sleep and
Sometimes we say that an object is an instance or a
clone of a class: all persons are instances, or clones, of the
But to use object-oriented programming to its fullest, we need two
more mechanisms: inheritance and polymorphism. Thanks to
those, you can easily add features to an existing module. You can
re-use all the work that was put into writing that module, and just
add your new features.
If you need a class that describes birds, and you already have a
class called "animal" that describes animals, you can create a new
class that inherits from the "animal" class. By inheriting, a
bird has all the attributes of an animal, and can do everything an
animal can do. Then you just add whatever is specific to birds, such
as flying. (Except that penguins don't fly, and bats do. We ignore
that for now.)
Polymorphism means that whatever we can do with an animal,
we can also do with a bird. If we already have some program code that
counts animals or sorts them, we can use the same program code to
count or sort birds, without changing anything. So not only can we
re-use the work that was put into the "animal" class: we can also
re-use the work that was put into much of the rest of the program.