You are on page 1of 73

CoffeeScript Ristretto
An intense cup of code
raganwald
This book is for sale at http://leanpub.com/coffeescript-ristretto
This version was published on 2014-10-29

This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing
process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and
many iterations to get reader feedback, pivot until you have the right book and build traction once
you do.
©2012 - 2014 raganwald

Tweet This Book!
Please help raganwald by spreading the word about this book on Twitter!
The suggested hashtag for this book is #coffeescriptristretto.
Find out what other people are saying about the book by clicking on this link to search for this
hashtag on Twitter:
https://twitter.com/search?q=#coffeescriptristretto

Quirky Birds.Also By raganwald Kestrels. and Hopeless Egocentricity JavaScript Allongé JavaScript Spessore .

Thomas Aston Braithwaite .This book is dedicated to my son.

. . . . . . . . . . . . . . . . and State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About The Author . . . . . . . . . . . . 2 3 9 11 15 20 24 30 An Extra Shot of Ideas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mutation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About This Book . . . . . . . . . . . . . . . . . . . . . . . . Comprehensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i ii iii iv CoffeeScript Ristretto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Summary . . . . . . . . . . . . . . . . . Encapsulating State with Closures . . . Foreword by Jeremy Ashkenas Legend . . . . . . . . . . . . JavaScript Allongé . . . . . . . . . . . . 51 52 54 55 58 59 62 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . This and That . . Refactoring to Combinators Method Decorators . . . . . . .Contents A Pull of the Lever: Prefaces . . . . . . . . . . . . . . . . . . Normal Variables . . Composition and Extension . . . . . . . . . . . . . . . . . . . . . . . . . Reassignment and Mutation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Callbacks and Promises . . . . . . . . . . . . Copyright Notice . . . . . . . . . . . . . 32 33 38 44 49 A Golden Crema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Thanks! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Stir the Espresso: Objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About These Sample Chapters How to run the examples . . . . . . . . . . . . . . . . . . . . .

”–David Schomer¹ ¹http://www.html . or restricted. The coffee is restricted to the most flavourful part of the shot.espressovivace.A Pull of the Lever: Prefaces Caffe Molinari “We always pour our coffee in the ristretto. This tradition offers the heaviest shot.com/archives/9507scr. thickest texture and finest flavour that the coffee has to offer. tradition.

A Pull of the Lever: Prefaces ii About This Book Learning about “for” loops is not learning to program. you understand what it does well. identity. any more than learning about pencils is learning to draw. dense read. As a result. closures. The syntax of a language defines its user interface. with values and expressions.com/LearnableProgramming/ ³http://coffeescript. scopes. CoffeeScript Ristretto is a rich.org . how this book is organized CoffeeScript Ristretto begins at the beginning. The semantics of a language defines its capabilities. and many more subjects up to working with classes and instances in Chapter Five. functions. without hand-waving or simplification. and builds from there to discuss types. If you understand a language’s syntax. much like the Espresso Ristretto beloved by coffee enthusiasts everywhere. each topic is covered thoroughly.” introduces advanced CoffeeScript idioms like method decorators. Chapter Six. If you understand a language’s semantics.–Bret Victor. Learnable Programming² Programming languages are characterized by their syntax and their semantics. because its flexible and powerful functions are what make the CoffeeScript³ programming language so capable. “An Extra Shot of Ideas. and what CoffeeScript does well. CoffeeScript Ristretto is first and foremost about a book about programming with functions. you understand what it makes easy. Since CoffeeScript Ristretto is a book about CoffeeScript’s semantics. ²http://worrydream.

And you’ll learn a great deal about the internals of CoffeeScript and the semantics of JavaScript along the way. brick by brick. callbacks.A Pull of the Lever: Prefaces Foreword by Jeremy Ashkenas “I particularly enjoyed this small book because I’ve reached for it a hundred times before and come up empty-handed. the method of mutation. and you put it back together yourself. prototypes.”—Jeremy Ashkenas. you’ll explore the nature of functions. If Reg had pulled it any thicker you’d have to chew it. Braithwaite as your guide. strong gulp. CoffeeScript’s creator iii . the essence of reference. but hopefully you’ve chosen it because you like your ristretto bold and strong. the construction of classes. but to find a book that tackles the fundamental features of functions and objects in a brief. is rare indeed. Every feature is broken apart into its basic pieces. “With the inimitable Mr. Large and heavy manuals on object-oriented programming and JavaScript are all around us. and more. “This book is dense. the nooks and crannies of lexical scope. promises.

. Some monospaced code in its own lines also represents code being discussed: 1 2 3 4 5 this. argv)) Sometimes it will contain some code for you to type in for yourself. It contains whimsey and other doupleplusunserious logorrhea that will not be on the test.apply(this.A Pull of the Lever: Prefaces iv Legend Some text in monospaced type like this in the text represents some code being discussed. A paragraph marked like this is an aside. . the result of typing something in will often be shown using #=>. A paragraph marked like this is a suggested exercise to be performed on your own.. It can be safely ignored. . When it does. like this: 1 2 2 + 2 #=> 4 A paragraph marked like this is a “key fact.async = do (async = undefined) -> async = (fn) -> (argv.. callback) -> callback(fn.” It summarizes an idea without adding anything new.

. properly dissected. properly roasted. CoffeeScript Ristretto begins with functions.CoffeeScript Ristretto The perfect Espresso Ristretto begins with the right beans.

It’s time to change everything. we have discussed what many call “pure functional” programming.wikipedia. because we have no way of changing state within a program using the tools we have examined. Mutation. where every expression is necessarily idempotent⁴. and State Life measured out by coffee spoons So far.org/wiki/Idempotence .Stir the Espresso: Objects. ⁴https://en.

'. Let’s take the time to fully explore what happens with reassigning values to variables. CoffeeScript allows you to re-assign the value of variables. The syntax is familiar to users of most popular languages: 1 2 3 4 do (age = 49) -> age = 50 age #=> 50 In CoffeeScript... .': global-environment}} Then back to: . So let’s consider what happens with a shadowed variable: 1 2 3 4 5 do (age = 49) -> do (age = 50) -> # yadda yadda age #=> 49 Binding 50 to age in the inner environment does not change age in the outer environment because the binding of age in the inner environment shadows the binding of age in the outer environment. '.. The key is to understand that we are rebinding a different value to the same name in the same environment.Stir the Espresso: Objects. and State 3 Reassignment and Mutation Like most imperative programming languages.': {age: 49. nearly everything is an expression. We took the time to carefully examine what happens with bindings in environments.': global-environment} To: 1 {age: 50. Mutation. We go from: 1 {age: 49. so we could just as easily write do (age = 49) -> age = 50. '. including statements that assign a value to a variable.

Their identities stay the same. mutation and aliases Now that we can reassign things. and State 1 4 {age: 49. Recall that you can access a value from within an array or an object using []. It then rebinds the name in that environment.. 2. but not their structure. You can reassign a value using [] as well: 1 2 3 4 do (oneTwoThree = [1. Specifically. reassigning it in a nested environment changes the original: 1 2 3 4 5 do (age = 49) -> do (height = 1. CoffeeScript searches for the binding in the current environment and then each ancestor in turn until it finds one. 2. '. if we don’t shadow age. when a binding is rebound. 2.85) -> age = 50 age #=> 50 Like evaluating variable labels. 3 ] You can even add a value: 1 2 3 4 do (oneTwoThree = [1. 2.': global-environment} However. 3. 3]) -> oneTwoThree[3] = 'four' oneTwoThree #=> [ 1. Mutation. 3]) -> oneTwoThree[0] = 'one' oneTwoThree #=> [ 'one'. there’s another important factor to consider: Some values can mutate. 'four' ] You can do the same thing with both syntaxes for accessing objects: .Stir the Espresso: Objects. arrays and objects can mutate.

. Consider what we already know about shadowing: 1 2 3 4 5 do (allHallowsEve = [2012. 10. For example: 1 2 do (allHallowsEve = [2012. 31]) -> do (allHallowsEve) -> # . the most important point about this is that the identities were the same. This is vital.Stir the Espresso: Objects.middleName = 'Austin' name #=> { firstName: 'Leonard'. 31]) -> do (allHallowsEve) -> allHallowsEve = [2013. )(allHallowsEve) There are two nested environments. what’s this? What does do (allHallowsEve) -> mean? Well. 10. lastName: 'Braithwaite'}) -> name. 10. CoffeeScript assumes you are deliberately trying to shadow a variable. # middleName: 'Austin' } We have established that CoffeeScript’s semantics allow for two different bindings to refer to the same value. when you put a name in the argument list for do -> but you don’t supply a value. Mutation.. and each one binds the name allHallowsEve to the exact same array value. 10. However. And also: 1 2 3 do (allHallowsEve = [2012. 10.. because they were the same value. 31] allHallowsEve #=> [ 2012. It acts as if you’d written: 1 2 3 ((allHallowsEve) -> # . 31 ] The outer value of allHallowsEve was not changed because all we did was rebind the name allHallowsEve within the inner environment. In each of these examples. Before we could reassign things.. 31]) -> halloween = allHallowsEve Both halloween and allHallowsEve are bound to the same array value within the local environment. # lastName: 'Braithwaite'. and State 1 2 3 4 5 6 5 do (name = {firstName: 'Leonard'. what happens if we mutate the value in the inner environment? . Hello. we have created two aliases for the same value.

like so: 1 2 3 do (identity = undefined. letrec One way to exploit reassignment is to “declare” your bindings with do and bind them to something temporarily. and State 1 2 3 4 5 6 do (allHallowsEve = [2012. . 31 ] This is different. grandMother = undefined) -> greatUncle = {firstName: 'Leonard'. The same thing is true whenever you have multiple aliases to the same value: 1 2 3 4 5 6 7 do (greatUncle = undefined. consider writing a recursive function⁵ like pow. and then rebind them inline. lastName: 'Barzey' } This example uses the letrec pattern for declaring bindings. Mutation. we’ll assume that p is an integer. Recall that let looks like this in CoffeeScript: 1 do (identity = ((x) -> x). lastName: 'Braithwaite'} grandMother = greatUncle grandMother['firstName'] = 'Lois' grandMother['lastName'] = 'Barzey' greatUncle #=> { firstName: 'Lois'. For simplicity. We haven’t rebound the inner name to a different variable. and returns n raised to the pth power. ⁵You may also find fixed point combinators interesting.Stir the Espresso: Objects. 10. let’s have a look at it. we’ve mutated the value that both bindings share. 31]) -> do (allHallowsEve) -> allHallowsEve[0] = 2013 allHallowsEve #=> [ 2013. Now that we’ve finished with mutation and aliases. n and p. kestrel = undefined) -> identity = (x) -> x kestrel = (x) -> (y) -> x This pattern is called letrec after the Lisp special form. kestrel = (x) -> (y) -> x) -> To see how letrec differs from let. 10. pow takes two arguments.

Math.floor(p/2)). p % 2)) -> half * half * remainder In order for pow to call itself. remainder = pow(n. pow must be bound in the environment in which pow is defined. -p) else if p is 0 1 else if p is 1 n else do (half = pow(n. such as: . if we wrote odd with letrec. recall that this is equivalent to writing: 1 2 3 ((odd) -> odd(5) )( (n) -> if n is 0 then false else not odd(n-1) ) The expression (n) -> if n is 0 then false else not odd(n-1) is evaluated in the parent environment. Whereas. recursively or otherwise. Here’s a misguided attempt to create a recursive function using let: 1 2 do (odd = (n) -> if n is 0 then false else not odd(n-1)) -> odd(5) To see why this doesn’t work. Mutation. p) -> if p < 0 1/pow(n. where odd hasn’t been bound yet. letrec also allows you to make expressions that depend upon each other. it would look like this: 1 2 3 do (odd = undefined) -> odd = (n) -> if n is 0 then false else not odd(n-1) odd(5) Which is equivalent to: 1 2 3 4 ((odd) -> odd = (n) -> if n is 0 then false else not odd(n-1) odd(5) )( undefined ) Now the odd function is bound in an environment that has a binding for the name odd.Stir the Espresso: Objects. This wouldn’t work if we tried to bind pow in the do itself. and State 1 2 3 4 5 6 7 8 9 10 11 7 do (pow = undefined) -> pow = (n.

Mutation. T = undefined. as well as the reassignment and assignment of new values to elements of containers such as arrays and objects. The letrec pattern allows us to bind interdependent and recursive expressions. and State 1 2 3 4 5 do (I I = K = T = F = = undefined. Mutating existing objects has special implications when two bindings are aliases of the same value. F = undefined) -> (x) -> x (x) -> (y) -> x K K(I) takeaway CoffeeScript permits the reassignment of new values to existing bindings. 8 . K = undefined.Stir the Espresso: Objects.

. A function created with the do syntax. an empty do -> is invisibly created to enclose the entire file. . Mutation. The first is that a misspelling creates a new binding rather than resulting in an error: . month: 6. and do. it’s time to discuss assignment.Stir the Espresso: Objects. The current function is any of the following: 1. 3. When compiling CoffeeScript in files. and State 9 Normal Variables Now that we’ve discussed reassignment. which is really syntactic sugar for the let pattern. Some feel this makes code more readable by putting variable definitions closer to their use. and => that we’ll see when we look at objects in more detail). There are two unfortunate consequences. In that case. not just at the top.. Up to now. It sounds odd to say we’ve reassigned things without assigning them. You can boldly write things like: 1 2 3 4 identity = (x) -> x kestrel = (x) -> (y) -> x truth = kestrel falsehood = kestrel(identity) You can also do your assignments wherever you like in a function. 2. day: 14 } The difference comes when there is no value bound to the name birthday in any of the user-defined environments. CoffeeScript creates one in the current function’s environment. we’ve bound values to names through arguments. In CoffeeScript. One good consequence of this feature is that you can dispense with all of the nested do (. the syntax for assignment is identical to the syntax for reassignment: 1 birthday = { year: 1962. A function created with an arrow operator (-> that we’ve seen.) -> expressions you’ve seen so far if you wish.

. you must be careful to scan the source of all of your function’s parents to ensure you haven’t accidentally reused the name of an existing binding.. meaning.⁶ CoffeeScript calls creating new bindings with assignment “normal . not 50 The second is that you may accidentally alias an existing variable if you are not careful. One very popular language assumes that if you haven’t otherwise declared a variable local to a function. CoffeeScript’s creator. that is because we are writing to be excruciatingly clear. Programming philosophy is a little outside of the scope of this book. use Normal variables as much as possible. Jeremy Ashkenas. If you see a lot of do in this book. It hasn’t done them any harm. not to construct software that is easy to read and maintain in a team setting. you must want a global variable that may clobber an existing global variable used by any piece of code in any file or module. If and when you find there’s a scoping problem. un-do So. should we use do to bind variables or should we use “normal” variables? This is a very interesting question. the good programmer does not attempt to design them into every piece of code from the outset. only uses do when it’s necessary. and constructions. and only then. Then. you can change a normal variable into a variable bound with do to solve the problem. Mutation. So here’s what we suggest: When writing new software. you can refactor to do. but it is generally sufficient to write with normal variables. idioms. . you can always show them how to use do to emulate let and letrec. the code is simple where it does not solve a difficult or edge case. agee = 50 # .. do is a good pattern to know and deeply understand. direct. does the good programmer refactor to a pattern. Just remember that if anyone criticizes CoffeeScript for being loose with scoping and aliases. Using do has a certain number of technical benefits. age #=> 49. However. If you’re in the habit of creating a lot of your variables with assignments rather than with do. and clear path until difficulties arise.” because it’s how most programmers normally create bindings. and uses a technique or idiom where there is a problem that needed solving. but there is a general principle worth knowing: A good programmer is familiar with many design patterns. In the end. and most CoffeeScript programmers follow his lead.. Then again. and State 1 2 3 4 5 6 10 do (age = 49) -> # . ⁶It could be worse. the good programmer proceeds along a simple. Instead. .Stir the Espresso: Objects.

But being a CoffeeScript programmer. you will no doubt embrace normal variables. Mutation. As you dive into CoffeeScript. you’ll discover many helpful features that aren’t “Lisp-y.” Eschewing them is to cut against CoffeeScript’s grain. a mechanism for working with collections that was popularized by Python. Here’s a sample comprehension: ⁷http://coffeescript. and State Comprehensions Cupping Grinds If you’re the type of person who can “Write Lisp in any language.11 Stir the Espresso: Objects. One of those features is the comprehension⁷.” you could set about writing entire CoffeeScript programs using let and letrec patterns such that you don’t have any normal variables.org/#loops .

# 'Hello rupert'. 'theodora'] "Hello #{yourName}" for yourName in names #=> [ 'Hello algernon'. # 'Hello theodora' ] Here’s a question: There’s a variable reference yourName in this code. Mutation. # 'Hello rupert'. It acts as if you’d written: . 'rupert'. However.Stir the Espresso: Objects. 'sabine'. Is it somehow bound to a new environment in the comprehension? Or is it a “normal variable” that is either bound in the current function’s environment or in a parent function’s environment? Let’s try it and see: 1 2 3 4 yourName = 'clyde' "Hello #{yourName}" for yourName in names yourName #=> 'theodora' It’s a normal variable. First. # 'Hello sabine'. you might want yourName to shadow the existing yourName binding. CoffeeScript assumes you are deliberately trying to shadow a variable. yourName would still be clyde as the comprehension’s binding would shadow the current environment’s binding. and State 1 2 3 4 5 6 7 12 names = ['algernon'. # 'Hello theodora' ] An alternate syntax for the same thing that supports multiple expressions is: 1 2 3 4 5 6 for yourName in names "Hello #{yourName}" #=> [ 'Hello algernon'. This is usually fine. # 'Hello sabine'. there are two times you don’t want that to happen. as creating a new environment for every comprehension could have performance implications. If it was somehow ‘local’ to the comprehension. You can use do to fix that: 1 2 3 4 5 yourName = 'clyde' do (yourName) -> "Hello #{yourName}" for yourName in names yourName #=> `clyde` Recall that when you put a name in the argument list for do -> but you don’t supply a value.

and State 1 2 3 4 5 6 13 yourName = 'clyde' ((yourName) -> "Hello #{yourName}" for yourName in names )(yourName) yourName #=> `clyde` So technically. but they share a parent environment. my name is rupert”. which means they share the exact same binding for myName. Each of the functions we generate has a closure that consists of a function and a local environment. yourName is bound in its local environment. # 'Hello reader. the inner yourName will be bound to the same value as the outer yourName initially. We can fix it using the “shadow” syntax for do: . that value will be overwritten in the inner environment but not the outer environment. my name is theodora'. myName was bound to one of the four names. but at the time the closures are evaluated. Mutation. we’ll quickly discover the problem. each of which can generate a sentence like “Hello reader. preventing a subtle comprehensions bug Consider this variation of the above comprehension: 1 2 for myName in names (yourName) -> "Hello #{yourName}. # 'Hello reader. my name is #{myName}" #=> [ 'Hello reader. my name is theodora'. but myName is bound in the comprehension’s environment. my name is theodora'.Stir the Espresso: Objects. my name is #{myName}" Now what we want is four functions. my name is theodora' ] WTF!? If we consider our model for binding. but as the comprehension is evaluated. # 'Hello reader. myName is bound to the last of the four names. At the time each closure was created. We can test that with a comprehension: 1 2 3 4 5 6 fn('reader') for fn in for myName in names (yourName) -> "Hello #{yourName}. Each of the four closures has its own local environment.

the comprehension’s changes to myName don’t change each closure’s binding. Thus. my name is #{myName}" #=> [ 'Hello reader. takeaway Comprehensions⁸ are extraordinarily useful for working with collections. shadowing the comprehension’s binding of myName. # 'Hello reader. Mutation. but their loop variables are normal variables and may require special care to obtain the desired results. each time we create a function we’re first creating its own environment and binding myName there.Stir the Espresso: Objects. and State 1 2 3 4 5 6 7 14 fn('reader') for fn in for myName in names do (myName) -> (yourName) -> "Hello #{yourName}. # 'Hello reader. ⁸http://coffeescript. my name is algernon'. my name is sabine'. Also worth noting: Comprehensions may be the only place where let or do is necessary in CoffeeScript. my name is rupert'. Every other case can probably be handled with appropriate use of normal variables. # 'Hello reader.org/#loops . my name is theodora' ] Now.

information hiding is the ability to prevent certain aspects of a class or software component from being accessible to its clients. but in CoffeeScript. You might need an index.wikipedia. You could grow and shrink the array.”–Wikipedia ¹¹https://en. so she reads the index directly. Now her code is coupled to the existence of an index. using either programming language features (like private variables) or an explicit exporting policy.–Alan Kay⁹ We’re going to look at encapsulation using CoffeeScript’s functions and objects. information hiding is the principle of segregation of the design decisions in a computer program that are most likely to change. We’re not going to call it object-oriented programming.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en ¹⁰“A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.fu-berlin. and State 15 Encapsulating State with Closures OOP to me means only messaging. These three operations are the stable interface. we will break her code. the array is highly efficient. sooner or later some programmer is going to find an advantage in using the index directly. and extreme late-binding of all things.wikipedia. Mutation. what is hiding of state-process. she may need to know the size of a stack. local retention and protection and hiding of stateprocess. This is just plain encapsulation¹⁰. Many stacks have an array for holding the contents of the stack. you might not.Stir the Espresso: Objects. mind you. and why does it matter? In computer science. or you could allocate a fixed size and use an index to keep track of how much of the array is in use. But she’s in a hurry. The design choices for keeping track of the head of the list are often driven by performance considerations. –Wikipedia¹¹ Consider a stack¹² data structure. thus protecting other parts of the program from extensive modification if the design decision is changed. The ideal choice would be to add a size function that continues to hide the implementation. This is relatively stable. with a dash of information-hiding. If you expose the implementation detail such as whether there is an index. popping a value off the top (pop). You could substitute a linked list. so if we wish to change the implementation to grow and shrink the array. For example. because that would start a long debate. and testing to see whether the stack is empty or not (isEmpty). ⁹http://userpage. The protection involves providing a stable interface which protects the remainder of the program from the implementation (the details that are most likely to change). There are three basic operations: Pushing a value onto the top (push). Written another way.org/wiki/Information_hiding ¹²https://en.org/wiki/Stack_ .

Stir the Espresso: Objects, Mutation, and State

16

The way to avoid this is to hide the array and index from other code and only expose the operations
we have deemed stable. If and when someone needs to know the size of the stack, we’ll add a size
function and expose it as well.
Hiding information (or “state”) is the design principle that allows us to limit the coupling between
components of software.

how do we hide state using coffeescript?
We’ve been introduced to CoffeeScript’s objects, and it’s fairly easy to see that objects can be used
to model what other programming languages call (variously) records, structs, frames, or what-haveyou. And given that their elements are mutable, they can clearly model state.
Given an object that holds our state (an array and an index¹³), we can easily implement our three
operations as functions. Bundling the functions with the state does not require any special “magic”
features. CoffeeScript objects can have elements of any type, including functions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

stack = do (obj = undefined) ->
obj =
array: []
index: -1
push: (value) ->
obj.array[obj.index += 1] = value
pop: ->
do (value = obj.array[obj.index]) ->
obj.array[obj.index] = undefined
obj.index -= 1 if obj.index >= 0
value
isEmpty: ->
obj.index < 0
stack.isEmpty()
#=> true
stack.push('hello')
#=> 'hello'
stack.push('CoffeeScript')
#=> 'CoffeeScript'
stack.isEmpty()
#=> false
stack.pop()
#=> 'CoffeeScript'
stack.pop()
¹³Yes, there’s another way to track the size of the array, but we don’t need it to demonstrate encapsulation and hiding of state.

Stir the Espresso: Objects, Mutation, and State

26
27
28

17

#=> 'hello'
stack.isEmpty()
#=> true

method-ology
In this text, we lurch from talking about functions belong to an object to methods. Other languages
may separate methods from functions very strictly, but in CoffeeScript every method is a function
but not all functions are methods.
The view taken in this book is that a function is a method of an object if it belongs to that object and
interacts with that object in some way. So the functions implementing the operations on the queue
are all absolutely methods of the queue.
But these wouldn’t be methods. Although they belong to an object, they don’t interact with it:
1
2
3
4

{
min: (x, y) -> if x < y then x else y
max: (x, y) -> if x > y then x else y
}

hiding state
Our stack does bundle functions with data, but it doesn’t hide its state. “Foreign” code could interfere
with its array or index. So how do we hide these? We already have a closure, let’s use it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

stack = do (array = [], index = -1) ->
push: (value) ->
array[index += 1] = value
pop: ->
do (value = array[index]) ->
array[index] = undefined
index -= 1 if index >= 0
value
isEmpty: ->
index < 0
stack.isEmpty()
#=> true
stack.push('hello')
#=> 'hello'
stack.push('CoffeeScript')
#=> 'CoffeeScript'

Stir the Espresso: Objects, Mutation, and State

18
19
20
21
22
23
24
25

18

stack.isEmpty()
#=> false
stack.pop()
#=> 'CoffeeScript'
stack.pop()
#=> 'hello'
stack.isEmpty()
#=> true

Coffee DOES grow on trees

We don’t want to repeat this code every time we want a stack, so let’s make ourselves a “stack
maker:”
1
2
3
4
5
6
7
8
9
10
11
12
13

StackMaker = ->
do (array = [], index = -1) ->
push: (value) ->
array[index += 1] = value
pop: ->
do (value = array[index]) ->
array[index] = undefined
index -= 1 if index >= 0
value
isEmpty: ->
index < 0
stack = StackMaker()

Now we can make stacks freely, and we’ve hidden their internal data elements. We have methods
and encapsulation, and we’ve built them out of CoffeeScript’s fundamental functions and objects.

and other opportunities for debating the nature of the One True Object-Oriented Style on the Internet. mixins. the key lesson experienced programmers repeat (although it often falls on deaf ears) is. we haven’t included all sorts of complicated mechanisms to support inheritance. Mutation. http://www. Composition instead of Inheritance.Stir the Espresso: Objects. we’ll look at CoffeeScript’s support for class-oriented programming and some of the idioms that functions bring to the party. is encapsulation “object-oriented?” We’ve built something with hidden internal state and “methods. So maybe we aren’t missing much.c2. .” all without needing special def or private keywords. Mind you.com/cgi/wiki?CompositionInsteadOfInheritance . and State 19 In Instances and Classes. Then again.

Mutation.Stir the Espresso: Objects. redoStack = StackMaker().push(shallowCopy(attributes)) redoStack = StackMaker() unless redoStack. and State 20 Composition and Extension composition A deeply fundamental practice is to build components out of smaller components.push(shallowCopy(attributes)) ¹⁴And when you take an already factored component and rearrange things so that it is factored into a different set of subcomponents without altering its behaviour.isEmpty() redoStack. value = undefined) -> dest[key] = value for own key. undoStack = StackMaker(). and the components can be put together into a single object or encapsulated with a closure.isEmpty() undoStack.pop() obj redo: -> unless redoStack.isEmpty() attributes[key] = value for own key. Here’s an abstract “model” that supports undo and redo composed from a pair of stacks (see Encapsulating State) and a Plain Old CoffeeScript Object: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 # helper function shallowCopy = (source) -> do (dest = {}. value of source dest # our model maker ModelMaker = (initialAttributes = {}) -> do (attributes = shallowCopy(initialAttributes). value of attrsToSet obj undo: -> unless undoStack. you are refactoring. key = undefined.push(shallowCopy(attributes)) attributes = undoStack. obj = undefined) -> obj = { set: (attrsToSet = {}) -> undoStack. The choice of how to divide a component into smaller components is called factoring. after the operation in number theory ¹⁴. . The simplest and easiest way to build components out of smaller components in CoffeeScript is also the most obvious: Each component is a value.

hasOwnProperty(key) attributes: -> shallowCopy(attributes) } obj The techniques used for encapsulation work well with composition.pop() obj get: (key) -> attributes(key) has: (key) -> attributes. encapsulation prevents us from adding operations that interact with the hidden data structures. we said nothing about types and classes.wikipedia.org/wiki/Double-ended_queue ¹⁷Before you start wondering whether a deque is-a “implemented in terms of a. we have a “model” that hides its attribute store as well as its implementation that is composed of of an undo stack and redo stack.21 Stir the Espresso: Objects. or . ¹⁵http://duckduckgo. and State 27 28 29 30 31 32 33 34 35 36 attributes = redoStack. Mutation.” queue. Meaning. This relationship is called was-a. Consider a queue¹⁵: 1 2 3 4 5 6 7 8 9 10 11 12 QueueMaker = -> do (array = []. tail = -1) -> pushTail: (value) -> array[tail += 1] = value pullHead: -> if tail >= head do (value = array[head]) -> array[head] = undefined head += 1 value isEmpty: -> tail < head Now we wish to create a deque¹⁶ by adding pullTail and pushHead operations to our queue.com/Queue_ ¹⁶https://en. In this case. head = 0. they wish to define a new data structure in terms of adding new operations and semantics to an existing data structure.¹⁷ Unfortunately. extension Another practice that many people consider fundamental is to extend an implementation.

and State 22 This isn’t really surprising: The entire point of encapsulation is to create an opaque data structure that can only be manipulated through its public interface.array[deque.head] = undefined queue.array[queue.tail += 1] = value pullHead: -> unless queue.Stir the Espresso: Objects.head]) -> queue. with a little help from a helper function extend: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # helper function extend = (object.tail] = undefined deque. size: -> deque.tail .tail < queue.tail -= 1 value pushHead: do (INCREMENT = 4) -> .deque. extensions) -> object[key] = value for key. Mutation.head + 1 pullTail: -> unless deque.isEmpty() do (value = deque.head += 1 value isEmpty: -> queue.isEmpty() do (value = queue.head Now we can extend a queue into a deque. Let’s “de-encapsulate” our queue: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 QueueMaker = -> do (queue = undefined) -> queue = array: [] head: 0 tail: -1 pushTail: (value) -> queue. value of extensions object # a deque maker DequeMaker = -> do (deque = QueueMaker()) -> extend(deque.tail]) -> deque.array[queue. The design goals of encapsulation and extension are always going to exist in tension.array[deque.array[queue.

at the cost of encapsulation. A program with elaborate encapsulation resists breakage but can also be difficult to refactor in other ways.tail. 23 .deque.head is 0 for i in [deque.head] deque.Stir the Espresso: Objects. and State 19 20 21 22 23 24 25 26 (value) -> if deque.head -= 1] = value ) Presto.. Encapsulation and Extension exist in a natural state of tension.array[i] deque.tail += INCREMENT deque. we have reuse through extension.head += INCREMENT deque. Be mindful of when it’s best to Compose and when it’s best to Extend.array[deque.array[i + INCREMENT] = deque. Mutation.

head += 1 value isEmpty: -> queue.pushTail('Hello') queue.tail += 1] = value pullHead: do (value = undefined) -> -> unless queue. Mutation. queue) copyOfQueue.array[queue.isEmpty() value = queue.tail < queue.array = (element for element in queue. Here’s a Queue: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 QueueMaker = -> do (queue = undefined) -> queue = array: [] head: 0 tail: -1 pushTail: (value) -> queue. value of extensions object copyOfQueue = extend({}. extensions) -> object[key] = value for key.array) queue isnt copyOfQueue #=> true And start playing with our copies: . and State 24 This and That Let’s take another look at extensible objects.pushTail('CoffeeScript') Let’s make a copy of our queue using a handy extend function and a comprehension to make sure we copy the array properly: 1 2 3 4 5 6 7 8 9 extend = (object.Stir the Espresso: Objects.head] queue.array[queue.array[queue.head] = undefined queue.head queue = QueueMaker() queue.

isEmpty(myself) value = myself. Alas. The problem is that while we’ve carefully copied our array and other elements over. we have to tell them who they are. You can work out . 'CoffeeScript') The AmnesiacQueueMaker makes queues with amnesia: They don’t know who they are.pullHead() #=> 'Hello' queue. it seems that our two queues behave like aliases of each other.Stir the Espresso: Objects.tail += 1] = value pullHead: do (value = undefined) -> (myself) -> unless myself. Let’s take an impossibly optimistic flight of fancy: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 AmnesiacQueueMaker = -> array: [] head: 0 tail: -1 pushTail: (myself. This is a general issue with closures. and therefore the functions in copyOfQueue all operate on the first queue. and very handy for making opaque data structures. . Closures couple functions to environments. When you’re trying to make reusable components. value) -> myself. so every time we invoke one of their functions.array[myself.tail < myself.head += 1 value isEmpty: (myself) -> myself.pushTail(queueWithAmnesia. this coupling is sometimes a hindrance.array[myself. the closures all share the same environment.head] myself. 'Hello') queueWithAmnesia.head queueWithAmnesia = AmnesiacQueueMaker() queueWithAmnesia.pushTail(queueWithAmnesia.head] = undefined myself. Mutation.pullHead() #=> 'CoffeeScript' What!? Even though we carefully made a copy of the array to prevent aliasing. and State 1 2 3 4 5 25 copyOfQueue. and that makes them very elegant in the small.array[myself. their strength in the small is their weakness in the large.

pushTail('CoffeeScript') Every time you invoke a function that is a member of an object.array[this.pushTail('Hello') banksQueue.¹⁸ Now we can easily make copies: ¹⁸CoffeeScript also does other things with this as well. of course.tail < this.array[this. is making sure we are always passing the correct queue in every time we invoke a function. CoffeeScript binds that object to the name this in the environment of the function just as if it was an argument. Mutation.head banksQueue = BanksQueueMaker() banksQueue. but this is all we care about right now. because every function operates on the queue you pass in. .tail += 1] = value pullHead: do (value = undefined) -> -> unless this. What to do? what’s all this? Any time we must do the same repetitive thing over and over and over again.array[this.Stir the Espresso: Objects. and State 26 the implications for copying queues as a thought experiment: We don’t have to worry about environments.head] this. we industrial humans try to build a machine to do it for us.head] = undefined this. The killer drawback.isEmpty() value = this. CoffeeScript is one such machine: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 BanksQueueMaker = -> array: [] head: 0 tail: -1 pushTail: (value) -> this.head += 1 value isEmpty: -> this.

fat arrows are the cure for obese idioms Wait a second! Let’s flip back a few pages and look at the code for a Queue: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 QueueMaker = -> do (queue = undefined) -> queue = array: [] head: 0 tail: -1 pushTail: (value) -> queue.array) copyOfQueue. Mutation.tail < queue.head]) -> queue.array[queue. Copying objects is but one example of where that flexibility is needed.Stir the Espresso: Objects. and the code is simpler as well.isEmpty() do (value = queue. By getting rid of the closure and taking advantage of this. Using this alleviates the coupling.array = (element for element in banksQueue.array[queue. banksQueue) copyOfQueue.head += 1 value isEmpty: -> queue. and State 1 2 3 4 5 6 7 8 27 copyOfQueue = extend({}. Closures tightly couple functions to the environments where they are created limiting their flexibility.head Spot the difference? Here’s the pullHead function we’re using now: .pullHead() #=> 'Hello' banksQueue. we have functions that are more easily portable between objects.pullHead() #=> 'Hello' Presto.array[queue. we now have a way to copy arrays.tail += 1] = value pullHead: -> unless queue.head] = undefined queue.

so this is not set to our object. procs. We invoke it.head]) -> this. Mutation. you don’t return from the function enclosing the do. The error-prone workaround is to write: . (Make that five: Ruby has unbound methods. you return from the do itself.isEmpty() value = this.array[this. lambdas.array[this. Since everything’s a function. and this is set to our object.head += 1 value Sneaky: The version of the pullHead function moves the do outside the function. and State 1 2 3 4 5 6 7 28 pullHead: do (value = undefined) -> -> unless this.head += 1 value Notice that we have a function.” The Ruby programming language tries to solve this problem by having something–blocks–that look a lot like functions. there are some ways that functions don’t appear to do exactly what we think they’ll do. For example. we invoke another function inside that. if you put a return 'foo' inside a do. Why? Let’s rewrite it to look like the old version: 1 2 3 4 5 6 pullHead: -> unless this. Oops! Interestingly.array[this.head] = undefined this. of course.head] = undefined this. and blocks. this showcases one of CoffeeScript’s greatest strengths and weaknesses. bound methods.isEmpty() do (value = this.array[this.head] this.) . but act more like syntax. we have a set of tools that interoperate on everything the exact same way. thanks to the do. The cost of that decision. is that you have two different kinds of things that look similar but behave differently.Stir the Espresso: Objects. And as we see. There are two solutions. this gets set “incorrectly. However. Then. The function invoked by the do keyword does not belong to our object.

head] = undefined this.head]) => this. especially when refactoring some code. CoffeeScript gives you the “fat arrow” or => for this purpose. “Treat this function as if we did the this and that idiom.array[this. . so that whenever I refer to this. Here it is: 1 2 3 4 5 6 pullHead: -> unless this.head += 1 value The fat arrow says. Mutation.” Which is exactly what we want if we don’t care to rearrange our code. Or that for this.array[that.head].head += 1 value Besides its lack of pulchritude. there are many opportunities to mistakingly write this when you meant to write that. Or something.array[this.Stir the Espresso: Objects.isEmpty() do (value = this.isEmpty() do (value = this.array[this.head] = undefined that. that = this) -> that. and State 1 2 3 4 5 6 29 pullHead: -> unless this. I get the outer one. The better way is to force the function to have the this you want.

30 . The letrec pattern permits defining recursive or mutually dependent functions. Encapsulations can be aggregated with composition. Encapsulation resists extension. The fat arrow (=>) is syntactic sugar for binding this. Comprehensions are convenient. but require care to avoid scoping bugs. and State Summary Objects. State can be encapsulated/hidden with closures. “Normal Case” variables are automagically scoped.Stir the Espresso: Objects. References permit aliasing of reference types. Mutation. The automagic binding this facilitates sharing of functions. and State • • • • • • • • • • • CoffeeScript permits reassignment/rebinding of variables. Mutation. Arrays and Objects are mutable.

Mutation. The place was Jet City Espresso.” ¹⁹http://www. Don’t go looking for it.Stir the Espresso: Objects. As the name implies. and State interlude… A beautiful espresso machine Michael Allen Smith¹⁹ on Ristretto: “It must have been 1996. I was living in South Tampa at the time and the area finally got a great coffee house. the owner Jessica was from Seattle and shared her coffee knowledge with her customers. I expected the short pull of the espresso shot would result in a more bitter flavor.ineedcoffee.com/07/ristretto-rant/ 31 . It is no longer there. Jessica thought it was time I tried a ristretto. After ordering numerous americanos and espressos. To my delight the shot was actually a sweeter and more intense version of her espresso blend.

An Extra Shot of Ideas The Intestines of an Espresso Machine .

An Extra Shot of Ideas 33 Refactoring to Combinators The word “combinator” has a precise technical meaning in mathematics: “A combinator is a higher-order function that uses only function application and earlier defined combinators to define a result from its arguments.wikipedia. here is a memoize implementation that works for many²¹ kinds of functions: ²⁰https://en. Within any function the name arguments is always bound to an object that behaves like a collection of all the arguments passed to a function. and so forth. it works for functions that take arguments that can be expressed with JSON. arrays of JSON. we look it up.toInt() ( (new Date()). . we calculate it and write the result in the table to use in the future.”–Wikipedia²⁰ In this book.565 Why is it so slow? Well.s ) / 1000 #=> 28. it has a nasty habit of recalculating the same results over and over and over again. of course). memoize. numbers. but it’s fine for strings. but let’s be lazy and trade space for time. Using arguments. If we don’t have it. Whenever we want a result. So you can’t memoize a function that is applied to functions. we return the result without recalculating it. What we want to do is use a lookup table. First. If we do have it.org/wiki/Combinatory_logic ²¹To be precise. Consider that age-old interview quiz. we will be using a much looser definition of “combinator:” Pure functions that act on other functions to produce functions. POCOs of JSON. Combinators are the adverbs of functional programming. We could write something specific for fibonacci and then generalize it. We could rearrange the computation to avoid this. a new feature. Here’s simple implementation: 1 2 3 4 5 fibonacci = (n) -> if n < 2 n else fibonacci(n-2) + fibonacci(n-1) We’ll time it: 1 2 3 4 s = (new Date()). writing a recursive fibonacci function (there are other ways to derive a fibonacci number.getTime() .getTime() new Fibonacci(45). memoize Let’s begin with an example of a combinator. but let’s skip right to a general solution (we’ll discuss extracting a combinator below).

apply(this. value = undefined) -> -> key = JSON.An Extra Shot of Ideas 1 2 3 4 5 34 memoized = (fn) -> do (lookupTable = {}. . Let’s try it: 1 2 3 4 5 6 7 8 9 fastFibonacci = memoized (n) -> if n < 2 n else fastFibonacci(n-2) + fastFibonacci(n-1) fastFibonacci(45) #=> 1134903170 We get the result back instantly. our fastFibonacci code is easy to read and understand. arguments) We can apply memoized to a function and we will get back a new function that memoizes its results. It works! Exercise: Optimistic Ophelia tries the following code: 1 2 3 4 5 6 7 fibonacci = (n) -> if n < 2 n else fibonacci(n-2) + fibonacci(n-1) quickFibonacci = memoize(fibonacci) Does quickFibonacci behave differently than fastFibonacci? Why? By using a combinator instead of tangling lookup code with the actual “domain logic” of fibonacci. we DRY up our application. as the same memoize combinator can be used in many different places.stringify(arguments) lookupTable[key] or= fn. key = undefined. As a bonus.

But in CoffeeScript.html ²³http://www. We can see that we’re tangling the concern of initializing once with the concern of how to perform the initialization. and several pieces of code might call this function before using “it:” 1 2 3 4 5 6 7 ensureItIsInitialized = do (itIsInitialized = false) -> -> unless itIsInitialized itIsInitialized = true # . # initialization code # . Let’s extract a method²²: 1 2 3 4 5 6 7 8 9 initializeIt = -> # . We’ll call the combinator once: ²²http://refactoring.An Extra Shot of Ideas 35 the once and future combinator refactoring Combinators can often be extracted from your code.. The result is cleaner than the kinds of refactorings possible in languages that have less flexible functions. we’d stop right there.com/catalog/extractMethod. we can see that ensureItIsInitialized is much more generic than its name suggests. Let’s convert it to a combinator with a slight variation on the extracting a parameter²³. ensureItIsInitialized = do (itIsInitialized = false) -> -> unless itIsInitialized itIsInitialized = true initializeIt() In many other languages.. it assumes there’s some “it” that needs to be initialized once.... but might be invoked more than once.html . Let’s walk through the process of discovering a combinator to get a feel for the refactoring to combinator process.com/xp/refactoring/extractParamter. Some functions should only be evaluated once.. You want to evaluate them the first time they are called.. We’d start with a function like this. but thereafter ignore the invocation. The typical meta-pattern is when several different functions all share a common precondition such as loading certain constant data from a server or initializing a resource.. # initialization code # .industriallogic.

..An Extra Shot of Ideas 1 2 3 4 5 6 36 once = (fn) -> do (done = false) -> -> unless done done = true fn. It should be possible to pass the result of one combinator as the argument to another.) Composition and Combinators Although you can write nearly any function and use it as a combinator. # initialization code # ... one property that is nearly essential is composability. ensureItIsInitialized = once(initializeIt) This is so clean you could get rid of initializeIt as a named function: 1 2 3 4 ensureItIsInitialized = once -> # .org . The meta-pattern is that when you are working with a function. The concept of a combinator is more important than having a specific portfolio of combinators at your fingertips (although that is always nice).. # initialization code # . identify the core “domain logic” the function should express.apply(this.js²⁴ library along with several other handy functions that operate on functions such as throttle and debounce... Try to extract that and turn what is left into one or more combinators that take functions as parameters rather than single-purpose methods. (The memoize and once combinators are available in the underscore. arguments) And now our code is very clean: 1 2 3 4 5 initializeIt = -> # . Let’s consider this combinator as an example: ²⁴http://underscorejs..

the property of combinators taking a function as an argument and returning a function that operates on the same arguments and returns something meaningful to code expecting to call the original function. it’s easy to compose functions in CoffeeScript: 1 2 checkBoth = (fn) -> requiresValues requiresReturnValue fn Libraries like Functional²⁵ also provide compose and sequence functions. arguments) And this one: 1 2 3 4 5 requiresReturnValue = (fn) -> -> do (result = fn. And speaking of composition. arguments)) -> throw "Value Required" unless result? result You can use both of these combinators and the once combinator on a function to add some runtime validation that both input arguments and the returned value are defined: 1 2 3 4 5 checkedFibonacci = once requiresValues requiresReturnValue (n) -> if n < 2 n else fibonacci(n-2) + fibonacci(n-1) Combinators should be designed by default to compose.apply(this.An Extra Shot of Ideas 1 2 3 4 37 requiresValues = (fn) -> -> throw "Value Required" unless arg? for arg in arguments fn.apply(this.com/sources/javascript/functional/ .compose(requiresValues. ²⁵http://osteele. so you can write things like: 1 checkBoth = Functional. requiresReturnValue) All of this is made possible by the simple property of composability.

# complicated stuff # . all method decorators are combinators.. methods are functions. we don’t need to have one kind of tool for functions and another for methods. That’s one of the great strengths of CoffeeScript. Let’s get our terminology synchronized..²⁶ decorating object methods As you recall... So. anotherInstanceMethod: (foo) -> @initialize() # .” With some caveats. decorating constructor methods Decorating constructor methods works just as well as decorating instance methods. it isn’t a great leap to ask if we can use combinators with methods. And the answer is.. A combinator is a function that modifies another function.. for example: ²⁶The term “method decorator” is borrowed from the Python programming language . A method decorator is a combinator that modifies a method expression used inline. but not all combinators are method decorators.An Extra Shot of Ideas 38 Method Decorators Now that we’ve seen how function combinators can make our code cleaner and DRYer. an object method is a method belonging directly to a Plain Old CoffeeScript object or an instance.. All combinators work as decorators for object methods. someInstanceMethod: -> @initialize() # . After all. “Yes we can. since methods are “just” functions. For example: 1 2 3 4 5 6 7 8 9 10 11 12 class LazyInitializedMechanism constructor: -> @initialize = once -> # . or a messy way of turning methods into functions and functions into methods..

For this class. someInstanceMethod: -> @initialize() # . The initialize method could be converted from an instance method to an object method as above. There is one initialize method...prototype. only one will ever be initialized...constructor. there’s some setup to be done. method) -> -> unless @[name] @[name] = true method. anotherInstanceMethod: (foo) -> @initialize() # ..apply(this. decorating instance methods Decorating instance methods can be tricky if they rely on closures to encapsulate state of any kind. and write a decorator designed for use on instance methods: 1 2 3 4 5 once = (name.. and it belongs to BrokenMechanism. # complicated stuff # .setUpLazyClazz() # . all others calling it for the same or different instances will not execute. # complicated stuff # . but it’s deferred until the first instance is created...An Extra Shot of Ideas 1 2 3 4 5 6 7 8 39 class LazyClazz @setUpLazyClazz: once -> # .. so once it is called for the first BrokenMechanism instance. arguments) Now the flag for being done has been changed to an element of the instance.. and we use it like this: . If you have more than one BrokenMechanism. For example.. this will not work: 1 2 3 4 5 6 7 8 9 10 11 class BrokenMechanism initialize: once -> # .. An alternate approach is to surrender the perfect encapsulation of once.. constructor: -> this..

arguments) this And it’s easy to use: ²⁷https://en. It’s easy to write a fluent decorator: 1 2 3 4 fluent = (method) -> -> method. (You do need to make sure that each method using the decorator has its own unique name..) a decorator for fluent interfaces Fluent interfaces²⁷ are a style of API often used for configuration. you must take care that they all return this.withStandardTransmission(5) . If there are multiple return paths..withDoors(4) To implement an interface with this simple API.. the one function works with all instances. The simplest (but not only) type of fluent interface is a cascade of methods configuring the same object.apply(this. such as: 1 2 3 4 car = new Automobile() ..withBucketSeats(2) . # complicated stuff # ..wikipedia.An Extra Shot of Ideas 1 2 3 4 5 6 7 8 9 10 11 40 class WorkingMechanism initialize: once 'doneInitializing'. anotherInstanceMethod: (foo) -> @initialize() # . but you look at the top of the method to see its name and the bottom of the method to see what it returns. Since the flag is stored in the instance. -> # . It’s one line and easy to do. methods need to return this....org/wiki/Fluent_interface . someInstanceMethod: -> @initialize() # . The principle is to return an instance that has meaningful methods for the next thing you want to do.

apply(this. withStandardTransmission: fluent (gears) -> # . including the initialization code if you wanted to: . -> # . This is a very common pattern: Do something before invoking a method. someInstanceMethod: forcesInitialize -> # .. arguments) base. Can we extract that into a combinator? Certainly. anotherInstanceMethod: forcesInitialize (foo) -> # .apply(this.. combinators for making decorators Quite a few of the examples involve initializing something before doing some work. you could put anything in there.. Here’s a combinator that takes a method and returns a decorator: 1 2 3 4 5 6 before = (decoration) -> (base) -> -> decoration. withDoors: fluent (num) -> # ....... Of course. arguments) You would use it like this: 1 2 3 4 5 6 7 8 9 10 11 forcesInitialize = before -> @initialize() class WorkingMechanism initialize: once 'doneInitializing'. # complicated stuff # ..An Extra Shot of Ideas 1 2 3 4 5 6 7 41 class Automobile withBucketSeats: fluent (num) -> # .....

apply(this. arguments) base.. You only want to execute the method’s base logic provided some condition is truthy.concat(argv)) __value__ provided = (condition) -> (base) -> -> if condition..apply(this.call(this. someInstanceMethod: forcesInitialize -> # . We saw before above..apply(this.An Extra Shot of Ideas 1 2 3 4 5 6 7 8 9 42 class WorkingMechanism forcesInitialize = before -> # . arguments) . 3.. # complicated stuff # . the same few patterns tend to crop up regularly: 1. When writing decorators. argv) decoration. [callback].apply(this. 2. You want to do something after the method’s base logic is executed.. anotherInstanceMethod: forcesInitialize (foo) -> # ... You want to wrap some logic around the method’s base logic.) -> __value__ = undefined callback = => __value__ = base. You want to do something before the method’s base logic is executed. 4. Here are three more combinators that are very useful for writing method decorators: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 after = (decoration) -> (base) -> -> decoration.. __value__ = base.apply(this.. arguments)) __value__ around = (decoration) -> (base) -> (argv..

They can be used with all CoffeeScript and JavaScript projects.com/raganwald/method-combinators . and many more can be found in the method combinators²⁸ module.An Extra Shot of Ideas 43 All four of these. ²⁸https://github.

CoffeeScript expresses programs as expressions that are composed together with a combination of operators.. You can write either: 1 2 3 4 5 6 7 customerList. That’s all baked into the underlying language.An Extra Shot of Ideas 44 Callbacks and Promises Like nearly all languages in widespread use. composition The very simplest example of composing functions is simply “pipelining” the values. and control flow constructs such as sequences of statements. In this chapter. currentSession = # ... function application. Given: 1 2 3 4 5 6 7 getIdFromSession = (session) -> # . we’re going to examine how to compose functions together when we have non-traditional forms of control-flow such as asynchronous function invocation. Much as a fish (perhaps) exists in the ocean without being aware that there is an ocean... Some people find it more readable to go from left-to-right. so it’s easy to use it without thinking about it. The sequence function accomplishes this: . CoffeeScript’s optional parentheses make this quite readable.add fetchCustomerById getIdFromSession currentSession The “flow” of data is from right-to-left.. fetchCustomerById = (id) -> # .add( fetchCustomerById( getIdFromSession( currentSession ) ) ) Or: 1 customerList.

log('Asynchronicity'). customerList.setTimeout(fn. If it isn’t. you can defer invocation of a function after all current processing has been completed: 1 2 defer (fn) -> window. This might be what you want. a browser application can asynchronously invoke a request to a remote server and invoke handler code when the request is satisfied or deemed to have failed.log('Hello') depends upon the code console. fetchCustomerById. There are a number of different models and abstractions for controlling these dependencies. you need to have a way to force the order of evaluation when there is supposed to be a dependency between different evaluations.log('Hello') console. But if we intend that the result be “Asynchronicity Hello.add )(currentSession) asynchronous code CoffeeScript executes within an environment where code can be invoked asynchronously. A very simple example is that in a browser application. .” we say that the function -> console. For example. We will examine two of them (callbacks and promises) briefly. Not for the purpose of learning the subtleties of using either model. 0) The result is that if you write: 1 2 defer -> console.An Extra Shot of Ideas 1 2 3 4 5 6 7 8 9 10 11 45 sequence = -> do (fns = arguments) -> (value) -> (value = fn(value)) for fn in fns value sequence( getIdFromSession.log('Asynchronicity') The console will show: 1 2 Asynchronicity Hello The computer has no idea whether the result should be “Asynchronicity Hello” or “Hello Asynchronicity” or sometimes one and sometimes the other. but rather to obtain an understanding of how functions can be used to implement an abstraction over an underlying model.

synchronous function . Here’s an example inspired by a blog post²⁹. callback) -> window.elm . That parameter is a function to be invoked when they have completed. we’re handing it a function that invokes fn and pipelines the result (if any) to callback. let’s say we have a displayPhoto function that is synchronous.. Now we can ensure that the output is in the correct order: 1 2 3 4 defer (-> console.setTimeout.setTimeout (-> callback fn). So our defer function looks like this if we want to use callbacks: 1 2 defer (fn.An Extra Shot of Ideas 46 callbacks The underlying premise of the callback model is that every function that invoked code asynchronously is responsible for invoking code that depends on it.. callback) -> callback(displayPhoto(photoData)) There’s a combinator we can extract: 1 2 3 callbackize = (fn) -> (arg. (-> console. The simplest protocol for this is also the most popular: Functions that invoke asynchronous code take an extra parameter called a callback. you can also chain them manually.org/learn/Escape-from-Callback-Hell. callback) -> callback(fn(arg)) You recall that with ordinary functions. and not callback-aware: 1 2 displayPhoto = (photoData) -> # . fetching photos from a remote photo sharing site using their asynchronous API: ²⁹http://elm-lang. It can also be converted to take a callback: 1 2 displayPhotoWithCallback = (photoData. With callbacks..log 'hello').log 'Asynchronicity') #=> Hello # Asynchronicity Likewise.. you could chain them with function application. 0 Instead of handing fn directly to window.

displayPhoto We can also create a callback-aware function that represents the composition of functions: 1 2 3 4 displayPhotoForTag = (tag. (photoId) -> fotositeGetPhoto photoId. index.An Extra Shot of Ideas 1 2 3 4 5 47 tag = 'ristretto' fotositeGetPhotosByTag tag. helper = undefined) -> helper = (arg. you can avoid the indentation and extra syntax by writing a sequenceWithCallbacks function: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 I = (x) -> x sequenceWithCallbacks = -> do (fns = arguments. As a bonus. callback displayPhotoForTag = sequenceWithCallbacks( fotositeGetPhotosByTag. (result) -> helper result. index + 1. callback = I) -> if index > lastIndex callback arg else fns[index] arg.1. lastIndex = arguments. displayPhoto This code is considerably less messy in CoffeeScript than other languages that require a lot of additional syntax for functions.length . displayPhotoWithCallback ) . although it has some extra scaffolding and indentation. (photoList) -> fotositeGetOneFromList photos. it’s already in sequence order from top to bottom and doesn’t require re-ordering like normal function application did. fotositeGetOneFromList. callback) -> helper arg. (photoId) -> fotositeGetPhoto photoId. 0. callback (arg. fotositeGetPhoto. callback) -> fotositeGetPhotosByTag tag. That being said. (photoList) -> fotositeGetOneFromList photos.

then can be invoked on a promise at any time. no caffeine.com/cujojs/when .then fotositeGetOneFromList .then fotositeGetPhoto . ³²Interactive promises also support . the function(s) provided by the . Once in either the fulfilled or failed states.then(fulfilledCallback. that function is invoked immediately.org/wiki/Promises/A ³¹A state machine is a mathematical model of computation used to design both computer programs and sequential logic circuits. . Each promise must at a bare minimum implement a single method.com/kriskowal/q ³⁴https://github. One model is called promises³⁰.then displayPhoto Crisp and clean. the promise model also differs from the callback model in that . it remains there permanently. the state it is in at any given time is called the current state. ³³https://github. The promises model provides linear code “out of the box. A promise is an object that acts as a state machine. failedCallback by a failed promise.get and . It is conceived as an abstract machine that can be in one of a finite number of states. As we have seen. Here’s how our fotosite API would be used if it implemented promises instead of callbacks (we’ll ignore handling failures): 1 2 3 4 fotositeGetPhotosByTag(tag) . this is called a transition. using either the explicit invocation of callbacks or using sequenceWithCallbacks to express the execution as a list.then calls. but it does help us make callback-aware code “linear” instead of nested/indented. we can compose linear execution of asynchronous functions. and when³⁴. In addition to this being an object-based protocol.³¹ Its permissible states are: • unfulfilled • fulfilled • failed The only permissible transitions are from unfulfilled to fulfilled and from unfulfilled to failed. solving this problem with promises Asynchronous control flow can also be expressed using objects and methods. The machine is in only one state at a time.An Extra Shot of Ideas 48 sequenceWithCallbacks is more complex than sequence. whereas callbacks must be specified in advance. .commonjs.³² fulfilledCallback is a function to be invoked by a fulfilled promise.then call are queued up to be invoked if and when the promise transitions to the appropriate state. and the triggering condition for each transition. Be sure to look at libraries supporting promises like q³³. If the promise is already in either state. If the promise is unfulfilled.call methods for interacting with a potentially remote object.” and it “scales up” to serve as a complete platform for managing asynchronous code and remote invocation. It can change from one state to another when initiated by a triggering event or condition. failedCallback).then returns another promise that is fulfilled when the appropriate callback is fulfilled or fails when the appropriate callback fails. This allows chaining of . ³⁰http://wiki. A particular FSM is defined by a list of its states.

Promises represent control flow with an object API. Callbacks abstract control flow.49 An Extra Shot of Ideas Summary An Extra Shot of Ideas • • • • • • • • • Combinators are pure functions that act on other functions to produce functions. Many combinators are also Method Decorators. . Combinators are the adverbs of functional programming. Callbacks hide asynchronicity. Combinators make code more composeable. Combinators can often be extracted from your code. Some combinators decorate decorators.

is thinner in texture. and contains more caffeine than a ristretto pull . or the long pull. more acidic.An Extra Shot of Ideas 50 the last word… Espresso a lungo.

A Golden Crema You’ve earned a break! .

Toronto. and State” as well as “An Extra Shot of Ideas” in their entirety. If you read CoffeeScript Ristretto and it doesn’t blow your mind. There’s a lot more in the full book. 2012 ³⁵http://leanpub.com/coffeescript-ristretto . Mutation. there’s really no risk at all. your money will be cheerfully refunded. –Reginald “Raganwald” Braithwaite. You have both “Objects. so download it today³⁵! Besides.A Golden Crema 52 About These Sample Chapters This sample edition of the book includes both the fourth and the sixth full chapters.

this is not the author: But he has free coffee! .53 A Golden Crema No.

org³⁶ to install NodeJS and CoffeeScript.org/#installation ³⁷Instructions for installing NodeJS and modules like CoffeeScript onto a desktop computer is beyond the scope of this book. you’ll need to either include a call to console. alert 2+2 will cause the alert box to be displayed with the message 4.wikipedia. e. allowing you to type CoffeeScript programs right within a web page and see the results (as well as a translation from CoffeeScript to JavaScript).wikipedia. Some websites function as online REPLs³⁹. The examples in this book have all been tested on coffeescript. ctrl-V switches between single-line and multi-line input mode. Fortunately. be sure to enter multi-line mode.A Golden Crema 54 How to run the examples If you follow the instructions at coffeescript. ³⁸https://en. and what many programmers will do. To actually see the result of your expressions. ³⁶http://coffeescript. Clicking “Run” evaluates the expression in the browser.org⁴⁰.³⁷ you can run an interactive CoffeeScript REPL³⁸ on your command line simply by typing coffee. there are always up-to-date instructions on the web.g.org/wiki/REPL ³⁹https://en. You simply type a CoffeeScript expression into the blank window and you will see its JavaScript translation live. especially given the speed with which things advance. When running CoffeeScript on the command line.org/wiki/REPL ⁴⁰http://coffeescript.org/#try: . If you need to enter more than one line of code. This is how the examples in this book were tested.log (and be using a browser that supports console logging) or you could go old-school and use alert.

com/0262560992?tag=raganwald001-20 .amzn. CoffeeScript Ristretto’s primary focus is functions as first-class values. But where The Little Schemer’s primary focus is recursion. ⁴¹http://www.55 A Golden Crema Thanks! Daniel Friedman and Matthias Felleisen The Little Schemer CoffeeScript Ristretto was inspired by The Little Schemer⁴¹ by Daniel Friedman and Matthias Felleisen.

concise terms that build upon each other logically. ⁴²http://www. or that a beam of light only interacts with a small portion of the mirror.com/0691125759?tag=raganwald001-20 . the angle of reflection equalling the angle of refraction. And everything is explained in simple.56 A Golden Crema Richard Feynman QED: The Strange Theory of Light and Matter Richard Feynman’s QED⁴² was another inspiration: A book that explains Quantum Electrodynamics and the “Sum of the Histories” methodology using the simple expedient of explaining how light reflects off a mirror. or that it reflects off a plane–are all wrong. and showing how most of the things we think are happening–such as light travelling on a straight line.amzn.

Trevor is the author of CoffeeScript: Accelerated JavaScript Development⁴³.com/book/tbcoffee/coffeescript .57 A Golden Crema Trevor Burnham CoffeeScript: Accelerated JavaScript Development Trevor Burnham provided invaluable assistance with this book. ⁴³http://pragprog. an excellent resource for CoffeeScript programmers.

58 A Golden Crema JavaScript Allongé a long and strong programming book JavaScript Allongé⁴⁴ is the companion book to CoffeeScript Ristretto.com/javascript-allonge . ⁴⁴http://leanpub.

org/licenses/by-nc-nd/3.com/photos/thedigitelmyr/6199419022/ ⁵⁷http://creativecommons.en ⁶²http://www.org/licenses/by/2. Stirling Noyes.com/photos/the_rev/2295096211/ ⁵⁵http://creativecommons. ⁴⁵https://leanpub.org/licenses/by-nd/2.0/ ⁴⁷http://www.0/deed.0/deed.en ⁵⁴http://www.flickr. Creative Commons Attribution-NonCommercial-NoDerivs 3. Myrtle Bech Digitel. • La Marzocco⁶⁰ (c) 2009.flickr. • Free Coffees⁵⁸ image (c) 2010.com/photos/digitalcolony/3924227011/ ⁶¹http://creativecommons.flickr. • Cafe Diplomatico⁶² (c) 2011. EVERYDAYLIFEMODERN.flickr.flickr. Reginald Braithwaite. Some rights reserved⁶³.com/photos/digitalcolony/5054568279/ ⁴⁹http://creativecommons.0/deed. Missi.en ⁵⁸http://www.en ⁵²http://www. • Sugar Service⁶⁴ (c) 2008 Tiago Fernandes. EVERYDAYLIFEMODERN. All Rights Reserved.com/photos/everydaylifemodern/434299813/ ⁵³http://creativecommons. • Espresso shot in a caffe molinari cup⁵² (c) 2007.com/photos/tjgfernandes/2785677276/ ⁶⁵http://creativecommons.org/licenses/by-sa/2.0 Unported⁴⁶ license.org/licenses/by-sa/2.0/deed. Some rights reserved⁴⁹. • Short espresso shot in a white cup with blunt handle⁵⁰ (c) 2007.0/deed.flickr.com/photos/everydaylifemodern/1353570874/ ⁵¹http://creativecommons.com/photos/trumpetca/ ⁴⁸http://www.en ⁶⁴http://www. This sample preview work is licensed under an Attribution-NonCommercial-NoDerivs 3. Some Rights Reserved⁵⁷. Michael Francis McCarthy. • Beans in a Bag⁵⁴ (c) 2008.en .0 Unported License images • The picture of the author is (c) 2008.0/deed.org/licenses/by-sa/2.com/photos/15481483@N06/6231443466/ ⁶³http://creativecommons.A Golden Crema 59 Copyright Notice The original words in this sample preview of CoffeeScript Ristretto⁴⁵ are (c) 2012.org/licenses/by/2.org/licenses/by-nd/2. Michael Allen Smith.0/deed.org/licenses/by-sa/2. Some Rights Reserved⁵⁹.0/deed.en ⁵⁰http://www.flickr.en ⁶⁰http://www. Some rights reserved⁵³.0/deed. Some rights reserved⁵¹. Some rights reserved⁶¹.com/photos/sagamiono/4391542823/ ⁵⁹http://creativecommons.flickr. Some Rights Reserved⁵⁵. • Double ristretto menu⁴⁸ (c) 2010.org/licenses/by-sa/2. Some rights reserved⁶⁵.en ⁵⁶http://www. • Free Samples⁵⁶ (c) 2011.flickr.com/coffeescript-ristretto ⁴⁶http://creativecommons. Joseph Hurtado⁴⁷. Michael Allen Smith.flickr.

Some rights reserved⁹¹. Blue Diedrich Roaster⁷⁶ (c) 2010 Michael Allen Smith.com/photos/nalundgaard/4785922266/ ⁸³http://creativecommons.en .flickr.com/photos/ilovememphis/7103931235/ ⁹⁷http://creativecommons.0/deed.com/photos/digitalcolony/4309812256/ ⁷⁷http://creativecommons.en ⁷⁴http://www. Some rights reserved⁸¹.flickr. Some rights reserved⁷³.org/licenses/by-sa/2.com/photos/jenny-pics/5053954146/ ⁶⁹http://creativecommons.org/licenses/by/2.0/deed. Bezzera Espresso Machine⁹⁰ (c) 2011 Andrew Nash.0/deed.flickr.flickr. Some rights reserved⁷⁷. Some rights reserved⁶⁹.flickr.flickr.org/licenses/by-sa/2.com/photos/kirstenloza/4805716699/ ⁶⁷http://creativecommons. Coffee Spoons⁶⁸ (c) 2010 Jenny Downing. Intestines of an Espresso Machine⁸⁸ (c) 2011 Angie Chung.org/licenses/by-nd/2.en ⁹²http://www.org/licenses/by/2. Some rights reserved⁹⁵.com/photos/tangysd/5953453156/ ⁷³http://creativecommons.com/photos/digitalcolony/4000837035/ ⁷⁵http://creativecommons.org/licenses/by-sa/2.com/photos/paulmccoubrie/6828131856/ ⁸⁵http://creativecommons. Some rights reserved⁷⁹.org/licenses/by-sa/2. Some rights reserved⁸⁹.en ⁸⁰http://www. Some rights reserved⁸³. Some rights reserved⁸⁷.0/deed.0/deed. Red Diedrich Roaster⁷⁸ (c) 2009 Richard Masoner. Ooh!⁸⁶ (c) 2012 Michael Coghlan. Anticipation⁸⁴ (c) 2012 Paul McCoubrie. Some rights reserved⁸⁵. Some rights reserved⁹⁷.com/photos/lacerabbit/2102801319/ ⁸¹http://creativecommons.0/deed.org/licenses/by-sa/2.com/photos/shavejonathan/2343081208/ ⁹⁵http://creativecommons. • Cafe Macchiato on Gazotta Della Sport⁹⁴ (c) 2008 Jon Shave.0/deed.com/photos/33388953@N04/4017985434/ ⁷¹http://creativecommons. • Jars of Coffee Beans⁹⁶ (c) 2012 Memphis CVB. Cupping Coffees⁷² (c) 2011 Dennis Tang.en ⁷²http://www.en ⁸⁶http://www.0/deed. *Beans Ripening on a Branch⁹² (c) 2008 John Pavelka.0/deed.en ⁹⁶http://www. Half Drunk⁸² (c) 2010 Nicholas Lundgaard.flickr.flickr.org/licenses/by/2.org/licenses/by/2.en ⁷⁰http://www.A Golden Crema • • • • • • • • • • • • • 60 Biscotti on a Rack⁶⁶ (c) 2010 Kirsten Loza.org/licenses/by-nd/2.com/photos/28705377@N04/5306009552/ ⁹³http://creativecommons.en ⁸⁸http://www.flickr.flickr. Roaster with Tree Leaves⁸⁰ (c) 2007 ting.en ⁹⁴http://www. ⁶⁶http://www.0/deed.flickr.0/deed. Some rights reserved⁶⁷. Some rights reserved⁷¹. Some rights reserved⁹³.en ⁸²http://www.com/photos/bike/3237859728/ ⁷⁹http://creativecommons.0/deed.en ⁹⁰http://www. Drawing a Doppio⁷⁰ (c) 2008 Osman Bas.org/licenses/by-sa/2.flickr.flickr.org/licenses/by/2.flickr.0/deed.0/deed.com/photos/andynash/6204253236/ ⁹¹http://creativecommons.en ⁷⁶http://www.flickr.org/licenses/by-nd/2.en ⁸⁴http://www.0/deed.flickr.en ⁶⁸http://www.com/photos/mikecogh/7676649034/ ⁸⁷http://creativecommons.org/licenses/by-sa/2.en ⁷⁸http://www. Three Coffee Roasters⁷⁴ (c) 2009 Michael Allen Smith.com/photos/yellowskyphotography/5641003165/ ⁸⁹http://creativecommons. Some rights reserved⁷⁵.0/deed.org/licenses/by-sa/2.

0/deed. ⁹⁸http://www.org/licenses/by/2.en ¹⁰⁶http://www.com/photos/joncrel/237026246/ ¹⁰⁹http://creativecommons. Some rights reserved¹⁰⁹. Some rights reserved¹⁰⁷.com/photos/93425126@N00/313053257/ ¹⁰³http://creativecommons. Coffee Trees¹⁰⁰ (c) 2011 Dave Townsend. Mirage¹⁰⁶ (c) 2010 Mira Helder.org/licenses/by-sa/2.0/deed. Coffee Van with Bullet Holes¹⁰⁸ (c) 2006 Jon Crel. Some rights reserved¹⁰¹.A Golden Crema • • • • • • Types of Coffee Drinks⁹⁸ (c) 2012 Michael Coghlan.org/licenses/by-sa/2.flickr.com/photos/mikecogh/7561440544/ ⁹⁹http://creativecommons.0/deed.com/photos/citizenhelder/5006498068/ ¹⁰⁷http://creativecommons. Cafe do Brasil¹⁰² (c) 2003 Temporalata.flickr.flickr.com/photos/digitalcolony/2833809436/ ¹⁰⁵http://creativecommons. Some rights reserved¹⁰³.org/licenses/by-sa/2. Brown Cups¹⁰⁴ (c) 2007 Michael Allen Smith.flickr. Some rights reserved¹⁰⁵.en 61 .0/deed. Some rights reserved⁹⁹.en ¹⁰⁰http://www.com/photos/dtownsend/6171015997/ ¹⁰¹http://creativecommons.en ¹⁰⁴http://www.0/deed.0/deed.en ¹⁰⁸http://www.flickr.en ¹⁰²http://www.org/licenses/by-sa/2.org/licenses/by-nd/2.flickr.

andand. contact Twitter: @raganwald¹¹⁴ Email: reg@braythwayt. YouAreDaChef.A Golden Crema 62 About The Author When he’s not shipping CoffeeScript. and others. Reg “Raganwald” Braithwaite has authored libraries¹¹⁰ for CoffeeScript.com/raganwald ¹¹⁵mailto:reg@braythwayt. JavaScript and Ruby programming such as Method Combinators.com . JavaScript and Java applications scaling out to millions of users. He writes about programming on his “Homoiconic¹¹¹” un-blog as well as general-purpose ruminations on his posterous space¹¹².com¹¹⁵ ¹¹⁰http://github. Katy.raganwald.com ¹¹³http://weblog. JQuery Combinators.com ¹¹⁴https://twitter.com/raganwald ¹¹¹http://github. He is also known for authoring the popular raganwald programming blog¹¹³ from 2005-2008.posterous.com/raganwald/homoiconic ¹¹²http://raganwald. Ruby.

63 A Golden Crema Reg “Raganwald” Braithwaite .