As the case with many Gen-X developers (or perhaps even Baby Boomers), I’ve worked with a wide variety of programming languages, but almost invariably the development environment for large scale projects was C or C++, often glued together by a variety of scripts and build tools.
C and C++ suffer are detrimental from two ends of the same spectrum. With C, the standard library only provides eighty seven functions, and usually entire libraries have to be written or procured from a third party. The saying used to be that when you hire a C developer, you are really buying their libraries. Of course, the standards have changed, and the ubiquity of the internet makes it possible to procure and share well-tested code easily. C also suffers from platform-dependence. The primary advantage of C is its simplicity and exceptional speed, which
are consequences of its evolutionary proximity to assembly language which greatly facilitates compiler optimizations.
When C++ was created at Bell Laboratories, the goals that were sought were reusability and the ability to develop large-scale systems through the collaborative work of teams of developers. Ostensibly, C++ is an object-oriented language, replete with encapsulation, polymorphism and inheritance. A language developed for these goals, and with an object-oriented approach would have been an ideal evolutionary step in the 1980s.
But there were two major flaws that were lethal to C++, and continue to haunt the billions of lines in codebases that have been developed since. First, C++ was to be backwardly compatible with C, and in fact the earliest C++ compilers were preprocessors that converted C++ code into C. This single language decision resulted in all of the atrocities of C (global variables, macros, conditional compilation) now inherited by C++. So from inception, bad C code could be processed perfectly as bad C++ code. And this continues to contemporary periods, though developers today would assume strong measures to avoid dangerous coding habits and design.
The second, more nuanced bombshell within C++ is that even though C++ can be regarded as an object-oriented langauge, it also can be viewed as a generic template-driven programming language. These two paradigms are completely orthogonal, and almost without exception, the single largest design flaws in C++ systems is a result of simultaneously combining both paradigms. Imagine nested template-driven code that would be applied a complex class hierarchy. To manage and continue to add to such a codebase would be a task worthy of Hercules. In my opinion, this is why highly experienced C++ developers are always in demand – only true experts can work with the multiple-inheritance, C-backward compatible template-driven complex class hierarchies that can be found in modern large scale C++ systems.
The year was 1993, and enter Java – an experimental language under development at Sun Microsystems (codename “Oak”) as a platform-independent language in which a virtual machine enables a “Write Once, Run Anywhere” development paradigm. Fortunately the designers of Java had decided to break ties with the inescapable detriments afforded by C/C++, and instead focus on designing a modern language for the 99% replete with automatic garbage collection, single inheritance, and a robust built-in library. Originally, Java was expected to run within browsers on the client side. However, the formidable qualities of the programming language from both business and development perspectives became exquisitely evident, and Java was being used in back end server-side projects, with a web presentation interface using an assortment of ancillary technologies. From the earliest versions through Java 7, a host of incremental refinements, performance improvements, and language features such as generics have resulted in Java supplanting C/C++ as the “gold standard” for software development. It was far easier for universities to teach and for students to learn Java, and it attained ubiquity in the professional development community.
Microsoft, beign the notorious laggard in innovation that it is, quickly realized that they were rapidly losing market share as the world moved towards the browser rather than applications, and developers were flocking to the new Java gold standard of modern programming language design. They responded in the same manner they dealt with in the past with other threats (including MacOS, Netscape Navigator) – they created a imitation product that retained the flagship features of the cloned product. Anders Hejlsberg, a designer of Turbo Pascal and Delphi, was in charge of this process. When C# 1.0 was first released, I can vividly recall not beign able to distinguish whether the code was Java or C#. The syntax, design, and even keywords were closely related. In fact, as of the late 1990s and early 2000s, writing a translator between Java
and C# would have been a modestly trivial enterprise. Of course, as the languages have evolved and the libraries grew enormously,
such a task would be much more complex today.
The stage was now set for Microsoft to actually innovate in terms of programming language design, and create a superb development environment and framework. I will follow this up shortly in another post (Part 2, Specifics).
Srikant Krishna (contact: firstname.lastname@example.org) is a financial technologist and quantiative trader. He has a strong background in biophysics, software development, and the capital markets.