Everything Old is New Again
16 02 2007So the latest hullaballoo is over Daniel Jalkut’s article, C is the New Assembly. His assertion that C’s role as general-purpose programming language or development tool will be supplanted by other languages and tools is absolutely correct. Development in C doesn’t scale well enough to keep pace with the requirements driving our industry today, and didn’t even when it was introduced to the world in 1974.
In essence, C is a simple language whose operators and constructs can be translated into assembler in a straightforward manner. The data types are rudimentary and can be easily supported either directly by the CPU or via run-time libraries. Data is either referenced directly or via a pointer and storage for it is allocated statically from the program’s global data space or dynamically from the program’s stack space. Compound data types such as structures, unions and arrays are implemented within the compiler itself using pointer arithmetic and offsets calculated either at compile-time or dynamically using simple math operators (addition and multiplication). Programming constructs such as loops, conditionals and functions can be easily converted to assembly-language equivalents. Because the language’s run-time environment lacks exception handling and complex data types, its run-time library is quite lightweight and could be quickly ported to any CPU. Anything that your application required outside of data types and constructs (e.g., I/O and dynamic allocation of arbitrarily large blocks of data) has to be handled by supplementary libraries.
What was especially important about programming in C was that the details of the CPU were irrelevant to the problems being solved. It didn’t matter whether it had four registers or twelve, one accumulator or sixteen, a half-carry or an overflow flag, or 8- or 32-bit registers. You coded algorithms with the purpose in mind, and the compiler dealt with the details necessary for that algorithm to execute on the target CPU. So as the architecture of each CPU brought to market was uniquely “innovative”, and during the 70’s and early 80’s there was a proliferation of bringing to market as companies vied for dominance and survival, the ability for C source code to remain largely unchanged across chip architectures served the industry well. You had a processor-neutral programming language and a lightweight run-time library written in assembly, and standardized libraries written predominantly in the language itself.
This is an extremely important point: C dominated the industry because it hid hardware architecture details from the programmer, not because it was ubiquitous. It became ubiquitous because it thus dominated the industry and its operators and constructs were so easily translatable into machine code.
However, C’s simplistic programming model (and C++’s in turn) is no longer sufficient for today’s applications. A much higher programming model to operate in, and integration with a far more sophisticated run-time model than what C offers is required. Today’s applications are client-server based. Today’s applications are web-based. Any component written today must be able to ignore whether communication is at the socket or RPC or REST or SOAP layer or data is encapsulated in RSS or ATOM. They must be able to handle exceptions due to a server not responding, or access is denied or a web page isn’t found.
While such applications can be written in C with the use of libraries, such implementations don’t scale well. It’s quite cumbersome having to access all your data and behavior through the syntax of functions. Need to pass data to a corporate server? Call a function. Need to see what type of server it is? Call a function. Call a function. Need to ensure incoming data is within the buffer limits? Call a function. Need to extract the next node in a linked-list? Call a function. It is cumbersome and unwieldy and the significance of any single data type and its API is diminished when all of them are looked at through the function call operator. Too many details of how code and data actually interact are visible to allow rapid development of the actual solution.
Programmers will need to wean themselves from the “performance superstition” in order to respond quicker to market forces. It was a long-shot that any software project would succeed in the micro-managed mentality of compiled languages. Without a suitably higher-level development environment, it will be nearly impossible. And performance counts for nothing when your process is blocked due to user (in-)activity or network latencies.
In addition, the typed data addiction programmers suffer is no longer pragmatic. You really don’t need to know how large the integer is. Seriously. If it isn’t big enough the computer can automatically enlarge it. Somewhat like growing a process’ virtual memory allocation when necessary, and without application intervention. Most programmers don’t even check for overflow (or underflow) errors, let alone handle them gracefully. It’s time someone (or something) did.
Dynamic languages should especially be used for those parts of an application where performance isn’t critical but flexibility and reliability are. Where applications don’t need the performance that static languages provide. Parts such as an application’s mid-section, where the UI drives and responds to the business logic and back-end.
Platforms now come with run-time support for various languages as well as frameworks and libraries. It’s much simpler to make use of these components than to reinvent the wheel or supporting infrastructure for your applications, especially with regards to error-handling, illegal memory accesses, etc.
Daniel’s suggestion that scripting, or dynamic, languages will take C’s place as a general purpose language is ironic because the language that used to be the general purpose programming language for microcomputers before C was a dynamic (and interpreted) language: BASIC. So dust off that old BASIC Computer Games! Bring that stack of Creative Computing down from the attic! Let’s hear it for the programming languages of tomorrow! They’re going to look a lot like the interactive languages of yesterday, at least initially. But they’ll help push the threshold of difficulty back down below where the micro industry was before GUIs became the norm. Sure, AppleScript is around, as is VBA, but even though they provide a lot of the safety nets that prevent the sort of bugs that snag professional developers today, they are far from easy for end users to add simple functionality to an application.
Which brings me to my final point in this posting. Daniel didn’t go far enough in predicting the predominant languages of the next decade because the mainstream programming languages of tomorrow won’t be text-based, but graphical. I don’t mean the Interface Builder, Visual Studio sort of connect the tiny little dots to create an application. I mean the point-and-click, drag and drop, template-driven programming that is at the heart of applications such as GarageBand. iMovie. They don’t generate something you’d call an interactive application? How about iDVD and DVD Studio? These tools and many others like them that allow non-programmers in the current sense of the word to generate programmed responses to user- or machine-input will prove to be the dominant programming environments of the future.






[...] and the like will frustrate seasoned developers. But the simplification of programming tools will continue to progress and then those who’ve gained in experience within the current landscape will gnash their [...]