Tuesday, March 31, 2015

Our tools shape our languages, and our programs

Our applications are shaped by many forces: budget, available talent, time, languages, and tools.

When designing applications, languages are sometimes overlooked. Yet it should be obvious to anyone who has used multiple languages. Different languages have different capabilities. C and its descendants have the notions of pointers, something absent in COBOL, Fortran, and BASIC. The notion of pointers lets one build dynamic, complex data structures; such structures are not possible in pointerless languages.

Our tools have an effect on our languages, which can have an effect on our applications.

In the Microsoft world, C# is a simple language, yet the .NET framework of classes is complex and wordy. A simple application in C# requires a significant amount of typing, and a moderately complex application requires a large amount of typing.

Languages such as Perl, Python, and Ruby require less typing. How is it that the .NET framework is so complex? The answer, I believe is in Visual Studio.

Microsoft's development environment is the result of competition and years (decades?) of development. Over that time, Microsoft has added features: debugging, test case management, design documents, and editing features. One significant editing feature is the auto-completion of typing with context-sensitive information. When I am typing a C# program and I start typing a name of a variable, Visual Studio gives me a list of existing variable names. (It also knows that the declaration of a variable is different from the use of a variable, and does not prompt me with existing names.) Visual Studio also lists methods for objects and provides templates for parameters.

This assistance from Visual Studio reduces the burden of typing. Thus, applications that use the .NET framework can appear wordy, but the effort to create them is less than it appears. (Some have argued that the assistance from Visual Studio helps reduce errors, as it suggests only valid possibilities.)

Thus, a development tool can affect our languages (and class frameworks), which in turn can affect our applications. When choosing our tools, we should be aware of their properties and how they can affect our projects.

Tuesday, March 24, 2015

Why Alan Turing is a hero to programmers

We in the programming world have few heroes. That is, we have few heroes who are programmers. There are people such as Bill Gates and Steve Jobs, but they were businessmen and visionaries, but not programmers.

Yet we do have a few heroes, a few programmers who have risen above the crowd. Here is a short list:

Grace Hopper Serving in the Navy, she created and advocated the idea of a compiler. At the time, computers were programmed either by wire (physical wires attached to plug-boards) or with assembly language. A compiler, converting English-like statements into machine instructions, was a bold step.

Donald Knuth His multi-volume work The Art of Computer Programming is a comprehensive work, comprising machine design, assemblers, compilers, searching, sorting, and the limits of digital computation. He also created the TeX language and the notion of "Literate Programming".

Brian Kernighan and Dennis Ritchie Created the C language.

Larry Wall Creator of the Perl language; also the creator of the 'patch' program used to apply changes across systems.

Fred Brooks The chief designer of IBM's operating system for the System/360 computers, his book The Mythical Man-Month has several interesting observations on the teams that construct software.

Gerald Weinberg Known for his books on system analysis and design, I find his work The Psychology of Computer Programming much more useful to programmers and program team managers.

All of these folks are (were) smart, creative, and contributors to the programming art. Yet one has a special place in this list: Alan Turing.

Alan Turing, subject of the recent movie "The Imitation Game", has made significant contributions to the programming craft. They are:

  • Code-breaking in World War II with the Bombe computer
  • The Turing Test
  • Turing Machines
  • The Halting Problem

All of these are impressive. Turing was many things: mathematician, biologist, philosopher, logician.

Of all of his accomplishments, I consider his proof of the halting problem to be the one act that raises him above our other heroes. His work with code-breaking clearly makes him a programmer. His idea of the Turing Test set clear (if perhaps unreachable) goals for artificial intelligence.

The notion of Turing machines, with the corresponding notion that one Turing machine can emulate another Turing machine is a brilliant insight, and enough to make him a hero above others.

Yet it is the halting problem, or more specifically Turing's proof of the halting problem (he proved that one cannot tell, in advance, that a program of sufficient complexity would be guaranteed to stop) is what pushes him across the line. The proof of the halting problem connects programming to mathematics.

Mathematics, of course, has been with us for centuries. It is as old as counting, and has rigorous and durable proofs. Euclid's work is two millennia old, yet still used today. It is these proofs that make mathematics special - math is the "Queen of the Sciences" and used by all other branches of knowledge.

Mathematics is not without problems. There is a proof called the Incompleteness Theorem, which states that any system of axioms (rules) that includes integers, there exist theorems which are known to be true yet cannot be proved with that system of axioms. (The Incompleteness Theorem also states that should you add an axiom to the system to allow such a proof, you will find that there are other theorems which are known to be true but not provable in the new system.)

That sounds a lot like the halting problem.

But the Incompleteness Theorem is the result of thousands of years of study, and computing is young; we have had digital computing for less than a century. Perhaps we can find another corresponding mathematical surprise, one that occurred earlier in the history of mathematics.

Perhaps Turing's proof of the halting problem is closer to the discovery of irrational numbers. The Greek philosophers were enchanted with mathematics, bot geometry and arithmetic. The reduction of physical phenomena to numbers was a specialty for them, and they loved integers and ratios. They were quite surprised (and by some accounts, horrified) to learn that numbers such as the square root of two could not be represented by an integer or a ratio of integers.

That kind of problem sounds close to our halting problem. For the Greeks, irrational numbers broke their nice, neat world of integers. For us, the halting problem breaks the nice, neat world of predictable programs. (To be clear, most of our programs do run "to completion" and halt. The theory states that we cannot know in advance that they will halt. We simply run them and find out.)

Turing gave us the proof of the halting problem. In doing so, he connected programming to mathematics, and (so I argue) us early programmers to the early mathematicians.

And that is why I consider Alan Turing a hero above others.

Thursday, March 19, 2015

The oldest high-level language

When discussing languages, we typically divide them into the groups "high-level" and "low-level".

The explanation I received at the time was that "low-level languages deal with machine-specific issues and high-level languages do not". I was taught this division when I started programming, many moons ago. It works, but it is awkward. It leads to the following:

Low-level languages:
  • Assembly
  • Machine language
Mid-level languages:
  • C
  • C++
  • Lisp
High-level languages:
  • Fortran
  • Cobol
  • BASIC
  • Pascal
  • C#
  • Java
  • Awk
  • Perl
  • Python
  • Ruby
  • Eiffel
  • Erlang
  • Haskell
The awkwardness is the imbalance. Almost every language is considered a high-level language.

If every language ends up "winning" in the high-level category, then the rule has little value. So I started thinking about different ways to divide languages.

The old rule is valid: languages which force the programmer to consider machine-specific details are low-level languages. That concept remains. What we need is a refinement, some concept that can split off some of the high-level languages and push them into the "mid-level" category.

For me, that refinement is memory layout.

If a programming language forces the programmer to think about memory layout, then it is, at best, a mid-level language.

This refinement is consistent with our original rule of machine-dependency. Machine language and assembly language are low-level languages (by convention) and they require attention for the layout of items in memory. Indeed, machine-language and assembly language require the programmer to think about the layout of instructions as well as data.

C and C++, with their pointers, require a fair amount of attention to memory layout. They also have structs which aggregate data elements in memory, and a fair amount of control over the alignment of elements within a struct. They stay within the mid-level group.

Cobol, normally considered a high-level language, drops to mid-level. Anyone who has programmed in Cobol knows that much attention is given to the layout of not only input and output records but also working storage (what most programmers would call "variables").

Fortran also drops to mid-level. Its handling of arrays, its COMMON blocks, and its EQUIVALENCE statement all make the programmer think about memory allocation.

Pascal too moves to mid-level, due to its pointer concept.

With this refinement, we now have the following list:

Low-level languages:
  • Assembly
  • Machine language
Mid-level languages:
  • C
  • C++
  • Lisp
  • Fortran
  • Cobol
  • Pascal
High-level languages:
  • BASIC
  • C#
  • Java
  • Awk
  • Perl
  • Python
  • Ruby
  • Eiffel
  • Erlang
  • Haskell
That improves my issue of "balance" -- although the low-level group remains small at only two members. Perhaps there is a further refinement that moves languages to that group. I am willing to let that wait for another day.

But I do notice that, of the high-level languages, BASIC is the oldest - and by a fair amount. BASIC was designed in the 1960s. The next languages were Awk (1970s) and Perl (1987). A programmer using BASIC does not have to worry about memory layout; variables are instantiated and reclaimed transparently. The BASIC language is limited, although it has been extended over time.

So using my refined heuristic, the oldest high-level programming language is BASIC.

Thursday, March 12, 2015

Smart watches are watches after all

The wristwatch has been called the "first wearable computer". Not the smart watch, but the classic, mechanical, wind-up wristwatch. I agree -- with a reservation about pocketwatches as being the first wearable computing devices.

Apple made a big splash in the news this week, finally announcing their smart watch (among other things). Apple calls their product a "watch". Is it? it seems much more than a plain old watch.

Apple did the same with their iPhone. The iPhone was really a small computer equipped with wireless communication. Yet who wants to carry around a small computer (wireless or not)? It's much easier (psychologically) to carry around a phone.

Looking at our experience with the iPhone, we can see that iPhones (and smart phones in general) are used for many purposes and only occasionally as a phone. We use them to take pictures, to watch movies, to play games, to read e-mail, to send and receive text messages, to navigate, to calculate, to bank online, ... The list is extensive.

Applying that logic to the Apple Watch (and smart watches in general) we can expect many purposes for them. Some of these will duplicate or extend our phones (those small wireless computers): notifications of appointments, navigation, display of e-mail and text messages, and of course to tell the time. Smart watches will offer new functions too: payments at checkout counters, unlocking house doors (equipped with smart locks), unlocking automobiles (and possibly replacing the key entirely), exchanging contact information (virtual business cards), ... the list is extensive.

Smart watches will provide convenience. Smart watches will also add a degree of complexity to our lives. Is my watch up to date? Have I charged it? Is my watch compatible with a merchant's payment system? Does it have a virus or other malware?

We'll call them "watches", since the name "small computing device that I wear on my wrist" is unwieldy. But that was the same issue with the original pocketwatches and wristwatches. They, too, were small computing devices. (Some, in addition to telling time, displayed the phase of the moon and other astronomic data. In the twentieth century, wristwatches often displayed the day of the month.)

So, yes, smart watches are not watches. They do much more than tell time. And yet they are watches, because we define the term "watch" to mean "small computing device that I wear on my wrist". We have for more than a century.