Functional Python Programming Discover the power of functional programming generator functions lazy evaluation the built in itertools library and monads 2nd Edition Steven F. Lott all chapter instant download
Functional Python Programming Discover the power of functional programming generator functions lazy evaluation the built in itertools library and monads 2nd Edition Steven F. Lott all chapter instant download
com
https://textbookfull.com/product/business-cycle-dynamics-and-
stabilization-policies-a-keynesian-approach-1st-edition-hajime-hori-
auth/
textbookfull.com
Paperback Therapy: Therapist-approved tools and advice for
mastering your mental health 1st Edition Tammi Miller
https://textbookfull.com/product/paperback-therapy-therapist-approved-
tools-and-advice-for-mastering-your-mental-health-1st-edition-tammi-
miller/
textbookfull.com
Finding Places The Search for the Brain s Gps 1st Edition
Unni Eikeseth
https://textbookfull.com/product/finding-places-the-search-for-the-
brain-s-gps-1st-edition-unni-eikeseth/
textbookfull.com
https://textbookfull.com/product/the-morals-of-the-market-human-
rights-and-the-rise-of-neoliberalism-jessica-whyte/
textbookfull.com
https://textbookfull.com/product/control-systems-and-transients-for-
competitive-exams-1st-edition-rony-parvez/
textbookfull.com
NFPA 70 National Electrical Code 1st Edition Coll.
https://textbookfull.com/product/nfpa-70-national-electrical-code-1st-
edition-coll/
textbookfull.com
Functional Python
Programming
Second Edition
%JTDPWFSUIFQPXFSPGGVODUJPOBMQSPHSBNNJOHHFOFSBUPS
GVODUJPOTMB[ZFWBMVBUJPOUIFCVJMUJOJUFSUPPMTMJCSBSZBOE
NPOBET
Steven F. Lott
BIRMINGHAM - MUMBAI
Functional Python Programming
Second Edition
Copyright a 2018 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form
or by any means, without the prior written permission of the publisher, except in the case of brief quotations
embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented.
However, the information contained in this book is sold without warranty, either express or implied. Neither the
author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to
have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products
mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy
of this information.
ISBN 978-1-78862-706-1
XXXQBDLUQVCDPN
NBQUJP
Mapt is an online digital library that gives you full access to over 5,000 books and videos, as
well as industry leading tools to help you plan your personal development and advance
your career. For more information, please visit our website.
Why subscribe?
Spend less time learning and more time coding with practical eBooks and Videos
from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
PacktPub.com
Did you know that Packt offers eBook versions of every book published, with PDF and
ePub files available? You can upgrade to the eBook version at XXX1BDLU1VCDPN and as a
print book customer, you are entitled to a discount on the eBook copy. Get in touch with us
at TFSWJDF!QBDLUQVCDPN for more details.
At XXX1BDLU1VCDPN, you can also read a collection of free technical articles, sign up for a
range of free newsletters, and receive exclusive discounts and offers on Packt books and
eBooks.
About the author
Steven F. Lott has been programming since the '70s, when computers were large,
expensive, and rare. He's been using Python to solve business problems for over 10 years.
His other titles with Packt Publishing include Python Essentials, Mastering Object-Oriented
Python, Functional Python Programming, and Python for Secret Agents. Steven is currently a
technomad who lives in city along the east coast of the U.S. You can follow his technology
blog (slott-softwarearchitect).
About the reviewer
Yogendra Sharma is a developer with experience in architecture, design, and development
of scalable and distributed applications. He was awarded a bachelorbs degree from the
Rajasthan Technical University in computer science. With a core interest in microservices
and Spring, he also has hands-on experience in technologies such as AWS Cloud, Python,
J2EE, NodeJS, JavaScript, Angular, MongoDB, and Docker.
Currently, he works as an IoT and Cloud Architect at Intelizign Engineering Services Pune.
Summary 58
Chapter 4: Working with Collections 60
An overview of function varieties 61
Working with iterables 61
Parsing an XML file 63
Parsing a file at a higher level 65
Pairing up items from a sequence 67
Using the iter() function explicitly 70
Extending a simple loop 71
Applying generator expressions to scalar functions 74
Using any() and all() as reductions 76
Using len() and sum() 79
Using sums and counts for statistics 79
Using zip() to structure and flatten sequences 82
Unzipping a zipped sequence 84
Flattening sequences 84
Structuring flat sequences 86
Structuring flat sequences – an alternative approach 88
Using reversed() to change the order 89
Using enumerate() to include a sequence number 90
Summary 91
Chapter 5: Higher-Order Functions 92
Using max() and min() to find extrema 93
Using Python lambda forms 97
Lambdas and the lambda calculus 98
Using the map() function to apply a function to a collection 99
Working with lambda forms and map() 100
Using map() with multiple sequences 101
Using the filter() function to pass or reject data 103
Using filter() to identify outliers 104
The iter() function with a sentinel value 105
Using sorted() to put data in order 106
Writing higher-order functions 108
Writing higher-order mappings and filters 108
Unwrapping data while mapping 110
Wrapping additional data while mapping 112
Flattening data while mapping 114
Structuring data while filtering 116
Writing generator functions 117
Building higher-order functions with callables 120
Assuring good functional design 121
Review of some design patterns 123
[ ii ]
Table of Contents
Summary 124
Chapter 6: Recursions and Reductions 126
Simple numerical recursions 127
Implementing tail-call optimization 128
Leaving recursion in place 129
Handling difficult tail-call optimization 130
Processing collections through recursion 131
Tail-call optimization for collections 132
Reductions and folding a collection from many items to one 134
Group-by reduction from many items to fewer 136
Building a mapping with Counter 137
Building a mapping by sorting 138
Grouping or partitioning data by key values 140
Writing more general group-by reductions 143
Writing higher-order reductions 144
Writing file parsers 146
Parsing CSV files 148
Parsing plain text files with headers 150
Summary 153
Chapter 7: Additional Tuple Techniques 154
Using tuples to collect data 155
Using named tuples to collect data 157
Building named tuples with functional constructors 160
Avoiding stateful classes by using families of tuples 161
Assigning statistical ranks 165
Wrapping instead of state changing 167
Rewrapping instead of state changing 168
Computing Spearman rank-order correlation 170
Polymorphism and type-pattern matching 171
Summary 178
Chapter 8: The Itertools Module 179
Working with the infinite iterators 180
Counting with count() 181
Counting with float arguments 182
Re-iterating a cycle with cycle() 184
Repeating a single value with repeat() 186
Using the finite iterators 187
Assigning numbers with enumerate() 188
Running totals with accumulate() 190
Combining iterators with chain() 191
Partitioning an iterator with groupby() 192
Merging iterables with zip_longest() and zip() 194
Filtering with compress() 194
[ iii ]
Table of Contents
[ iv ]
Visit https://textbookfull.com
now to explore a rich
collection of eBooks, textbook
and enjoy exciting offers!
Table of Contents
[v]
Table of Contents
[ vi ]
Table of Contents
Index 378
[ vii ]
Preface
Functional programming offers a variety of techniques for creating succinct and expressive
software. While Python is not a purely functional programming language, we can do a
great deal of functional programming in Python.
Python has a core set of functional programming features. This lets us borrow many design
patterns and techniques from other functional languages. These borrowed concepts can lead
us to create succinct and elegant programs. Python's generator expressions, in particular,
negate the need to create large in-memory data structures, leading to programs that may
execute more quickly because they use fewer resources.
We canbt easily create purely functional programs in Python. Python lacks a number of
features that would be required for this. We donbt have unlimited recursion, for example,
we donbt have lazy evaluation of all expressions, and we donbt have an optimizing compiler.
There are several key features of functional programming languages that are available in
Python. One of the most important ones is the idea of functions being first-class
objects. Python also offers a number of higher-order functions. The built-in NBQ ,
GJMUFS , and GVODUPPMTSFEVDF functions are widely used in this role, and less-
obvious are functions such as TPSUFE , NJO , and NBY .
Webll look at the core features of functional programming from a Python point of view. Our
objective is to borrow good ideas from functional programming languages and use those
ideas to create expressive and succinct applications in Python.
In some cases, a functional approach to a problem will also lead to extremely high-
performance algorithms. Python makes it too easy to create large intermediate data
structures, tying up memory (and processor time.) With functional programming design
patterns, we can often replace large lists with generator expressions that are equally
expressive but take up much less memory and run much more quickly.
Preface
$IBQUFS, Introducing Essential Functional Concepts, delves into six central features of the
functional programming paradigm. Webll look at each in some detail to see how theybre
implemented in Python. Webll also point out some features of functional languages that
donbt apply well to Python. In particular, many functional languages have complex type-
matching rules required to support compiling and optimizing.
$IBQUFS, Functions, Iterators, and Generators, will show how to leverage immutable Python
objects, and generator expressions adapt functional programming concepts to the Python
language. Webll look at some of the built-in Python collections and how we can leverage
them without departing too far from functional programming concepts.
$IBQUFS, Working with Collections, shows how you can use a number of built-in Python
functions to operate on collections of data. This chapter will focus on a number of relatively
simple functions, such as BOZ and BMM , which will reduce a collection of values to a
single result.
$IBQUFS, Recursions and Reductions, teaches how to design an algorithm using recursion
and then optimize it into a high-performance GPS loop. Webll also look at some other
reductions that are widely used, including DPMMFDUJPOT$PVOUFS .
$IBQUFS, Additional Tuple Techniques, showcases a number of ways that we can use
immutable tuples (and namedtuples) instead of stateful objects. Immutable objects have a
much simpler interfacecwe never have to worry about abusing an attribute and setting an
object into some inconsistent or invalid state.
$IBQUFS, The Itertools Module, examines a number of functions in this standard library
module. This collection of functions simplifies writing programs that deal with collections
or generator functions.
[2]
Preface
$IBQUFS, More Itertools Techniques, covers the combinatoric functions in the itertools
module. These functions are somewhat less useful. This chapter includes some examples
that illustrate ill-considered use of these functions and the consequences of combinatoric
explosion.
$IBQUFS, The Functools Module, focuses on how to use some of the functions in this
module for functional programming. A few functions in this module are more appropriate
for building decorators, and they are left for $IBQUFS, Decorator Design Techniques. The
other functions, however, provide several more ways to design and implement function
programs.
$IBQUFS, Decorator Design Techniques, looks at how you can look at a decorator as a way
to build a composite function. While there is considerable flexibility here, there are also
some conceptual limitations: webll look at ways that overly-complex decorators can become
confusing rather than helpful.
$IBQUFS, Conditional Expressions and the Operator Module, lists some ways to break out of
Pythonbs strict order of evaluation. There are limitations to what we can achieve here. Webll
also look at the operator module and how this can lead to slight clarification of some simple
kinds of processing.
$IBQUFS, The PyMonad Library, examines some of the features of the PyMonad library.
This provides some additional functional programming features. It also provides a way to
learn more about monads. In some functional languages, monads are an important way to
force a particular order for operations that might get optimized into an undesirable order.
Since Python already has strict ordering of f expressions and statements, the monad feature
is more instructive than practical.
$IBQUFS, A Functional Approach to Web Services, shows how we can think of web services
as a nested collection of functions that transform a request into a reply. Webll see ways to
leverage functional programming concepts for building responsive, dynamic web content.
[3]
Preface
Webll presume some familiarity with functional programming. Since Python is not a
functional programming language, we canbt dig deeply into functional concepts. Webll pick
and choose the aspects of functional programming that fit well with Python and leverage
just those that seem useful.
Some of the examples use exploratory data analysis (EDA) as a problem domain to show
the value of functional programming. Some familiarity with basic probability and statistics
will help with this. There are only a few examples that move into more serious data science.
Youbll need to have Python 3.6 installed and running. For more information on Python, visit
IUUQXXXQZUIPOPSH. The examples all make extensive use of type hints, which means
that the latest version of mypy must be installed as well.
Examples in $IBQUFS, More Itertools Techniques, use PIL and Beautiful Soup 4. The Pillow
fork of the original PIL library works nicely; refer to IUUQTQZQJQZUIPOPSHQZQJ
1JMMPX and IUUQTQZQJQZUIPOPSHQZQJCFBVUJGVMTPVQ.
Examples in $IBQUFS, The PyMonad Library, use PyMonad; check out IUUQTQZQJ
QZUIPOPSHQZQJ1Z.POBE.
[4]
Preface
Once the file is downloaded, please make sure that you unzip or extract the folder using the
latest version of:
The code bundle for the book is also hosted on GitHub at IUUQTHJUIVCDPN
1BDLU1VCMJTIJOH'VODUJPOBM1ZUIPO1SPHSBNNJOH4FDPOE&EJUJPO. We also have other
code bundles from our rich catalog of books and videos available at IUUQTHJUIVCDPN
1BDLU1VCMJTIJOH. Check them out!
Conventions used
There are a number of text conventions used throughout this book.
$PEF*O5FYU: Indicates code words in text, database table names, folder names, filenames,
file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an
example: "Python has other statements, such as HMPCBM or OPOMPDBM, which modify the
rules for variables in a particular namespace."
[5]
Preface
When we wish to draw your attention to a particular part of a code block, the relevant lines
or items are set in bold:
T
GPSOJOSBOHF
JGOPSO
s += n
QSJOU T
Bold: Indicates a new term, an important word, or words that you see onscreen. For
example, words in menus or dialog boxes appear in the text like this. Here is an example:
"For our purposes, we will distinguish between only two of the many
paradigms: functional programming and imperative programming."
Get in touch
Feedback from our readers is always welcome.
General feedback: Email GFFECBDL!QBDLUQVCDPN and mention the book title in the
subject of your message. If you have questions about any aspect of this book, please email
us at RVFTUJPOT!QBDLUQVCDPN.
[6]
Preface
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes
do happen. If you have found a mistake in this book, we would be grateful if you would
report this to us. Please visit XXXQBDLUQVCDPNTVCNJUFSSBUB, selecting your book,
clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the Internet, we
would be grateful if you would provide us with the location address or website name.
Please contact us at DPQZSJHIU!QBDLUQVCDPN with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in
and you are interested in either writing or contributing to a book, please visit
BVUIPSTQBDLUQVCDPN.
Reviews
Please leave a review. Once you have read and used this book, why not leave a review on
the site that you purchased it from? Potential readers can then see and use your unbiased
opinion to make purchase decisions, we at Packt can understand what you think about our
products, and our authors can see your feedback on their book. Thank you!
[7]
Visit https://textbookfull.com
now to explore a rich
collection of eBooks, textbook
and enjoy exciting offers!
1
Understanding Functional
Programming
Functional programming defines a computation using expressions and evaluation; often
these are encapsulated in function definitions. It de-emphasizes or avoids the complexity of
state change and mutable objects. This tends to create programs that are more succinct and
expressive. In this chapter, we'll introduce some of the techniques that characterize
functional programming. We'll identify some of the ways to map these features to Python.
Finally, we'll also address some ways in which the benefits of functional programming
accrue when we use these design patterns to build Python applications.
We'll also look at a problem domain that we'll use for many of the examples in this book.
We'll try to stick closely to Exploratory Data Analysis (EDA) because its algorithms are
often good examples of functional programming. Furthermore, the benefits of functional
programming accrue rapidly in this problem domain.
Our goal is to establish some essential principles of functional programming. The more
serious Python code will begin in $IBQUFS, Introducing Some Functional Features.
We'll focus on Python 3.6 features in this book. However, some of the
examples might also work in Python 2.
Understanding Functional Programming Chapter 1
Identifying a paradigm
It's difficult to be definitive on the universe of programming paradigms. For our purposes,
we will distinguish between only two of the many
paradigms: functional programming and imperative programming. One important
distinguishing feature between these two is the concept of state.
In an imperative language, such as Python, the state of the computation is reflected by the
values of the variables in the various namespaces; some kinds of statements make a well-
defined change to the state by adding or changing (or even removing) a variable. A
language is imperative because each statement is a command, which changes the state
in some way.
Our general focus is on the assignment statement and how it changes the state. Python has
other statements, such as HMPCBM or OPOMPDBM, which modify the rules for variables in a
particular namespace. Statements such as EFG, DMBTT, and JNQPSU change the processing
context. Other statements such as USZ, FYDFQU, JG, FMJG, and FMTF act as guards to modify
how a collection of statements will change the computation's state. Statements such as GPS
and XIJMF, similarly, wrap a block of statements so that the statements can make repeated
changes to the state of the computation. The focus of all these various statement types,
however, is on changing the state of the variables.
Ideally, each assignment statement advances the state of the computation from an initial
condition toward the desired final outcome. This advancing the computation assertion can be
challenging to prove. One approach is to define the final state, identify a statement that will
establish this final state, and then deduce the precondition required for this final statement
to work. This design process can be iterated until an acceptable initial state is derived.
[9]
Understanding Functional Programming Chapter 1
It's important to note that functional programs tend to be relatively succinct, expressive,
and efficient compared to imperative (object-oriented or procedural) programs. The benefit
isn't automatic; it requires a careful design. This design effort for functional programming is
often easier than for procedural programming.
We'll use code examples to illustrate the concepts. For some, this will feel like reinventing
the wheel. For others, it provides a concrete expression of abstract concepts.
For some kinds of computations, we can ignore Python's object-oriented features and write
simple numeric algorithms. For example, we might write something like the following to
sum a range of numbers that share a common property:
T
GPSOJOSBOHF
JGOPSO
T O
QSJOU T
The sum T includes only numbers that are multiples of three or five. We've made this
program strictly procedural, avoiding any explicit use of Python's object features. The
program's state is defined by the values of the variables T and O. The variable O takes on
values such that 1 d n < 10. As the loop involves an ordered exploration of values of O, we
can prove that it will terminate when O. Similar code would work in C or Java
language, using their primitive (non-object) data types.
[ 10 ]
Understanding Functional Programming Chapter 1
This program produces the same result but it accumulates a stateful collection object, N, as it
proceeds. The state of the computation is defined by the values of the variables N and O.
The syntax of NBQQFOE O and TVN N can be confusing. It causes some programmers to
insist (wrongly) that Python is somehow not purely object-oriented because it has a mixture
of the GVODUJPO and PCKFDUNFUIPE syntax. Rest assured, Python is purely object-
oriented. Some languages, such as C++, allow the use of primitive data types such as JOU,
GMPBU, and MPOH, which are not objects. Python doesn't have these primitive types. The
presence of prefix syntax, TVN N , doesn't change the nature of the language.
To be pedantic, we could fully embrace the object model, by defining a subclass of the MJTU
class. This new class will include a TVN method:
DMBTT4VNNBCMF@-JTU MJTU
EFGTVN TFMG
T
GPSWJOTFMG
T W
SFUVSOT
If we initialize the variable N with an instance of the 4VNNBCMF@-JTU class instead of the
MJTU method, we can use the NTVN method instead of the TVN N method. This kind
of change can help to clarify the idea that Python is truly and completely object-oriented.
The use of prefix function notation is purely syntactic sugar.
All three of these examples rely on variables to explicitly show the state of the program.
They rely on the assignment statements to change the values of the variables and advance
the computation toward completion. We can insert the BTTFSU statements throughout these
examples to demonstrate that the expected state changes are implemented properly.
The point is not that imperative programming is broken in some way. The point is that
functional programming leads to a change in viewpoint, which can, in many cases, be very
helpful. We'll show a function view of the same algorithm. Functional programming doesn't
make this example dramatically shorter or faster.
[ 11 ]
Understanding Functional Programming Chapter 1
We've defined the sum of a sequence in two cases: the base case states that the sum of a
zero length sequence is 0, while the recursive case states that the sum of a sequence is the
first value plus the sum of the rest of the sequence. Since the recursive definition depends
on a shorter sequence, we can be sure that it will (eventually) devolve to the base case.
The first example computes the sum of a list with multiple items. The second example
shows how the recursion rule works by adding the first item, TFR<>, to the sum of the
remaining items, TVNS TFR<> . Eventually, the computation of the result involves the
sum of an empty list, which is defined as zero.
The operator on the last line of the preceding example and the initial value of in the base
case characterize the equation as a sum. If we change the operator to and the initial value
to , it would just as easily compute a product. We'll return to this simple idea of
generalization in the following chapters.
In this function, we've compared a given value, W, against the upper bound, O. If W reaches
the upper bound, the resulting list must be empty. This is the base case for the given
recursion.
[ 12 ]
Random documents with unrelated
content Scribd suggests to you:
The Project Gutenberg eBook of Tom Swift and
his airline express
This ebook is for the use of anyone anywhere in the United States
and most other parts of the world at no cost and with almost no
restrictions whatsoever. You may copy it, give it away or re-use it
under the terms of the Project Gutenberg License included with this
ebook or online at www.gutenberg.org. If you are not located in the
United States, you will have to check the laws of the country where
you are located before using this eBook.
Language: English
by
VICTOR APPLETON
Copyright, 1926, by
GROSSET & DUNLAP, Inc.
New York, N. Y.
ALL RIGHTS RESERVED
Printed in U. S. A.
CONTENTS
I. Something Queer
II. Waiting in the Dark
III. Masked Men
IV. A Night of Worry
V. A Crash
VI. Again a Prisoner
VII. The Plot
VIII. Mr. Damon’s News
IX. Koku’s Alarm
X. Tom’s Plight
XI. The Explosion
XII. A Dangerous Search
XIII. An Ominous Message
XIV. The Airline Express
XV. A Trial Flight
XVI. Jason Jacks
XVII. The Airline Starts
XVIII. Chicago
XIX. Denver
XX. A Mountain Storm
XXI. The Golden Gate
XXII. Kenny Breaks Down
XXIII. Another Capture
XXIV. Troubles and Worries
XXV. A Glorious Finish
Tom Swift and His Airline Express
CHAPTER I
SOMETHING QUEER
After the treatment that had been accorded him, Tom Swift rather
welcomed than otherwise a chance to come to grips with the men
who were responsible for his position. Usually even-tempered and
generous, just now he felt eager for vengeance and he would not
have cared much if two men had attacked him at once.
Strangely enough he did not feel weak or ill now. He had,
somewhat, when he first regained his senses after having been
overpowered by some drug. But his brain had cleared and he kept
himself in such good physical trim all the while that even a night of
unconsciousness had not sapped his strength.
The light in the distance did not increase any, from which Tom
gathered that it was full daylight with the sun well above the horizon,
and after that first murmur of voices and the sound of footsteps these
sounds did not come any nearer. Nor did Tom catch a glimpse of any
figures between himself and that little circle of light.
Then from some point outside the cave or tunnel he heard voices
calling. They were louder than the first, and there seemed to be
some dispute or disturbance.
The voices rose to a high pitch and then died away. Silence
followed, and then came the sound of retreating footsteps.
“They’re going away!” exulted Tom. “Now I’ve got a chance to
walk toward that daylight and see where I am. Maybe I’d better wait
a few minutes, though. They may come back.”
He waited what he thought was several minutes and then,
hearing no other sounds of voices or footsteps, began a cautious
approach toward that gleam of light. What a blessed thing light was,
after all that black and clinging darkness!
In silence Tom crept on, advancing one foot after the other
cautiously, and keeping one hand extended to give warning of his
approach toward any obstruction while in his other hand he held the
file like a dagger, ready to use.
But there was no occasion for this. A little later he found himself
standing in a circle of daylight illumination that filtered down an
inclined shaft which led out of a tunnel, such as Tom could now
ascertain he was in. A natural tunnel it appeared to be, with rocks
jutting out here and there in the earthen sides. Roughly the tunnel
was in the form of a half circle, the floor being flat and the roof
arched. The inclined entrance led upward in a gentle slope.
“Well, now to see what’s up there!” said Tom to himself, taking a
long breath and holding his weapon ready. He tensed his muscles
and steeled his nerves for what he felt might be a desperate
struggle. Yet he did not shrink back.
As he advanced cautiously, step by step, up the incline that led to
daylight and the outer world, he felt at first a sense of disappointment
when he saw no one with whom he might come to grips. He had
been treated so meanly that it would have been a source of
satisfaction to have had it out in a rough-and-tumble fight with those
responsible.
But, to his surprise, Tom pushed his way out through a tangle of
underbrush and bushes which grew about this end of the tunnel and
found none to dispute him. This surprise was added to when he
looked about him and found out where he was.
“On Barn Door Island!” exclaimed Tom. “Of all places! Barn Door
Island! But how did I get here? It’s miles away from where I went
down those steps near our plant. Of all places! Barn Door Island!”
This was a small island in Lake Carlopa which had been named
Barn Door because, some time or other, one of the early settlers
happened to remark that it was no larger than the door of a barn.
The island was at the end of the lake farthest removed from Shopton
and the Swift plant.
“I never knew there was an entrance to a tunnel here!” said Tom,
as he looked about him. “But then I’ve never explored here very
much.”
Nor had any of the other lads of Shopton. Barn Door Island was a
barren place—merely a collection of scrubby trees and tangled
bushes and great boulders set down at the swampy end of Lake
Carlopa. It was not a good fishing location and too dreary for picnic
parties, so Barn Door was seldom visited.
“But if I had an idea there was a tunnel entrance here—the
beginning of a passage that led under the lake and under the land