Letters to a Computer
Programming is writing a letter to a computer. Our letters to humans introduce new babies, report life updates, and share recipes, just as our letters to computers introduce new variables, modify data, and describe functions. We write to our human correspondents asking them to perform tasks for us: water the plants, send us a copy of that photo. Likewise, we ask our computer correspondents to perform tasks: sort this list of numbers, find the fastest route.
We call our letters to computers programs. Programs tend to be direct and commanding, containing none of the pleasantries we expect in communication between humans. Nevertheless, upon receiving a letter, the computer dutifully gets to work on our behalf and performs the computation we request.
Writing letters and writing programs are both iterative processes. We don't sit down knowing exactly what to say, but each draft helps us form our thoughts and gets us closer to communicating them clearly.
We write and program in order to move thoughts from one being to another. When beings are biologically separate from one another, they need a bridge to span the gulf between them. Language is that bridge. It is an association between internal thoughts and external symbols. When I want you to think a certain thought, I encode it using the associated symbols. I hope that you receive the symbols intact and that you decode them using the same associations that I used to encode them.
The gulf between humans is spanned by human languages like English, Spanish, and Japanese. There's also a gulf between the programmer and the computer. In order for a programmer and computer to work together, they need a shared agreement that associates symbols and actions that the computer is to take. These agreements are programming languages like Ruby, Haskell, and Rust.
What then makes a language a programming language? Perhaps the difference is that the intended audience of a program is a computer. Abelson and Sussman claim that programming is very much a human activity in Structure and Interpretation of Computer Programs:
Programs must be written for people to read, and only incidentally for machines to execute.
An alternative definition of programming language might be a language through which programmers describe an algorithm. But this too may be overly narrow. When you write a database query, you aren't describing an algorithm. Are you programming? Is the query language a programming language? When you mark up a document with HTML tags, are you programming?
Maybe you can think of a better definition.
At this point in your study of computer science, you probably know a few programming languages. In this course, you will learn a few more. But our objective is deeper. This course is about the wide variety of ideas that humans have had about how to program computers over the past several decades. Our goal is to help you see the expansive design space of programming languages. We will look at this design space primarily through the lenses of Ruby, Haskell, and Rust. But we will also encounter C, C++, Java, JavaScript, Kotlin, and a few other languages with interesting features.
In this chapter, we postpone our discussion of any particular programming language and instead examine programming languages as a subdiscipline of computer science. By the end of this chapter, you'll have first-draft answers to these questions:
- Why is there a programming languages course in most university computer science programs?
- Why are there so many programming languages?
- How does a program written in a high-level language get executed by a CPU that only responds to a small set of low-level instructions?
- What notation and tools do language designers use to invent new languages?
This book is just another letter between humans. May it transfer thoughts about programming languages across the gulf between author and reader.