100% found this document useful (2 votes)
49 views

(Ebook) Learning Functional Programming: Managing Code Complexity by Thinking Functionally by Jack Widman ISBN 9781098111748, 1098111745 - Download the full ebook now for a seamless reading experience

The document provides information about various ebooks related to functional programming, including titles by Jack Widman and others. It highlights the benefits of functional programming, focusing on concepts like immutability and referential transparency, which help manage code complexity. The text emphasizes that functional programming can simplify coding practices and reduce bugs by minimizing mutable state.

Uploaded by

schozamkkz25
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (2 votes)
49 views

(Ebook) Learning Functional Programming: Managing Code Complexity by Thinking Functionally by Jack Widman ISBN 9781098111748, 1098111745 - Download the full ebook now for a seamless reading experience

The document provides information about various ebooks related to functional programming, including titles by Jack Widman and others. It highlights the benefits of functional programming, focusing on concepts like immutability and referential transparency, which help manage code complexity. The text emphasizes that functional programming can simplify coding practices and reduce bugs by minimizing mutable state.

Uploaded by

schozamkkz25
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 81

Instant Ebook Access, One Click Away – Begin at ebooknice.

com

(Ebook) Learning Functional Programming: Managing


Code Complexity by Thinking Functionally by Jack
Widman ISBN 9781098111748, 1098111745

https://ebooknice.com/product/learning-functional-
programming-managing-code-complexity-by-thinking-
functionally-34883372

OR CLICK BUTTON

DOWLOAD EBOOK

Get Instant Ebook Downloads – Browse at https://ebooknice.com


Instant digital products (PDF, ePub, MOBI) ready for you
Download now and discover formats that fit your needs...

Start reading on any device today!

(Ebook) Learning Functional Programming (Fifth Early Release) by Jack Widman ISBN
9781098111755, 9781098111748, 1098111753, 1098111745

https://ebooknice.com/product/learning-functional-programming-fifth-early-
release-43470558

ebooknice.com

(Ebook) Functional Python Programming...Efficient Python Code by Lott S.

https://ebooknice.com/product/functional-python-programming-efficient-python-
code-56115518

ebooknice.com

(Ebook) Thinking Functionally With Haskell by Richard Bird ISBN 9781107087200,


9781107452640, 1107087201, 1107452643

https://ebooknice.com/product/thinking-functionally-with-haskell-10508692

ebooknice.com

(Ebook) Learning Java Functional Programming by Reese, Richard M ISBN 9781783558483,


1783558482

https://ebooknice.com/product/learning-java-functional-programming-55591800

ebooknice.com
(Ebook) Functional Programming in C#: How to write better C# code by Enrico Buonanno
ISBN 9781617293955, 1617293954

https://ebooknice.com/product/functional-programming-in-c-how-to-write-better-c-
code-6855324

ebooknice.com

(Ebook) Learning Scala: Practical Functional Programming for the JVM by Jason Swartz
ISBN 9781449367930, 1449367933

https://ebooknice.com/product/learning-scala-practical-functional-programming-
for-the-jvm-6545280

ebooknice.com

(Ebook) Learning Elixir: Unveil many hidden gems of programming functionally by


taking the foundational steps with Elixir by Kenny Ballou ISBN 9781785881749,
9781849513623, 9781849698764, 9781849696524, 9781849695220, 1785881744, 1849513627,
1849698767, 1849696527
https://ebooknice.com/product/learning-elixir-unveil-many-hidden-gems-of-
programming-functionally-by-taking-the-foundational-steps-with-elixir-37613916

ebooknice.com

(Ebook) Pro Functional PHP Programming: Application Development Strategies for


Performance Optimization, Concurrency, Testability, and Code Brevity by Rob Aley
ISBN 9781484229576, 1484229576

https://ebooknice.com/product/pro-functional-php-programming-application-
development-strategies-for-performance-optimization-concurrency-testability-and-
code-brevity-6766936

ebooknice.com

(Ebook) Functional Programming with C#: Create more supportable, robust, and
testable code (Second Early Release) by Simon J. Painter ISBN 9781492097013,
9781492097068, 1492097012, 1492097063

https://ebooknice.com/product/functional-programming-with-c-create-more-
supportable-robust-and-testable-code-second-early-release-44883856

ebooknice.com
Learning Functional
Programming
Managing Code Complexity by Thinking
Functionally

With Early Release ebooks, you get books in their earliest form—the
author’s raw and unedited content as they write—so you can take
advantage of these technologies long before the official release of these
titles.

Jack Widman, PhD


Learning Functional Programming
by Jack Widman
Copyright © Jack Widman. All rights reserved.
Printed in the United States of America.
Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North,
Sebastopol, CA 95472.
O’Reilly books may be purchased for educational, business, or sales
promotional use. Online editions are also available for most titles
(http://oreilly.com). For more information, contact our
corporate/institutional sales department: 800-998-9938 or
[email protected].

Editors: Mary Preap and Shira Evans

Production Editor: Kate Galloway

Interior Designer: David Futato

Cover Designer: Karen Montgomery

Illustrator: Kate Dullea

June 2022: First Edition

Revision History for the First Edition


2021-08-30: First Release

See http://oreilly.com/catalog/errata.csp?isbn=9781098111755 for release


details.
The O’Reilly logo is a registered trademark of O’Reilly Media, Inc.
Learning Functional Programming, the cover image, and related trade dress
are trademarks of O’Reilly Media, Inc.
The views expressed in this work are those of the author, and do not
represent the publisher’s views. While the publisher and the author have
used good faith efforts to ensure that the information and instructions
contained in this work are accurate, the publisher and the author disclaim all
responsibility for errors or omissions, including without limitation
responsibility for damages resulting from the use of or reliance on this
work. Use of the information and instructions contained in this work is at
your own risk. If any code samples or other technology this work contains
or describes is subject to open source licenses or the intellectual property
rights of others, it is your responsibility to ensure that your use thereof
complies with such licenses and/or rights.
978-1-098-11168-7
Chapter 1. What Is Functional
Programming?

A NOTE FOR EARLY RELEASE READERS


With Early Release ebooks, you get books in their earliest form—the
author’s raw and unedited content as they write—so you can take
advantage of these technologies long before the official release of these
titles.
This will be the 1st chapter of the final book. Please note that the
GitHub repo will be made active later on.
If you have comments about how we might improve the content and/or
examples in this book, or if you notice missing material within this
chapter, please reach out to the author at
[email protected].

Functional programming? Functors? Monads? “I’m not a mathematician!”


you might say. How can I learn these esoteric concepts? And why would I
want to? These concerns are totally understandable. But the truth is you
don’t need to be a mathematician to be a functional programmer. The
fundamental concepts of functional programming are easy to understand
when presented in a clear, straightforward way. And that is what this book
is about. Making functional programming understandable and practical. But
why would you want to learn functional programming?
Picture this. It’s 10 pm and you are totally stuck while trying to fix a bug in
a program you need to hand in in the morning. The problem seems to be
centered around a variable called ratio. The problem is that depending on
the state of the system you are modeling, the variable ratio keeps changing.
Your frustration builds. Or you have a deadline at work and there is an
elusive bug in your microservice that you are chasing down. The problem
seems to be in two nested for loops in which variables are modified in a
fairly complex way. The logic is complex and you don’t quite see the
solution. If only there were a way to write programs in a way in which the
value of variables would not change! Functional Programming to the
rescue.
So, what is functional programming? What makes one language functional
and another not functional? The truth is that to some extent it is a matter of
degree. You don’t have to follow every principle that falls under the
heading of functional programming. Some people will try to follow all of
them, and others will pick and choose. It is totally up to you. Functional
Programming (FP), is a paradigm, an approach to programming, a way of
breaking up the world and putting it back together in code. It involves both
how we organize that piece of the world we are modeling and how we
organize and structure the code.
In order to better describe the essence of FP, let us begin by contrasting it
with Imperative Programming and Object Oriented Programming (OOP).
There are others, such as Logic Programming, but the three mentioned, are
by far, the most popular. Imperative is what you might think of as plain old
programming. It’s what programming was before functional and object
oriented programming. In imperative programming, you write functions or
procedures, use for loops and while loops and mutate state often. Languages
like C or Pascal are typical imperative programming languages. Then there
is OOP. Currently the most popular paradigm, OOP is a process of
modeling the world as a collection of objects. Each object has state and
methods, which are operations representing behaviors specific and relevant
to that object. As the program runs, the state of the objects changes. The
benefits of this approach include encapsulation, which means the state and
methods that belong to an object, exist, at the code level, within the object.
This is a much better idea than letting the state be scattered all throughout
the code because managing mutable state is just plain difficult. You have
multiple variables, possibly many, and their values are changing. The
approach of FP is to acknowledge this and attempt to minimize, if not
erradicate, changing state altogether. Ultimately, it is not always possible to
have no mutable state at all and so the standard FP approach is to isolate
that part of the code that mutates state.

Immutability
The single most important aspect of FP is immutability.1 Generally
speaking, this means a lack of change. Something is considered immutable,
if we cannot modify it in some way. In functional programming this means
a few things. Once a variable is set, its value cannot be changed. If x = 3 at
the beginning of a program, it has that value for the remainder of the
program. Does that mean that if a program is written in a functional style,
and a person’s age changes, this change cannot be modeled? Of course not.
That would be a disaster for functional programming. There are techniques
like copying that allow us to efficiently, manipulate our code, without ever
mutating state. Consider the following simple for loop in Java that prints the
numbers 0 to 99.
Java

for (int i = 0; i < 100; i++) {


System.out.println( i );
}

This type of code occurs all the time. You might wonder how we could
possibly express this in an immutable way. It seems that the essence of this
code is the changing of the value of the variable i. A common approach in
FP is to use recursive functions. A recursive function is a function that calls
itself. In the case of the above code, you can put the code in a function and
then call the function on the next value of i, in each iteration. It might look
something like:
Java

void f(int i) {
if (i > 99) {
return;
}
else {
System.out.println( i)
return f(i+1)
}
}

f(0)

Now this code is a little longer but it does not mutate any state. If you know
a little about FP, you might know that the return type of void is a sure
giveaway that there will be side effects.2 A side effect is anything that
affects the program outside of the function. Things like writing to a file,
throwing an exception or modifying a global variable. The above example
is just meant to show one way of avoiding the mutation of state. You have
probably been mutating state your whole programming career and it likely
seems indispensible. But remember two things

NOTE
1) It feels very natural to mutate state.
2) Mutating state is a major cause of code complexity.

The good news is that with practice, the FP way will feel just as natural.
Let us consider another technique for avoiding the mutation of state.
Imagine you have an object, which has a property, or field and it changes.
Remember, I never made the claim that this never happens. That would be
absurd. The point is to model this situation without mutating a variable in
the code. Let us consider a Java example first.
Java

public class Person {


private final String name;
private final int age;

public Person(String name, int age) {


this.name = name;
this.age = age;
}

public static void main(String[] args) {


Person person = new Person("Carl", 32);
//A year passes
Person changedPerson = new Person("Carl", 33);
System.out.println(changedPerson);
}
}

Instead of modifying the value of age in the Person object, we create a


new object and initialize the new age value in the constructor. Let us
now look at an example in Python.

Python

class Person:
def __init__(self,name,age):
self.name = name
self.age = age

def main():
person = Person("John",22)
#One year later
changedPerson = Person("John",23)

One year passes and we need the person object to reflect this. But we can’t
modify the value age. So we create another immutable object with the age
variable initialized to 23
Let us now look at an example in Scala.
Scala

case class Person(name: String, age: Int)


val person = Person("Katherine", 25)
val changedPerson = person.copy(age=26)
Declare a case class

Create an instance of the class

This line makes a new instance of Person and initializes age to 26. No
state has been mutated.

You may recall that I believe immutability to be the most important aspect
of FP. Lots of mutable state in a program is a source of many bugs. It’s
simply not easy to keep track of all the changing values. Above, we have
seen some examples of how to get around the apparent need to mutate state.
It takes some getting used to but with a little practice, using these
techniques may even start to seem natural.

Referential Transparency
You have seen some examples of immutability. Now we will look another
crucial piece of what makes up FP, Referential Transparency. We say an
expression is referentially transparent if we can replace it with its value
anywhere in the code. You might think, upon first hearing about this, that
you can always do this. Let us consider a simple example of a non
referentially transparent function.
Java

today()

If I call this function, and get, say May 29th, 2021, and I replace its body
with this value, and then call it tomorrow, I will get the wrong answer. It
might seem impossible to express this function as a referentially transparent
function but we will see how to approach this in a functional way later in
the book.
Here are a few more examples of non referential transparency:
A function that returns a random number. Obviously you can’t
replace the body of the function with a value you get when you call
it once.
A function that throws and exception. Exceptions are generally
avoided in FP. I will come back to that later.

It probably seems that if we throw out all non referentially transparent


functions (and that is what we will aim for), that we will lose some valuable
capabilities. It seems there will be many useful things we need to express
but will not be able to. Rest assured, there are functional ways of expressing
these things and once you get use to them, they may even seem more
uniform and simpler.
A related concept that you will see in writings about functional
programming is purity. I am afraid to say there is some confusion in the
literature about the relationship between purity and referential transparency
and not everybody agrees on the meanings of these terms. Generally, a
function is said to be pure if it has no side effects and for a given input,
always returns the same output. This basically means that if you put in the
same input,you get out the same output. If the input is x and the output is y,
no matter how many times you call the function with x as the input
parameter, the function will return y. A side effect is anything that happens
outside of the context of the function. Writing to a file and throwing an
exception are two examples of side effects. Forget for the moment that we
need to write to files, (though arguably we don’t need to throw exceptions)
and think how nice it would be if everytime we call a function with the
same input parameters, we get the same output and nothing, outside of the
function is changed. That is something we enjoy in functional
programming. Because different people have different views on this, and
because the differences between referential transparency and purity are
subtle, I will treat the two terms as synonymous.
Now, I said you don’t have to be a mathematician to write functional
programs and you don’t. But functional programming does come from
mathematics. A field called lambda calculus, to be precise. Much of it also
comes from a field called category theory. Category theory has much to do
with functions. And in mathematics, functions are what we pure. When a
programmer looks at an expression like x = x + 1, she says ah, increment
the variable. When a mathematician looks at x = x + 1, she says No, its
not.3
Now what would an impure function look like?
Scala

object Main extends App {


def impureFunction(x: Int): Int = {
import scala.util.Random
return Random.nextInt(100) + x
}
println(impureFunction(5))
println(impureFunction(8))
}

The two function calls will very likely return different output values for the
same input value. This function is not pure. We have said mathematical
functions are pure. Well, programming has gained quite alot from this
mathematical approach. Functional programs are clean and pure and
elegant. The functional style of programming may take a little bit of getting
use to at first,but as we gradually move through the basic ideas of
functional programming in this book, you will little by little start thinking
like a functional programmer. Your functions will be pure and your code
will be clean. The biggest benefit, however, of writing functional programs
is that you will have a much stronger expectation that your programs will be
correct.
Let me make an important point here. We can’t ultimately just define what
FP is in a negative way. We can’t say its the same as ordinary programming
except that we leave out this and this and that and the other thing. The hard
part, the part accomplished by the many creators of FP is how to express
everything we need, in a functional way.
Higher Order Functions
Functional Programming is all about functions. What we want, in a
functional programming language, is the ability to treat functions as first
class citizens. This means we should be able to pass them as function
parameters and return them from functions as return values. Let’s discuss
why higher order functions are an important part of functional
programming. One key goal in functional programming is to get to the heart
of the matter. This means we need to be able to express concepts concisely
in our language. If we want to square every integer in a list, for example,
we shouldn’t have to loop through the list and modify each number by
squaring it. We should be able simply to directly apply a square function to
every element of the list simultaneously, as it were. The map function, in
many languages, allows us to do this. It allows us to work at a higher level
of abstraction. That higher level corresponds to a higher order function. We
will see this as a major theme as we proceed.
Example 1 (an imperative approach)
Python

def square(nums):
squared = []
for i in nums:
squared.append(i*i)
return squared

Example 2 (a functional approach)


Python

def square(nums):
return map(lambda n: n*n, nums)

As you saw in chapter 2, lambda is a way of creating an anonymous


function; that is, creating a function with out a name. The map funtion that
acts on members of a list, and all at once, applies it to all the elements of the
list.
Lazy Evaluation
Another component of functional programming is lazy evaluation. This
simply means an expression is not evaluated until it is needed. This is not,
strictly speaking, necessary for a language to be functional but often
languages which are, by nature, more functional, tend to be lazy. Haskell,
for example, is lazy by default. Most popular languages are not lazy though,
and they use, what is called, eager evaluation. This means an expression is
evaluated the first (and every) time it is encountered. As you’ll see in the
example below, there are two benefits of lazy evaluation:
It allows you to define control flow structures in your code directly
as opposed to having to be operators built into the language.
It can speed up performance.

Imagine you want to define your own if statement. Let’s call the function
myIf. You might want to add a logging line to every if statement, for
example. If you try the following, you will encounter a problem.
Scala

def myIf(condition: Boolean, thenAction: Unit, elseAction: Unit):


Unit = if (condition)
thenAction
else elseAction

Can you see the problem with this definition? With eager evaluation, which
most common languages have, when the function is called, the first thing
that happens is that all of the parameters are evaluated. So in the case of
myIf, both the thenAction and the elseAction will be evaluated when you
only want one of them to be evaluated, depending on the condition variable.
However, with lazy evaluation, this would work. In this and related cases, it
would allow you to write your own control statements. Another benefit is
performance improvement in certain situations. Since the lazy code is only
evaluated when it is needed, it is often the case that it is actually evaluated
less than it would be in the eager evaluation case. This can speed up the
program.
In Scala we can use call by name parameters. In the code below, thenAction
and elseAction are only evaluated when they are needed. That is, they are
evaluated lazily. The following will work as expected.
Scala

def myIf(condition: Boolean, thenAction: => Unit, elseAction: =>


Unit): Unit = if (condition)
thenAction
else elseAction
}

Thinking likek a functional programmer


In this book, we will focus on how to think like a functional programmer.
This presupposes, of course, functional programmers think a certain way.
While there are a wide range of approaches to functional programming,
there are basic ideas functional programmers use and and basic ways of
thinking. Functional programmers don’t mutate state, for example. That is
once a variable has been set, it is never changed. Also, functional
programmers tend to use lots of higer order functions. These are functions
that take other functions as parameters and/or return a function as a return
value. But to know how a functional programer really thinks involves
knowing a set of idioms, or patterns that promote functional code. It’s all
well and good for me to tell you not to mutate your variables, but unless
you know how, specifically to do this, implementing immutability may not
make any sense. In other words, patterns are an important part of functional
programming.
Now you may have heard that functional programmers don’t really care as
much about patterns as object oriented programmers do. This is largely
mistaken. What is true is that the term pattern, in the context of FP refers to
something different than the Gang of Four patterns. The Gang of Four
patterns were developed in the context of object oriented programming.
Patterns like the Prototype, Proxy and Flyweight patterns. These can largely
be implemented in a functional style and are useful in the design of
programs. But there is nothing particulary functional about these type of
patterns. One might say they are functional - neutral. There is another type
of pattern that is quintessentially functional and these are ideas that come
from category theory. We will address this in some detail in chapter 3.

The Benefits of Functional Programming


The benefits of functional programming are by now clear. It aids us in our
quest for bug-free code. Or as close to bug-free code as is possible. And
how does it do this? By rewiring our brains, as it were, so that we no longer
see the world as a mass of objects each with its own changing state and
processes that transform that state in such a whirlwind of complexity that
we can hardly wrap our minds around it. There is no doubting it now. State
is the culprit. When things change, we need to keep track of them. And that
is the problem. A multitude of variables and objects each with its own state,
and each with its own set of transformations modifying it. Many a night has
been spent by a tired programmer searching for a bug created by a change
in state somewhere in the program. There is only so much complexity the
human mind can bring under its control. Only so much complexity we can
take, before we start writing code that isn’t quite correct. But ’wait’, you
say. ’The world is made up of objects. And those objects have state, and
that state changes over time! So we are right to model the world this way.
That’s exactly how the world is!’ And to that, I respond, maybe, maybe not.
There is another way of looking at the world, however, which might make
thinking functionally easier. We will address that at a later time.4
For now,the important thing is to realize that writing bugfree software is not
something we really know how to do. I knew a Computer Science professor
who once started off his introduction to programming class with the
sentence The human race does not yet know how to program. A bit
dramatic, perhaps, but true. Projects typically come in above budget and
take much longer than predicted. The reason is complexity. Programming is
the art and science and engineering of managing complexity. Functional
programming brings with it tools we can use in an attempt to restrain and
control this complexity. Tools like immutability, referential transparency
and higher order functions, to name a few. Master these tools and your code
will be better, and more bug-free.

FP can improve productivity


So Functional Programming is a programming paradigm. What other
paradigms are there?
The most popular is arguably5 something called Object Oriented
Programming, or OOP. If you have programmed in Java or C# or C++ or
Python for example, you are probably familiar with this way of
programming. In this case, the world is modeled as a collection of objects
each with its own state and its own behavior. There are many benefits of
OOP. But even with these benefits, our code still suffers from coming in
overbudget and overtime. Before FP and OOP became popular, there was
procedural programming, also called imperative programming. Some might
distinguish between the two, saying that procedural is built upon
procedures. OFten the two terms are treated as synonyms. On the surface,
procedural resembles functional programming a bit. Functions are the main
things and there are no objects or classes. But upon closer look, one sees
that state is mutable, functions are not referentially transparent and
procedural languages didn’t necessarily have higher order functions. Much
complexity C and Pascal are two examples of procedural programming
languages.
You could argue that the best programmers will produce better code no
matter what paradigm they use and this is probably true. But the question is
if we have two developers of equal skill, one working with an object
oriented approach and the other working with a functional approach, who
will be more productive. I believe that the clarity, power, and higher level of
abstraction will allow the functional programmer to produce more correct
code, faster.6
FP is fun!
But there is another reason to program with functional programming. And
this is perhaps the most important reason yet. Writing code with functional
programming is fun! And it is fun for deep reasons. Functional
programming lets you get to the heart of the matter. It lets you cut to the
chase and spend more time coding on the subject matter. It is at a
sufficiently high level of abstraction that it feels as if you are manipulating
important, relevant concepts instead of moving drudgingly through low
level details that closely model what a machine does.
The history of programming languages, from one perspective, is largely a
story of ever increasing abstraction level. The higher the level, the easier it
is to avoid manipulating masses of detail. But abstraction does not have to
be hard. And functional programming is showing us this. Yes, there is a
learning curve. But it is possible to shorten this curve by making the change
little by little. If you currently code in Java or Javascript or Python for
example, it is possible to gradually include idioms and structures and
practices that will make your code more functional and before you know it,
you will start to naturally rely on functional idioms for the power and
tendency toward simplification they gives you. If you read this book
carefully and study the examples given and start to incorporate some
functional ideas into your code, you will soon see great benefits. You may
even decide you want to investigate some programming languages that
provide more support for the functional paradigm.
A note about the examples in this book. I will be providing examples in
various languages. This is to demonstrate the way different langauges
implement functional ideas. The languages will include Java, Python and
Javascript. I will also provide many examples in the Scala language,
especially when describing category theory. I would argue that a language
like Scala allows for more concise functional constructs and in many cases
it may drive a point home to show how to do it in Scala. There are other
languages I could have used for this purpose; other languages which are
functional to one degree or another; Haskell or Clojure or ML for example.
I simply felt that the clarity of Scala and the fact that it often resembles
pseudocode, made it a good choice for many of the examples. In fact, if you
have been using Java and you are interested in functional programming and
you have the opportunity, you may want to try out Scala. I would argue that
especially for greenfield projects, you might find it useful.
Before we dive, in chapter 3, into functional patterns, let us spend a chapter
on the various languages we will be using for examples and in particular,
the constructions, like Option and List, you will need to understand what
follows.

1 Some might argue that referential transparency is the most important.


2 In FP, all functions should return a value. void is a sure sign of side effects.
3 This is meant to be a joke but I’ve experienced these reactions first hand.
4 A link to the final chapter will go here when that chapter is available
5 While there is more OOP code in existence currently, there is clearly a move in the direction
of FP among many developers. It remains to see how this will play out. Perhaps a hybrid
approach that mixes both approaches will become the norm. Or perhaps FP will just continue
to get more popular.
6 oclas i.e. Opinion, clearly labeled as such.
Chapter 2. Category Theory and
Patterns

A NOTE FOR EARLY RELEASE READERS


With Early Release ebooks, you get books in their earliest form—the author’s
raw and unedited content as they write—so you can take advantage of these
technologies long before the official release of these titles.
This will be the 3rd chapter of the final book. Please note that the GitHub repo
will be made active later on.
If you have comments about how we might improve the content and/or
examples in this book, or if you notice missing material within this chapter,
please reach out to the author at [email protected].

Two Kinds of Patterns


A software design pattern is a reusable solution to a commonly occurring problem
within a given context in software design.1 Software patterns mean that we do not
have to start from scratch, everytime we write code, and they were made well
known in the Gang of Four software patterns book.2 If you ask functional
programmers about patterns, they may say that patterns are not particulary relevant
in functional programming. When they say this, they probably have in mind the
traditional, gang of four patterns mentioned here. But there is another set of
structures, commonly used by functional programmers that they simply may not
think of as patterns. These structures come from a branch of mathematics called
Category theory. I choose to call these functional patterns and will investigate
them next.

Category Theory Based Patterns


I like to think of these patterns as hard-core functional programming patterns. By
this I mean to suggest that hard-core functional programmers use these idioms
liberally in their code. In a sense, along with immutability, referential transparency
and higher order functions, these patterns form the main content of what it means
for code to be functional. What are some examples of category theory based
patterns? Things like Functor, Monoid and Monad are some examples. Now where
do these patterns come from? They come from an abstract but very useful branch of
mathematics called category theory. Now we could just introduce these patterns as
they are without any reference to category theory. But I think you may appreciate
and find useful the origin of these patterns. And who knows, you might just find
you like category theory as a subject in its own right. So what is Category Theory
and how did it come about?
In the 1940s, Saunders Mac Lane and Samuel Eilenberg were discussing a lecture
one of them gave. They both came to the same conclusion, together, that the
subjects each was working on, one in algebra and one in topology, were actually
instances of the same phenomenon. After fleshing out their ideas, they realized they
had discovered a new subject. Thus was born category theory!
They cowrote a book called ’Categories for the Working Mathematician’ which
became a big source for future development in the subject. Then in 1990, the purely
functional programming language Haskell was created. Many ideas were taken
from category theory in creating Haskell. Some of these concepts have found their
way into other functional and partly functional programming languages, such as
Scala, F# and Java. Another way functional capabilities were incorporated was
through software libraries.
Now let us look at the definition of a category.

Objects and Morphisms


The basic definition of category theory involves two concepts, objects3 and
morphisms. Objects can be anything: sets, numbers, matrices, just to name a few. A
category also needs morphisms. A morphism can only be defined in the context of
two objects from the category. Let us suppose that A and B are objects from a
category C. Then a morphism is an arrow from A to B. We write it like this:
A → B

But what does an arrow mean exactly? Well, it connects object A to object B.
Where the arrow starts and where the arrow ends is what’s most important, and this
relationship is the morphism. People tend to think of this arrow as a function, in
part because the above diagram makes it look like a function, and in most cases it is
a function. But there are categories where the morphisms are not functions.4 For
our purposes, we can think of a morphism between A and B as a function from A to
B, possibly with some conditions on the functions. Now if f is a morphism from A
to B, then A is called the domain of f and B is called the codomain of f. This
corresponds to the language used for functions.5

The category Set


Let us start with the category of all sets. That is, the objects are all sets. What are
the morphisms? Consider two objects A and B from the category. What are the
morphisms from A to B? Simply all functions from A to B. In this case, there are
no conditions on the functions. Every function from A to B is a morphism. So the
category Set is the category whose objects are sets and morphisms are functions
from A to B, for all pairs of sets, A and B. Now just to be clear, you may have
heard of the term range, of a function. Why does the definition of morphism
specify a codomain and not a range? For functions, range is the set of all things in
B that are actually mapped to by some element of A. The codomain contains the
range but doesn’t necessarily have to equal it.6 The following example shows two
objects in the category Set and two morphisms with domain A and codomain B.
Let A = {1,2,3,4} and B = {'a','b','c','d','e'}.
These are two perfectly good sets so they are objects in the category Set. Let us
now define two morphisms from A to B.
Morphism f from A to B:
For all x in A, f(x) = ‘a’. This could be called a constant morphism.
Morphism g from A to B:
g(1) = ‘a’
g(2) = ‘b’
g(3) = ‘c’
g(4) = ‘d’
The above two functions from A to B are two morphisms in the category Set.
Notice that there is no element of A that is mapped to the element ‘e’ in B. This is
fine. B is the codomain and not the range. Note that this is a very large category. It
contains all sets and all functions from A to B.
Before we look at some more examples, there are a couple of things about
morphisms we have to say. First, morphisms compose. What does this mean?
Suppose f : A → B is a morphism and g : B → C is a morphism.
Then there must exist a morphism h satisfying:

h(x) = g(f(x))

We denote h by the expression g ∘ f and we say g composed with f. If the


composition does not exist, then what we were considering was not a category. In
every category, morphisms must compose.
There is one other property morphisms must have in order to have a category: For
each object A in the category, there must exist a morphism id : A → A with the
A

property that for any morphism f: A → B and morphism g: A → B in the category,


we have:
f ∘ idA = f and idB ∘ g = g

This may look mysterious but it is just the category theory way of saying that id is
A

the identity function on A. Category theorists tend to think not in terms of points,
but rather in terms of composition of functions. The above expression is how you
express the identity function in category theory in terms of composition. Instead of
saying identity morphism takes every point in the object to itself (because we don’t
think about the points), you say that when you compose the identity morphism with
another morphism, you get the original morphism back. This is actually a deep
point. Much of category theory is about expressing mathematical concepts through
the notion of composition.
Let’s look at some more examples. We will need something called a semigroup,
which you may have come across in a course on abstract algebra. It is really quite
simple. A semigroup has two main parts, a set of elements, (could be any non-
empty set) and a binary operation on the set. A binary operation, like multiplication
for whole numbers, or union for two sets, takes two things and returns a third thing.
There is one condition that must hold. The binary operation must be associative.
We will denote the binary operation by *.
* is associative means that for all x,y and z, we have:
x*(y*z) = (x*y)*z

So a semigroup is a non-empty set with an associative binary operation on it.


Example 1: Let the set be all whole numbers and let the operation be
multiplication.
First notice that when we multiply two numbers together, we get another whole
number. This is necessary for a semigroup. When you combine two elements in a
semigroup with the binary operation, you’d better get something that is again in the
semigroup.7 We won’t prove it here but multiplication on whole numbers is
associative. We all learned that in school. So all whole numbers plus multiplication
form a semigroup.
Example 2: Let the set be all three by three matrices of real numbers. The
operation will be multiplication of matrices. One can show this is associative. It just
so happens that matrix multiplication is not commutative. A*B is not necessarily
equal to B*A. But commutativity is not a requirement for something to be a
semigroup; associativity is necessary.
I’ve shown you two examples of semigroups, but suppose we want to study all
semigroups. In this case, we could study the category of semigroups. This category
is called Semigroup and the objects are (obviously) all semigroups. What are the
morphisms? This is a bit more involved. We might want to say that the morphisms
are functions from one semigroup to another semigroup, but this would not be
sufficient. Category theory is all about structure and finding similar structures in
seemingly different objects, so what structure does a semigroup have? The structure
is determined by the multiplication operation.

NOTE
(In a semigroup, we often call the binary operation multiplication, even if it is not necessarily the
usual multiplication of numbers).

So the notion of morphism in this case, has to somehow capture the multiplicative
structure of the semigroup. In the following example, I’ll show you how this works.
Let S and S be two objects in the category Semigroup.
1 2

A function h from S to S is a morphism if for all x, y in S , we have:


1 2 1

h(x*y) = h(x)*h(y)

What this essentially is saying is that the two semigroups have similar
multiplicative structure. It says if you want to know where h maps x*y, just look at
where h maps x and where h maps y and then multiply them together in S2. You
can think of the morphism as renaming the object it maps. In this case, x in S 1

corresponds to h(x) in S . And y in S corresponds to h(y) in S . h being a


2 1 2

morphism means that x*y corresponds to h(x)*h(y). It is like an alternate universe


in which every entity in the original universe has a corresponding entity in the
alternate universe.
We can talk about the semigroup comprised of whole numbers with multiplication,
the semigroup of 3x3 matrices of real numbers with matrix multiplication. But we
can also study the category of ALL semigroups.
What does all of this have to do with functional programming?

The category Scal


When it comes down to it, even though much of functional programming theory
comes to us from category theory, often through the programming language
Haskell, we are really only interested in one particular category. Let us describe this
category. First, select a programming language. In theory, it can be any
programming language with types. We will choose Scala, because it is particularly
suited to functional constructions and because much of Scala code is sufficiently
clear that it al most resembles pseudocode. I call this category Scal8.
The objects in the category Scal are the set of all types of Scala. Not only simple
types like String, Int, Boolean but also List[String], Map[Int,Double] and any type
we can build up from basic ones. We could also include user defined types like
User, Account etc. but we will stick to built in types and types that can be built up
from them. Let me also say here that in theory, we could look at the category for
any programming language. We are working with the category Scal but we could, if
we wanted to, work with a category based on, say, Java. In this case, the objects
would be types in the Java language and morphisms from type A to type B would
be functions from objects of type A to objects of type B.

Morphisms
Now if we take two types, say String and Int, how should we define a morphism
between them? Simply define a morphism from String to Int to be any function
which takes a String and returns an Int. So an example of a morphism between
these two types would be the length function. It takes a string, say “abc” and
returns an Int, in this case, 3. Now let’s give an example of the composition of two
morphisms. We know that in any category, if there is a morphism f : A → B and a
morphism g : B → C , then there must be a morphism h : A → C with h = g ∘ f .
Let’s take two morphisms that line up the right way and see what their composition
is.
f : String → I nt is defined by f (s) = s. length
g : I nt → I nt is defined by g(n) = n*n.
So f is the length function and g is the square function. What does their
composition look like?
g ∘ f (s) = (s. length)(s. length)

So we have our category Scal where the objects are types and for two types A and
B, the morphisms are functions that take an A and return a B.

NOTE
Once you have selected a programming language, Scala, in this case, all the category theory that is
applied to functional programming deals with this one category Scal, where the objects are Scala’s
types and the morphisms from A to B are functions that take an object of type A and return an
object of type B.

Functors
Functor is a funny word. It sounds like function and it is, indeed, a function. But it
is a very special kind of function. Before we define it, let’s look at some examples
in Scala that correspond to Functors. Some functors in Scala are List, Option and
Future.9 These examples have two things in common. First, they are generic types,
meaning that they take other types as parameters. You can’t just have a List in
Scala. You can have List[String], List[Int] or List[User], for example. List[String]
is not a functor. It is a type. But List by itself, is a functor. Same for the other two
examples. The second thing they have in common is that they all have a map
function. Let’s see an example:
Scala

val lst = List(1,2,3,4)


lst.map(n => n*n)
//returns List(1,4,9,16)
Create a list of four numbers.

List is a functor so it has a map function We will see where map comes from in
Category theory later in the chapter.

Now let’s define functor. I first need to specify two categories C and C . 1 2

Then a functor F from C to C is a function from the first category to the second
1 2

category which satisfies the following properties.


1. F takes objects in C to objects in C . (Just like List takes String to
1 2

List[String])
2. F takes morphisms in C to morphisms in C . (What List does to a
1 2

morphism is trickier. It involves the map function and we will treat this
below.)
3. F (f ∘ g) = F (f ) ∘ F (g) whenever the morphism domains and codomains
of f and g line up.

This condition basically means that the two categories C and C have similar 1 2

structure with respect to morphisms. The idea to keep in mind when considering
functors is that they measure how similar two categories are.
Now we said earlier that the category we will be interested in is Scal.

NOTE
Don’t we need two categories to define a functor? Actually no. A functor can go from a category
to itself. Such a functor is called an endofunctor. So all the functors we will be considering, in the
category Scal, will be endofunctors.

Example 1 The List type constructor in Scala. (Notice I didn’t say type). What’s a
type constructor? List is not a type in its own right. It needs to take a type
parameter before it becomes a bonafide type. We can have a List of Strings, a list of
Ints etc. Once we pick a type parameter, say String, then we get the type
List[String]. So List by itself is called a type constructor. What are some other
examples like this in Scala? Option and Future to name a few.
In the category Scal, the above are examples of functors. List, Option and Future.
They are functors from the category Scal to itself. Remember, we called such a
functor an endofunctor. So List, Option and Future are examples of endofunctors,
and all endofunctors are functors.

What does a functor do to a morphism?


First of all, List takes objects of Scal to objects of Scal. For example, List takes the
object String to the object List[String]. Secondly, List also takes morphisms to
morphisms. How does this work? Let us consider the two morphisms length and
square. length is a morphism from String to Int and square is a morphism from Int
to Int. So their composition square ∘ length is a morphism from String to Int. It
takes a string and spits out the square of the string’s length. (a bit contrived, I know,
but it illustrates composition of morphisms). So we understand how List takes
String to List[String] but how does List act on the morphisms? What is
List(length)? This looks odd. We are not accustomed to taking the list of a
function.10 What can this mean? Since length goes from String to Int, list(length)
must go from List[String] to List[Int]. Can you think of any function, possibly with
another name, that maps List[String] to List[Int]? If you said map, you are right. In
Scala, we would write this:
Scala

List("abc", "defgh").map(_.length) //== List(3,5)

This can be confusing so lets be very clear. In Scala, certain types have a map
function defined. (We will see that these are precisely the functors). So given a
functor, there is this map function in the background. And when we want to know
what the functor does to a morphism, we need to use the map function in a certain
way. We expressed this above with length but let us see what this looks like in the
general case.
Consider the morphism f : A → B, where A and B are two Scala types.
(i.e. two objects in the category Scal)
And let F : Scal → Scal be a functor from the category Scal to itself.
We write what F does to an object A as F[A] (think List[A] or Future[A] etc)
And to the morphism f, how do we write what F does?
If fa is an element of F[A], and f : A → B is a morphism
we write f a. map(f ). This function that takes fa to fa.map(f) is F(f).
In Scala, we don’t think of this function as, List(length),but rather as the map
function. There are actually many map functions, one for each functor. In Scala, we
think of this as just one map function, which can be applied to any container like
data structure. But in Category Theory, the map function is what you get when you
apply a functor to a morphism.
So this leads us to another, and more common way, of looking at functors. A
functor is simply an interface (or trait in Scala) that implements the map method.
We could even have called functor Mappable. And as we mentioned above, on a
higher level of abstraction, a functor is a way of measuring how similar two
categories are. Or in the case of endofunctors on the category Scal, a functor relates
the category Scal to a part of Scal.
I have now explained some of the major players in category theory: the category,
objects in the category, morphisms and functors. The reason I chose Scal as the
category to investigate is that functional constructions and idioms are more natural
in Scala than some of the other popular languages.11 In addition, the constructions
in Scala are so natural, they often almost look like pseudocode, which makes it
easier to give examples to a multilingual audience.
As we have seen, there are two ways of looking at a functor. We can represent
functor as a trait (or interface) that implements the map method or we can think of
it the way we think of it in category theory. From this perspective, a functor is a
function from the types of Scala to the types of Scala and it is also a function from
morphisms in the category Scal to other morphisms in Scal. In particular, if A and
B are two scala types, and f is a morphism from A to B, then F(f) is a morphism
from F[A] to F[B]. We could think of F as providing a context for two types and a
morphism between them. We start off working in A and in B and end up working in
F[A] and F[B]. So we have contextualized A and B. If I want to know what
represents the morphism f in the context F, we look at the morphism F(f) from F[A]
to F[B]. What is this morphism? Well if fa is an element of F[A], then
F (f ) takes f a to f a. map(f ).
Remember, that every Functor has a map method associated with it, so we can
always carry out the above expression. Let me give an example of the above. I can
use the functor List. In this example, A = Int and B = Int. F = List and let the
morphism
square : A → B be the square function.
Then F[A] = List[Int] and F[B] = List[Int] too.
What is F(square). That is to say, what is List(square)? Remember, for this we need
the map function that comes along with List (as it does with every functor). So we
have:
F (square)(f a) = f a. map(f ) or List(square)(f a) = f a. map(square).
This gives us:
List(square)(List(1, 2, 3, 4)) = List(1, 2, 3, 4). map(square) = List(1, 4, 9, 16)

Now we said that there are three properties a functor from category C to category D
must satisfy.
1) A functor F takes objects in C to objects in D. In the case of the category Scal,
this means F takes Scala types to Scala types.
2) F takes morphisms in C to morphisms in D.
3) A composition property, seen below:
F (f ∘ g) = F (f ) ∘ F (g) where f and g are morphisms.
Let us check this property for the functor List and two morphisms length and
square.12 So here length is a morphism from String to Int and square is a morphism
from Int to Int.
Plugging in the values, I have to show:
List(square ∘ length) = List(square) ∘ List(length)

Now the expression on the left takes an object of type List[String] to an object of
type List[Int] For example:
List(square ∘ length)(List(“ hello”, “ universe”)) =

List(“ hello”, “ universe”). map(square ∘ length) =

List((square ∘ length)(“ hello”), (square ∘ length)(“ universe”)) =

List(square(5), square(8)) = List(25, 64)

Now lets evaluate List(square) ∘ List(length).


(List(square)oList(length))(List(“ hello”, “ universe”)) =

List(square)(List(length)(List(“ hello”, “ universe”))) =

List(square)(List(“ hello”, “ universe”). map(length) =


List(square)(List(5, 8) = List(5, 8). map(square) = List(25, 64)

So the two sides are equal. What we have shown, in this particular case, is in fact,
always true. For any functor F and two morphisms f and g, we always have:
F (f ∘ g) = F (f ) ∘ F (g)

So for example, this will hold for other functors such as Option and Future. Once
we know something is a functor, we know we can compose morphisms in this way.
Why do we care?

The Patterns

The pattern Functor


Now that we have some idea of what a functor is, let us see how this pattern can be
useful. Functors are useful for two reasons:
1)They always have a map function.
2)They can always be composed.
In the following example, I will show you how composing two functors can be
useful.
Suppose we have a list of options, say:
Scala

val listOfOptions = List(Some(8), None, Some(2))

If you are unfamiliar with Some and None, see chapter two. Suppose we want to
add 1 to 8 and 2. Most languages don’t provide functor constructions out of the
box. Even Scala, which is fairly functional, doesn’t have this capability. But there is
a library called Cats13, which provides category theory constructs, as first class
objects, as it were. First, let’s look at the trait Functor, which comes with Cats.
Scala

trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
We can see the map function, which every functor has. But what is F[_]?
F[_] is Scala’s way of expressing a type constructor, So the F, here, is what we are
thinking of as the functor. Now remember what we are trying to show. We want to
illustrate how composition of functors, which you always have, is useful. So back
to our example of listOfOptions.
The definition of the trait Functor in the scala library Cats, is much simplified for
our example. One method it comes with is compose. So in order to add one to the
numbers in the options, we can do the following.
Scala

Functor[List].compose[Option].map(listOption)(_ + 1)

We have a list of options of ints and we want to map over the Ints. So the above
expression lets us compose List and Option to get a new functor, and then use that
new functor’s map method to map over the ints with the anonymous function _ + 1,
which is just Scala’s way of writing an anonymous function that adds one. We
started with:

val listOfOptions = List(Some(8), None, Some(2))

and ended up with:

val listOfOptions = List(Some(9), None, Some(3))

Notice that alot of meaning is packed into the above expression.


This is a good example of the power of composition of functors for functional
programming.

Monoids
As I mentioned earlier in the chapter, a semigroup is a set with an associative
operation on it. If a semigroup has an identify element, which means an element e,
in the semigroup, with the property that: e*x = x*e = x for all elements x the
semigroup, the semigroup is called a monoid.
In the following examples, I’ll show you some examples of monoids.
Example 1
Let M be the set of all non-negative whole numbers. Along with the operation
addition, this is a semigroup. But notice that 0 is in the set M. We know that if we
add 0 to any non-negative whole number, on the left or right, you get the original
whole number back.

NOTE
We say left side or right side because not all semigroups are commutative. Its not always true, in a
semigroup, that a*b = b*a.

In the case of non-negative whole numbers, addition is commutative. So saying left


side and right side in the definition is unnecessary. So this is a monoid. We can
write it like this (N, + , 0).
Example 2
Let M be the set of all 2x2 integer matrices with matrix multiplication. With the
identity matrix, the one with ones on the diagonal and zeros off the diagonal, this is
a monoid. Note that matrix multiplilcation is not commutative in general but if you
multiply the identity matrix on the left or right of a given matrix, you get that
matrix back again.
Now how are monoids useful in functional programming?
Well let us start with a simple example. We want a function that adds up a bunch of
numbers. Let’s write this code in Java in a common, imperative style. We might do
something obvious like:
Java

int sum(List<Integer> lst) {


int result = 0;
for (int i=0; i<lst.size(); i++) {
result += lst.get(i);
}
return result;
}

This code computes the sum of a list of integers. Let’s analyze it from a functional
perspective. First, notice how it mutates state. The value of result continually
changes throughout the program. So does the value of i. Let us try to write a
functional version of this function that does not mutate state and also that uses an
abstraction like monoid to express the sum with a higher level of abstraction. There
is a function in functional programming called foldLeft (There is also a foldRight.
You will see this function with various names depending on the programming
languages. For example, foldLeft, foldl, fold, foldRight, foldr and fold). FoldLeft
essentially comes out of the concept of a monoid.
Consider the following monoid: the set of integers with addition as the operation
and 0 as the identity element. In any monoid we can create the foldLeft function.
(or foldRight, but I won’t keep repeating this). We combine the identity with the
first element of the monoid. Then we take the result of that and combine it on the
left (respectively right) with the next element in the monoid. We do this until there
are no more elements. We can describe this as follows: We are given a binary
operation, that is, one that combines two elements. And fold applies the operation
pairwise to get the combination of all the elements. Of course, in a commutative
monoid, foldLeft is equal to foldRight. In Java, there is a similar function called
reduce. Let’s see an example.
Java

Integer sumAll(List<Integer>lst) {
return lst.stream().reduce(0, Integer::sum);
}

In Scala, we have:
Scala

def sumAll(Lst: List[Integer]):


return lst.foldLeft(0)(_+_)

In Scala, foldLeft is a method in the List[Int] class and _ + _ is an anonymous


function. FoldLeft can be used in many situations. For every monoid in a category,
there is a foldLeft function. For example strings with concatenation or booleans
with and. Monoids can get complex but no matter how complex it is, there is
always a foldLeft function you can use. This illustrates how we can get a useful
function, foldLeft, in this case, that comes directly from the caegorical notion of
monoid. foldLeft is a vast generalization of adding up a bunch of numbers,
concatenating a bunch of strings, or anding together a bunch of boolean
expressions. Any monoid has a foldLeft (or foldRight) method, though, as I said,
they may be named slightly differently in different languages.
Next we will look at natural transformations. Our goal is to get to monads, see
where they come from and how they relate to functional programming.

Natural Transformations
To keep things simple, we will not go into all the technical details that make up the
definition of natural transformations.14 My goal here is to give some idea of what a
monad is, in the context of category theory, and more importantly, to make clear
how they are useful in functional programming. If you wish, you can skip what
follows, if you are not interested in the theoretical underpinnings of the monad.
Then I will look at monads from a more practical, programming perspective. We
need natural transformations in order to define monads. It just so happens that there
is a way of thinking about natural transformations that is, well, natural. Functors, as
we know, are functions from one category to another category (for example, from
Scal to Scal). But we can change our perspective and build a new category where
the objects of the new categories are the functors from the original category. Let us
confine ourselves to endofunctors. Let us denote by End(C), the set of all functors
from C to C, for some category C.
Now we want these functors to be the objects in a new category, and to do so, we
need morphisms. That is, we need functions between endofunctors that satisfy the
rules for morphisms. Natural transformations in the category C correspond to
morphisms in this new category of endofunctors. What properties will these
morphisms have?
Let E , E and E be three endomorphisms of C. That is, they are three objects of
1 2 3

End(C).

Let us further suppose we have two morphisms f and g where


f : E → E and g : E → E .
1 2 2 3

Then by the definition of morphism, there exist the composition


g ∘ f : E1 → E . 3

And this composition is associative. These morphisms, in End(C) are what we call
natural transformations in the original category C. There is another definition of
them, which you would ordinarily see in a category theory book, but that is a bit
more involved. Thinking of them as morphisms in the category of endofunctors is
more straightforward. In other words, we start with a category C, form the category
End(C) and the morphisms of End(C) are natural transformations in C. Now how

do we get from here to monads?


The trick is to bring in the concept of monoid again. Pick any endomorphism M in
End(C). It turns out that M can be given the structure of a monoid. So we have a

monoid (M, *, e) in the category End(C). We have a monoid in the category of


endofunctors. This is a monad. A monoid in the category of endofunctors is how
monads appear in category theory.

NOTE
Remember, every monad is a monoid but not every monoid is a monad. A monad is a monoid with
some extra structure, which we defined above.

Now the road from a simple category to a monoid in the category of endofunctors
is a long one. I just wanted to give you some feel for what is involved. There are
ways of treating monads that are more practical and useful. In fact, there is a way to
get from the * operation of the monoid to a function called flatMap and to get from
the identity e in the monoid to a function called unit. And these two functions will
provide us with a more practical way of describing monads.
Now a monad is a monoid and it is also a functor. As a functor, it has a map method
(like all functors) and as a monad it also has a flatMap method.

Monads
We have hopefully gotten some idea of where monads come from. But what about
monads from a practical perspective? Do we need to deal with endofunctors
whenever we want to use a monad? And how are monads useful? It turns out that
there is a much simpler description of monads in the category Scal (or any other
category associated with a programming language). This simpler description has to
do with the functions flatMap and unit.

flatMap and unit


In Scala, flatMap and unit are two functions you may have seen before. They have
the following signature:
Scala

trait Monad[M[_]] {
def flatMap[A](ma: M[A])(f: A => M[B]): M[B]
def unit[A](a: A): M[A]
}

How should you think about monads? There is a mystery about them and based on
my description of where they come from in category theory, this is not surprising.
The definition of monad in a category theory is complex. There are many moving
parts. But if we think of the above trait, it becomes easier. The best way to think
about monads, from a functional programming perspective is that it provides a
context for an object. We can also think of it as adding additional structure to an
object.
Let’s start with unit, since this is simpler than flatMap. Unit takes an element of
type A and puts it into the context M[A], where M is the monad above. So for
example if M is Option, and we start with the string “abc”, we get the object
Some(“abc”). And this has type Option[String]. It’s not quite right to say that
Some(“abc”) is a string but we want to say something like this. Well we can say
this is a String in the context of Option. We have Optionized the String. Or we can
say we have added additional structure.
Now what about flatMap? Well let’s first consider the function map. That is
simpler. So we have something like:
Let ma be of type M[A]. Suppose we have a function f : A → B. Then ma.map(f)
will give us a value of type M[B] . map will basically take the value ma out of its
context M[A], apply f to it, get a value of type B and then wrap it in the context to
get a value of type M[B].
But suppose now we have ma again, a value of type M[A], but now we have
f : A → M[B]. This happens alot. M might be Option or List, for example. If we

try map, we get: ma.map(f). If you think this through, you will see map returns a
value of type M[M[B]]. And this is probably not what we want. This is where
flatMap comes into play. flatMap maps f over ma but then it flattens the result.
Let ma be of type M[A]. Let f : A → M[B].
Then ma.flatMap(f) will return a value of type M[B], not M[M[B]] .
Let’s see an example of this:
Scala

class User(fname: String {


def firstName: String = firstName
}
def getUser(id: Int): Option[User]

val users = List(1,2,3).flatMap(id => getUser(id))

If we used map here instead of flatMap, we would have ended up with a List of
options of users. flatMap maps and then flattens, In this example, flattening means
taking the users out of the options. In general, flatMap is useful for chaining
together functions that involve monads.
Incidentally, you only need flatMap and unit to have a monad. If you have these
two, you can get map as follows:
Scala

m map g = m flatMap (x => unit(g(x)))

So we can say a monad is a trait (or interface of some kind depending on the
programming language) that implements two methods. flatMap and unit. Also,
every monad is also a functor. So it must have a map function. And the above
expression shows how to get it from flatMap and unit.
To fully understand monad as it is in category theory would require more work. I
hope you have gotten a feel for the complexity involved in constructing a monad on
the one hand and the more straightforward programming approach where we model
a monad as an interface or trait that implements flatMap and unit.
Also, when somebody asks you what a monad is, you can answer It is a monoid in
the category of endofunctors and have, at least, a bit of an idea what that means.

Conclusion
You have learned what a category is, what the category Scal is, and some examples
of how to apply functors, natural transformations, monoids and monads to your
code. I will present more examples in the course of the book. It is important to
emphasize here that it is not absolutely necessary to learn category theory before
you learn about constructions like functors and monads and how to apply them to
your code, but I believe knowing where these constructions come from will give
more context and perhaps suggest novel ways of applying them to your code.

1 https://en.wikipedia.org/wiki/Software_design_pattern
2 https://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-
ebook/dp/B000SEIBB8
3 Let us make clear here that objects, in this context, are distinct from objects in object oriented
programming.
4 As an example of this, consider the natural numbers. There is an arrow from m to n if m ≤ n. We get
composition from transitivity of ≤ and we get identity arrows from reflexivity. i.e. n ≤ n for all n.
5 See chapter 2.
6 See chapter 2.
7 So for example, Negative numbers with multiplication couldn’t form a semigroup because when you
multiply two negative numbers, you don’t get a nother negative number.
8 I call this category Scal because of the well established category Hask associated with the Haskell
language.
9 For more familiarity with these concepts, see chapter 2.
10 Unless its a list of functions. In this example, we do not mean a list of functions. We are applying List to
the function as a functor.
11 Opinion clearly labeled as such.
12 This part is a bit formula heavy. Feel free to skip it if its not your thing.
13 https://typelevel.org/cats
14 For more information on natural transformations, see
https://en.wikipedia.org/wiki/Natural_transformation. Natural transformations are complex.
About the Author
Jack Widman started his professional life as a mathematician in academia.
He studied and taught the intricacies of pseudo-compact topological groups,
as well as teaching calculus and discrete math courses. At the suggestion of
some friends, he decided to try out programming and see it this was his cup
of tea. It is now twenty-three years later and Jack has been designing and
writing code ever since. With a PhD in mathematics and twenty-three years
of software industry experience, Jack conceived of the idea to write a book
on functional programming, undoubtedly a subject with deep mathematical
roots, and this book you have in your hands is the result.
In his spare time, Jack enjoys Aikido, cycling, guitar and reading.
Another Random Scribd Document
with Unrelated Content
Undergoing more than his fair share of laceration, Peter crawled
under the brushwood. The three men crouched in the dim light that
filtered through the thicket, and silently contemplated the mouth of
the cave.

Minalto looked upon it as a place where fresh pork was to be


obtained and that soon; Peter, in the light of romance, tried to
conjure up visions of the long-gone buccaneers; Alwyn, in view of
possibilities, regarded it and its approach as a hiding-place should
Black Strogoff and his satellites succeed in finding the castaways.

"May as well see the thing through," observed Burgoyne. "It's no


use hanging on to the slack."

"Certainly, sir," agreed Minalto, and proceeded to secure the rope


round his waist by means of a bowline. "Du you pay out, sir, 'n case
there's a big drop."

Prodding the ground with the haft of his spear, Jasper cautiously
entered the cave. For the first eight or ten paces the sides of the
tunnel-like entrance were fairly regular and less than a yard apart.
Then he found that the cave expanded both in height and width,
until it was impossible even with the spear to reach from one wall to
the other. Standing upright, Minalto found that he could just touch
the roof with his extended hand.

Guided by the faint squeals, Jasper followed the right-hand wall


until his knees came in contact with what he thought to be a large
ledge of rock. Groping with his hands, he discovered that the
obstruction was a large box with a hinged lid.

Instantly all thoughts of the pig vanished from the man's mind, and
again the long-dormant strain derived from his wrecking and
smuggling ancestors reasserted itself.

"Ho! ho!" he shouted in stentorian tones. "We'm in luck, sir.


Treasure an' all!"
He fumbled with the lid, then, struck by the thought that a lot of
the glamour of the discovery of hidden specie and bullion would be
lost unless he viewed his find in the glare of a torch, he retraced his
footsteps and rejoined Alwyn and Peter.

"Girt sea-chest!" he announced excitedly. "Lifted 'en lid, I did."

"And the pig?" asked the matter-of-fact Burgoyne.

"Drat that pig!" exclaimed Minalto explosively. "The chest, sir. Ef us


had a light, like... sort o' torch, now say?"

"How about it, Peter?" asked Alwyn, turning to the Wireless Officer.

"We'll manage that," replied Mostyn confidently. "Let's get out of


the thicket. Suppose we ought to beat a clear path through this
stuff?"

Burgoyne shook his head.

"No," he decided; "we won't disturb it more than necessary. The


less we do the better. If we're careful we ought to be able to take a
lighted torch into the cave without setting fire to the brushwood
outside."

Returning to the open, they explained the delay to Hilda, whose


eagerness to explore the cave was only quelled by the knowledge
that the dying pig was somewhere in that gloomy vault. She would
have endured the thorny passage without complaint; but there were
limits, and the expiring porker was beyond them.

Hurrying back to the camp, Mostyn returned with his fire-making


gear, and proceeded to work. Meanwhile Burgoyne and Minalto had
wrenched off some resinous branches to serve as torches.

"All ready!" announced Peter.


With a torch burning faintly, Minalto forced his way under the
scrub, Burgoyne and Mostyn following in his tracks. At the mouth of
the cave they coaxed the flames into greater activity, and from it
lighted two more torches.

Jasper advanced boldly. He had been there before. His companions


followed cautiously, until the glare of the reddish flames revealed the
treasure-chest.

It was in fairly good condition, having been painted white with a


black lid. There were rope beckets at each end, rove through two
large half-round wooden chocks.

The lid creaked on its hinges as Jasper threw it back. Then he gave
a howl of disappointment. All the chest contained was a rusty
cutlass, a clay pipe with a broken stem, and a number of brown
paper bundles containing candles all stuck together by the heat.

"So much for your treasure, Jasper!" said Burgoyne with a laugh.
"Never mind; we found something useful, the candles especially."

"P'raps 'en buried et," suggested Minalto hopefully, casting anxious


glances at the walls and floor of the cave.

Burgoyne made no remark. He was deeply interested in the


construction of the cave. It was partly natural and partly artificial.
Human hands had enlarged the entrance and "faired off" the walls.
In length it was about forty feet, and twenty in breadth, with a hewn
pillar in the centre to give greater support to the roof. Except for the
chest there were no other relics of the previous occupier. In one
corner lay the pig, by this time quite dead.

"No use stopping here," decided Alwyn. "Bend that rope round the
pig, Minalto, and we'll haul the brute out. Yes, bring the cutlass,
Peter, and a couple of packets of candles. The others can stop, in
case we want them here."
"Want them here?" repeated Mostyn.

"Rather," replied his chum. "This cave will make an ideal retreat if
we have to hide. I hope we shan't, but we must look things fairly in
the face. That's why I didn't want the brushwood cleared away. Had
it not been for the pig we should not have found the cave, and so
most likely no one else will."

"Someone did at one time," remarked Peter.

"Yes, but how long ago we don't know, unless that cutlass gives us
a clue. I'll have a look at it when we get into the open. You see, the
person or persons who enlarged this place threw the excavated
material on a mound just outside. That shows they hadn't any idea
of concealing the cave. Since then this scrub has sprung up and
hidden it. Now then, Jasper, all ready? Heave away!"

At the mouth of the cave they extinguished their torches, leaving


them leaning against the wall in case they might be required again.
Then, carrying and hauling their various trophies, the three men
rejoined Hilda in the open.

"Now, where's that cutlass?" inquired Alwyn, after relating the story
of how their high expectations had been thwarted. "H'm, thought so.
Our predecessors on Swan Island weren't so very ancient after all.
This is a cutlass-bayonet, Peter, issued to the Navy in the late '70's
and '80's. That ring in the guard is where the muzzle went, but I see
the spring socket is rusted away. Nice job for you, Peter. You can
clean the thing up. It'll do to carve the Christmas dinner if we're
here long enough."

CHAPTER XXIV
The Cave proves Useful

During the two days following all hands were kept busily employed.
In addition to carrying out the usual routine, they made preparations
to lay in a stock of provisions. Mostyn tried his hand at obtaining salt
by evaporation, and succeeded in making about a pound of very
saline powder. Minalto cut up the porker, reserving some of the meat
for present use and pickling the rest. Hilda experimented with
making biscuits of taro root finely powdered and bruised between
two large stones.

In addition the three men took turns at climbing to the summit of


the look-out hill. This they did every four hours in calm weather, and
every two hours when the wind blew with any strength, so that no
sailing vessel could close with the island between those intervals
without first being sighted in the offing.

On the morning of the fourth day Jasper called Burgoyne's


attention to a rectangular object lying on the top of a low-lying part
of the reef. The tide had fallen exceptionally, and more of the reef
was exposed than they had seen before.

"I believe it's our water-tank," declared Alwyn. "That's about where
the boat broke her back."

"So I thinks, too, sir," agreed Minalto.

"In that case we'll have the thing ashore," declared Burgoyne. "It
would never do to leave such a monument to our mishaps lying in
such a conspicuous position."

"How would you bring it across?" asked Mostyn.

"It looks as if it is lying on its side," replied the Third Officer,


shading his eyes with his hand. "We'll have to up-right it and let the
rising tide float it off. A couple of us could easily swim over there
and push it across the lagoon. No, not yet. We'll have to wait for the
young flood to make. Meanwhile it's your turn, Jasper, to climb the
hill. Nothing like exercise before breakfast."

Minalto swung off, and hurried to perform his task of look-out man.
In less than a quarter of an hour he was back again, breathless with
running.

"A sail!" he announced pantingly. "Away to nor'ard."

"Dash it all!" exclaimed Burgoyne.

The information disconcerted him. For the sake of his companions


both on Swan Island and in the hands of the pirates at the secret
base, he would have welcomed the intelligence if he knew for
certain that the strange craft was a friendly one. But an instinctive
feeling told him that the craft was manned by some of Ramon
Porfirio's ruffianly crowd, and that the object of her voyage was to
recapture the four fugitives.

Without undue delay all hands hurried to the summit of the hill,
Alwyn pausing only to scatter the burning logs over which the
morning meal was boiling, Hilda suffering the interruption of her
culinary task without protest.

From the elevated look-out post the vessel could be seen fairly
clearly. The morning was bright, with no sign of haze, and the craft
appeared nearer than she actually was. In spite of the light breeze
she was approaching rapidly, so that it was evident that she was
equipped with a motor.

She was then about a mile and a half or two miles off the northern
part of the island, shaping a course for the eastern side. She was a
fore-and-aft schooner, carrying jib-headed top-sails, and was of
about eighty tons displacement. She flew no colours.

"What would I not give for my prism binoculars?" sighed Alwyn.


"Seen her before, Minalto?"
Jasper nodded. He was still rather breathless.

"Yes," continued Burgoyne, "unless I'm much mistaken she was


one of those small craft lying in the pirates' harbour; but I'm hanged
if I noticed whether any of them had motors. Well, we'll have to get
a move on, Miss Vivian. I'm sorry to say that your wish of a few days
ago will have to be complied with. We must hide in the cave,
perhaps for several days. I don't suppose those rascals will abandon
the search until they've examined every visible part of the island."

"How about the water-tank?" asked Mostyn.

"Too late, now, I'm afraid," replied his chum. "It will be as much as
we can do to transfer ourselves and our traps to the cave.... This
way down; in case they've a glass bearing on us."

Keeping to the south slope of the hill until the tree-tops shut out
the sight of the approaching vessel, the fugitives returned to the
camp.

There was much to be done in a very short time. The tent was
levelled and packed up in the smallest possible compass. The canvas
between the two upturned parts of the broken life-boat was
removed. The hot embers of the dying fire was carefully scattered,
lest they might kindle into flame and smoke. Then, heavily laden
with stores and provisions, the four hastened towards the cave.

"One minute, sir!" exclaimed Jasper, stopping short in his tracks


and setting down his burden. "If us ain't forgotten the li'l ole cask o'
rum."

Burgoyne glanced behind towards the lagoon, a small portion of


which was visible through the glade.

"Too late, now," he replied. "The schooner's passing through the


reef. Yes, she has an engine right enough. The water-tank must
have given us away. Come along, Jasper; you've seen the last of
your li'l ole cask, I'm thinking."

There was a stubborn look on Minalto's bronzed and bearded face


as he reluctantly re-shouldered his burden. It went sorely against
the grain, this tame surrender of what he considered to be his
property by finding.

"Come along!" repeated Burgoyne sternly.

"Ay, ay, sir," replied Minalto; then under his breath he added: "an' I
hope th' li'l ole cask'll poison the lot o' they."

It was now a slow and cautious business getting the stores and
gear into the cave, and in spite of every care Burgoyne noticed with
concern that the tracks under the scrub were by no means covered.
A keen Malay tracker would be able to find their retreat with little
difficulty. The only hope lay in the fact that the crew of the schooner
were unskilled in woodcraft, and that the broken twigs and
brushwood would escape notice.

"Here's our present abode, Miss Vivian," announced Burgoyne,


when the four and their portable property were inside the cave, a
couple of candles lighted, and a double sheet of canvas hung across
the entrance to screen any gleam from within.

"It reminds me of London during an air-raid," observed Hilda. "I


had to spend several nights in a cellar—I was made to go down, but
I would have much preferred to stop in an upper room. But there is
nothing to be afraid of here as far as bombs are concerned."

"No; silence is the chief consideration," cautioned Alwyn. "I don't


suppose they've sent a boat ashore yet, but I think I'll find out."

"Don't run unnecessary risks, please, Mr. Burgoyne," said Hilda.


"Trust me for that, Miss Vivian," declared the Third Officer
earnestly. "Risks, yes; unnecessary risks, no. I've no use for the
fellow who goes out asking for trouble."

"I'm going with you, old son," said Peter.

"My festive Sparks, you are not," decided Burgoyne. "For the
present this is a one-man show. You stop here, and don't stir outside
till I come back. All being well, I'll return in twenty minutes, if not
before."

Withdrawing the cartridges from his revolver, Alwyn carefully tried


the mechanism of the little weapon. Then, after reloading, he thrust
the revolver into his hip-pocket, and, with a wave of his hand,
disappeared behind the canvas hanging.

It was a tedious wait for the three who remained. Without means
of knowing the time, the minutes passed very, very slowly. Peter
tried to gauge the interval by observing the burning down of one of
the candles. The others waited and listened intently for any sounds
that might reach their ears from without the cave. Even the practical
Hilda Vivian looked anxious and worried. Mostyn, not usually
observant of people's characters, noticed that, and wondered
whether the girl was anxious on Burgoyne's account or merely
because of the peril that threatened her.

At length Minalto stood up, stretched his huge arms and picked up
the cutlass, which Mostyn had brought to a state bordering on
perfection, for the blade had been cleaned and sharpened, and the
hilt shone like a convex mirror in the candle-light.

"I'm going to look for 'e," he declared in a hoarse whisper.

"You're going to stay here," said Mostyn firmly. "Officer's orders,


you know."
Minalto was about to frame an argumentative reply, when a chorus
of raucous voices sounded in the distance.

Without further delay Jasper pulled aside the canvas screen, only
to collide violently with Alwyn Burgoyne.

"Ssh!" exclaimed the latter warningly. "Get back. They're ashore."

"The pirates?" asked Mostyn.

"Yes, unfortunately," replied Burgoyne. "They brought up off the


little creek and hoisted Yankee colours. Thought they'd have us cold,
but it didn't come off. I waited under a bush—rather longer than I
intended, perhaps; but, you see, I wanted to make sure of their little
game. After a bit they got tired of seeing the Stars and Stripes at the
main truck, so they hauled the bunting down. Up to that point I'd
seen only three men aboard; but by this time they'd come to the
conclusion that we weren't having any. So they launched a boat and
rowed ashore: eight men armed with rifles, and our old friend
Strogoff sporting a pair of automatics. I thought it high time to sheer
off, so I crept back for about fifty yards and again watched
developments."

"Eight of 'em, not a-countin' Black Strogoff, were you sayin', sir?"
inquired Minalto thoughtfully. "Sure, 'tes long odds, wi' only a pistol
an' a cutlass 'twixt three on us. Was there more on 'em left aboard,
sir?"

"I cannot say, Jasper. More than likely there were, but I didn't see
them. They'd hardly all go ashore."

"Ef us could slip along, like," resumed Jasper, "an' swim off to the
schooner—— When all's nice an' dark like."

"They'll probably go on board again to-night," said Burgoyne. "We'll


have to think things out a bit. But when I left them they were
smashing up our happy home just out of sheer mischief. When
they've got tired of that they'll begin searching the island, so we had
better lie low and keep quiet."

Presently the four fugitives heard the sounds of men forcing their
way through the undergrowth, uttering fierce oaths in half a dozen
different languages and occasionally firing their rifles. During
intervals between the din, Black Strogoff's voice could be heard
shouting an ultimatum to the objects of his search, to the effect that
if they gave themselves up without further trouble, "including the
young woman" ("so they know," thought Alwyn), their lives would be
spared. Otherwise he, Strogoff, would search the island from end to
end and shoot the men down without mercy.

The pirates were evidently following a trail, which turned out to be


the well-trodden path leading to the summit of the look-out hill. So
keen were they on the obvious track that they failed entirely to
notice the tell-tale broken brushwood concealing the mouth of the
cave.

After the sounds of the pursuit had died away in the distance,
Jasper proposed that he should go out and see what was happening
in the lagoon.

"No, you don't," said Burgoyne decidedly. "Ten to one you'll play
straight into their hands, if you did. I shouldn't be at all surprised to
know that they had posted snipers at various intervals to pick us off
if we ventured out. Patience and discretion, Jasper. That's our motto
for the present. How about grub?"

Another candle was lighted. They were of a kind known in the


Royal Navy as "candles, lantern, ship's police ", and in their present
condition might be reckoned upon to burn four or five hours; so with
the stock at their command the fugitives were not likely to be
compelled to sit in the darkness.

Slowly the long day passed. At intervals the voices of the pirates
could be heard, as they returned to the boat apparently to hold a
council as to the next course to pursue. Black Strogoff had
abandoned his delivery of an ultimatum. He was still sanguine of
success, since the discovery of the wreckage of the life-boat and the
hot ashes of the camp-fire proved almost conclusively that his quarry
was on the island and unable to leave it.

At last night fell upon the scene. Although it made no visible


difference to the interior of the cave, the darkness was noticed by
the four fugitives mainly by the change of temperature, and the fact
was confirmed when Burgoyne cautiously drew the screen and
looked out.

"We'll have to be jolly careful with that light now," he observed. "A
glimmer escaping and shining on the brushwood would give the
show away in a brace of shakes. Put the candle in the old chest,
Jasper; that will screen it a bit."

After a cold supper Hilda and Mostyn dropped off into fitful
slumbers. Alwyn and Jasper remained on watch, straining their ears
to catch any sound that might indicate the presence and occupation
of their pursuers.

Soon there were no doubts on the matter. The rogues had not
gone on board the schooner but were carousing on shore. Some of
them in wanton mischief and with the lust of destruction had fired
the brush-wood. The roaring of the flames outvoiced that of the
pirates, but fortunately the nor'east wind kept the fire from
spreading towards the mouth of the cave.

"They're going it strong," remarked Burgoyne. "It must be long


after midnight. They've started to quarrel now, I think."

"An' the li'l ole cask," said Minalto broodingly. "Ef I'd but taken ut
away...."

The distant pandemonium waxed and waned according to the


temper and excitability of the roysterers. The ribald singing was
succeeded by a volley of oaths and rifle-shots and blood-curdling
shrieks.

Minalto jogged his companion's elbow.

"That's fine!" he exclaimed with marked approval.

For the next hour the loud roar of the flames, as the fire
overwhelmed the coco-palms, completely muffled all other sounds,
but when at length, towards morning, the conflagration burnt itself
out, there was a strange uncanny silence.

"Have a caulk, sir," said Jasper. "I'll be wide awake, if you'm of a


mind to sleep."

"I think I will, then," replied Burgoyne gratefully, and for the next
two hours he slept like a log.

The slanting rays of the sun were penetrating the brushwood when
Alwyn awoke and lifted the canvas covering the entrance to the
cave. The air was thick with pungent smoke.

"Wake up, Peter!" exclaimed Burgoyne. "Stand by till we return.


We're going out to see what's doing."

CHAPTER XXV
The Tables Turned

Gripping the cutlass, Jasper Minalto followed the Third Officer into
the open air, or rather to the edge of the belt of undergrowth that
marked the fugitives' hiding-place.
This part of the island had undergone a complete transformation.
Trees, scrub, and grass had vanished, leaving an expanse of
blackened, still smouldering ashes. The lagoon, previously screened
from the mouth of the cave, was fully exposed to an extent of
almost a mile. On it, riding to a cable that hung perpendicularly from
the hawse-pipe, was the schooner, with her sails lowered but loosely
furled in a way that no self-respecting seaman would have been
guilty of performing. There was the camp, too, with the shelter
constructed from the wreckage of the life-boat lying upon the
ground, and a fire still burning in the fire-place.

But what particularly attracted the attention of the two men was
the sight of half a dozen or more motionless figures lying in strange
attitudes upon the ground.

"By Jove!" exclaimed Burgoyne. "Minalto, my lad, your li'l ole cask
has done us a good turn. They're all dead drunk. Two, four, six, eight
of them. One's not accounted for. We'll risk that one. Stop here, and
don't let yourself be seen. I'll go back and bring Mostyn along."

Burgoyne returned to the cave.

"Game for a big stunt, Peter?" he inquired.

"Rather, I'm on," replied Mostyn promptly. "What's doing?"

"Bring as much rope as you can carry," said Alwyn, "and come
along. We've got them cold. Yes, and bring Minalto's spear. We may
have to do a bit of gentle persuasion in the clubbing line."

The three men advanced cautiously upon the silent forms of the
prostrate pirates, but it was not until they were within twenty paces
of their intended prey that Burgoyne checked his companions.

No words were necessary. The three men could see for themselves
what had happened.
There were eight pirates all dead. One, a Malay, was lying with his
head and shoulders in the still-smouldering embers. The others, all
bearing wounds of bullets or knives, had fought to a finish. Jasper's
li'l ole cask had vindicated its existence. Unused to spirits for months
past, the pirates had hailed the discovery of the keg with wild
delight. The potent stuff had made them mad drunk, and in their
beastly state of intoxication they had quarrelled, using knives and
rifles to back up their senseless arguments until all had fallen.
Apparently the Malay had survived the others, but had rolled
helplessly into the fire.

"Sarve 'em right!" exclaimed Jasper.

None of the three men felt any sense but that of gratitude for their
deliverance. Humane though they undoubtedly were, they had no
pity for the ruffianly crew now lying dead almost at their feet.

"Now for the schooner!" exclaimed Peter, stooping and securing a


rifle and ammunition that had belonged to one of the villainous dead
—an example which Jasper was not slow to follow.

"Steady!" cautioned Burgoyne. "There are eight here; where is the


ninth?"

"Black Strogoff?"

"Ay; he'll want watching. He's not on board."

"How do you know that?" asked Mostyn.

"The boat isn't alongside. Come on; we'll find her along the beach."

Skirting the shore of the little creek, they gained the beach fronted
by the lagoon. Rather more than a stone's throw away was the
schooner's boat with her bow a good twelve feet from the water's
edge. Tugging and straining at the boat was Black Strogoff, trying in
vain to anticipate the rising tide by launching the small but heavily-
built dinghy into the water.

Revolver in hand, Burgoyne stealthily approached the pirate


lieutenant. The latter, furtively turning his head, caught sight of the
three men whose capture he had so ardently desired, and now as
devotedly wished to avoid.

"Hands up, Strogoff!" ordered Burgoyne.

For answer the rogue whipped out an automatic, at the same time
kneeling behind the boat and resting the muzzle of the weapon on
the gunwale.

Without hesitation Mostyn and Jasper both raised their rifles and
took rapid aim. Both weapons barked simultaneously, even as Black
Strogoff wildly loosed ten rounds from his pistol. The next instant
the automatic was violently wrenched from the pirate-lieutenant's
hand, leaving Strogoff not only defenceless, but with a dislocated
wrist and his face cut in half a dozen places by fragments of the
splayed nickel bullet.

"Surrender!" shouted the Third Officer, brandishing his revolver as


he leapt towards the pirate.

Strogoff had not the faintest desire to avail himself of the offer. He
knew that capture meant death at the rope's end.

"Shoot away!" he replied tauntingly.

Burgoyne did nothing of the sort. It was one thing to exchange


shots in hot blood with a criminal; another to strike a human being
down in cold blood.

Strogoff saw the Englishman's hesitation and took his chance.


Wading waist-deep, he began swimming for the schooner, which was
lying at anchor less than four hundred yards distant.
"Don't fire!" cautioned Alwyn.

"Don't mean to," rejoined Peter, snapping the safety-catch of his


rifle.

"Launch the boat," continued Burgoyne. "We'll nab him long before
he gains the schooner."

It was a man-hunt with a vengeance. The excitement of the chase


provided far greater scope than merely shooting the swimmer
through the head. To effect a capture appealed to their sporting
instincts. Taking human life, or any animal life for that matter, did
not, unless there were ample justification for it.

"What are you going to do with him?" asked Peter, when by the
united efforts of the three men the boat was launched and the oars
manned.

"Maroon him on the island," replied Burgoyne grimly. "He'll have


the same chances as we did, anyway, and if he wins through——"

He stopped suddenly, let go the tiller, and sprang to his feet.

"Your rifle—quick, Peter!" he exclaimed hurriedly.

Mostyn handed over the weapon. The rowers laid on their oars and
turned their heads to see what their companion was aiming at.

Black Strogoff was now only fifty yards ahead, swimming strongly
in spite of his broken wrist, but close behind him was a dark,
triangular-shaped object following the disturbed wake of the
swimmer.

It was the dorsal fin of an enormous shark.

The pirate, unconscious of the dire peril that threatened him, swam
steadily towards the schooner. Burgoyne, looking along the sights of
the rifle, hesitated to fire, for the shark and the swimmer were in
line with the muzzle. He might hit the shark, but the bullet would
then ricochet and settle Strogoff into the bargain.

"Look out!" shouted the Third Officer. "Sharks!"

At the warning the pirate-lieutenant turned his head just in time to


see the monster's dorsal fin disappear. The shark was turning on its
back in order to seize its prey.

With a blood-curdling scream Black Strogoff threw up his arms and


disappeared.

Thirty seconds later the boat was over the spot, where an ever-
widening circle of ripples surrounded the blood-tinged patch that
indicated the manner of Black Strogoff's death.

Burgoyne, pale under his tan, slipped the safety-catch of his rifle,
laid the weapon in the stern-sheets, and resumed the tiller. As he did
so he noticed that the boat's bottom boards and gratings were
awash.

Kicking aside the stern-sheets grating, Alwyn felt for the plug. It
was in position and jammed hard into the bung-hole.

"We've sprung a leak!" exclaimed Mostyn, stating an obvious fact;


then, laying aside his oar, he quickly extracted a cartridge from one
of the rifles, and inserted the bullet in a small hole just under the
middle thwart.

Peter and Jasper exchanged meaning glances. One of the two had
fired the shot that had completely penetrated both sides of the boat,
although one of the holes was above water-line. Each, by that
glance, tried to insinuate that the other was the culprit, at the same
time proving that the shot that had disabled Black Strogoff was his.
"We'll appraise responsibility when we've finished the job," declared
Burgoyne. "Now, steady all. Give way."

Keeping a keen watch on the apparently deserted schooner, the


Third Officer steered the boat in her direction, holding a rifle ready
to fire at the first sign of resistance.

"Easy all! Lay on your oars," ordered Burgoyne.

The boat, being bluff-bowed and laden, soon lost way, drifting idly
at a distance of about twenty yards from the schooner.

Burgoyne fancied he heard a scuffling sound like metal being


dragged across the deck. It might have been the grinding of the
badly secured main-boom and yard as the vessel rolled sluggishly in
the gentle swell.

"Take both oars, Minalto," continued Burgoyne. "Peter, old son,


stand by with a rifle. Unless I'm much——"

Before he could complete the sentence the head and shoulders of a


negro appeared above the low bulkhead. There was a flash, and a
bullet sung past Burgoyne's right ear.

The rifles of the two Englishmen cracked in unison. Leaping a full


three feet in the air, the negro fell writhing across the rail, and,
slowly overbalancing, toppled into the sea.

The boarders waited, finger on trigger, for a full minute. All was
quiet on board. Burgoyne judged it prudent to take possession of
the craft.

"Stroke ahead, Jasper.... Good enough."

Minalto fended off the dinghy as she ranged up alongside. Then,


holding the slack of the painter in his left hand, he grasped the main
shrouds and swung himself on to the chain-plate.
Burgoyne was about to follow Minalto's example when Jasper,
relinquishing his hold and raising a shout of alarm, fell backwards.
Missing the gunwale of the boat by a hair's-breadth, he fell with a
terrific splash into the water. Where his hand had been grasping the
bulwark not a second before, a glittering knife was quivering, its
point sunk an inch deep into the teak rail.

Leaving Jasper to shift for himself, Burgoyne leapt on deck just in


time to see Ah Ling disappearing into a low deck-house just for'ard
of the wheel.

The door crashed to. Alwyn could hear the Chinaman hurriedly
barricading it. Then a spurt of flame leapt from one of the side
scuttles, and a revolver bullet chipped the mainmast.

"Keep where you are, Peter!" shouted Burgoyne. "I'll manage this
part of the show. Where's Minalto?"

"In t' boat," replied that worthy.

"Hurt?"

"No, sir."

"Then stay there," said the Third Officer peremptorily.

Burgoyne had already thrown himself flat upon the deck behind the
raised coaming of the main hatch. With his rifle by his side he
exposed no more than a part of his head, his right shoulder and arm
to the fire of the trapped Chinaman.

Ah Ling was evidently prepared to put up a stiff fight. With Oriental


fatalism he seemed to realize that his chance of escape was
hopeless, but at the same time he had no intention of surrendering.
Nor had Burgoyne any desire to invite the Chink to give himself up,
for with Ah Ling a prisoner the fugitives would be constantly in fear
that the Celestial would free himself. And Alwyn had had experience
of the ferocity and diabolical cunning of Chinese.

"'Tany rate," he soliloquized. "It's a fair scrap. One against one, not
three."

A hand grasping an automatic appeared through one of the scuttles


on the port side of the deck-house. Burgoyne promptly fired at it.
The hand remained, although the marksman felt sure that at that
comparatively short range it was impossible to miss.

Ejecting the still-smoking cylinder, Burgoyne thrust another


cartridge into the breech, keeping the cut-off of the magazine closed
in order to provide against the possibility of a blind rush on the part
of his yellow antagonist.

At the second shot the automatic fell to the deck and the hand was
withdrawn. Yells of pain issued from the deck-house.

"That's got him!" ejaculated Burgoyne, and, springing to his feet,


he rushed towards Ah Ling's retreat. It was a false, almost fatal
move, for as the Third Officer emerged from behind the cover of the
hatchway a tongue of flame leapt from the deck-house close to the
rise of the door-step. The bullet literally sent some of the
Englishman's hair flying.

Partly dazed by the nickel missile, Burgoyne retained sufficient


presence of mind to drop flat upon the deck and wriggle back to his
cover, but not before Ah Ling had fired two more shots that were
quite ineffectual.

Burgoyne decided that he was up against a tough proposition. He


had to take into consideration the fact that he was not only fighting
a well-armed man but a wily one into the bargain. Ah Ling had
certainly got the best of the first round, for Alwyn's rifle was lying on
the deck beyond reach of his hand and in an uninterrupted line of
fire from the deck-house.
"That hand was a dummy," decided Burgoyne. "The whole time the
Chink was lying on the deck waiting for me. When I get hold of that
rifle again, I'll let him know what's what."

He scorned the idea of calling upon his comrades to throw him


another rifle, nor would he entertain the suggestion that they should
join in the scrap. Somehow it didn't seem quite British. The odds
were level, and that appealed to his sense of fair play.

Keeping close to the deck, Burgoyne crawled to the base of the


main-mast, thanking his lucky stars that nine inches of heavy oak
faced with iron comprised the construction of the main-hatch
coaming. That was sufficient to stop a bullet, otherwise Ah Ling
would have raked the woodwork and rendered the Englishman's
position untenable.

From the spider band of the main-mast Alwyn took a coil of light
rope. With this he retraced his course, and, arriving at his "sniper's
post", proceeded to throw a bight of the rope over the rifle until it
engaged in the upturned bolt.

"That's the ticket!" he chuckled, as he retrieved the weapon. "Now,


my festive Chink, you're going to have the time of your life."

Aiming at the lower part of the door at a height of a foot or


eighteen inches from the deck, Burgoyne sent bullet after bullet
crashing through the woodwork; then, varying the performance, he
peppered the whole exposed front of the deck-house indiscriminately
until he could see daylight through it.

Not a sight nor a sound of the Celestial could be seen or heard.

"No hurry," decided Alwyn, bearing in mind his former rashness.


"By Jove! This is where a stink-bomb would come in jolly handy."

"When you've done smashing up his happy home, old bird!" sung
out Mostyn from the dinghy, "where do we come in?"
"You sit tight," replied Burgoyne. "The Chink very nearly pipped
me. He's as artful as a waggon-load of monkeys. I'll let you know
when you're wanted."

Placing his rifle by his side, Alwyn resumed his passive attitude
towards the silent and invisible Celestial. There could be very little
doubt, he reasoned, that Ah Ling had survived that fusillade.

For quite five minutes he remained on the alert, but a strange,


uncanny silence seemed to brood over that bullet-riddled structure.

"I'll put in five more rounds," he decided. "Then I'll investigate at


close quarters. The blighter must be done in absolutely by this time."

He was on the point of carrying his intention into effect when


Mostyn hailed excitedly:

"He's done you, my festive! The Chink's half-way to shore."

Burgoyne sprang to his feet and looked over the side. Swimming
towards the little inlet was a Chinaman, bareheaded and with his
pigtail trailing in the water. Ah Ling, he knew, wore a pigtail. Very
few of the Chinese pirates did, but he was evidently not a believer in
the Western craze that was sweeping over the yellow republic. But it
might be just possible that there had been a third man on board the
schooner.

Unhesitatingly the Third Officer ran aft and peered into the riddled
deck-house. It was empty as far as human beings were concerned.
There were a couple of rifles and several pistols, while raised at an
angle of about 45 degrees to the floor was a sheet of steel that,
while not stout enough to stop a direct hit, was capable of deflecting
an obliquely striking bullet.

Unseen and unheard, Ah Ling had abandoned his defences and had
slipped over the taffrail. He was now within fifty yards of the shore,
where, to the horror of Burgoyne and his companions, Hilda Vivian
was standing gazing with perplexity at the captured schooner.

CHAPTER XXVI
The Fate of Ah Ling

"I've made a thorough mess of things this time," thought Alwyn,


angry with himself that his idea of a "one man show" had run Miss
Vivian into danger. "If I'd had Peter and Minalto to bear a hand, we'd
have settled the Chink on the spot."

Jumping into the stern-sheets of the dinghy, Burgoyne urged his


companions to "pull like blue smoke", then, shouting at the top of
his voice, he warned Hilda of her peril.

Hitherto the girl's attention had been centred on the dinghy lying
alongside the schooner. She had heard the fusillade, and, unable to
remain any longer in suspense, she had left the cave and made her
way to the shore, fortunately giving the site of the camp and its
ghastly occupants a wide berth.

The fact that Peter and Jasper were in the boat reassured her to a
great extent, but she could not think of a satisfactory explanation of
Burgoyne's disappearance.

The Third Officer's stentorian warning called her attention to the


yellow, expressionless features of the Chinaman as he swam for the
beach. For a moment Hilda hesitated, half inclined to swim off to
meet the rapidly approaching boat, but the danger of being
intercepted by the Celestial urged her to make for the cave.
She had a little less than a hundred yards start when Ah Ling
gained the shore. Brandishing a knife in one hand and an automatic
pistol in the other, he ran in pursuit.

Thrice did Alwyn fire at the Chinaman before he disappeared


behind the palm trees, but the jerky motion of the boat spoilt his
aim. Ah Ling paid not the faintest attention to the shots. He seemed
to ignore the fact that he was being pursued, and devoted all his
energies to overtake the terrified girl. In short, he had a fixed idea
that he would soon be killed, but before he died he would take care
to slay the "white she-devil", in quest of whom his companions had
met with utter disaster.

Well before the dinghy's forefoot grounded on the sandy beach,


Burgoyne leapt out of the boat and ran in the direction taken by
Hilda and the Chinaman, Mostyn being a good second, while the
heavily built Minalto followed at his top speed, which was barely half
that of his agile companions.

Alwyn had discarded his rifle on account of the weight of the


weapon, trusting to his small but powerful revolver. The others
carried rifles, Jasper in addition having the naked cutlass stuck in his
leather belt.

The dull thud of Ah Ling's wooden shoes upon the hard ground
guided them until with uncanny suddenness the sounds ceased. The
hitherto clearly defined trail of moisture dropping from the
Chinaman's sodden clothes also failed. Burgoyne, revolver in hand,
found himself standing at the junction of two forked paths, utterly
uncertain which direction to take.

He was afraid to shout to Hilda lest her reply should betray her
whereabouts. Listening intently, he could hear nothing of either the
pursued or the pursuer.

"Take that path, Peter!" he said hurriedly, as Mostyn overtook him.


"I'll take this one. Let the brute have it on sight if you spot him."
[Illustration: THE FATE OF AH LING]

Alwyn, following the left-hand branch of the fork, had barely


covered a hundred paces when he almost stumbled over the
motionless figure of Hilda Vivian lying face downwards in a patch of
trodden grass. Before he could get to the girl he heard a heavy body
crashing through the brushwood.

Wild with fury and desperate to wreck vengeance upon the


Chinaman, Alwyn dashed in pursuit, forcing his way at breakneck
speed through the dense undergrowth. With feelings of grim
satisfaction he realized that he was gaining on the object of his
pursuit.

Meanwhile Jasper Minalto, proceeding as fast as he could along the


path, was beginning to grasp the fact that his companions were
forging ahead hand over fist. More than once the cutlass nearly
tripped him up, and the weight of the rifle proved a heavy
encumbrance. Pausing for breath, he laid his rifle against the trunk
of a tree, removed the cutlass from his belt, taking in the slack of
the latter.

The temporary halt had caused the perspiration to run freely.


Before he resumed his way he was obliged to wipe the moisture
from his face and eyes with the broad leaf of a large plant.

Then, grasping the cutlass, he was about to start running again,


when to his surprise he saw Ah Ling's head and shoulders cautiously
appear from behind a clump of canes.

The Chinaman's tactics were fairly obvious. He had worked to the


rear of his pursuers by a circular route, hoping to be able to take
them unawares and shoot them down. His strategy was good up to
a certain point. He had reckoned that the three white men would
keep together, not knowing that the giant Scillonian was eighty yards
or more behind the others.

Well it was that Minalto had made no sound during his brief halt;
and so intent was Ah Ling upon stalking his foes that he was quite
unaware that one of them was stalking him.

There were moments when the usually slow-working mind of


Jasper Minalto moved rapidly, and this was one of them. In a trice
the now keen cutlass, wielded by a brawny muscular arm, flashed in
the sunlight. The swish of the blade through the air was followed by
a dull, indescribable thud, as Ah Ling's head parted company with
his shoulders.

During the Great War Jasper Minalto had seen some ghastly sights.
He had served on board a Q-boat when shells from a U-boat were
taking heavy toll of the devoted crew; he had seen the same Q-boat,
almost a wreck, suddenly spring into activity and send the Boche to
the bottom with one well-directed salvo. On another occasion the
same ship had rammed a U-boat with all hands. And on board the
Donibristle he had seen his unresisting comrades mown down by
shells from the pirate Malfilio. But never before had he knowingly
killed a man. He had assisted in the slaughter of dozens, but that
was hardly the same thing as personally sending a human being—
even though he were a Chinese pirate and ruffian—into the
unknown The thought of it made him feel sick. Like most men of
great stature, he was a child at heart, although brought up in a
rough school.

Having deliberately cleaned the blade of the cutlass by thrusting it


into the ground, Jasper leisurely resumed his way. He decided that,
Ah Ling being of no further account, there was no need to exert
himself. At the fork of the path he stopped irresolutely, until a rifle-
shot fired at no great distance stirred him to action.
Hurrying along the left-hand path, he, too, almost stumbled over
the unconscious form of Hilda Vivian. Her white canvas coat was
stained with blood that flowed copiously from a small wound in the
left shoulder.

Horror stricken, Jasper raised the girl. Then in helpless perplexity


he raised his voice and shouted, calling to Burgoyne for aid.

Totally unaware of the rapid events of the last few minutes, Alwyn
was closely following up his prey. Suddenly he noticed a movement
in the brushwood, not five yards ahead of him. Raising his revolver,
he sent a bullet straight at the writhing object. An unearthly groan
followed the report of the weapon, and a heavy body collapsed on
the hard ground.

"That's done for you!" ejaculated Burgoyne wrathfully.

Then, tearing aside the undergrowth, he found that the supposed


Chinaman was a young boar, killed outright by the severing of the
spinal cord.

Alwyn decided that his luck was right out. There was Hilda lying
murdered while her ruffianly assailant Ah Ling had escaped, and was
probably hiding safe from pursuit in the dense undergrowth that
covered the greater part of the island.

"I'll have the brute yet," he vowed, "even if we have to burn the
rest of the scrub."

He was on the point of hailing Mostyn to warn him of what had


occurred, when he heard his own name shouted in a voice that he
hardly recognized as Minalto's.

Retracing his course, Burgoyne found Jasper trying to restore Miss


Vivian to consciousness.
"I've lost the blighter, Jasper," announced Alwyn regretfully. "He's
somewhere in the scrub."

"He is, sir," agreed Minalto with firm conviction.

"I'd give my right hand," continued the Third Officer, "to see Ah
Ling dead as a door-nail."

"Then put it here, sir," rejoined Jasper, extending his hand.

"What do you mean?" demanded Burgoyne.

"Same's what I was a-sayin', sir," replied the imperturbable man,


for his agitation had vanished at his companion's return. "But seems
best as if we wur tu tak the young leddy out o' this. She ain't much
hurt as I can see. Looks more like a graze than a bullet hole or a
stick wi' a knife."

"Right-o," agreed Alwyn. "What we want is fresh water to dress the


wound. Yes, you're right, Jasper; it is a graze."

Burgoyne raised the unconscious girl.

"Best let me, sir," interposed Jasper. "Seein' as' 'ow we might be
fallin' foul of that there Chink, an' I left me rifle up along."

Realizing the soundness of Minalto's advice but ignorant of the


motives that prompted the tendering of it, Burgoyne transferred the
girl's limp form to Jasper's massive arms. Then, with his revolver
ready for instant use, Alwyn led the way back to the spring hard by
the devastated camp.

Suddenly he stopped dead, hardly able to credit the evidence of his


eyes, for lying in his path was the head of the pirate Ah Ling.

Burgoyne glanced over his shoulder and met the stolid gaze of his
companion.
"You did this, then," he said.

"Ay, ay, sir," was the calm admission.

"Then why on earth didn't you tell me?"

"I never was axed; arter all, it wurn't much tu brag about, seeing
as 'ow I took 'im unawares-like. An' me bein' a quiet, well-disposed
man. But, there, sir; I did gi' ye my 'and when you offered yours, so
you'm no call to say I didn't warn 'ee."

Although considerably nettled by the bad breakdown of his method


of conducting operations, Burgoyne was quite ready to admit that
the fault was his. After all, success had crowned the united efforts of
the castaways. Black Strogoff, Ah Ling, and the rest of the pirates
were back numbers, and the schooner was a prize to Burgoyne and
his companions. As an off-set Hilda Vivian had been stricken down,
but how as yet remained an unsolved problem. Had the Chinaman
been her assailant she would not have got off so lightly.

For her injuries were found to be slight. Beyond the wound in her
shoulder and a slight gash on her forehead there were no evidences
of injury.

Deftly Burgoyne and Minalto dressed the hurts and bathed her
temples and wrists in cold water. By the time Peter Mostyn returned,
having scoured the greater part of the island in an unsuccessful
search, Hilda was able to sit up.

She was considerably shaken, and her nerves, already subjected to


a severe strain, were on edge, but she was able to give a clear
account of her adventures after the three men had sallied forth from
the cave to try conclusions with the crew of the schooner.

For a considerable time after their departure Hilda remained in her


retreat, until, unable to resist her anxiety, she had cautiously made
her way down to the shore, without seeing anything of the dead
pirates lying around the ashes of the camp-fire.

When Burgoyne's shouts warned her of her peril, the girl saw Ah
Ling's evil face as he swam towards the shore. Once she made up
her mind she started to return to the cave, but the Chinaman had
already cut off her retreat in that direction; or at all events she
would not have been able to regain the shelter without betraying its
whereabouts.

So she took to the woods, hoping either to elude the Chinaman or


else to make a circuitous route back to the beach, where by that
time Burgoyne and his companions would have landed.

Then, as luck would have it, a boar dashed out of the undergrowth,
and, charging, threw her violently to the ground. She remembered
nothing more until she found herself on the shore with Burgoyne
and Jasper bathing her face and hands with cold water.

"There's nothing now to fear from the pirates," Alwyn reassured


her. "We've captured the schooner, and as soon as we can we'll
leave Swan Island astern of us. But try and get a few hours' quiet
sleep. By that time we ought to be ready to go aboard."

Hilda obeyed readily enough. She was too weak to do otherwise,


although she would have liked to take an active part in the
preparations for continuing the interrupted voyage.

"Now, lads," said Burgoyne. "We've work to do, and the sooner the
better. We'll have to make the schooner habitable. I don't know what
she's like 'tween decks, but I can guess. And another thing: Miss
Vivian mustn't be allowed to see our old camp. We'll square things
up a bit, but that isn't everything."

"I suppose the schooner's properly moored," remarked Mostyn.


"I doubt it. Single anchor," replied Alwyn. "We'll tow her into the
creek at high water; there'll be depth enough and more over the bar,
and once inside she'll be safer and easier to provision."

While waiting for sufficient depth of water to float the captured


schooner into the creek, Burgoyne and his companions proceeded to
the spot where lay the bodies of the eight pirates. As they expected,
nothing of use was left in the camp. Even the bow and stern
portions had been smashed up and burnt, but the staves of Minalto's
li'l ole cask were still in evidence.

Presently Peter touched Alwyn's arm.

"Come here a minute," he said, and led him to where one of the
men lay with his skull battered in, and a broken rifle by his side.

"Good heavens!" ejaculated Burgoyne. "It's Miles, or what's left of


him."

The treacherous Canuk bagman had met with his just deserts. It
was he who had betrayed the identity of Young Bill, hoping to curry
favour with the pirate leaders. Black Strogoff, in Ramon Porfirio's
absence, decided to act upon the information, but he was a few
hours too late. Miles's reward was not at all what he expected. He
was curtly ordered to join the band of pirates told off to man the
schooner that was to set sail in pursuit of the English girl and her
three companions. And the traitor was to a great extent responsible
for the disaster that had overtaken the pursuers, for it was he who
had found the li'l ole keg, and had started the quarrel when most of
the men were drunk with the well-matured rum.
CHAPTER XXVII
Farewell to Swan Island

Launching the dinghy, Burgoyne and his companions rowed off to


the schooner. It was now close on high water and the wind had
dropped to almost a flat calm. Laboriously they manned the winch
until the cable was up and down, then for half an hour they toiled
before they succeeded in breaking out the heavy anchor from the
tenacious hold of the bed of the lagoon. Then followed a strenuous
task under the broiling rays of the afternoon sun as they towed the
vessel into the creek.

By that time Burgoyne realized that he had been over sanguine in


his surmise. He had not taken into account the almost inevitable
hitches in his plans, and he had forgotten the now patent fact that
none of them had had a good sleep for the last thirty hours.

"She'll lie there nicely," he decided, as the anchor was let go and a
stout warp taken ashore and made fast to a sturdy palm tree. "We'll
spend the rest of the day making everything ship-shape, but I don't
quite fancy sleeping aboard to-night."

The work of cleansing this maritime Augean stables proceeded with


a will, for the schooner was indescribably filthy both on deck and
below. Her paraffin motor was in a terribly neglected state, so that it
was a source of wonder to Alwyn and Peter that the pirates ever
succeeded in getting the engine to perform duty at all. Most of the
running gear was good, having been renewed from cordage taken
from the captured merchantmen; but the sails, though serviceable in
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebooknice.com

You might also like