Welcome to this new blog on the Design and Engineering of Programming Languages. The intent is to cover the process of designing a programming language, coupled with the engineering of the language, which essentially means making the trade-offs necessary to produce a useful result. We include in the engineering not only the conventional notions of software engineering and language engineering, but also what we consider perhaps the most important, the notion of human engineering.
Of course right off the bat we are "begging" all sorts of questions, many of which revolve around what exactly is the role of programming languages. One could argue that high-level programming languages are the most important invention (or discovery?) of the computer era, and without them none of the benefits (as well as the malignancies, perhaps) we associate with computers would have come to pass. One could claim that this invention was inevitable, since no one could remain in their right mind for long if they were only allowed to program directly at the machine level.
Nevertheless, in the earliest days of computing, there was some fear that we might never be able to write a program that could translate another "program" written in a higher level language into something understandable by a computer. Some of this fear carried over into the design of the first programming languages, resulting in fixed formats, primitive control structures, primitive data structures, etc. But much of the primitiveness probably came from the lack of any real precedent on which to base the design of these new languages. Algorithms, proofs, recipes, instruction manuals, etc., tended to be written as an explicit series of steps, with very simple ways for repeating steps. Recursion was virtually unknown, though certain algorithms and proofs might have effectively been recursive, there were rarely described as such. Proof by induction today we would probably describe as a recursive proof. In any case, it is clear that once the process started, it was inevitable that programming languages would evolve.
What were the big steps in programming language design? Certainly recursion in Lisp. Certainly record structures in Cobol. Certainly classes in Simula. Certainly enumeration types in Pascal. Certainly abstraction and clusters in CLU. Perhaps the most important single item written about programming languages was Djikstra's letter to CACM in March 1968 on "Go To Statement Considered Harmful." What makes it so important is that someone could even imagine that a particular feature of a programming language could be harmful. That statement opens up a new vista on how we should view the features of programming languages. They are not just part of a bag of tricks. Their presence or absence can shape the way we express our ideas -- their clarity, their correctness, their verifiability. Donald Knuth (with a bit of poetic license) is quoted as saying that "programming is the art of telling another human being what one wants the computer to do." And of course the programming language (or other notation, which for these purposes we will consider a language) is the way that we communicate, and as such, it is critical for the language to capture both the essence, and the details, in a way that a human can understand, and a computer can unambiguously obey.
Popular posts from this blog
The term human engineering is not that widely used when talking about programming languages, but arguably it is the most important job of a language designer. Closely related to the term ergonomics , human engineering is the act of ensuring that a design is fit for use by humans. In the context of a programming language, that means the language should help prevent errors during the construction of a program, and be designed so as to faithfully communicate the intended meaning of the program from the programmer both to the readers, and to the automated tools that might analyze the program or convert it into a machine executable form. One well known technique for preventing errors is to require (or at least allow) some degree of checked redundancy . That is, you can say some things that could potentially be inferred from earlier (or later) parts of a communication, because the redundancy enables an automated check that the intent of the communication was correctly captured in the gi