Tuesday, February 25, 2020

The language treadmill

Technology is not a platform, but a treadmill. Readers of a certain age may remember the closing credits of "The Jetsons", in which George Jetson walks their dog astro on a space-age treadmill that runs a bit faster than he would like. The image is not too far off from the technology treadmill.

We're accustomed to thinking of hardware as changing. This year's laptop computer is better (faster, more powerul, more memory) than last year's laptop computer. We consistently improve processors, memory, storage, displays, ... just about everything. Yet the hardware also changes; today's laptop PCs are a far cry from the original IBM PC. Even desktop PCs are different from the original IBM PC. So different, in fact, that they would not be considered "PC compatible" at the time. (Today's USBC-attached displays would not connect, today's USB keyboards would not connect, nor would USB thumb drives. Nothing from today's PC's would connect to an IBM PC model 5150, nor would anything from 1982's IBM PC connect to today's PCs.)

The treadmill includes more that hardware. It also includes software. Operating systems are the most visible software that changes; we deal with them every day. Microsoft has made improvements to each version of Windows, and Windows 10 is different from Windows 3.11 and especially Windows 1.0. Apple changes OS X and that is quite different from the original OS X and much different from the previous Apple OS versions.

The treadmill extends beyond hardware and operating systems. It includes applications (Microsoft Word, for example) and it also includes programming languages.

Programming languages, whether governed by committee (C, C++) or individual (Perl, Python) change over time. Many times, a new version is "backwards compatible", meaning that your old code will work with the new compiler or interpreter. But not always.

Some years ago, I worked on a project that built and maintained a large-ish C++ application which was deployed on Windows and Solaris. The C++ language was chosen because both platforms supported that language; compilers were available for Windows and for Solaris. But the compilers were upgraded on different schedules: Microsoft had their schedule for upgrades to their compiler, and Sun had their (different) schedules for upgrades to their compiler.

Different upgrade schedules could have been a problem, but it wasn't. (Until we made it one. More on that later.) Most updates to the compilers were backwards-compatible, so old code could be moved to the new compiler, recompiled, and the resulting program run immediately.

Most updates worked that way.

One update did not. It was an update to the C++ language, one that changed the way C++ worked and just so happened to break existing code. (The C++ governing committee was reluctant to make the change, but it was necessary and I agree with the reasoning.) So the upgrade required changes to the code. But we couldn't make the changes immediately; we had to wait for both compilers (Microsoft and Solaris) to support the new version of C++.

It turns out that we also had to wait for our managers to allocate time to make the code changes for the new compilers. Our time was allocated for new features to the large-ish application, not to technical improvements that provided no new business features. Thus, our code stayed with the old (soon to be outdated) structures.

Eventually, we saw a chain of events that forced us to update our code. Sun released a new version of the Solaris operating system, and we had to install that to stay current with out licenses. Once installed, we learned that the new operating system supported only the new version of the C++ compiler, and our code immediately broke. We could not compile and build our application on Solaris, nor release it to our production servers (which had been updated to the new Solaris).

This caused a scramble in the development teams. Our managers (who had prevented us from modifying the C++ code and moving to the new C++ compiler) were now anxious for us to make the changes, run tests, and deploy our application to our servers. We did make the changes, but it required us to stop our current work, make changes, run tests, and deploy the applications. Those efforts delayed other work for new features.

This is a cautionary tale, illustrating the need to stay up to date with programming tools. It also shows that programming languages change. Our example was with C++, but other languages change. Python has had two version "tracks" for some time (version 2 and version 3) and development and support of version 2 has come to an end. The future of Python is its version 3. (Do you use Python? Are you using version 3?)

Oracle has released Java version 14. Many businesses still use version 8.

There have been changes to JavaScript, TypeScript, C# (and .NET, on which C# rests), and even SQL. Most of these changes are backwards-compatible, so no code changes are required to move to the new version.

You will eventually move to the new operating system, or compiler, or interpreter. Your code may have to change. The changes can be on your schedule, or on someone else's schedule. My advice: be aware of updates and migrate your programming tools on yours.

Wednesday, February 19, 2020

A server that is not a PC

Today, servers are PCs. They have the same architecture as PCs. They run PC operating systems. But do they have to be PCs? Is there another approach? There might be.

First, let's consider PCs. PCs have lots of parts, from processor to memory to storage, but the one thing that makes a PC a PC is the video. PCs use memory-mapped video. They dedicate a portion of memory to video display. (Today, the dedicated memory is a "window" into the much larger memory on the video card.)

Which is a waste, as servers do not display video. (Virtual machines on servers do display video, but it is all a game of re-assigned memory. If you attach a display to a server, it does not show the virtual desktop.)

Suppose we made a server that did not dedicate this memory to video. Suppose we created a new architecture for servers, an architecture that is exactly like the servers today, but with no memory reserved for video and no video card.

Such a change creates two challenges: installing an operating system and the requirements of the operating system.

First, we need a way to install an operating system (or a hypervisor that will run guest operating systems). Today, the process is simple: attach a keyboard and display to the server, plug in a bootable USB memory stick, and install the operating system. The boot ROM and the installer program both use the keyboard and display to communicate with the user.

In our new design, they cannot use a keyboard and display. (The keyboard would be possible, but the server has no video circuitry.)

My first though was to use a terminal and attach it to a USB port. A terminal contains the circuitry for a keyboard and display; it has the video board. But no such devices exist nowadays (outside of museums and basements) and asking someone to manufacture them would be a big ask. I suppose one could use a tiny computer such as a Raspberry Pi, with a terminal emulator program. But that solution is merely a throwback to the pre-PC days.

A second idea is to change the server boot ROM. Instead of presenting messages on a video display, and accepting input from a keyboard, the server could run a small web server and accept requests from the network port. (A server is guaranteed to have a network port.)

The boot program could run a web server, just as network routers allow configuration with built-in web servers. When installing a new server, one can simply attach it to your network and then connect to it via SSH.

Which brings us to the next challenge: an operating system. (Or a hypervisor.)

Today, servers run PC operating systems. Hypervisors (such as Microsoft's Hyper-V) are nothing more than standard PC operating systems that have been tweaked to support guest operating systems. As such, they expect to find a video card.

Since our server does not have a video card, these hypervisors will not work properly (if at all). They will have to be tweaked again to run without a video card. (Which should be somewhat easy, as hypervisors do not use the video card for their normal operation.)

Guest operating systems may be standard, unmodified PC operating systems. They want to see a video card, but the hypervisor provides virtualized video cards, one for each instance of a guest operating system. The guest operating systems never see the real video card, and don't need to know that one is present -- or not.

What's the benefit? A simpler architecture. Servers don't need video cards, and in my opinion, shouldn't have them.

Which would, according to my "a PC must have memory-mapped video" rule, make servers different from PCs. Which I think we want.

The video-less server is an idea, and I suspect that it will remain an idea. Implementing it requires special hardware (a PC minus the video circuitry that it normally has) and special software (an operating system that doesn't demand a video card) and special boot ROM (one that talks over SSH). As long as PCs are dominant, our servers will simply be PCs with no display attached.

But if the market changes, and PCs lose their dominance, then perhaps one day we will see servers without video cards.

Wednesday, February 12, 2020

Advances in platforms and in programming languages

The history of computing can be described as a series of developments, alternating between computing platforms and programming languages. The predominant pattern is one in which hardware is advanced, and then programming languages. Occasionally, hardware and programming languages advance together, but that is less common. (Hardware and system software -- not programming languages -- do advance together.)

The early mainframe computers were single-purpose devices. In the early 21st century, we think of computers as general-purpose devices, handling financial transactions, personal communication, navigation, and games, because our computing devices perform all of those tasks. But in the early days of electronic computing, devices were not so flexible. Mainframe computers were designed for a single purpose; either commercial (financial) processing, or scientific computation. The distinction was visible through all aspects of the computer system, from the processor and representations for numeric values to input-output devices and the characters available.

Once we had those computers, for commercial and for scientific computation, we built languages. COBOL for commercial processing; FORTRAN for scientific processing.

And thus began the cycle of alternating developments: computing platforms and programming languages. The programming languages follow the platforms.

The next advance in hardware was the general-purpose mainframe. The IBM System/360 was designed for both types of computing, and it used COBOL and FORTRAN. But we also continued the cycle of "platform and then language" with the invention of a general-purpose programming language: PL/1.

PL/1 was the intended successor to COBOL and to FORTRAN. It improved the syntax of both languages and was supposed to replace them. It did not. But it was the language we invented after general-purpose hardware, and it fits in the general pattern of advances in platforms alternating with advances in languages.

The next advance was timesharing. This advance in hardware and in system software let people use computers interactively. It was a big change from the older style of scheduled jobs that ran on batches of data.

The language we invented for this platform? It was BASIC. BASIC was designed for interactive use, and also designed to avoid requests of system operators to load disks or tapes. A BASIC program could contain its code and its data, all in one. Such a thing was not possible in earlier languages.

The next advance was minicomputers. The minicomputer revolution (DEC's PDP-8, PDP-11 and other  systems from other vendors) used BASIC (adopted from timesharing) and FORTRAN. Once again, a new platform initially used the languages from the previous platform.

We also invented languages for minicomputers. DEC invented FOCAL (a lightweight FORTRAN) and DIBOL (a lightweight COBOL). Neither replaced its corresponding "heavyweight" language, but invent them we did.

The PC revolution followed minicomputers. PCs were small computers that could be purchased and used by individuals. Initially, PCs used BASIC. It was a good choice: small enough to fit into the small computers, and simple enough that individuals could quickly understand it.

The PC revolution invented its own languages: CBASIC (a compiled form of BASIC), dBase (later named "xbase"), and most importantly, spreadsheets. While not a programming language, a spreadsheet is a form of programming. It organizes data and specifies calculations. I count it as a programming platform.

The next computing platform was GUI programming, made possible with both the Apple Macintosh and Microsoft Windows. These "operating environments" (as they were called) changed programming from text-oriented to graphics, and required more powerful hardware -- and software. But the Macintosh first used Pascal, and Windows used C, two languages that were already available.

Later, Microsoft invented Visual Basic and provided Visual C++ (a concoction of C++ and macros to handle the needs of GUI programming), which became the dominant languages of Windows. Apple switched from Pascal to Objective-C, which it enhanced for programming the Mac.

The web was another computing advance, bringing two distinct platforms: the server and the browser. At first, servers used Perl and C (or possibly C++); browsers were without a language and had to use plug-ins such as Flash. We quickly invented Java and (somewhat less quickly) adopted it for servers. We also invented JavaScript, and today all browsers provide JavaScript for web pages.

Mobile computing (phones and tablets) started with Objective-C (Apple) and Java (Android), two languages that were convenient for those devices. Apple later invented Swift, to fix problems with the syntax of Objective-C and to provide a better experience for its users. Google invented Go and made it available for Android development, but it has seen limited adoption.

Looking back, we can see a clear pattern. A new computing platform emerges. At first, it uses existing languages. Shortly after the arrival of the platform, we invent new languages for that platform. Sometimes these languages are adopted, sometimes not. Sometimes a language gains popularity much later than expected, as in the case of BASIC, invented for timesharing but used for minicomputers and PCs.

It is a consistent pattern.

Consistent that is, until we get to cloud computing.

Cloud computing is a new platform, much like the web was a new platform, and PCs were a new platform, and general-purpose mainframes were a new platform. And while each of those platforms saw the development of new languages to take advantage of new features, the cloud computing platform has seen... nothing.

Well, "nothing" is a bit harsh and not quite true.

True to the pattern, cloud computing uses existing languages. Cloud applications can be built in Java, JavaScript, Python, C#, C++, and probably Fortran and COBOL. (And there are probably cloud applications that use these languages.)

And we have invented Node.js, a framework in JavaScript that is useful for cloud computing.

But there is no native language for cloud computing. No language that has been designed specifically for cloud computing. (No language of which I am aware. Perhaps there is, lurking in the dark corners of the internet that I have yet to visit.)

Why no language for the cloud platform? I can think of a few reasons:

First, it may be that our current languages are suitable for the development of cloud applications. Languages such as Java and C# may have the overhead of object-oriented design, but that overhead is minimal with careful design. Languages such as Python and JavaScript are interpreted, but that may not be a problem with the scale of cloud processing. Maybe the pressure to design a new language is low.

Second, it may be that developers, managers, and anyone else connected with projects for cloud applications is too busy learning the platform. Cloud platforms (AWS, Azure, GCP, etc.) are complex beasts, and there is a lot to learn. It is possible that we are still learning about cloud platforms and not ready to develop a cloud-specific language.

Third, it may be too complex to develop a cloud-specific programming language. The complexity may reside in separating cloud operations from programming, and we need to understand the cloud before we can understand its limits and the boundaries for a programming language.

I suspect that we will eventually see one or more programming languages for cloud platforms. The new languages may come from the big cloud providers (Amazon, Microsoft, Google) or smaller providers (Dell, Oracle, IBM) or possibly even someone else. Programming languages from the big providers will be applicable for their respective platforms (of course). A programming language from an independent party may work across all cloud platforms -- or may work on only one or a few.

We will have to wait this one out. But keep yours eyes open. Programming languages designed for cloud applications will offer exciting advances for programming.

Wednesday, February 5, 2020

Windows succeeded because of laser printers

It is easy to survey the realm of computing and see that Windows is dominant (at least on desktop computers, and on lots of laptops in offices). But Windows did not always have dominance; it had to fight its way to the top. Windows had to replace PC-DOS/MS-DOS, it had to fight off OS/2, and it had to beat a number of other (smaller) contenders.

Much has been written about the transition from PC-DOS to Windows and the competition between Windows and OS/2. There is one factor, I think, that has received little attention. This one factor, by itself, may not have made the decision, but it was a factor that favored Windows.

That factor was the laser printer. (Specifically the Hewlett-Packard LaserJet printer.)

Laser printers were desired. They were expensive, which dampened their acceptance, but people wanted them. They were quieter, they were faster, and they produced better quality output. They could provide different typefaces and they could print graphics. And people wanted quiet, fast, high-quality output, especially with graphics.

One could use a laser printer with programs in PC-DOS. It was not always easy, and it was not always possible. PC-DOS provided few services for devices; just enough to send data to a parallel port or a serial port. Applications that wanted to use sophisticated devices (such as laser printers) had to build their own drivers. (The same issue was present for video cards, too.) Thus, when purchasing software, the first question was "Will it support a laser printer?". Some software did, some did not, and some supported laser printers poorly.

Windows supported graphics, video cards, and laser printers from the start. Windows was built around graphics; the first release of Windows was a graphics program. Windows also handled device drivers, allowing a device to have a single driver for all applications. If a program ran in Windows, it could print on all of the printers supported by Windows. Windows was graphics.

In contrast, the first version of OS/2 worked only in text mode. OS/2 users had to wait for version 2.1 to have graphics. Microsoft and IBM (developing OS/2 jointly) focused on multitasking and memory and security.

The difference between Windows and OS/2 was that orientation. Windows was an operating system for a PC; that is, an operating system for a video display board that had a processor and memory and storage attached. OS/2 was an operating system for a minicomputer; very good at multitasking for a use that communicated through a character interface. Even though PCs at the time had video boards, OS/2 pretended that the user was sitting at a terminal.

But people wanted graphics. They wanted graphics because they could see the print-outs from laser printers. They were willing to pay lots of money for laser printers, to impress their co-workers and their bosses.

Windows had graphics. OS/2 did not.

I cannot help but think that laser printers helped Windows win over OS/2.

(I do recognize that other factors contributed to the success of Windows. Those factors include licensing arrangements, marketing, and compatibility with PC-DOS applications. I think laser printers are another -- unrecognized -- factor.)

Today, we casually accept that just about every device works with Windows, and that we can print from any application to any device (laser printer, ink-jet printer, and even PDF file), and that it all works. The computing world of 2020 is very different from the world of 1985.

But maybe we should be looking forward instead of backward. Windows won over OS/2 because it met the demand of the market. It provided graphics on screen and on printouts. It gave people what they wanted.

Today, in 2020, what do people want? And which companies are providing it?