It used to be that the “user interface” for a computer was assembly language and its “user manual” was the programming manual. Back in those days, the distinction between the physical machine and its programming interface was somewhat academic.

These days, there’s a lot more layers involved. Taking the “simple” example of C++, the layers could look like this:

In this example, the physical machine is a x86, 64 bit. The machine’s architecture has various ramifications, for example a 64 bit machine can allow a single process to address much more memory than a 32 bit machine. The operating system has numerous implications; any “system call” like accessing a file goes through the operating system. Then there’s the libraries, for example the C standard library which provides functions like printf() for formatted output. Then there’s the programming language itself.

I draw the software stack with the language and the libraries intertwined because:

  • When you’re programming, you’re often using library features without realizing it. You may assume something as primitive as printf() is just part of the language, but it’s really a library feature. When you compile your code, it contains references to these library functions. Usually these references are to a shared library.

  • When your code is running, it uses the library functions as if they were built into the program itself.

This is all rather straightforward, until you start to look outside of the machine sitting on your desk. Your physical machine will have certain features, you’ll have an operating system installed, you may have several libraries and languages at your disposal. But what about all the other machines in the world? Some are like yours, many are different. How many of them will your program run on?

The Platform Concept

The combination of language, libraries, and other features that make your program run is called its platform. For our simple C++ case, we can say our platform is C++, the C standard library, C++ STL, and Linux. Making these assumptions, your program will probably run on any similar Linux boxes with ease. You may need to recompile, however, for different versions of libraries or different processor architectures. And if you wanted to move to Windows, you could be looking at a lot more changes.

Back in the 90’s this became a very hairy problem because libraries were not standardized well, in particular C++ was a complete mess because its Standard Template Library was still in flux and even some language features had spotty support. Developers tended to pick one platform and stick with it, and that platform tended to be C++ with MFC on Windows. Microsoft owned the desktop platform because it had a large installed base and, as it happens, it’s very hard to adapt a MFC application to run anywhere else—you often need to rewrite nearly everything. Which is precisely what Microsoft wanted.

Sun attempted to break Microsoft’s strangle-hold on the platform by creating its own platform, Java. Java was quite different, though, in how it approached the software stack:

The machine they created was an abstract one. This “virtual machine” would run on Windows, Linux, Mac OS, whatever. The application developer didn’t need to care; Sun’s promise was “write one, run anywhere.” Java 1.0 didn’t quite deliver—the joke was “write once, debug everywhere.” However, after a couple revisions, Java, its libraries, and the virtual machine were really quite good.

Java never did take over the desktop like Sun hoped, but it remains heavily used in server applications. Instead the web browser, of all things, took over as the “desktop platform” of choice. God help us, it’s terrible, but it least Microsoft’s strangle-hold has been broken. For web-based applications, the stack looks more like this:

The back-end can be implemented on one platform (e.g. Ruby on Rails) and the front-end is a web browser. Now you’ve got two platforms that two halves of your application need to run on. Lucky you.

Platform Investment

There’s a point in this history lesson: one platform does not rule them all. Furthermore, the platform you have sitting on your desk is not necessarily the platform you should invest your time in. It takes a tremendous amount of time to master a programming language, its libraries, and the features of an operating system.

Suddenly the concept of being a “C++ programmer” raises a lot of questions: C++ and what? Do you know STL well? How about the Boost libraries? How well do you know the threading library on your operating system? (Hint: pthreads is harder to use correctly than it looks.) The same kinds of questions arise with any other language.

So here’s the question: what platform are you going to invest your time in? Since there’s so much to learn, it takes months to gain any real proficiency with a platform. It takes years to master one.

The Machine on Your Desk, Reloaded

Let’s say you’ve got a Windows box on your desk and you don’t have a college computer lab you can sneak into. That’s no excuse to ignore other possible platforms. You can create virtual machines that use resources from your physical machine and you can install new operating systems, tools, and whatnot in that self-contained virtual environment. Want to experiment with FreeBSD? No problem, start up a VM, install FreeBSD, and away you go—on your Windows box.

If your desktop machine can’t run virtualization software (e.g. VMware, Virtual Box) then you can rent virtual machines. Many “cloud computing” companies will rent you virtual machine time on their cloud for relatively little money. It’s pay-as-you-go, so it’s easy to do the math on what you’ll get for how much money you can commit.