Javascript Allong A Long Pull of Functions Combinators Decorators Reginald Braithwaite Download
Javascript Allong A Long Pull of Functions Combinators Decorators Reginald Braithwaite Download
https://ebookbell.com/product/javascript-allong-a-long-pull-of-
functions-combinators-decorators-reginald-braithwaite-4722952
https://ebookbell.com/product/javascript-allong-a-long-pull-of-
functions-combinators-decorators-reginald-braithwaite-4722950
https://ebookbell.com/product/javascript-allong-the-six-edition-
programming-from-functions-to-classes-in-ecmascript-2015-2nd-edition-
reg-braithwaite-33392624
https://ebookbell.com/product/javascript-allong-the-six-edition-
braithwaite-reginald-11706334
Javascript For R Chapman Hallcrc The R Series 1st Edition John Coene
https://ebookbell.com/product/javascript-for-r-chapman-hallcrc-the-r-
series-1st-edition-john-coene-45035150
Javascript Jquery The Missing Manual Second Edition 2nd Edition David
Sawyer Mcfarland
https://ebookbell.com/product/javascript-jquery-the-missing-manual-
second-edition-2nd-edition-david-sawyer-mcfarland-46096056
https://ebookbell.com/product/javascript-the-comprehensive-guide-1st-
edition-philip-ackermann-46150184
https://ebookbell.com/product/javascript-from-beginner-to-
professional-december-2021-laurence-lars-svekis-46425446
https://ebookbell.com/product/javascript-the-definitive-guide-7th-
edition-david-flanagan-48389656
https://ebookbell.com/product/javascript-allinone-for-dummies-1st-
chris-minnick-48448890
JavaScript Allongé
A long pull of functions, combinators, & decorators
raganwald
This book is for sale at http://leanpub.com/javascript-allonge
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.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License
Tweet This Book!
Please help raganwald by spreading the word about this book on Twitter!
The suggested hashtag for this book is #javascript-allonge.
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=#javascript-allonge
Also By raganwald
Kestrels, Quirky Birds, and Hopeless Egocentricity
What I’ve Learned From Failure
How to Do What You Love & Earn What You’re Worth as a Programmer
CoffeeScript Ristretto
JavaScript Spessore
This book is dedicated to my daughter, Clara Maude Braithwaite
Contents
10 Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Introduction: Compose and Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Caffe Molinari
“Café Allongé, also called Espresso Lungo, is a drink midway between an Espresso and
Americano in strength. There are two different ways to make it. The first, and the one I
prefer, is to add a small amount of hot water to a double or quadruple Espresso Ristretto.
Like adding a splash of water to whiskey, the small dilution releases more of the complex
flavours in the mouth.
“The second way is to pull an extra long double shot of Espresso. This achieves
approximately the same ratio of oils to water as the dilution method, but also releases a
different mix of flavours due to the longer extraction. Some complain that the long pull
is more bitter and detracts from the best character of the coffee, others feel it releases
even more complexity.
“The important thing is that neither method of preparation should use so much water
as to result in a sickly, pale ghost of Espresso. Moderation in all things.”
Not only was this a great book, but it was also a great way to write and distribute books. Having
written books myself, I know the pain of soliciting and receiving feedback.
The act of writing is an iterative process with (very often) tight revision loops. However, the process
of soliciting feedback, gathering responses, sending out copies, waiting for people to actually read
it (if they ever do), receiving feedback and then ultimately making sense out of how to use it takes
weeks and sometimes months. On more than one occasion I’ve found myself attempting to reify
feedback with content that either no longer existed or was changed beyond recognition. However,
with the Leanpub model the read-feedback-change process is extremely efficient, leaving in its wake
a quality book that continues to get better as others likewise read and comment into infinitude.
In the case of JavaScript Allongé, you’ll find the Leanpub model a shining example of effectiveness.
Reg has crafted (and continues to craft) not only an interesting book from the perspective of a
connoisseur, but also an entertaining exploration into some of the most interesting aspects of his
art. No matter how much of an expert you think you are, JavaScript Allongé has something to teach
you… about coffee. I kid.
As a staunch advocate of functional programming, much of what Reg has written rings true to me.
While not exclusively a book about functional programming, JavaScript Allongé will provide a solid
foundation for functional techniques. However, you’ll not be beaten about the head and neck with
dogma. Instead, every section is motivated by relevant dialog and fortified with compelling source
examples. As an author of programming books I admire what Reg has managed to accomplish and I
envy the fine reader who finds JavaScript Allongé via some darkened channel in the Internet sprawl
and reads it for the first time.
Enjoy.
– Fogus, fogus.me¹
1 return mapWith(maybe(getWith('name')))(customerList);
Instead of:
As well as how it works and how to refactor it when you need. This style of programming is
hardly the most common thing anyone does in JavaScript, so the argument can be made that more
“practical” or “commonplace” recipes would be helpful. If you never read any other books about
JavaScript, if you avoid blog posts and screen casts about JavaScript, if you don’t attend workshops
or talks about JavaScript, then I agree that this is not One Book to Rule Them All.
But given that there are other resources out there, and that programmers are curious creatures with
an unslakable thirst for personal growth, we choose to provide recipes that you are unlikely to find
anywhere else in anything like this concentration. The recipes reinforce the lessons taught in the
book about functions in JavaScript.
You’ll find all of the recipes collected online at http://allong.es⁴. They’re free to share under the MIT
license.
Reginald Braithwaite⁵
[email protected]
@raganwald
Legend
Some text in monospaced type like this in the text represents some code being discussed. Some
monospaced code in its own lines also represents code being discussed:
⁴http://allong.es
⁵http://braythwayt.com
A Pull of the Lever: Prefaces v
Sometimes it will contain some code for you to type in for yourself. When it does, the result of
typing something in will often be shown using //=>, like this:
1 2 + 2
2 //=> 4
A paragraph marked like this is a “key fact.” It summarizes an idea without adding anything
new.
A paragraph marked like this is an aside. It can be safely ignored. It contains whimsey and other
doupleplusunserious logorrhea that will not be on the test.
.
Prelude: Values and Expressions
The following material is extremely basic, however like most stories, the best way to begin is to start
at the very beginning.
Imagine we are visiting our favourite coffee shop. They will make for you just about any drink you
desire, from a short, intense espresso ristretto through a dry cappuccino, up to those coffee-flavoured
desert concoctions featuring various concentrated syrups and milks. (You tolerate the existence of
sugary drinks because they provide a sufficient profit margin to the establishment to finance your
hanging out there all day using their WiFi and ordering a $3 drink every few hours.)
You express your order at one end of their counter, the folks behind the counter perform their magic,
and deliver the coffee you value at the other end. This is exactly how the JavaScript environment
works for the purpose of this book. We are going to dispense with web servers, browsers and other
complexities and deal with this simple model: You give the computer an expression⁶, and it returns
a value⁷, just as you express your wishes to a barista and receive a coffee in return.
1 42
1 42
2 //=> 42
⁶https://en.wikipedia.org/wiki/Expression_
⁷https://en.wikipedia.org/wiki/Value_
⁸Technically, it’s a representation of a value using Base10 notation, but we needn’t worry about that in this book. You and I both understand that
this means “42,” and so does the computer.
Prelude: Values and Expressions vii
All values are expressions. That’s easy! Are there any other kinds of expressions? Sure! let’s go back
to the coffee shop. Instead of handing over the finished coffee, we can hand over the ingredients.
Let’s hand over some ground coffee plus some boiling water.
Astute readers will realize we’re omitting something. Congratulations! Take a sip of espresso. We’ll
get to that in a moment.
.
Now the barista gives us back an espresso. And if we hand over the espresso, we get the espresso
right back. So, boiling water plus ground coffee is an expression, but it isn’t a value.⁹ Boiling water
is a value. Ground coffee is a value. Espresso is a value. Boiling water plus ground coffee is an
expression.
Let’s try this as well with something else the computer understands easily:
Now we see that “strings” are values, and you can make an expression out of strings and an operator
+. Since strings are values, they are also expressions by themselves. But strings with operators are
not values, they are expressions. Now we know what was missing with our “coffee grounds plus hot
water” example. The coffee grounds were a value, the boiling hot water was a value, and the “plus”
operator between them made the whole thing an expression that was not a value.
1 2 === 2
2 //=> true
3
4 'hello' !== 'goodbye'
5 //=> true
How does === work, exactly? Imagine that you’re shown a cup of coffee. And then you’re shown
another cup of coffee. Are the two cups “identical?” In JavaScript, there are four possibilities:
First, sometimes, the cups are of different kinds. One is a demitasse, the other a mug. This
corresponds to comparing two things in JavaScript that have different types. For example, the string
"2" is not the same thing as the number 2. Strings and numbers are different types, so strings and
numbers are never identical:
⁹In some languages, expressions are a kind of value unto themselves and can be manipulated. The grandfather of such languages is Lisp. JavaScript
is not such a language, expressions in and of themselves are not values.
Prelude: Values and Expressions viii
1 2 === '2'
2 //=> false
3
4 true !== 'true'
5 //=> true
Second, sometimes, the cups are of the same type–perhaps two espresso cups–but they have different
contents. One holds a single, one a double. This corresponds to comparing two JavaScript values that
have the same type but different “content.” For example, the number 5 is not the same thing as the
number 2.
What if the cups are of the same type and the contents are the same? Well, JavaScript’s third and
fourth possibilities cover that.
value types
Third, some types of cups have no distinguishing marks on them. If they are the same kind of cup,
and they hold the same contents, we have no way to tell the difference between them. This is the
case with the strings, numbers, and booleans we have seen so far.
1 2 + 2 === 4
2 //=> true
3
4 (2 + 2 === 4) === (2 !== 5)
5 //=> true
Note well what is happening with these examples: Even when we obtain a string, number, or boolean
as the result of evaluating an expression, it is identical to another value of the same type with the
same “content.” Strings, numbers, and booleans are examples of what JavaScript calls “value” or
“primitive” types. We’ll use both terms interchangeably.
We haven’t encountered the fourth possibility yet. Stretching the metaphor somewhat, some types
of cups have a serial number on the bottom. So even if you have two cups of the same type, and
their contents are the same, you can still distinguish between them.
Prelude: Values and Expressions ix
Cafe Macchiato is also a fine drink, especially when following up on the fortunes of the Azzuri or the standings
in the Giro D’Italia
reference types
So what kinds of values might be the same type and have the same contents, but not be
considered identical to JavaScript? Let’s meet a data structure that is very common in contemporary
programming languages, the Array (other languages sometimes call it a List or a Vector).
An array looks like this: [1, 2, 3]. This is an expression, and you can combine [] with other
expressions. Go wild with things like:
1 [2-1, 2, 2+1]
2 [1, 1+1, 1+1+1]
Notice that you are always generating arrays with the same contents. But are they identical the same
way that every value of 42 is identical to every other value of 42? Try these for yourself:
How about that! When you type [1, 2, 3] or any of its variations, you are typing an expression
that generates its own unique array that is not identical to any other array, even if that other array
also looks like [1, 2, 3]. It’s as if JavaScript is generating new cups of coffee with serial numbers
on the bottom.
Prelude: Values and Expressions x
Arrays look exceedingly simple, but this word “reference” is so laden with possibilities that there’s
an entire chapter devoted to discussing rebinding and references. Try typing this code out:
They look the same, but if you examine them with ===, you see that they are different. Every time
you evaluate an expression (including typing something in) to create an array, you’re creating a
new, distinct value even if it appears to be the same as some other array value. As we’ll see, this is
true of many other kinds of values, including functions, the main subject of this book.
Prelude: Values and Expressions 1
1 The first sip: Basic Functions
The perfect Café Allongé begins with the right beans, properly roasted. JavaScript Allongé begins with functions,
properly dissected.
The first sip: Basic Functions 3
1 function () {}
This is a function that is applied to no values and produces no value. How do we represent “no value”
in JavaScript? We’ll find out in a minute. First, let’s verify that our function is a value:
1 (function () {})
2 //=> [Function]
What!? Why didn’t it type back function () {} for us? This seems to break our rule that if an
expression is also a value, JavaScript will give the same value back to us. What’s going on? The
simplest and easiest answer is that although the JavaScript interpreter does indeed return that value,
displaying it on the screen is a slightly different matter. [Function] is a choice made by the people
who wrote Node.js, the JavaScript environment that hosts the JavaScript REPL. If you try the same
thing in a browser, you’ll see the code you typed.
The first sip: Basic Functions 4
I’d prefer something else, but I must accept that what gets typed back to us on the screen is arbitrary,
and all that really counts is that it is somewhat useful for a human to read. But we must understand
that whether we see [Function] or function () {}, internally JavaScript has a full and proper
function.
.
Like arrays, every time you evaluate an expression to produce a function, you get a new function that
is not identical to any other function, even if you use the same expression to generate it. “Function”
is a reference type.
applying functions
Let’s put functions to work. The way we use functions is to apply them to zero or more values called
arguments. Just as 2 + 2 produces a value (in this case 4), applying a function to zero or more
arguments produces a value as well.
Here’s how we apply a function to some values in JavaScript: Let’s say that fn_expr is an expression
that when evaluated, produces a function. Let’s call the arguments args. Here’s how to apply a
function to some arguments:
fn_expr (args)
Right now, we only know about one such expression: function () {}, so let’s use it. We’ll put it in
parentheses¹ to keep the parser happy, like we did above: (function () {}). Since we aren’t giving
it any arguments, we’ll simply write () after the expression. So we write:
¹If you’re used to other programming languages, you’ve probably internalized the idea that sometimes parentheses are used to group operations
in an expression like math, and sometimes to apply a function to arguments. If not… Welcome to the ALGOL family of programming languages!
The first sip: Basic Functions 5
1 (function () {})()
2 //=> undefined
undefined
In JavaScript, the absence of a value is written undefined, and it means there is no value. It will crop
up again. undefined is its own type of value, and it acts like a value type:
1 undefined
2 //=> undefined
Like numbers, booleans and strings, JavaScript can print out the value undefined.
No matter how you evaluate undefined, you get an identical value back. undefined is a value that
means “I don’t have a value.” But it’s still a value :-)
You might think that undefined in JavaScript is equivalent to NULL in SQL. No. In SQL, two things
that are NULL are not equal to nor share the same identity, because two unknowns can’t be equal.
In JavaScript, every undefined is identical to every other undefined.
.
void
We’ve seen that JavaScript represents an undefined value by typing undefined, and we’ve generated
undefined values in two ways:
1 void 0
2 //=> undefined
3 void 1
4 //=> undefined
5 void (2 + 2)
6 //=> undefined
void is an operator that takes any value and evaluates to undefined, always. So, when we
deliberately want an undefined value, should we use the first, second, or third form?² The answer
is, use void. By convention, use void 0.
The first form works but it’s cumbersome. The second form works most of the time, but it is possible
to break it by reassigning undefined to a different value, something we’ll discuss in Reassignment
and Mutation. The third form is guaranteed to always work, so that’s what we will use.³
1 (function () {})()
2 //=> undefined
Let’s recall that we were applying the function function () {} to no arguments (because there was
nothing inside of ()). So how do we know to expect undefined? That’s easy:
When we define a function⁴, we write the word function. We then put a (possibly empty) list of
arguments, then we give the function a body that is enclosed in braces {...}. Function bodies are
(possibly empty) lists of JavaScript statements separated by semicolons.
Something like: { statement1 ; statement2 ; statement3 ; … ; statementn }
We haven’t discussed these statements. What’s a statement?
There are many kinds of JavaScript statements, but the first kind is one we’ve already met. An
expression is a JavaScript statement. Although they aren’t very practical, the following are all valid
JavaScript functions, and they all evaluate to undefined when applied:
²Experienced JavaScript programmers are aware that there’s a fourth way, using a function argument. This was actually the preferred mechanism
until void became commonplace.
³As an exercise for the reader, we suggest you ask your friendly neighbourhood programming language designer or human factors subject-matter
expert to explain why a keyword called void is used to generate an undefined value, instead of calling them both void or both undefined. We have
no idea.
⁴TODO: Named functions, probably discussed in a whole new section when we discuss var hoisting.
The first sip: Basic Functions 7
1 (function () { 2 + 2 })
2
3 (function () { 1 + 1; 2 + 2 })
You can also separate statements with line breaks.⁵ The convention is to use some form of consistent
indenting:
1 (function () {
2 1 + 1;
3 2 + 2
4 })
5
6 (function () {
7 (function () {
8 (function () {
9 (function () {
10 })
11 })
12 });
13 (function () {
14 })
15 })
That last one’s a doozy, but since a function body can contain a statement, and a statement can be
an expression, and a function is an expression…. You get the idea.
So how do we get a function to return a value when applied? With the return keyword and any
expression:
The return keyword creates a return statement that immediately terminates the function application
and returns the result of evaluating its expression.
⁵Readers who follow internet flame-fests may be aware of something called automatic semi-colon insertion. Basically, there’s a step where
JavaScript looks at your code and follows some rules to guess where you meant to put semicolons in should you leave them out. This feature was
originally created as a kind of helpful error-correction. Some programmers argue that since it’s part of the language’s definition, it’s fair game to write
code that exploits it, so they deliberately omit any semicolon that JavaScript will insert for them.
The first sip: Basic Functions 8
1 function () {
2 return (function () {})
3 }
That’s a function! It’s a function that when applied, evaluates to a function that when applied,
evaluates to undefined.⁶ Let’s use a simpler terminology. Instead of saying “that when applied,
evaluates to _____,” we will say “gives _____.” And instead of saying “gives undefined,” we’ll say
“doesn’t give anything.”
So we have a function, that gives a function, that doesn’t give anything. Likewise:
1 function () {
2 return (function () {
3 return true
4 })
5 }
1 (function () {
2 return (function () {
3 return true
4 })
5 })()()
6 //=> true
Well. We’ve been very clever, but so far this all seems very abstract. Diffraction of a crystal is
beautiful and interesting in its own right, but you can’t blame us for wanting to be shown a practical
use for it, like being able to determine the composition of a star millions of light years away. So… In
the next chapter, “I’d Like to Have an Argument, Please,” we’ll see how to make functions practical.
⁶What a mouthful! This is why other languages with a strong emphasis on functions come up with syntaxes like ‘ -> -> undefined‘
The first sip: Basic Functions 9
Most programmers are perfectly familiar with arguments (often called “parameters”). Secondary
school mathematics discusses this. So you know what they are, and I know that you know what
they are, but please be patient with the explanation!
.
1 function (room) {}
This function has one argument, room, and no body. Here’s a function with two arguments and no
body:
I’m sure you are perfectly comfortable with the idea that this function has two arguments, room,
and board. What does one do with the arguments? Use them in the body, of course. What do you
think this is?
It’s a function for calculating the circumference of a circle given the diameter. I read that aloud
as “When applied to a value representing the diameter, this function returns the diameter times
3.14159265.”
Remember that to apply a function with no arguments, we wrote (function () {})(). To apply
a function with an argument (or arguments), we put the argument (or arguments) within the
parentheses, like this:
You won’t be surprised to see how to write and apply a function to two arguments:
⁷The Argument Sketch from “Monty Python’s Previous Record” and “Monty Python’s Instant Record Collection”
The first sip: Basic Functions 10
1 function () {
2 return function () {}
3 }
4
5 function () {
6 return [ 1, 2, 3]
7 }
8
9 [1, [2, 3], 4]
10
11 function () {
12 return [
13 (function () { return 1}),
14 (function () { return 2}),
15 (function () { return 3})
16 ]
17 }
The first sip: Basic Functions 11
call by value
Like most contemporary programming languages, JavaScript uses the “call by value” evaluation
strategy⁸. That means that when you write some code that appears to apply a function to an
expression or expressions, JavaScript evaluates all of those expressions and applies the functions
to the resulting value(s).
So when you write:
What happened internally is that the expression 1 + 1 was evaluated first, resulting in 2. Then our
circumference function was applied to 2.⁹
function (x) { return (function (y) { return x }) } just looks crazy, as if we are learning
English as a second language and the teacher promises us that soon we will be using words like
antidisestablishmentarianism. Besides a desire to use long words to sound impressive, this is not
going to seem attractive until we find ourselves wanting to discuss the role of the Church of England
in 19th century British politics.
But there’s another reason for learning the word antidisestablishmentarianism: We might learn
how prefixes and postfixes work in English grammar. It’s the same thing with function (x) {
return (function (y) { return x }) }. It has a certain important meaning in its own right, and
it’s also an excellent excuse to learn about functions that make functions, environments, variables,
and more.
.
In order to talk about how this works, we should agree on a few terms (you may already know them,
but let’s check-in together and “synchronize our dictionaries”). The first x, the one in function (x)
..., is an argument. The y in function (y) ... is another argument. The second x, the one in {
⁸http://en.wikipedia.org/wiki/Evaluation_strategy
⁹We said that you can’t apply a function to an expression. You can apply a function to one or more functions. Functions are values! This has
interesting applications, and they will be explored much more thoroughly in Functions That Are Applied to Functions.
The first sip: Basic Functions 12
return x }, is not an argument, it’s an expression referring to a variable. Arguments and variables
work the same way whether we’re talking about function (x) { return (function (y) { return
x }) } or just plain function (x) { return x }.
Every time a function is invoked (“invoked” means “applied to zero or more arguments”), a new
environment is created. An environment is a (possibly empty) dictionary that maps variables to
values by name. The x in the expression that we call a “variable” is itself an expression that is
evaluated by looking up the value in the environment.
How does the value get put in the environment? Well for arguments, that is very simple. When you
apply the function to the arguments, an entry is placed in the dictionary for each argument. So when
we write:
When we talk about environments, we’ll use an unsurprising syntax¹⁰ for showing their bindings:
{x: 2, ...}. meaning, that the environment is a dictionary, and that the value 2 is bound to the
name x, and that there might be other stuff in that dictionary we aren’t discussing right now.
¹⁰http://json.org/
The first sip: Basic Functions 13
call by sharing
Earlier, we distinguished JavaScript’s value types from its reference types. At that time, we looked
at how JavaScript distinguishes objects that are identical from objects that are not. Now it is time to
take another look at the distinction between value and reference types.
There is a property that JavaScript strictly maintains: When a value–any value–is passed as an
argument to a function, the value bound in the function’s environment must be identical to the
original.
We said that JavaScript binds names to values, but we didn’t say what it means to bind a name to a
value. Now we can elaborate: When JavaScript binds a value-type to a name, it makes a copy of the
value and places the copy in the environment. As you recall, value types like strings and numbers
are identical to each other if they have the same content. So JavaScript can make as many copies of
strings, numbers, or booleans as it wishes.
What about reference types? JavaScript does not place copies of reference values in any environment.
JavaScript places references to reference types in environments, and when the value needs to be used,
JavaScript uses the reference to obtain the original.
Because many references can share the same value, and because JavaScript passes references as
arguments, JavaScript can be said to implement “call by sharing” semantics. Call by sharing is
generally understood to be a specialization of call by value, and it explains why some values are
known as value types and other values are known as reference types.
And with that, we’re ready to look at closures. When we combine our knowledge of value types,
reference types, arguments, and closures, we’ll understand why this function always evaluates to
true no matter what argument you apply it to:
1 function (value) {
2 return (function (copy) {
3 return copy === value
4 })(value)
5 }
1 (function (x) {
2 return function (y) {
3 return x
4 }
5 })(1)(2)
6 //=> 1
First off, let’s use what we learned above. Given (some function)(some argument ), we know that
we apply the function to the argument, create an environment, bind the value of the argument to
the name, and evaluate the function’s expression. So we do that first with this code:
1 (function (x) {
2 return function (y) {
3 return x
4 }
5 })(1)
6 //=> [Function]
The environment belonging to the function with signature function (x) ... becomes {x: 1, ...},
and the result of applying the function is another function value. It makes sense that the result value
is a function, because the expression for function (x) ...’s body is:
1 function (y) {
2 return x
3 }
So now we have a value representing that function. Then we’re going to take the value of that
function and apply it to the argument 2, something like this:
1 (function (y) {
2 return x
3 })(2)
So we seem to get a new environment {y: 2, ...}. How is the expression x going to be evaluated in
that function’s environment? There is no x in its environment, it must come from somewhere else.
This, by the way, is one of the great defining characteristics of JavaScript and languages in the
same family: Whether they allow things like functions to nest inside each other, and if so, how they
handle variables from “outside” of a function that are referenced inside a function. For example,
here’s the equivalent code in Ruby:
.
The first sip: Basic Functions 15
1 lambda { |x|
2 lambda { |y| x }
3 }[1][2]
4 #=> 1
Pure functions are easiest to understand. They always mean the same thing wherever you use them.
Here are some pure functions we’ve already seen:
1 function () {}
2
3 function (x) {
4 return x
5 }
6
7 function (x) {
8 return function (y) {
9 return x
10 }
11 }
The first function doesn’t have any variables, therefore doesn’t have any free variables. The second
doesn’t have any free variables, because its only variable is bound. The third one is actually two
¹¹You may also hear the term “non-local variable.” Both are correct.
The first sip: Basic Functions 16
functions, one in side the other. function (y) ... has a free variable, but the entire expression
refers to function (x) ..., and it doesn’t have a free variable: The only variable anywhere in its
body is x, which is certainly bound within function (x) ....
From this, we learn something: A pure function can contain a closure.
If pure functions can contain closures, can a closure contain a pure function? Using only
what we’ve learned so far, attempt to compose a closure that contains a pure function. If
you can’t, give your reasoning for why it’s impossible.
Pure functions always mean the same thing because all of their “inputs” are fully defined by their
arguments. Not so with a closure. If I present to you this pure function function (x, y) { return
x + y }, we know exactly what it does with (2, 2). But what about this closure: function (y) {
return x + y }? We can’t say what it will do with argument (2) without understanding the magic
for evaluating the free variable x.
The environment for (function (y) { return x })(2) is actually {y: 2, '..': {x: 1, ...}}.
'..' means something like “parent” or “enclosure” or “super-environment.” It’s function (x) ...’s
environment, because the function function (y) { return x } is within function (x) ...’s
body. So whenever a function is applied to arguments, its environment always has a reference to its
parent environment.
And now you can guess how we evaluate (function (y) { return x })(2) in the environment
{y: 2, '..': {x: 1, ...}}. The variable x isn’t in function (y) ...’s immediate environment,
but it is in its parent’s environment, so it evaluates to 1 and that’s what (function (y) { return
x })(2) returns even though it ended up ignoring its own argument.
function (x) { return x } is called the I Combinator or Identity Function. function (x) {
return (function (y) { return x }) } is called the K Combinator or Kestrel. Some people get
so excited by this that they write entire books about them, some are great, some–how shall I put
this–are interesting if you use Ruby.
http://www.amzn.com/0192801422?tag=raganwald001-20
https://leanpub.com/combinators
.
The first sip: Basic Functions 17
1 function (x) {
2 return function (y) {
3 return function (z) {
4 return x + y + z
5 }
6 }
7 }
1 function (x, y, z) {
2 return x + y + z
3 }
Only you call it with (1)(2)(3) instead of (1, 2, 3). The other big difference is that you can call
it with (1) and get a function back that you can later call with (2)(3).
The first sip: Basic Functions 18
The first function is the result of currying the second function. Calling a curried function with
only some of its arguments is sometimes called partial application. Some programming languages
automatically curry and partially evaluate functions without the need to manually nest them.
https://en.wikipedia.org/wiki/Currying
https://en.wikipedia.org/wiki/Partial_application
1 function (x) {
2 return function (x, y) {
3 return x + y
4 }
5 }
The function function (x, y) { return x + y } is a pure function, because its x is defined
within its own environment. Although its parent also defines an x, it is ignored when evaluating x
+ y. JavaScript always searches for a binding starting with the functions own environment and then
each parent in turn until it finds one. The same is true of:
1 function (x) {
2 return function (x, y) {
3 return function (w, z) {
4 return function (w) {
5 return x + y + z
6 }
7 }
8 }
9 }
When evaluating x + y + z, JavaScript will find x and y in the great-grandparent scope and z in the
parent scope. The x in the great-great-grandparent scope is ignored, as are both ws. When a variable
has the same name as an ancestor environment’s binding, it is said to shadow the ancestor.
This is often a good thing.
The first sip: Basic Functions 19
The effect is to insert a new, empty environment in between the global environment and your own
functions: {x: 1, '..': {'..': global environment }}. As we’ll see when we discuss mutable state,
this helps to prevent programmers from accidentally changing the global state that is shared by code
in every file when they use the var keyword properly.
1 function (diameter) {
2 return diameter * 3.14159265
3 }
What is this “3.14159265” number? Pi¹², obviously. We’d like to name it so that we can write
something like:
1 function (diameter) {
2 return diameter * Pi
3 }
In order to bind 3.14159265 to the name Pi, we’ll need a function with a parameter of Pi applied
to an argument of 3.14159265. If we put our function expression in parentheses, we can apply it to
the argument of 3.14159265:
1 (function (Pi) {
2 return ????
3 })(3.14159265)
What do we put inside our new function that binds 3.14159265 to the name Pi when evaluated?
Our circumference function, of course:
1 (function (Pi) {
2 return function (diameter) {
3 return diameter * Pi
4 }
5 })(3.14159265)
This expression, when evaluated, returns a function that calculates circumferences. It differs from
our original in that it names the constant Pi. Let’s test it:
1 (function (Pi) {
2 return function (diameter) {
3 return diameter * Pi
4 }
5 })(3.14159265)(2)
6 //=> 6.2831853
That works! We can bind anything we want in an expression by wrapping it in a function that is
immediately invoked with the value we want to bind.
¹²https://en.wikipedia.org/wiki/Pi
The first sip: Basic Functions 21
1 (function () {
2 // ... do something here...
3 })();
When an IIFE binds values to names (as we did above with Pi), retro-grouch programmers often call
it “let.”¹⁴ And confusing the issue, upcoming versions of JavaScript have support for a let keyword
that has a similar binding behaviour.
var
Using an IIFE to bind names works very well, but only a masochist would write programs this way
in JavaScript. Besides all the extra characters, it suffers from a fundamental semantic problem: there
is a big visual distance between the name Pi and the value 3.14159265 we bind to it. They should
be closer. Is there another way?
Yes.
Another way to write our “circumference” function would be to pass Pi along with the diameter
argument, something like this:
This differs from our example above in that there is only one environment, rather than two. We have
one binding in the environment representing our regular argument, and another our “constant.”
That’s more efficient, and it’s almost what we wanted all along: A way to bind 3.14159265 to a
readable name.
JavaScript gives us a way to do that, the var keyword. We’ll learn a lot more about var in future
chapters, but here’s the most important thing you can do with var:
1 function (diameter) {
2 var Pi = 3.14159265;
3
4 return diameter * Pi
5 }
The var keyword introduces one or more bindings in the current function’s environment. It works
just as we want:
1 (function (diameter) {
2 var Pi = 3.14159265;
3
4 return diameter * Pi
5 })(2)
6 //=> 6.2831853
You can bind any expression. Functions are expressions, so you can bind helper functions:
1 function (d) {
2 var calc = function (diameter) {
3 var Pi = 3.14159265;
4
5 return diameter * Pi
6 };
7
8 return "The circumference is " + calc(d)
9 }
Notice calc(d)? This underscores what we’ve said: if you have an expression that evaluates to a
function, you apply it with (). A name that’s bound to a function is a valid expression evaluating
to a function.¹⁵
¹⁵We’re into the second chapter and we’ve finally named a function. Sheesh.
The first sip: Basic Functions 23
You can bind more than one name-value pair by separating them with commas. For readability,
most people put one binding per line:
1 function (d) {
2 var Pi = 3.14159265,
3 calc = function (diameter) {
4 return diameter * Pi
5 };
6
7 return "The circumference is " + calc(d)
8 }
These examples use the var keyword to bind names in the same environment as our function. We
can also create a new scope using an IIFE if we wish to bind some names in part of a function:
1 function foobar () {
2
3 // do something without foo or bar
4
5 (function () {
6 var foo = 'foo',
7 bar = 'bar';
8
9 // ... do something with foo and bar ...
10
11 })();
12
13 // do something else without foo or bar
14
15 }
Naming Functions
Let’s get right to it. This code does not name a function:
The first sip: Basic Functions 24
It doesn’t name the function “repeat” for the same reason that var answer = 42 doesn’t name the
number 42. That snippet of code binds an anonymous function to a name in an environment, but
the function itself remains anonymous.
JavaScript does have a syntax for naming a function, it looks like this:
In this expression, bindingName is the name in the environment, but actualName is the function’s
actual name. This is a named function expression. That may seem confusing, but think of the binding
names as properties of the environment, not the function itself. And indeed the name is a property:
1 bindingName.name
2 //=> 'actualName'
In this book we are not examining JavaScript’s tooling such as debuggers baked into browsers, but
we will note that when you are navigating call stacks in all modern tools, the function’s binding
name is ignored but its actual name is displayed, so naming functions is very useful even if they
don’t get a formal binding, e.g.
Now, the function’s actual name has no effect on the environment in which it is used. To whit:
So “actualName” isn’t bound in the environment where we use the named function expression. Is it
bound anywhere else? Yes it is:
The first sip: Basic Functions 25
even is bound within the function itself, but not outside it. This is useful for making recursive
functions.
function declarations
We’ve actually buried the lede.¹⁶ Naming functions for the purpose of debugging is not as important
as what we’re about to discuss. There is another syntax for naming and/or defining a function. It’s
called a function declaration, and it looks like this:
1 function someName () {
2 // ...
3 }
In that it binds a name in the environment to a named function. However, consider this piece of
code:
¹⁶A lead (or lede) paragraph in literature refers to the opening paragraph of an article, essay, news story or book chapter. In journalism, the failure
to mention the most important, interesting or attention-grabbing elements of a story in the first paragraph is sometimes called “burying the lede.”
The first sip: Basic Functions 26
1 (function () {
2 return someName;
3
4 var someName = function someName () {
5 // ...
6 }
7 })()
8 //=> undefined
This is what we expect given what we learned about var: Although someName is declared later in the
function, JavaScript behaves as if you’d written:
1 (function () {
2 var someName;
3
4 return someName;
5
6 someName = function someName () {
7 // ...
8 }
9 })()
1 (function () {
2 return someName;
3
4 function someName () {
5 // ...
6 }
7 })()
8 //=> [Function: someName]
1 (function () {
2 var someName = function someName () {
3 // ...
4 }
5 return someName;
6 })()
That difference is intentional on the part of JavaScript’s design to facilitate a certain style of
programming where you put the main logic up front, and the “helper functions” at the bottom.
It is not necessary to declare functions in this way in JavaScript, but understanding the syntax and
its behaviour (especially the way it differs from var) is essential for working with production code.
The big trouble with expressions like this is that they may work just fine in your test environment
but work a different way in production. Or it may work one way today and a different way when
the JavaScript engine is updated, say with a new optimization.
Another caveat is that a function declaration cannot exist inside of any expression, otherwise it’s a
function expression. So this is a function declaration:
higher-order functions
As we’ve seen, JavaScript functions take values as arguments and return values. JavaScript functions
are values, so JavaScript functions can take functions as arguments, return functions, or both.
Generally speaking, a function that either takes functions as arguments or returns a function (or
both) is referred to as a “higher-order” function.
Here’s very simple higher-order function that takes a function as an argument:
Higher-order functions dominate JavaScript Allongé. But before we go on, we’ll talk about some
specific types of higher-order functions.
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¹⁸
¹⁸https://en.wikipedia.org/wiki/Combinatory_logic
The first sip: Basic Functions 29
If we were learning Combinatorial Logic, we’d start with the most basic combinators like S, K, and
I, and work up from there to practical combinators. We’d learn that the fundamental combinators
are named after birds following the example of Raymond Smullyan’s famous book To Mock a
Mockingbird¹⁹.
In this book, we will be using a looser definition of “combinator:” Higher-order pure functions
that take only functions as arguments and return a function. We won’t be strict about using only
previously defined combinators in their construction.
Let’s start with a useful combinator: Most programmers call it Compose, although the logicians call
it the B combinator or “Bluebird.” Here is the typical²⁰ programming implementation:
This is, of course, just one example of many. You’ll find lots more perusing the recipes in this book.
While some programmers believe “There Should Only Be One Way To Do It,” having combinators
available as well as explicitly writing things out with lots of symbols and keywords has some
advantages when used judiciously.
¹⁹http://www.amazon.com/gp/product/B00A1P096Y/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=
B00A1P096Y&linkCode=as2&tag=raganwald001-20
²⁰As we’ll discuss later, this implementation of the B Combinator is correct in languages like Scheme, but for truly general-purpose use in JavaScript
it needs to correctly manage the function context.
The first sip: Basic Functions 30
function decorators
A function decorator is a higher-order function that takes one function as an argument, returns
another function, and the returned function is a variation of the argument function. Here’s a
ridiculous example of a decorator:
Or:
not is a function decorator because it modifies a function while remaining strongly related to the
original function’s semantics. You’ll see other function decorators in the recipes, like once, mapWith,
and maybe. Function decorators aren’t strict about being pure functions, so there’s more latitude for
making decorators than combinators.
The first sip: Basic Functions 31
Building Blocks
When you look at functions within functions in JavaScript, there’s a bit of a “spaghetti code” look
to it. The strength of JavaScript is that you can do anything. The weakness is that you will. There
are ifs, fors, returns, everything thrown higgledy piggledy together. Although you needn’t restrict
yourself to a small number of simple patterns, it can be helpful to understand the patterns so that
you can structure your code around some basic building blocks.
composition
One of the most basic of these building blocks is composition:
It’s really that simple: Whenever you are chaining two or more functions together, you’re composing
them. You can compose them with explicit JavaScript code as we’ve just done. You can also generalize
composition with the B Combinator or “compose” that we saw in Combinators and Decorators:
If that was all there was to it, composition wouldn’t matter much. But like many patterns, using it
when it applies is only 20% of the benefit. The other 80% comes from organizing your code such that
you can use it: Writing functions that can be composed in various ways.
In the recipes, we’ll look at a decorator called once: It ensures that a function can only be executed
once. Thereafter, it does nothing. Once is useful for ensuring that certain side effects are not repeated.
We’ll also look at maybe: It ensures that a function does nothing if it is given nothing (like null or
undefined) as an argument.
Of course, you needn’t use combinators to implement either of these ideas, you can use if statements.
But once and maybe compose, so you can chain them together as you see fit:
The first sip: Basic Functions 32
partial application
Another basic building block is partial application. When a function takes multiple arguments, we
“apply” the function to the arguments by evaluating it with all of the arguments, producing a value.
But what if we only supply some of the arguments? In that case, we can’t get the final value, but we
can get a function that represents part of our application.
Code is easier than words for this. The Underscore²¹ library provides a higher-order function called
map.²² It applies another function to each element of an array, like this:
This code implements a partial application of the map function by applying the function function
(n) { return n * n } as its second argument:
The resulting function–squareAll–is still the map function, it’s just that we’ve applied one of its two
arguments already. squareAll is nice, but why write one function every time we want to partially
apply a function to a map? We can abstract this one level higher. mapWith takes any function as an
argument and returns a partially applied map function.
²¹http://underscorejs.org
²²Modern JavaScript implementations provide a map method for arrays, but Underscore’s implementation also works with older browsers if you
are working with that headache.
Another Random Document on
Scribd Without Any Related Topics
drunk noo—sin' he couldna keep his ain saydel the last time I saw him on
horseback, it's but richt he should pay for the lost ane—Keck, keck, keck.
Noo, Saunders, ye're a decent lad, sae satisfy yere conscience, and mind ye
gie up, in shape o' discoont, at the settlement, the amount o' aw the fictitious
items, barring the saydels and the grunstanes, though—mind that—barring
the saydels and the grunstanes. Noo, soom up and close, ye deevil—soom
up and close."
"Well, namesake, how are you?" said Twig to the old man who owned
the small voice, and who now emerged and became visible, as he crept
before us and opened the door.
"Oo, fine, Maister Twig, fine—did ye fin' the accoonts against Roaring
River and Hector's Folly estates aw correct, Mr Twig?"
"Yes, all correct, all correct; only you have charged me a saddle too
many."
The old withered anatomy looked with a quizzical leer of his eye at him,
as much as to say, "have you overheard me, master Twig?—but I am rich
and don't care."
"Saunders," cried the old man, "I say, Saunders, bring the ink and ae
chair for the custos and the gentlemen," as if we all could have sat upon
one; "and, Abrahaam," to one of the store negroes, "shool away that shell
into a corner, and gie them room."
"Shell," said I, in some surprise; "why, is that great mass all tortoise-
shell?"
"Here, sir," said the young man whom I had seen at the desk, as he
entered with writing materials in one hand, a chair for his Honour in the
other, and a Bible (as he naturally concluded that some depositions on oath
were to be taken) in his teeth. I paid no particular attention to him until he
startled me by suddenly dropping the chair on Twig's toes, exclaiming, as he
caught the Bible in his hand, "Gude hae a care o' us, Mr Brail, is this you
yeersell?"—And lo, who should stand before me, but our old friend
Lennox.
"Why, old shipmate, how are you?—I am glad to see you; but I thought
you had turned coffee-planter by this time?"
"And so I have, sir. My uncle there sends me up the end of every week to
superintend his plantation in the mountains; but I am here for the most part
of my time in the store, helping him. But where are you lodging, Mr Brail?
I hope you will permit me to call on you; for I see you are likely to be
engaged at present."
I told him where I staid, and in few words what the reader knows already
regarding my Jamaica expectations and the cause of my visit; farther, that I
was about leaving town, but that I would not fail having a chat with him
soon, as I should no doubt be often at the bay.
The custos, after taking our depositions, wrote to the admiral at Port-
Royal, and to correspondents of his at all the outports, with an outline of the
circumstances, in case any of His Majesty's ships should be there; and in the
mean time it was determined that poor Hause, after giving his underwriters
in Kingston notice of his calamity, should remain at Montego bay until it
was seen what should turn up. Here I must do old Jacob Munroe justice.
Before the meeting broke up, he in our presence invited him to stay in his
house as long as it suited him. Lennox, seeing I was surprised at this,
whispered in my ear, that, "Snell as his uncle was in business matters, the
auld-farrant body had a warm heart still to a fellow-creature in distress."
"Come along, Mr Brail," said Flamingo—"as we cannot make a start of
it this evening now, let us adjourn to our friend Sally's, and see what
entertainment she can provide for us; and then hey for Ballywindle at
daybreak to-morrow."
However, our troubles were not over for that day; for we had not
proceeded fifty yards on our way to our lodgings, when an ugly bloated
drunken-looking white man, with great flabby yellow cheeks, that shook as
he walked like flannel-bags full of jelly, and in a most profuse perspiration,
driven forth, I make no doubt, by a glorious rummer of grog, came up to us,
and touched both of us on the shoulder—most people are rather sensitive
regarding a touch thereabouts, so we faced suddenly round.
"I warn you bote, gentlemen, to attend one coroner's inquest at Jacob
Munroe's wharf."
"The deuce you do?" said I. "Pray, what authority have you for this, my
fine fellow?"
"Oh, we are nailed, Mr Brail," quoth Don Felix. "Crowner's Quest law is
not to be disputed—no use in kicking. So pray, my good man, do you want
any more jurors?"
"Oh, then, do you see that red-faced gentleman coming round the corner
there?"
"Then bone him instanter, or he will bolt." This was no less a personage
than Jacob Twig again. The man on this made a detour, and took our friend
in flank, but the moment Jacob saw him he seemed to suspect his object,
and began to walk down the street very fast, followed by the constable.
There was a narrow turning to the right, near to where we stood, that led
amongst a nest of nanny houses, as they are called, inhabited by brown free
people, which was quite closed up by a party washing clothes and a girl
milking a cow beyond them. How Jacob was to escape, if his evil genius
should prompt him to try this channel, I could not conceive. As yet his
sense of propriety had only allowed him to get into a very fast walk.
Shamming deafness, however, all the while, to the reiterated shouts of the
constable, to "stand in de Kin's name;" but the moment he opened the lane,
off he started, with the long skirts of his frogged coat streaming in the wind,
and his little glazed hat blazing in the sun like a meteor, or the steel
headpiece of one of Bonaparte's cuirassiers.
There was an old woman stooping down over her tub, right fronting him,
that is, facing him in an Irish fashion, for she looked t'other way from him,
and two younger ones, similarly employed on each side of her. How he was
to clear them and their tubs, and the cow beyond, was the puzzle, as the
projecting eaves of the two lines of small houses, whose inmates were thus
employed, nearly met overhead. However, we were not left long in
suspense. Massa Twig now quickened his pace, and clapping his hands on
the old lady's shoulders, cleared her and her tub cleverly by a regular leap-
frog, tipping the heads of the two young women on each flank with his toes,
and alighted at the feet of the girl who was milking the cow, which had not
time to start before he followed up the fun by vaulting on her back; and then
charged down the lane through the tubs and over the prostrate constable,
passing us like a whirlwind, the quadruped funking up her heels, and
tossing the dry sand with her horns, as if startled by a myriad of gad-flies.
Both Flamingo and I strained our eyes to follow him, as he flew along like
smoke, careering down the lane that ended in the sea.
"Why don't he throw himself off?" said I; "the frantic brute is making
straight for the water—it will drown him if he don't."
"Jump off, man—jump off," roared Don Felix. But in vain; for the next
moment there was Jacob Twig of the Dream, in St Thomas in the East,
flashing and splashing in the sea, cow and all, an Irish illustration of the
fable of Europa. Presently both biped and quadruped were in deep water,
when they parted company, and all that we could see was a glazed hat and a
red face, and a redder face and a pair of horns, making for the shore again
as fast as they could.
"Now, Twig is cheap of that," quoth Flamingo. "He is always aiming at
something out of the way, and certainly he has accomplished it this time;
but, see, there are people about him, so he is safe."
However, we were boned, and could not escape, so having lost sight of
him, we waited until the poor constable, a German, had gathered himself up
and joined us.—"And now, Master Constable, lead the way, if you please."
Next morning, Lennox came to see me off, and gave me all his news. I
was exceedingly glad to learn that the poor fellow was so happily situated,
and promised to call on him the first time I came to the bay.
While lounging about the piazza before breakfast, I noticed our friend
Quacco busily employed cleaning a fowling-piece.
"Wery clever leetle gone, for sartain, massa; but all de caps dem spoil,
sir. See de powder—percossion dem call—quite moist, and useless." By
this time he had fitted on one of the copper caps, and snapped the piece, but
it was dumb. "I am going to fill de caps wid fresh powder, massa; but really
dis percossion powder too lively, massa—only see"—and he gave a few
grains of it a small tip with the shank of the bullet mould, when it instantly
flashed up.
"Master Quacco," said I, "mind your hand; that is dangerous stuff. Tell
Mr Flamingo to be wary also, or he will be shooting people, for it is wrong
mixed, I am certain."
"Good morning."
"All ready for the start, I see," said Twig. "Why, Felix, what is Mr Brail's
man doing with your gun?"
"Cleaning it, and filling these caps anew with fresh percussion powder:
the old has mildewed, or got damp, he tells me. Indeed, the last time I shot,
it was not one in three that exploded."
"Mind how you play with those caps," said I; but before I could proceed
——
"Sally, make haste and get breakfast," bawled Twig. "Do you hear?"
"Yes, massa," squeaked Sal from the profundities of the back premises.
"Why, Felix," continued our friend, "there has been another burglary last
night: My spleuchan, as Rory Macgregor calls it, has been ravished of its
treasures."
"Better that than the horned animal that led me such a dance yesterday,"
quoth his friend, laughing. "But, joking apart, your man Twister must have
mistaken my tobacco for his own: He has emptied my tobacco-pouch, as
sure as fate, for none of my own people eat it; and the fellow has always
that capacious hole in his ugly phiz filled with it—with my prime patent
chewing tobacco, as I am a gentleman."
"Poo, poo! what does it signify?" said his ally. "A fair exchange, Twig—
tobacco for spurs, you know—a simple quid pro quo."
"Shame!" said Jacob; "I thought you were above picking up such
crumbs, Felix. But here is breakfast—so, come."
After proceeding about ten miles, the road wound into a cocoa-nut grove
close to the beach; indeed, the beach became the road for a good mile, with
the white surf rolling in and frothing over the beautiful hard sand, quickly
obliterating all traces of the wheels. Macadam was at a discount here. One
fine peculiarity of the West India seas is, independent of their crystal
clearness, they are always brimfull—no steamy wastes of slush and slime,
no muddy tideways. And overhead the sea-breeze was whistling through the
tall trees, making their long feather-like leaves rustle and rattle like a
thousand watchmen's alarms sprung in the midst of a torrent of rain, or a
fall of peas.
"Hillo! what is that?" as a cocoa-nut fell bang into the bottom of my gig,
and bounded out again like a foot-ball.
"Oh, only a cocoa-nut," said Twig, looking over his shoulder with the
usual knowing twist of his mouth, but without pulling up.
"A white man's certainly," quoth Flamingo, with all the coolness in life,
as if it had fallen a hundred miles from me, in place of barely shaving the
point of my nose: "But it has not hit you—a miss is as good as a mile, you
know; so suppose we go and bathe until they get dinner ready yonder. Let
us send the boys on to the tavern to order dinner. We are within two miles of
it, Jacob—eh?"
"No, no," quoth Twig; "come along a quarter of a mile further, and I will
show you a nook within the reef where we shall be safe from John Shark, or
rather the sharks will be safe from Flamingo's bones there. He would be like
a sackful of wooden ladles tossed to them. The fish would find him as
digestible as a bag of nutcrackers, seasoned with cocoa-nut shells—ah!—
but come along, come along. Oh such a bath, Mr Brail, as I will show you!"
We left the cocoa-nut grove, and when we arrived at the spot indicated
we got out to reconnoitre. There was a long reef, about musket-shot from
the beach at the widest, on the outside of which the swell broke in thunder,
the strong breeze blowing the spray and flakes of frothy brine back in our
faces, even where we stood.
"Now, if one were riding incautiously here, he might break his horse's
leg without much trouble," quoth Don Felix.
"Why, Jacob, speaking of horsemanship, how did you like your style of
immersion yesterday?—a novel sort of bathing-machine, to be sure."
"You be hanged, Felix," quoth his ally, with a most quizzical grin, as he
continued his peeling.
"Do you know I've a great mind to try an equestrian dip myself,"
persisted his friend. "Here, Twister—take off Monkey's saddle, and bring
him here."
"Oh, I see what you would be at," said Jacob. "Romulus, bring me Dare-
devil—so"—and thereupon, to my great surprise and amazement, it pleased
my friends to undress under a neighbouring clump of trees, and to send the
equipages and servants on to the tavern, about half a mile distant. They then
mounted two led horses, bare-backed, with watering bits, and, naked as the
day they were born, with the exception of a red handkerchief tied round Mr
Twig's head and down his redder cheeks, they dashed right into the sea.
As cavalry was an arm I had never seen used with much effect at sea, I
swam out to the reef, and there plowtering about in the dead water, under
the lee of it, enjoyed the most glorious shower-bath from the descending
spray, that flew up and curled far overhead, like a snow storm, mingled with
ten thousand miniature rainbows. I had cooled myself sufficiently, and was
leisurely swimming for the shore.
Here Flamingo's steed threw him, by rearing and pawing the water with
his fore legs and sinking his croup, so that his master, after an unavailing
attempt to mount him again, had to strike out for the beach, the animal
following, and splashing him, as if he wanted to get on his back by way of a
change.
"And that's what I call swimming," roared Don Felix. But he scarcely
had uttered the words when the horse made at him in earnest, and I thought
he had struck him with the near fore-foot.
"And that's what I call drowning," thought I, "or something deuced like
it."
Master Twister had been all this time enacting groom of the stole to the
two equestrian bathers, and so soon as he had arrayed them, we proceeded
to the tavern, dined, and after enjoying a cool bottle of wine, continued our
journey to Ballywindle, which we hoped to reach shortly after nightfall.
The sun was now fast declining; I had shot ahead of my two cronies and
their outriders, I cannot now recollect why, and we were just entering a
grove of magnificent trees, with their hoary trunks gilded by his setting
effulgence, when Twister's head (he had changed places with Cousin
Teemoty, and was driving me) suddenly, to my great alarm, gave a sharp
crack, as if it had split open, and a tiny jet of smoke puffed out of his mouth
—I was all wonder and amazement, but before I could gather my wits about
me, he jumped from the voiture into the dirty ditch by the side of the road,
and popped his head, ears and all, below the stagnant green scum, while his
limbs, and all that was seen of him above water, quivered in the utmost
extremity of fear.
As soon as Twig and Flamingo came up, I saw that neither they nor
Serjeant Quacco could contain themselves for laughter. The latter was
scarcely able to sit his mule—at length he jumped, or rather tumbled, oft,
and pulled Twister out by the legs; who, the instant he could stand, and long
before he could see for the mud that filled his eyes, started up the road like
a demoniac, shouting, "Obeah, Obeah!" which so frightened the sumpter-
mule, that he was by this time alongside of, that she turned and came down,
rattling past us like a whirlwind, until she jammed between the stems of two
of the cocoa-nut trees with a most furious shock, when lo! the starboard
portmanteau she carried burst and blew up like a shell, and shirts, trowsers,
nightcaps, and handkerchiefs, of all colours, shapes, and sizes, were shot
hither and thither, upwards and downwards, this side and that, until the
neighbouring trees and bushes were hung with all manner of garments and
streamers, like a pawnbroker's shop.
"Ay, ay," shouted Flamingo, who had dismounted and was endeavouring
to catch the mule as she careered through the wood towards the sea, kicking
and flinging in a vain attempt to disentangle herself from the other
portmanteau, which had now turned under her belly, and the sumpter-saddle
that hung at her side; "and there goes your kit, Jacob, an offering to
Neptune bodily, mule and all"—as the poor beast dashed into the surf, after
having threaded through the stems of the trees without farther damage.
The cause of all this was no longer a mystery, for I had made my guess
already; but presently I was enlightened, if need had been, by friend
Quacco. He had, it appeared, with Mr Twig's sanction, charged certain of
the pieces of patent tobacco in the spleuchan with several small quantities
of detonating powder, enclosed in the glass-brittle seeds of the sand-box, as
a trap for Master Twister, who was suspected of making free with it—the
issue, so far as he was concerned, has been seen; but in the hurry of coming
away and packing up, instead of placing the bottle containing the powder in
Mr Flamingo's gun-case, where it should have been, he hurriedly dropped it
into his portmanteau, as Twister was packing it; so that when the sumpter
mule jambed between the trunks of the trees after it took fright it exploded
and blew up.
"I say, Massa Twister, you never make free with my patent tobacco?"
"Oh, oh, oh!" roared poor Twister, holding his jaws with both hands
—"Oh, massa, my tongue blow out—my palate blow down—de roof of my
mouse blow up—and all my teets blow clean gan—Oh no, massa, never,
never will touch him no more, massa—never, never no more."
"Now, Mr Brail, give your horse the rein—let him pick his own steps, if
you please; for the road is cruelly cut up by the weather and waggons
hereabouts, and none of the widest either, as you may feel, for you can't see
it."
I took his advice, and soon found the advantage of it, as we came to
several groups of negroes sitting invariably on the inner side of the road,
which I would certainly have been tempted to avoid at my own peril; but
my horse was not so scrupulous, for he always poked his nose between
them and the bank, and snorted and nuzzled until they rose and shuffled out
of our way, either by creeping to the side next the ravine, or up on the bank;
presently the road widened, and we got along more comfortably.
I could not but admire the thousands and tens of thousands of fire-flies
that spangled the gulf below us, in a tiny galaxy; they did not twinkle
promiscuously, but seemed to emit their small green lights by signal,
beginning at the head of the ravine, and glancing all the way down in a
wavy continuous lambent flash, every individual fly, as it were, taking the
time from his neighbour ahead. Then for a moment all would be dark again,
until the stream of sparkles flowed down once more from the head of the
valley, and again disappeared astern of us; while the usual West India
concert of lizards, beetles, crickets, and tree toads, filled the dull ear of
night with their sleepy monotony.
"I must heave to until I get my bat's eyes shipped, Mr Twig," said I—"I
can't see an inch before my nose."
"Then send Flamingo ahead, my dear fellow, for if he sees the length of
his we shall do—his proboscis is long enough to give us warning of any
impediment."
"Come, you must get on, though, since we have not room to pass—no
time to study natural philosophy," said Twig; and I once more fanned my
horse into a gentle trot, with very much the sensation of one running
through an unknown sound in the night, without either chart or pilot.
After a little, I saw a cluster of red fire-flies, as I thought, before us. "Oh,
come along, I see now famously."
The rain now began to descend in torrents, with a roar like a cataract.
—"What uncommonly pleasant weather," thought I. "Why, Mr Twig, you
see I am a bad pilot—so, do you think you have room to pass me now? for,
to say the truth, I don't think I can see a yard of the road, and you know I
am an utter stranger here."
He could not pass, however, and at length I had to set Master Teemoty to
lead the horse. Presently I heard a splash.
"De Fairywell no tell lie, massa—De Devil's Golly,[1] dat has been dry
like one bone for tree mont, hab come down, massa—dat all."
"Ah!" said Twig,—"and we are to sleep here in the cold and damp, I
suppose—the fellow's a fool, and must have got off the path into some
puddle. We are a mile from the gully—let me see"—and before you could
have turned, Massa Jacob was splashing up to the knees alongside of Massa
Teemoty. However, he was right—it was only a streamlet—and we got
across without much difficulty; but in ten minutes the roar of a large torrent,
heard hoarse and loud above the sound of the rain, gave convincing proof
that we were at length approaching the gully—moreover, that it was down,
and that with a vengeance. We now found ourselves amongst a group of
negroes, who had also been stopped by the swollen stream. There was a
loud thundering noise above us on the left hand, which (we had now all
alighted) absolutely shook the solid earth under our feet, as if in that
direction the waters had been pitched from the mountain side headlong over
a precipice. From the same quarter, although quite calm otherwise, a strong
cold wind gushed in eddies and sudden gusts, as if from a nook or valley in
the hill-side, charged with a thick, wetting spray, that we could feel curling
and boiling about us, sometimes stronger and sometimes weaker, like the
undulations of a London fog. Close to our feet we could hear the river
tearing past us, with a great rushing and gurgling, occasionally intermingled
with the rasping and crashing of trees and floating spars, as they were
dashed along on the gushes and swirls of the stream; while every now and
then the warm water (for so it felt in contrast with the cold damp night-
breeze) surged a foot or two beyond its usual level, so as to cover us to the
ankle, and make us start back; and immediately ebb again. It was some
time, amidst this "groan of rock and roar of stream" before we could make
out any thing that the negroes about us said.
"Why, you may have mud of all consistencies, and of any depth."
"True, water beds are all the fashion now, and possibly mud ones might
be an improvement; but had we not better try back," I continued, as I really
began to think it no joke remaining where we were all night.
"Wery good plan, wery good plan," shouted Cousin Teemoty; "but"——
"But, but, but—oh, confound your buts," roared Twig; "but what, sir?"
"Oh," said Tim, whose dignity was a little hurt, "noting, noting—no
reason why massa should not return—only Carrion-crow gully dat we lef
behind, will, by dis time, be twenty time more down as dis, dat all."
"The deuce you do! then you have good eyes," quoth Felix.
"I say, Flamingo, pick me up a stone that I can sling, and hold your
tongue; do, that's a good fellow."
"Never you mind, Flam, but pick me up a stone that I can tie a string to,
will ye?—There, you absurd creature, you have given me one as round and
smooth as a cricket ball; how can I fasten a string round it?—give me a
longish one, man—one shaped like a kidney-potato or your own nose, you
blundering good-for-nothing—ah, that will do. Now, some string, boys—
string."
Every negro carries a string of one kind or another with him in the crown
of his hat, and three or four black paws were in an instant groping for Jacob
Twig's hand in the dark with pieces of twine.
He got the cards, and all was silent except the turmoil of the elements for
a few seconds. At length, in a temporary lull of the rain, I thought I heard
the shout of a human voice from the opposite bank, blending with the roar
of the stream.
"Ay, ay," cried Jacob—"there, don't you hear people on the other side?—
so here goes."
"Hillo, who the deuce has knocked off my hat?" cried Flamingo.
"Why don't you stand on one side then, or get yourself shortened by the
knees? such a steeple is always in the way," bawled Twig. "Leave me scope
to make my cast now, will ye—don't you see I want to throw the stone with
the cards across amongst the people on the opposite bank—There," and he
made another cast—"ah, I have caught a fish this time—more string,
Teemoty—more string—or they will drag it out of my hand. Now some one
has got a precious pelt on the skull with the kidney potato, Felix, as I am a
gentleman; but he understands us, whoever he may be that has got hold of it
—feel here—how he jerks the string without hauling on it—wait—wait!"
Presently the line was let go at the opposite side, and our friend hauled it
in—it had been cut short off, and instead of the stone and cards, a negro
clasp knife was now attached to it.
The scene was striking enough. A quantity of dry splinters of some kind
of resinous wood being heaped on the fire, it now blazed up brilliantly in
massive tongues of flame, that glanced as they twined up the fissures,
scorching the lichens into sudden blackness, and licking, like fiery serpents,
the tortuous fretwork of naked roots depending from the trees that grew on
the verge of the bank above, which spread like a net over the face of the
bald grey rock; and lighting up the fringe of dry fibres depending from the
narrow eave of red earth that projected over the brink of the precipice,
under which the bank appeared white and dusty, but lower down, where wet
by the beating of the rain, it was red, and glittering with pebbles, as if it had
been the wall of a salt mine in Cheshire.
The bright glare, and luminous smoke of the fire, in which a number of
birds, frightened from their perches, glanced about like sparks, blasted the
figures of such of the negroes as stood beyond it into the appearance of
demons—little Rory Macgregor looking, to use his own phrase, like the deil
himsell, while those of them who intervened between us and the fire seemed
magnified into giants—their dark bodies edged with red flame; while every
tree, and stock, and stone appeared as if half bronze and half red-hot iron—
a shadock growing close by, looked as if hung with clusters of red-hot
cannon balls.
Our own party was very noticeable. I was leaning on the neck of my gig-
horse, with his eyes glancing, and the brazen ornaments of his harness
flashing like burnished gold. Abreast of me were Massas Twig, Flamingo,
and Cosin Teemoty, wet as muck, and quite as steamy, to use a genteel
phrase, with our cold drenched physiognomies thrust into the light, and the
sparkling rain-drops hanging at our noses; Jacob's glazed hat glancing as if
his caput had been covered with a glass porringer; while the group of
mounted negroes and led horses in the background, with the animals
pawing and splashing in the red stream that ran rippling and twinkling
down the road, and the steam of our rapid travelling rising up like smoke
above them, gave one a very lively idea of a cavalry picquet on the qui vive.
As we looked, the bodies of two bullocks and a mule came past, rolling
over and over, legs, tails, and heads, in much admired confusion.
On the starboard hand the ravine sunk down as dark as Erebus; and now
the weather clearing, disclosed in that direction, through storm-rents of the
heavy clouds, shreds of translucent blue sky, sparkling with bright stars; and
lo! the fair moon once more!—her cold, pale-green light struggling with the
hot red glare of the fire, as she reposed on the fleecy edge of that dark——
"An owl, Master Brail—an owl which the light has dazzled, and that has
flown against your head by mistake—but catch, man—catch"—as he
sprang into the water up to the knees to secure my hat, that the bird of
Minerva had knocked off—and be hanged to it. "An owl may be a wise
bird, but it is a deuced blind one to bounce against your head as
unceremoniously as if it had been a pumpkin or a calabash."
Little Rory Macgregor had all this time remained at the edge of the
stream, squatted on his hams like a large bull-frog, and apparently, if we
could judge from his action, shouting at the top of his voice; but it was all
dumb show to us, or very nearly so, as we could not make out one word that
he said.
Flamingo confronted him, assuming the same attitude. "See how he has
doubled up his long legs—there, now—said the grasshopper to the frog,"
quoth Twig to me. Here friend Felix made most energetic signs, a-la
Grimaldi, that he wanted some food and drink.
The puzzle now was, "how were the good things to be had across?" but
my friends seemed up to every emergency. In a moment Flamingo had
ascended a scathed stump that projected a good way over the gully, with
Twig's string and stone in his hand; the latter enabling him to pitch the line
at Rory's feet, who immediately made the joint of meat fast, which Don
Felix swung across, and untying it, chucked it down to us who stood below;
the fowl, and the rum, and the bottle of lemonade, or beverage, as it is
called in Jamaica, were secured in like manner.
"So," said our ally, "we shan't starve for want of food, anyhow, whatever
we may do of cold." But we were nearer being released than we thought;
for suddenly, as if from the giving way of some obstruction below that had
dammed up the water in the gully, it ebbed nearly two feet, of which we
promptly availed ourselves to pass over to the other side of the Devil's
Gully. But, notwithstanding, this was a work of no small difficulty, and
even considerable danger. Being safely landed, and having thanked Mr
Macgregor, who owned a very fine coffee property in the neighbourhood,
for his kindness, we mounted our vehicles once more, and drove rapidly out
of the defile, now lit by the moon, and in a quarter of an hour found
ourselves amongst the Works; that is, in the very centre of the mill-yard of
Ballywindle.
CHAPTER VIII.
MY UNCLE.
Here, late as it was, all was bustle and activity; the boiling-house was
brilliantly lighted up, the clouds of white luminous vapour steaming
through the apertures in the roof; while the negroes feeding the fires,
sheltered under the stokehole arches from the weather, and almost
smothered amongst heaps of dry cane-stalks, or trash, as it is called, from
which the juice had been crushed, looked in their glancing nakedness like
fiends, as their dark bodies flitted between us and the glowing mouths of
the furnaces. A little farther on we came to the two cone-roofed mill-houses,
one of which was put in motion by a spell of oxen, the other being worked
by mules, while the shouting of the drivers, the cries of the boilermen to the
firemakers to make stronger fires, the crashing of the canes as they were
crushed in the mills, the groaning and squealing of the machinery, the
spanking of whips, the lumbering and rattling of wains and waggons, the
hot dry axles screaming for grease, and the loud laugh and song rising
occasionally shrill above the Babel sounds, absolutely confounded me.
On seeing us, the overseer hastily dismissed his levee, and ordered his
people to take charge of our horses.
"Oh, yes, sir—all alone up at the great house there," pointing to a little
shed of a place, perched on an insulated rocky eminence, to the left of the
abode he himself occupied, which overlooked the works and whole
neighbourhood.
This hill, rising as abruptly from the dead level of the estate as if it had
been a rock recently dropped on it,—rather a huge areolite, by the way,—
was seen in strong relief against the sky, now clear of clouds, and
illuminated by the moon.
"Cold comfort in prospect for me," thought I; "but allons, let us see,"—
and we moved on until we came to a small outhouse beside a gate, which
seemed to open into the enclosure, in the centre of which stood the solitary
building.
I gave in to the frolic of the moment, and slipped silently up the few
steps of the steep stair, as I was desired. There, on the landing-place,
reposed, al fresco, Uncle Lathom, sure enough—his chair swung back, his
head resting on the door-post, and his legs cocked up, as already described,
on the outer railing of the stair. He was sound asleep, and snoring most
harmoniously; but just as I stole up, and was in the very act of creeping
beneath the yoke to get past him, I touched his limbs slightly; but the start
made him lose his balance and fall back into the house, and there I was, like
a shrimp in the claws of a lobster, firmly locked in the embrace of my
excellent relative—for although his arms were not round my neck, his legs
were.
"Who is that, and what is that, and what have I got hold of now?" roared
Uncle Latham, in purest Tipperary.
"It is me, sir," I shouted as loud as I could bellow; for as we rolled over
and over on the head of the stair, I discovered he had spurs on; but the devil
a bit would he relax in his hold of my neck with his legs,—"me, your
dutiful nephew, Benjamin Brail—but, for goodness sake, mind you have
spurs on, uncle."
"Ah," he said, "it must be all a drame, and looking at people drinking,
has made me dry—so let me wet my whistle a bit—here's the beverage, so
—now—ah, this is the rum bottle—I know it by the smell—and what the
devil else should I know it by in the dark before tasting, I should like to
know?—he! he!—if I could but lay my paw on a tumbler now, or a glass of
any kind—not one to be found, I declare—Murphy, you villain, why don't
you come when I call you, sirrah?"—There was now a concerto of
coughing, and sneezing, and oich, oiching, and yawning, as if from beneath.
—"Will these lazy rascals never make their appearance?" continued Mr
Frenche, impatiently—"Well, I cannot find even a teacup to make some
punch in—hard enough this in a man's own house, any how—but I have the
materials—and—and—now, for the fun of the thing—I will mix it Irish
fashion—deuce take me if I don't," and thereupon I heard him gurgle,
gurgle something out of one bottle—and then a long gurgle, gurgle, gurgle,
out of another, apparently, for the gurgling was on different keys,—both
followed by a long expiration. He then gave several jumps on the floor.
He had, as I guessed, first swallowed the raw caulker from the rum
decanter, and then sent down the lemonade to take care of it. "Now, that
rum is very strong—stop, let me qualify it a bit with some more beverage—
how thirsty I am, to be sure—murder!—confound that wide-necked
decanter." Here I could hear the liquid splash all over him. "There—so
much for having a beautiful small mouth—why, Rory Macgregor, with that
hole in his face from ear to ear, would have drunk you the whole bottle
without spilling a drop, and here am I, suffocated and drowned entirely, and
as wet as if I had been dragged through the Bog of Allan—Murphy, you
scoundrel?"
Anon, two negro servants, stretching and yawning, each with a candle in
his hand, made their appearance, one in his shirt, with his livery coat
hanging over his head, the cape projecting forward, and a sleeve hanging
down on each side; the other had his coat on certainly, but stern foremost,
and not another rag of any kind or description whatever, saving and
excepting his Kilmarnock nightcap.
The gentleman, evidently not broad awake yet, was dressed in light-
coloured kerseymere small-clothes, top-boots, white vest, and blue coat—
he was very bald, with the exception of two tufts of jet-black hair behind his
ears, blending into very bushy whiskers. His forehead was round and
beetling—you would have said he was somewhat bullet-headed; had the
obduracy of the feature not been redeemed by his eyebrows, which were
thick, well arched, and, like his hair and whiskers, jet-black—and also by
his genuine Irish sparklers, dark, flashing, and frolicsome.
His complexion was of the clearest I had seen in Jamaica—I could never
have guessed that he had been above a few weeks from the "First gem of
the Sea,"—and his features generally large and well formed. There was a
playful opening of the lips every now and then, disclosing nice ivory teeth,
and evincing, like his eyes, the native humour of his country.
"Pray, can you tell me, Murphy, if any one has arrived here—any
stranger come into the house while I slept;" then aside, as the players say,
"or has it really and truly been all a drame?"
"You didn't, oh—there, do you see any thing now?" said my uncle—as
he took the candle out of the black paw, and put the lighted end, with all the
composure in life, into Murphy's open mouth, where it shone through his
cheeks like a rushlight in a winter turnip, until it burned the poor fellow,
and he started back, overturning his sleepy coadjutor, Dennis, headlong on
the floor. On which signal, Twig and Flamingo, who were all this time
coiled up like two baboons below the sideboard, choking with laughter,
caught Uncle Frenche by the legs, a limb a piece, who thereupon set up a
regular howl—"ach, murder! murder! it is abducted, and ravished, and
married against my will I shall be—murder!"—as he in turn capsized over
the prostrate negroes, and all was confusion and vociferation once more—
until my two travelling friends, who had cleverly slipped out of the mêlée,
while my uncle was clapperclawing with his serving-men, returned from the
pantry, whither they had betaken themselves; and now stood on the original
field of battle, the landing-place of the stair, each with a lighted candle in
his hand, and making believe to be in great amazement at the scene before
them.
"Uproar?" shouted Uncle Lathom, still sitting on the floor, scratching his
poll—"uproar, were you pleased to say?—pray, who the mischief are you,
gentlemen, who conceive yourselves privileged to speak of any little noise I
choose to make in my own house?—tell me in an instant, or by the powers I
will shoot you for a brace of robbers"—clapping the lemonade decanter,
which had all this time escaped by a miracle, to his shoulder, blunderbuss
fashion.
Here gradually slewing himself round on his tail, and rubbing his eyes,
he at length confronted me, as I sat coiled up behind the leaf of the door
—"Why, here is a second edition of my drame." The very absurd expression
of face with which he said this, and regarded me, fairly upset my gravity,
already heavily taxed, and losing all control, I laughed outright.
"Another of them! and who may you be, young gentleman?—you seem
to find yourself at home, at any rate, I think."
ebookbell.com