Last Wednesday I had the first meeting with my C++ study group. If you read my last post, you will know what I’m talking about. In this first session, I noticed the professor had a little bit of trouble explaining namespaces mainly because explaining namespaces in 5 minutes to people with little programming background is hard. In this post, I will try to explain namespaces taking more than 5 minutes, and hope that it may be helpful for some people.
Before we can actually talk about namespaces, we need to look at a different concept: Identifiers. Understanding identifiers is key in understanding other concepts, among which is that of namespaces.
Identifiers are nothing else than names that we give to variables, constants, functions and classes (there are other “things” that we also give names to, but that I’m not going to talk about for the sake of simplicity). When we declare a variable, we normally do it using a name, and then we assign a value. When we create a function, we normally give it a name that we can use to invoke the function later. Wen we declare a constant, we give it a name so we can refer to it later. When we create a class, we give it a name so we can instantiate it later.
All of these names that we give to “things” are identifiers, and they should be unique to the thing we are naming. There are cases where the name is not unique, like in the case of overloading, but for now, lets not consider those cases.
Scope is another concept we need to understand. If you understand scope, you’ve understood half of closures, another important and powerful concept available in some programming languages, but we will talk about that some other time.
I like to think of scope as the reach that an identifier has within a program. Although this is not the proper definition, and it may not be the most accurate, it is one that I’ve found makes it easy to understand the concept. Simply put, the scope of an identifier is anywhere where you can use that identifier to find the entity that it refers, the entity being the value of a variable, a function, a class or the value of a constant.
Scope by Example
Suppose you have a function f1, and a function f2 declared in a language that has function scope. Now, in f1, you declare a variable called v1, and in f2 you try to reference that variable. What you will get is an error because the variable v1 is local to the function f1, which prevents function f2 from accessing v1. That is scope.
Now that you have an understanding of identifiers and scope, we can begin to talk about namespaces. First, lets consider the following problem:
Suppose you are working on a program that has the functionality of an email client, and of a news reader. At some point during the program’s execution, you will need to fetch information from the net such as news and emails. You have divided your program in two different parts. One is the part that handles all of the email functionality, and the other one is the one that handles all of the reader functionality. Since you need to fetch information from the net, you have created two classes, one for each part of the program. One class fetches information from the email server, and the other one from the news server. You call both of these classes Fetcher.
I hope at this point you can see the problem, but if you can’t, look a bit closer and realize that we have two classes named Fetcher, and this will be a problem.
We will assume that the scope of these classes is global, meaning you can reach them from anywhere in the program. Depending on the language and the compiler, you can have one of multiple possible errors, but they all boil down to the same issue. You have two classes that are named the same, and no way to distinguish one from the other.
Why would anyone do that? Why not just call them EmailFetcher, and NewsFetcher? Well, sometimes you did not write those classes. Maybe you are using a library that comes with those classes, so you have no real say in what the classes are named.
To solve that problem, some clever people came up with namespaces. Namespaces, are, like the name suggests, spaces for names, or identifiers. Namespaces help us distinguish from two identifiers that have the same name but that belong to different context.
The simplest example of namespaces is computer directories. A computer directory, most commonly known as a folder, is a place where you can store files. Suppose you have a directory dir1. Inside dir1 you create a file called myFile.txt. Now, what would happen if you want to create a new file, with different content, but that is also called myFile.txt? The computer will either complain that you cannot have the same name on two different files, or worst, overwrite the original file. One solution to this problem would be to create a second directory called dir2, and in dir2 put the new myFile.txt file. Now you have two files that have the same name, but in different context (think of every directory as a separate context).
This is clearer with a more real-life-like example. Suppose you have your Music directory, where all your music is stored. Two of your favorite bands have a song called “The Wild Loop”, so the file has a name like the_whild_loop.mp3. What happens when you add both of these songs to your Music library? Do they get overwritten? No. What happens is that your music player program may be using a different directory to store the songs of each band.
Lets say one of the bands is called The Pythonist, and the other one is called The Rubyist. The files in your Music directory may be organized like this:
|- The Pythonist
|- Album Name
|- The Rubyist
|- Album Name
As you can see, you have two the_wild_loop.mp3 files, and not only that, but you also have two directories called Album Name, but one is in the context of The Pythonist, and the other one in the context of The Rubyist.
That is basically what namespaces do in programming languages. They allow us to have entities referred by the same name but in a different context. This context lets us distinguish one entity from the other.
Since my study group is about C++, I will publish another posts about the implementation of namespaces in C++ later today or tomorrow, but I hope this article has been a good introduction to namespaces.