When I first learned programming in the mid 90s, everyone told me to learn Java, since it would be the wave of the future. Java imposes a performance penalty compared to traditional compiled languages like C, C++, Fortran and Pascal, because its code is translated into bytecode that runs in a virtual machine. The feeling at the time was that the extra processing and memory required to run the Java virtual machine would make little difference in the long run since computers were forever getting faster and more powerful. A few more iterations of Moore’s Law would obviate the need for compiled languages, since the difference in speed would soon be imperceptible to most humans.
Java was considered the best language, because it was designed to “write once, run anywhere,” which seemed wise considering how the world was moving from minicomputers with terminals to networked personal computers (PCs). When I first arrived at university, the entire campus ran on VAX terminals, although some students brought their own PCs to use in their dorm rooms. By the time I graduated 4 years later, almost the entire campus had switched to networked PCs. I had a job staffing the college computer lab and I fondly recall the excitement on campus when PCs replaced the monochrome VAX terminals with their pea green screens. There was a raging debate at the time whether PCs should use an operating system from Microsoft or Apple. My friends in the computer lab predicted with all the confidence of sages that Java was the future since it could be used to create desktop applications that would run in Windows 95, Mac OS 7 or even Solaris. Everyone knew at the time that desktop applications running on PCs was the future of computing and we all wanted our software to be able to escape the clutches of Microsoft, who was the geek’s great Satan.
The geeks who hung around the UNIX lab gave me some odd advice which I thought was really strange at the time. They told me to learn Perl or Python as my first programming language, since it would make me even more productive. I dismissed these people as weird oddballs, but their arguments in favor of interpreted languages were very similar to the people arguing for Java. They told me that computers were getting faster and faster, so why worry about performance, but they said that the flexibility of interpreted languages would make me far more productive as a programmer.
Since I have always been a contrarian, I bucked all the trends and decided to learn C as my first programming language. Everyone told me that C was a hard language to learn, especially for someone who didn’t have an instructor to guide me. Besides, object oriented programming and graphical interfaces were the wave of the future, so it was pointless to learn C, but I wanted to get as close to the bare metal as possible so that I could figure out how they actually worked. Over Christmas break in 1995, I worked my way through the New C Primer Plus by Micheal Waite and Stephen Prata, with just a pencil and paper to write out sample programs since I didn’t have a C compiler at the time. For me it was like reading philosophy–purely theoretical ideas that tickled my imagination and were fun to ponder. The book had whole chapters on pointers, memory allocation and bit fiddling—none of which have I ever used, but I recall being thrilled to learn how computers work at the lowest level. I remember being fascinated by an algorithm in the book that converted numbers from binary to decimal and back again.
A couple years after I graduated from college, everyone started talking about programming for the web. Those interpreted languages that the geeks in the UNIX lab had told me to learn were suddenly the wave of the future. Perl, PHP, Python and Ruby were the languages that everyone wanted to learn. Having looked at HTML code in web pages which was generated by these languages, web programming didn’t seem that interesting to me. However, when I eventually decided to learn a new language after C, I chose PHP because it seemed to be the language that everyone was learning to do web programming and it syntax was close enough to C to make it easy to pick up.
The predictions of the geeky prognosticators in the mid-90s have come to pass over the last 2 decades. Code run in virtual machines did become the dominant way to program desktop applications on the PC, as most applications programmers chose Java, C# or Visual Basic, as their preferred languages over the traditional compiled languages of C and C++, while other compiled languages such as Pascal, Ada, Fortran and Cobol have largely disappeared outside of some recondite niches. Desktop application programming was followed by a wave of web programming based on interpreted languages, such as Perl, Python, PHP and Ruby.
Something strange, however, has happened recently which has bucked the trend toward greater levels of abstraction from the hardware through virtual machines and interpreted languages. Programmers are increasingly focusing on code that requires less memory and fewer processing cycles. This renewed focus on better performance and efficiency was caused in part by the surge in mobile devices and the need to program for devices that have fewer resources to waste and need to conserve battery power. Most of the programming of apps for Apple mobile devices is done in Objective-C, which is generally compiled to be as efficient as possible. For Android devices, Google created Dalvik, a Java virtual machine that was much leaner and required fewer resources than the standard Java virtual machine from Sun.
The second cause of this renewed focus on efficiency in software was the rise of giant web companies like Google and Facebook, which spend hundreds of millions of dollars building their own server farms. An inefficient desktop application makes little difference on a PC, but an inefficient web service can cost a company like Google or Facebook millions of dollars in extra hardware, so it pays for these companies to develop software which uses as little RAM and processing cycles as possible. These companies even design the motherboards and power supplies of their servers, so they will use less energy to save money.
The third cause for greater efficiency in software has been the growing recognition that Moore’s Law is starting to falter. The traditional tick-tock cycle where Intel introduced a shrink in node size every two years has now become a tick-tock-tock cycle every three years. It has become harder and harder for the silicon industry to keep shrinking its process tech and each new generation of process tech is no longer bringing dramatic falls in the cost per transistor. The expected roll out of extreme ultraviolet (EUV) lithiography at 13.5 nm wavelengths has taken years longer than expected. The industry has been forced to keep using deep ultraviolet (DUV) excimer lasers with a 193 nm wavelength. In order to overcome the fact that the amplitude of the wave is so much larger than the line widths of the circuits, the silicon fabs have resorted to costly measures such as immersion lithiography at 32nm node sizes and lower, double patterning at 16/14nm, and triple patterning at 10nm. In addition, the silicon fabs have employed new materials such as hafnium and germanium with a high-K dielectic and silicon on insulator (SOI) in order to keep shrinking the node size, plus they developed non-planar transistors known as Fin Field Effect Transistors (FinFET).
As the node sizes keep shrinking, the costs of new silicon fabs are skyrocketing and the cost of overcoming currency leakage and quantum-mechanical effects at the nanoscale will become ever greater. Given the increasing costs, many chip companies such as GlobalFoundries are choosing to skip the 10nm node and go straight to a 7nm node size. Semico estimates that the cost of designing a system on a chip (SoC) rose 89% between the 28nm and 14nm nodes and will rise another 32% at 10nm, plus another 45% at 7nm. Gartner is even more pessimistic, estimating that a SoC, which cost $30 million to design on a planar 28nm node, now costs $80 million on a FinFET 14nm node. Gartner predicts that the same SoC will cost $271 million at a 7nm node size and $500 million at 5nm.
Some in the silicon fab industry are now saying that node sizes will not able to shrink to 5nm or smaller node sizes due to the effects of quantum tunneling, so the industry will have to go vertical with 2.5D or 3D packaging. Others are saying that 5nm will be possible using finFETs with new materials, gate-all-around FETs with nanowires or nanosheet FETs, but it will be very costly and few will be able to compete at the scale required. Only 4 companies (Intel, TMSC, GlobalFoundries and Samsung) can compete at the current 14/16nm node size, and it is unclear whether GlobalFoundries will be able to raise the kind of capital needed to survive in the future. Samsung estimates that its 10nm fab in Pyeongtaek City, South Korea will cost $14 billion to build and TMSC predicts that its 5nm fab in Taiwan will cost $15.7 billion.
Given these rising costs of manufacturing silicon chips, it is highly questionable whether the cost per transistor can continue falling like it has for the last 4 decades. There may be an occasional break-through in process tech to lower the costs, but the relentless march of the past is likely to become sporadic advances in sputters and spurts, as the industry runs into thorny obstacles that require years of R&D to overcome.
What the rising cost of silicon also means is that hardware in the future will cost more than what many futurists expected. The costs of developing ASICs (i.e. custom chips) will be prohibitively expensive for many applications, so device makers will have to either design their chips with larger node sizes such as 28nm or use generic chips in low-end devices, which will increase their costs. There will still be smart homes hooked into a smart electric grid, but the toaster and the coffee machine may be left off that grid, because the chips will cost too much for such lowly devices and the chips running the lights, air conditioner, washing machine and car charger will have less memory and fewer processing cores than the sanguine futurists once predicted.
The Internet of Things (IoT) will certainly happen, but it will be rolled out more slowly and with fewer devices than once thought. Many thought that smart watches would be the next big wave of the future after smartphones, but the high cost of cramming advanced processing in such tiny spaces has limited the demand for smart watches. Rather than a multi-functional device running a full operating system, most of the so-called “smart watches” being sold today are fitness gear with fixed functionality and limited extendability.
Much of the future innovation in the IoT will have to come not from more powerful hardware, but from efficient software with a small footprint. The kind of low-level programming that was so valued in the early days of computing will be coming back into vogue as more and more programming will be done on devices with 8 and 16 bit processors and a couple hundred megabytes of memory.
Most of the focus in computer science for the last couple decades has been on employing greater levels of abstraction over the hardware to make programming safer and easier with fewer lines of code. There are signs, however, that the tide is now shifting toward software requiring less memory and consuming fewer processing cycles. A decade ago, much of the innovation in programming was taking place in interpreted languages and frameworks designed principally for the web such as Ruby on Rails and jQuery. Most efforts to improve performance were focused on measures such as Just in Time (JIT) compiling and opcode caching to make interpreted languages run faster.
Today, the innovation is taking place in compiled languages, which strive to be just as fast and resource-efficient as C/C++, but without their downsides. A whole plethora of new languages have appeared on the scene, such as Go, Swift, Rust, Julia and Nim which seek to improve on hoary C, which is showing its age as a language designed 45 years ago.
Go was designed by a team in Google that included Dennis Richie and Ken Thompson, who were the original designers of C. They created a programming language which is based on parallelism and safety. Go is simpler in syntax than C/C++ and employs automatic garbage collection like Java, but with better performance. The language isn’t low-level enough for operating systems and device drivers, but it is finding a large number of uses, including running Google Web Services.
Swift is designed to replace Apple’s Objective-C. Unlike Go, it incorporates more of the features from higher-level languages. It also has automatic freeing of memory, but it uses resource counters to determine when to free the memory, rather than a garbage collector which imposes a performance penalty.
The most interesting of these new languages in my opinion is Rust, which was designed by the Mozilla Foundation in order to develop a new web browser engine based on safety and parallelism. Instead of a garbage collector or resource counter, Rust uses a novel concept of ownership to determine when to free memory. Only one variable at a time can own a piece of memory, so memory is automatically freed once its variable goes out of scope. This same concept of ownership is used to eliminate concurrency bugs with data races and sharing resources across different processing threads.
Rust strives to give the programmer all the control of C/C++, but with greater safety and many features of high level languages such as closures, pattern matching, generics, loops with automatic iterators, and traits without the overhead of classes and inheritance. The Rust designers describe these features as “zero-cost abstraction,” meaning that they want to give programmers features from high-level languages, but without the performance cost of that abstraction.
Unfortunately, the safety, control and abstraction of Rust do come at a cost, not in terms of performance which rivals C, but in terms of the work of the programmer. Whereas Go and Swift are easier to learn and the syntax is simpler than C/C++, Rust has a very complex syntax and is much harder to learn in my opinion. Writing code in Rust forces the programmer to do a lot more mental work from the outset and type more code to do the same thing as Go or Swift. There are few books on the language and the online documentation is often spotty in its explanation, so you have to rely on its avid community for help and advice to learn the language. Unlike Go and Swift, Rust development is a community-driven affair, which partially explains the passionate way programmers have embraced the language.
Despite its steep learning curve and complex syntax, Rust is rated by Stack Overflow’s 2016 Developer Survey as the programming language with the highest percentage of users who want to continue using it. The language with the second highest percentage is Swift and Go is the fifth highest. The people who have learned how to program with these new compiled languages appear to highly appreciate them and want to keep using them.
According to RedMonk, which ranks the popularity of programming languages according to the amount of code posted on Github and the number of questions on Stack Overflow, Rust leaped from number 47 to 26 in the list of languages between June 2016 and January 2017. This stellar rise in popularity follows the trend set by Apple’s Swift whose ranking similarly rose from number 68 to 22 between June 2014 and January 2015. Go rose less dramatically from number 34 in January 2013 to number 15 in June 2015. Among the programming languages tracked by RedMonk, the only languages which have dramatically improved their rankings over the last 5 years have been Go, Swift, Rust and TypeScript. During the same time period, the popularity of ASP, Assembly, ActionScript and Perl have declined, but the rest of the programming languages in the top 20 have seen remarkably little movement in their popularity.
Interpreted languages and languages that run in virtual machines will continue to comprise the majority of programming in the future, but rise of new compiled languages indicates that attitudes are changing and programmers are increasingly worried about speed and resource efficiency. Part of the popularity of these languages is due to the fact that they are being used in place of C, C++, and Objective-C, but none of these traditional compiled languages have seen a drop in their rankings. Swift may eventually replace Objective-C, but it is also gaining new adherents outside the Apple ecosystem. Apple open sourced the language and ported it to Linux and BSD and is in the process of porting it to Windows. Go is gaining traction as a language for desktop applications, but it is also being used in the backend to provide REST or web services, whereas Java, Perl, Python, PHP or Ruby would have been chosen 5 years ago for that task. It is a sign of the times that Dropbox chose to reimplement its site in Go and program some of the most mission-critical bits in Rust.
It is not surprising that Go and Swift are proving to be very popular, since they sport a simpler syntax, provide automatic memory management and are better designed for concurrency compared to C/C++/Objective-C. What is surprising, however, is the fact that Rust is so beloved by its users, considering how difficult it is to learn and the amount of extra mental work the language requires from the programmer to keep track of ownership, borrowing, lifetimes and distinguish between the stack and the heap. Perhaps Rust’s popularity among its users is due to the fact that using Rust in the first place is a self-selecting process. It attracts the kind of programmers who don’t mind the hiccups of playing with cutting edge tools and spotty documentation and enjoy the challenge of learning new concepts. The high popularity of Go, Swift and Rust among their users will probably fall to some degree once these languages start to be used by less adventurous programmers, who are directed to use them by management, rather than discovering the languages themselves.
The rise of Go, Swift and Rust is a sign of the growing recognition that Moore’s Law is sputtering out and we will need to live in a world of limited resources. We don’t have the luxury of solving all problems by simply throwing more hardware and costly layers of abstraction at it. Instead, we need leaner code that consumes as little memory and processing cycles as possible, while still providing safety and concurrency. This is a brave new world for many programmers, since it requires learning new skills and new ways of thinking, but it also makes the ability of programmers more important than ever to get the most functionality out of limited hardware.