book cover
Programming Language Explorations
Ray Toal, Loyola Marymount University
Rachel Rivera, Netflix
Alex Schneider, Twitter
Eileen Choe, Google
© 2017 CRC Press

This text covers various programming language concepts, including binding, scope, typing, parameterization, modularity, concurrency, and meta­programming—not with a list of explanations of each topic, but rather within the context of whole-language overviews containing plenty of runnable example programs. We aim to help developers learn a bit of theory, and introduce students to a number of modern languages. All of the source code for the book’s examples, as well as number of bonus scripts, reside in this GitHub repository.

Contents
Chapter 0 Introduction
A little on why the study of languages is fun and some hints about what’s coming up in the rest of the book.
Chapter 1 JavaScript
A tour of one of the world’s most popular languages, introducing assignment, references, shallow and deep copies, null and undefined, weak typing, assertions, anonymous and higher-order functions, stack frames, closures, static vs. dynamic scope, shallow vs. deep binding, methods, prototypes, and asynchronous programming with both callbacks and promises.
Chapter 2 CoffeeScript
A tour of a language that compiles to JavaScript, or as is sometimes said, is JavaScript—though with an alternate syntax (you’ll notice a lot less clutter). We take a first look at destructuring and existential operators, and explore a very interesting design decision that avoids shadowing almost everywhere.
Chapter 3 Lua
A tour of the well-loved lightweight scripting language behind World of Warcraft and Angry Birds (among others), introducing some new types, an approach to errors that avoids exceptions, and a unification of arrays and dictionaries known as the table. We also see metatables, which provide both differential inheritance and operator overloading, and see coroutines for the first time.
Chapter 4 Python
Our first language with a complex type system: types are first-class objects within the language and the programmer can define new types. This chapter introduces supertype-subtype relationships, multiple inheritance, keyword arguments, pass-by-sharing, special methods, iterators and generators, and decorators.
Chapter 5 Ruby
Object-orientation and much more within an overview of the language billed as “A programmer’s best friend.” We define messaging, encapsulation, class-based inheritance, and polymorphism, and look at access controls and singleton classes. Ruby’s blocks and mixins bring up some new issues, as does the language’s extensive metaprogramming capabilities.
Chapter 6 Julia
A tour of the new dynamic language for scientific computing where we encounter abstract types, parametric types, sum and product types, and the notions of covariance, contravariance, and invariance. We see polymorphism with multiple dispatch (which differs from the single-receiver forms of previous languages), a metaprogramming facility with hygienic macros, and language support for parallel and distributed computing.
Chapter 7 Java
An exploration of our first statically-typed language with coverage of classes, modifiers, interfaces, generics, optionals (and their relationship to the billion dollar mistake), reflection, and quite a bit about threads and synchronization.
Chapter 8 Clojure
A tour of the mostly-functional, modern dialect of Lisp, that inter­operates with Java. We look at its interesting syntax, its rich set of data types, and its implementation of namespaces; then introduce persistent data structures, transients, software transactional memory, and agents. We look at two approaches to the expression problem (protocols and multimethods) and discuss how Clojure’s hygienic macros compare to Julia’s.
Chapter 9 Elm
An overview of the member of the ML-family of languages that makes it fun to write reactive web clients in a functional style. Our tour introduces the beautiful aspects of the ML-family—Hindley-Milner typing with type variables and extensive type inference, pattern-matching, and tagged union types—as well as Elm’s contributions, including record types and subscriptions. This chapter (together with the overviews of Haskell and Idris in Chapter 14) discusses the general problem of managing side-effects in pure functional programming.
Chapter 10 Erlang
The language known for scalability and incredible seven-nines availability that powers the messaging infrastructure behind Whisper and WhatsApp. As Erlang is a functional language like Clojure and Elm (though with a rather unique syntax), this chapter continues our discussion on loop-free, matching-oriented programming with immutable data. We focus on what makes Erlang Erlang: its messaging system based on processes without shared memory, and its achievement of high availability through a philosophy known as “Let it Crash.”
Chapter 11 Go
Another language emphasizing distributed programming via message passing, but unlike Erlang, places the focus on channels rather than on named processes. Our tour introduces a few other concepts, such as multiple-value function returns, defer statements, explicit pointers, slices, and panics. We examine Go’s level of type inference, which falls somewhere in between Java’s and Elm’s.
Chapter 12 Swift
A look at the elegantly-designed, safe, fun, and powerful modern language most often used for writing native applications in macOS, iOS, tvOS, and watchOS. Here we see character processing done right, common collections implemented as library types rather than hardwired into the language (though with syntactic sugar to trick you), more on optionals, custom operator definitions, extensions, and protocols. We also spend time on the details of automatic reference counting (ARC).
Chapter 13 Additional Languages
Brief looks at Fortran, COBOL, Lisp, Algol, Simula, Smalltalk, C, C++, Rust, CLU, Ada, C#, Scala, Bash, Perl, Standard ML, OCaml, Haskell, F#, Idris, ParaSail, Chapel, Elixir, PHP, Hack, TypeScript, Dart, APL, Prolog, K, Io, Factor, Brainfuck, Befunge, LOLCODE, and nasm (an assembly language for the x86 architecture). This chapter is by no means an afterthought or an aside; the sections on Rust and C, in particular, discuss how one deals with explicit pointers without a garbage collector, while other sections introduce new programming paradigms not covered in the twelve featured language chapters.
Chapter 14 Afterword
A review of language concepts in a Socratic fashion.
Appendix A Numbers
Encodings of fixed-size integers and IEEE-754 floating point numbers.
Appendix B Text
All you need to know about Unicode (including what extended grapheme clusters are, and how exactly UTF-8 works), and a little bit more.
Good to Know

Some prerequisites: This book is not for beginning programmers. We assume you know at least two languages pretty well, and hopefully a couple more. You should know the basic concepts surrounding variables, expressions, operators, functions, and basic data structures, and have experience writing nontrivial applications—this book is a tour, not a tutorial. We cover many interesting (and often powerful) features, and purposely do so with code that is often very dense and sometimes cryptic, even when presenting unfamiliar paradigms for the first time. If you like to learn by reading example code, and performing your own experiments, you should find the approach to your liking.

Most of the code examples are written as their own unit tests, which should help you learn the concepts as you read the code itself. We favor this style over excessive commenting. Uncle Bob tells us why comments are not “pure good.”

Please note the book is not a treatise based on formal syntax and semantics. For deeper theory, see, for example, Harper, Pierce, or Turbak and Gifford. Looking for more on history? Start with Wikipedia’s articles on programming language history and follow links. Make sure to go way back and read some early papers; the classics by Knuth and Kay are must reads for anyone that appreciates and values where the field has come from. Finally, for an approach to language practice and theory organized around programming style and paradigms, don't miss Lopes.

Additional Resources

We’ve put all of our examples, and unit tests galore, on GitHub, of course. The repo contains pointers to additional resources (books, papers, applications, frameworks, etc.) for each of the programming languages covered in their respective README.md files. See something wrong or want to add anything? Send us a pull request.

There are, however, many resources not tied to any particular language that you may enjoy. Here are just a few:

In addition, you might want to visit a few languages not covered in the book. Here are some of our favorites:

NileScratchSnap!GPIokeJSelfRacketDCrystalCeylonKotlinBooZimbuFantomOpaValaGMLPureScriptNimNemerleKittenMercuryBlackCiaoRoyUrQuipperPureQuorumFalconQ#TypeScriptZig

Just for fun, we’ve gotten started on a little “browser” of language highlights for each of the languages from the book and many others as well.

Updates

The languages covered in the book are evolving! Sometimes this means the text in the book goes out of date. We’ll do our best to keep with breaking changes and provide text changes and replacement pages here. Here’s what we know so far:

Changes to Ruby

Ruby 2.4 arrived after the book was first printed, and came with one welcome language change: the old Fixnum and Bignum classes are now unified into a single Integer class. Fortunately the only page in the book dependent on this difference was page 80. Please download the updated page.

Changes to Swift

The first printing took place when Swift 3 was in beta. The release version of Swift 3 included significant language changes, requiring several scripts and a couple pages to be rewritten.

Changes to the xregexp library used in JavaScript and CoffeeScript

Recent versions of the xregexp library now export the XRegExp function as the module default, therefore:

Changes to Elm

The first printing of the book took place when Elm was at version 0.17. Recent language changes have been quite significant; for example, backticks to make functions infix are gone, apostrophes are no longer allowed in identifiers, the argument order for andThen has changed, and range expressions such as [1..10] have been removed from the language. More significantly, the elm-test package has completely changed. We have decided to remove elm-test assertions (and the dependency on this package) from our sample code and replace them with our own trivial assertions module.Because of these changes, the entire chapter has had to be rewritten. Download replacement pages for the book.

Changes to Julia

The first printing of the book took place when Julia was at version 0.4.0. Recent language changes have been quite significant.

Errata

Here are the outright mistakes in the printed text we know about that are not due to language evolution. Please let us know if you find anything. Email one of the authors or submit a pull request for this file.

Additional Exercises

The text features 300 exercises, most of which are “further explorations” in which you find or install compilers or interpreters, investigate aspects of a language not covered in the chapter proper, muse about language designers’ intents, and try your hand at both large and small programming tasks. For those wishing more practice or are looking to explore many programming language topics not covered in the text, we’ve provided a page with a few more.

If you are interested in some short language-specific questions useful for training your short-term memory and reinforcing your fluency with the material, we have hundreds of these as well.