The road to CoffeeScript - Foundations - CoffeeScript in Action (2014)

CoffeeScript in Action (2014)

Part 1. Foundations

Although there are many theories about exactly how the process works, learning a new language is known to involve comprehensible input, comprehensible output, and reflection for you, the learner. This part of the book provides many opportunities for all three, and you’ll get the most benefit if you take advantage of all those opportunities not only by reading the content and the code but also by running and experimenting with the examples, doing the exercises, and taking some time to consider the deeper implications of the underlying concepts.

Because this part covers CoffeeScript language fundamentals, your current experience level with CoffeeScript (and to an extent JavaScript) will affect how quickly you take it in.

Chapter 1. The road to CoffeeScript

This chapter covers

· Why CoffeeScript matters

· How to get started

· The evolution of JavaScript

· Adapting to evolution by using CoffeeScript

CoffeeScript is a small, general-purpose programming language. It was created by Jeremy Ashkenas and first released in 2009. It’s a compiled language: you write your program in CoffeeScript and then use the compiler to translate it to an equivalent JavaScript program. When you run your program, it’s the compiled JavaScript that runs. Think of your CoffeeScript programs as being JavaScript programs underneath.

There are many programming languages that can compile to JavaScript, so many that they might even outnumber the programming languages that don’t compile to JavaScript. CoffeeScript is rare among these languages because it keeps the core structure and semantics of JavaScript intact. CoffeeScript is essentially JavaScript. If it’s essentially JavaScript though, why bother to use CoffeeScript? What’s the benefit?

1.1. Why CoffeeScript?

CoffeeScript is a simple language, and there are two simple reasons for learning it. First, it fixes some problems in JavaScript that are unpleasant to work with. Second, understanding CoffeeScript will help you learn new ways of using JavaScript, and new ways of programming in general.

JavaScript is an elegant programming language with some unfortunate gnarled edges. It has problems that other popular programming languages don’t have. Layers of these problems obscure the simple elegance of JavaScript and any programs you write with it. The goal of CoffeeScript is to peel back those layers. Think of your JavaScript programs as being CoffeeScript programs underneath.

Why CoffeeScript? One reason is that it can help you to make smaller and easier-to-understand programs that are easier to maintain. You say you don’t have a problem with programs being large, difficult to understand, and difficult to maintain? Meet Agtron and Scruffy (figure 1.1).

Figure 1.1. Meet Agtron and Scruffy.

Agtron and Scruffy have recently started working on a massive JavaScript program. This program contains more lines of JavaScript than Scruffy cares to count (though Agtron informs Scruffy that when he last looked it was 532,565). Agtron and Scruffy both consider the application they inherited to be disgusting. Scruffy thinks it’s disgusting because he can’t figure out what’s going on. Agtron thinks it’s disgusting because he can figure out what’s going on. Why is the program disgusting? Because it’s too big and the different components are too complicated and intertwined. The program is incomprehensible. Understanding how any of it works requires understanding of how all of it works.

How might CoffeeScript help? By simplifying JavaScript syntax and making each line easier to comprehend. That simplicity of expression will encourage you to compose programs that are, in turn, simpler and easier to comprehend. Your programs will become less complicated and not so intertwined. Simplifying small things, like syntax, can lead to simpler big things, like programs. Although it’s not a panacea (it’s possible to write incomprehensible garbage in CoffeeScript), learning CoffeeScript will help you to write better programs. It’s time to get started, time to write some CoffeeScript.

1.2. Running CoffeeScript

One thing you need to get out of the way is to make sure you’re ready to start experimenting with CoffeeScript. Assuming you already have CoffeeScript installed (if not, refer to the “About this book” section before this chapter), open a console or terminal, type the word coffee, and press Enter. You see a prompt:

coffee>

You’re now in the CoffeeScript REPL (pronounced like ripple but with an e instead of an i). Now enter some CoffeeScript and press Enter again:

coffee> 'CoffeeScript!'

'CoffeeScript!'

That’s it, you’ve written CoffeeScript. To exit the REPL, press Ctrl-D (that’s the Ctrl and D keys pressed simultaneously), and you’ll be back to your regular command line. Why is it called a REPL? It stands for Read-Eval-Print Loop, and that’s exactly what it does:

coffee> 'CoffeeScript!' # Read 'CoffeeScript!'

# Evaluate 'CoffeeScript!'

'CoffeeScript!' # Print the evaluation of 'CoffeeScript!'

coffee> # Loop (to start again)

By default, the CoffeeScript REPL will read only one line at a time before evaluating. In some cases you might want to evaluate two lines at a time. To do this, press Ctrl-V, and you’ll see the prompt change. Now, regardless of how many times you press Enter, the REPL will continue to read until you press Ctrl-V again, at which point it will evaluate, print, and resume the loop:

coffee> CTRL-V

------> 'CoffeeScript!' # Read

.......

.......

....... CTRL-V # Eval

'CoffeeScript!' # Print

coffee> # Loop

Now that you’re familiar with the REPL, any time you are working with a single-line snippet of CoffeeScript, you can enter it into the REPL and see it evaluated:

'CoffeeScript!'

# 'CoffeeScript!'

When you see a snippet of CoffeeScript that requires the multiline mode, press Ctrl-V first and then type or paste it in, and finally press Ctrl-V again to see it evaluated.

Although the REPL is fun, and it will often be your companion as you learn CoffeeScript, you didn’t come here for a lesson on how to use your keyboard. No, you came to learn about CoffeeScript, how to use it, and what it means. To begin, you want to know where you are and how you got here. How did you get here? The answer starts with a small historical detour, beginning with JavaScript.

1.3. JavaScript

To understand CoffeeScript and how it relates to JavaScript, you first need to know about some other languages that influenced JavaScript. Programming language influences can come in many forms, but the ones of significance in your understanding of CoffeeScript and JavaScript are the ones that led to the style, semantics, and syntax. The first influence for JavaScript in these three areas (and your starting place) is the C programming language and a humble little character called the curly brace.

1.3.1. C

The C programming language is one of the most widely used, and enduring, general-purpose programming languages of all time. JavaScript deliberately looks like the C programming language with many syntactical similarities. One of the most obvious similarities is the use of curly braces,{ and }, to indicate the beginning and end of each block of code. JavaScript is not alone in sharing this syntax with C—many mainstream programming languages look like C. Why should it matter that JavaScript borrows syntax from C? It matters because the story of a programming language (like the story of any language) is, in many regards, a social one. Here’s one account of that story.

Anybody who studied computer science when grunge music was popular knew that all the cool kids were using C with curly braces and that C programming was real programming, involving things like managing memory and manipulating strings as arrays of char pointers. The C programming language was the most grown-up thing to write besides assembly language, and the computer science departments in universities around the world were full of youth. Finally, and perhaps most importantly, most computer games at the time were written in C, and all those young people wanted to write computer games.

The schools of computer science were motivated to produce graduates who could get jobs, so the three most popular languages at the time were often taught. All three of these languages—C, C++, and Java—have curly braces. There were many less-popular languages with different styles, syntax, semantics, and ideas, but things found in unpopular places are easily ignored—regardless of whether they’re good or bad. That’s why JavaScript looks like the C programming language.

Despite being dressed in a curly-brace suit and semicolon top hat to look like C, JavaScript took two core ideas from other languages called Scheme and Self. As it happens, neither Scheme nor Self was quite so popular or looked very much like C, C++, or Java. So, although JavaScript looks very much like C, some of the core ideas are very much unlike C. To understand the friction this causes, you need to look closer at these two languages, Scheme and Self.

1.3.2. Scheme

Scheme is a general-purpose programming language created by Guy Steele and Gerald Sussman. It’s considered a dialect of the programming language Lisp, which the late John McCarthy created when he was a young man. Lisp dialects don’t look like the C programming language at all.

Over time, the popularity of Lisp dialects waned while the popularity of the C programming language grew. Finally, when Brendan Eich created the C-resembling JavaScript language to be used in the web browser of a company called Netscape, all of McCarthy’s hair was gray. Lisp dialects might have been moderately popular choices for programming languages when men in rock bands had perms, but they were no longer popular by the time Eich created JavaScript. Because they weren’t popular, there was no way that JavaScript was going to look like one of them. But Lisp contained some powerful programming ideas that JavaScript needed, so, syntax aside, there was nothing preventing it from being inspired by Lisp.

The ideas that JavaScript takes from Scheme have foundations in a mathematical system called lambda calculus. In terms of modern computer programming, some of these ideas fall under the term functional programming, which is the style of programming encouraged by Scheme. Functional programming very loosely means programming with functions (which you’ll start to learn about in chapter 3). How about C? The style of programming encouraged by C is called imperative programming. JavaScript has the syntax of C, but it was inspired, in a small but important way, by the functional style of Scheme.

While the popularity of Lisp and the functional programming style was declining, another programming style called object-oriented programming was starting to gain popularity. An object-oriented language called Self was the basis of a core idea in JavaScript called prototypes.

1.3.3. Self

The Self programming language was created as a research project by David Ungar and Randall Smith based on a programming concept known as prototypes. Being based on prototypes, Self was very different from the popular object-oriented languages of the time (such as C++ and Java) that were based on classes. You’ll learn more about classes and prototypes in later chapters, but for now, think of classes as being a more rigid and static approach, and prototypes as a more fluid and dynamic approach.

Self also had a different style than the other popular object-oriented languages of the time by preferring a small but powerful set of operations to more numerous and elaborate ones. This style was a direct inspiration in the creation of JavaScript, which took not only the idea of prototypes from Self but also this idea of having a small set of powerful primitive tools as a primary design goal. So, although JavaScript looks more like Java or C++ than it does Self, it has some core ideas taken directly from Self. It looks one way but acts another.

Although JavaScript looks like C (the syntax and to some extent the style and semantics), some of the key ideas (and to some extent the style and semantics) are borrowed from Self and Scheme. What happens when a language has many competing factors?

1.4. Evolving JavaScript

The inherent friction between the competing ideas behind JavaScript’s creation is compounded by it now being the most widely used programming language in the world. The social aspect of JavaScript as a programming language has more influencing factors than most other programming languages, and the widespread use of JavaScript serves to amplify all of the influences. This is important in understanding the future of JavaScript because the people who use any language (JavaScript or otherwise) are those who shape it over time. To illustrate, consider a brief account of a particular spoken language.

1.4.1. A little story about language

Sometime around the fifth century, a West Germanic tribe invaded Britain and brought with them their language. As a result, the existing languages of the region (Celtic and Cornish) were mostly replaced with the West Germanic dialect of the invaders, leaving only a hint of Celtic and Cornish in modern English today. A few hundred years later some Vikings, who spoke a Scandinavian language, colonized parts of Northern Britain. They needed to speak the local language (now a West Germanic dialect) in order to trade with nearby people, but they didn’t know it very well, so they spoke a simplified, broken version of it. The broken way they spoke the language changed the way everybody else spoke it, the language evolved as a result.

Later, in the eleventh century, the Norman French conquered England, and William the Conqueror became the king of England. During the Norman occupancy the official language of the region was Norman French, but English was still spoken by the commoners on the streets and on their farms. This is why English farm animals such as cows and pigs have one name, but the meats used in the restaurants by people speaking Norman French have other names such as beef and pork. The entire history of English is like this. When the printing press was invented, it had only the Latin alphabet, so English was changed again, one of the changes being to replace the thorn, þ, with the digraph th.

Now, you might think that a community doesn’t shape a constructed programming language like JavaScript in the same way it shapes a spoken language like English, but a language that isn’t shaped by a community is a dead language. A language can initially be constructed, but eventually it either evolves and changes as part of a community or it perishes. Just consider any one of the thousands of constructed spoken languages created in the history of mankind. Even Esperanto, perhaps the best-known constructed language, has today fewer than 1,000 native speakers.

1.4.2. The lesson for JavaScript

As the unavoidable language of the web, as the language used to create experiences in the web browser from its very inception, JavaScript is a melting pot of different language ideas. It’s not a language used exclusively by JavaScript programmers; it’s a language frequently used by people who typically program in another language. JavaScript is a language used by people who don’t necessarily understand (or want to understand) every subtle nuance. Because of all these different people who use JavaScript, it has necessarily changed substantially over time. At least, the way it is used, the techniques, and the types of things written in JavaScript have changed substantially. Not the syntax, though; that hasn’t changed much at all.

JavaScript was created in about the time it takes to get over a cold. The short time frame in which JavaScript was created (and subsequently standardized) led to some problems being set into the language—problems that are still in the process of being fixed many years later. So, take a language that was created in a matter of days, add in some competing ideas, give it to a whole lot of people who don’t know it very well, and what happens? You can fill in the rest of that story yourself.

How does CoffeeScript fit into this picture? CoffeeScript changes JavaScript’s syntax. CoffeeScript simplifies JavaScript so that it expresses those key ideas borrowed from Self and Scheme, as understood by users of the language today. In doing so, it also fixes some of the problems caused by JavaScript’s quick birth. Sure, as with all things, these changes come with their own unique set of trade-offs. To see if those trade-offs are right for you, it’s time to see what CoffeeScript does to JavaScript syntax and how it arrived at the changes that it did. Doing this starts with a simple thought experiment. What syntax can be taken away from a JavaScript program while still leaving the meaning intact?

1.5. Creating CoffeeScript

CoffeeScript starts with an experiment to remove as much nonessential syntax from JavaScript as possible. By working through that experiment, you can begin to understand CoffeeScript syntax and see how it differs from JavaScript. Relax if your JavaScript is still rusty at this point; just follow along and look at the syntax.

1.5.1. Designing new syntax

To arrive at CoffeeScript syntax, start with a small JavaScript program and see what can be removed without changing the meaning of the program. An uninteresting program serves this purpose well, so consider a function to square two numbers:

var square = function (x) {

return x * x;

};

How much of the syntax is necessary? For a start, you can remove the semicolons:

var square = function (x) {

return x * x

}

You can also remove the C-inspired curly braces:

var square = function (x)

return x * x

You can also remove the var statement by making it implicit instead of explicit:

square = function (x)

return x * x

The same applies to the return statement. Remove that also:

square = function (x)

x * x

Finally, the function keyword is important and used frequently, but suppose you replace it with something that doesn’t take so long to read or type:

square = (x) ->

x * x

Now you have CoffeeScript. Think of it as JavaScript after a little bit of spring cleaning (see figure 1.2). Most Ruby or Python developers will immediately find this new syntax comfortable and familiar, whereas most C, C++, or Java programmers will immediately find it alien. But the familiarity of the syntax isn’t important. What is important is how the new syntax fits how people think about the programs written using it. Why? Because a more natural syntax can not only make your life as a programmer easier; it can also help you start to think differently about your programs by letting you concentrate on other things—like the problems you’re trying to solve with the language. In that way, learning CoffeeScript can help you learn new ways of programming.

Figure 1.2. Agtron and Scruffy doing some spring cleaning of the JavaScript syntax

1.5.2. Achieving new syntax

Deciding on the syntax that you want is a good start. What you need now is some way for the new CoffeeScript syntax to actually work. In order for your CoffeeScript program to execute as a JavaScript program, you need something that can take CoffeeScript,

square = (x) ->

x * x

and turn it into the equivalent executable JavaScript:

var square = function (x) {

return x * x;

};

That’s exactly what a compiler is for, and it’s exactly what the CoffeeScript compiler does. On the command line again, if you have a file called square.coffee containing the CoffeeScript, then you convert it to a JavaScript file like so:

> coffee –c square.coffee

Once that’s done, you’ll have a new file called square.js containing your newly compiled JavaScript program. That leaves just one question: If the CoffeeScript program must be compiled first, then how does the REPL work? Well, it’s read-eval-print, right? The CoffeeScript is simply compiled before evaluation:

square = (x) -> x * x # Read

# Compile to JavaScript

# Evaluate the resulting JavaScript

# [Function] # Print

# Loop

square 2 # Read

# Compile to JavaScript

# Evaluate the resulting JavaScript

# 4 # Print

# Loop

Without needing to fully understand the CoffeeScript shown here, you see that it can be converted to JavaScript on the fly as you enter it into the REPL. Whether entered into the REPL or written to a file to be compiled later, all of your CoffeeScript is converted to JavaScript before it runs. The CoffeeScript compiler gives you the CoffeeScript syntax that makes it easy for you to express your program the way you want.

1.6. Summary

CoffeeScript is the JavaScript you’re already using—just with a new syntax. Remember those Vikings? They changed English forever because they didn’t know or care how to handle the nuances of the language. The same goes for JavaScript, the most widely used programming language in the world. It won’t remain unchanged in the face of all the different people who are starting to use it, and recent revisions to the language specification that take inspiration from the community (and CoffeeScript in at least one case) are clear evidence of that. Whether you plan to stick with JavaScript syntax at all costs or you’re looking to move away from it, you’ll be better off for your new understanding of CoffeeScript. Read on in the next chapter when you’re ready to take a deeper look at the syntax.