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

Functional Programming Patterns in Scala and Clojure 1st Edition Michael Bevilacqua-Linn - Quickly download the ebook to never miss any content

The document promotes various ebooks on functional programming in Scala and Clojure, highlighting titles such as 'Functional Programming Patterns in Scala and Clojure' by Michael Bevilacqua-Linn. It emphasizes the benefits of functional programming for object-oriented programmers and provides links for instant downloads. Additionally, it includes early praise for the featured book and outlines its structure, focusing on patterns and practical applications in programming.

Uploaded by

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

Functional Programming Patterns in Scala and Clojure 1st Edition Michael Bevilacqua-Linn - Quickly download the ebook to never miss any content

The document promotes various ebooks on functional programming in Scala and Clojure, highlighting titles such as 'Functional Programming Patterns in Scala and Clojure' by Michael Bevilacqua-Linn. It emphasizes the benefits of functional programming for object-oriented programmers and provides links for instant downloads. Additionally, it includes early praise for the featured book and outlines its structure, focusing on patterns and practical applications in programming.

Uploaded by

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

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

com

Functional Programming Patterns in Scala and


Clojure 1st Edition Michael Bevilacqua-Linn

https://ebookgate.com/product/functional-programming-
patterns-in-scala-and-clojure-1st-edition-michael-
bevilacqua-linn/

OR CLICK BUTTON

DOWLOAD EBOOK

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


Click here to visit ebookgate.com and download ebook now
Instant digital products (PDF, ePub, MOBI) available
Download now and explore formats that suit you...

Programming Scala 2nd Edition Scalability Functional


Programming Objects Second Edition Dean Wampler

https://ebookgate.com/product/programming-scala-2nd-edition-
scalability-functional-programming-objects-second-edition-dean-
wampler/
ebookgate.com

Learning Scala Practical Functional Programming for the


JVM 1st Edition Jason Swartz

https://ebookgate.com/product/learning-scala-practical-functional-
programming-for-the-jvm-1st-edition-jason-swartz/

ebookgate.com

Programming Clojure 1st Edition Stuart Halloway

https://ebookgate.com/product/programming-clojure-1st-edition-stuart-
halloway/

ebookgate.com

Clojure Programming 1st Edition Chas Emerick

https://ebookgate.com/product/clojure-programming-1st-edition-chas-
emerick/

ebookgate.com
Programming in Scala 2nd 2nd Edition Martin Odersky

https://ebookgate.com/product/programming-in-scala-2nd-2nd-edition-
martin-odersky/

ebookgate.com

Scala High Performance Programming 1st Edition Theron

https://ebookgate.com/product/scala-high-performance-programming-1st-
edition-theron/

ebookgate.com

The Joy of Clojure Thinking the Clojure Way 1st Edition


Michael Fogus

https://ebookgate.com/product/the-joy-of-clojure-thinking-the-clojure-
way-1st-edition-michael-fogus/

ebookgate.com

Science Learning and Instruction 1st Edition Linn

https://ebookgate.com/product/science-learning-and-instruction-1st-
edition-linn/

ebookgate.com

Functional Programming and Input Output Distinguished


Dissertations in Computer Science 1st Edition Andrew D.
Gordon
https://ebookgate.com/product/functional-programming-and-input-output-
distinguished-dissertations-in-computer-science-1st-edition-andrew-d-
gordon/
ebookgate.com
Download from Wow! eBook <www.wowebook.com>
Download from Wow! eBook <www.wowebook.com>
Early Praise for Functional Programming Patterns

This book is an absolute gem and should be required reading for anybody looking
to transition from OO to FP. It is an extremely well-built safety rope for those
crossing the bridge between two very different worlds. Consider this mandatory
reading.
➤ Colin Yates, technical team leader at QFI Consulting, LLP

This book sticks to the meat and potatoes of what functional programming can do
for the object-oriented JVM programmer. The functional patterns are sectioned in
the back of the book separate from the functional replacements of the object-oriented
patterns, making the book handy reference material. As a Scala programmer, I even
picked up some new tricks along the read.
➤ Justin James, developer with Full Stack Apps

This book is good for those who have dabbled a bit in Clojure or Scala but are not
really comfortable with it; the ideal audience is seasoned OO programmers looking
to adopt a functional style, as it gives those programmers a guide for transitioning
away from the patterns they are comfortable with.
➤ Rod Hilton, Java developer and PhD candidate at the University of Colorado

Download from Wow! eBook <www.wowebook.com>


Functional Programming Patterns
in Scala and Clojure
Write Lean Programs for the JVM

Michael Bevilacqua-Linn

The Pragmatic Bookshelf


Dallas, Texas • Raleigh, North Carolina

Download from Wow! eBook <www.wowebook.com>


Many of the designations used by manufacturers and sellers to distinguish their products
are claimed as trademarks. Where those designations appear in this book, and The Pragmatic
Programmers, LLC was aware of a trademark claim, the designations have been printed in
initial capital letters or in all capitals. The Pragmatic Starter Kit, The Pragmatic Programmer,
Pragmatic Programming, Pragmatic Bookshelf, PragProg and the linking g device are trade-
marks of The Pragmatic Programmers, LLC.
Every precaution was taken in the preparation of this book. However, the publisher assumes
no responsibility for errors or omissions, or for damages that may result from the use of
information (including program listings) contained herein.
Our Pragmatic courses, workshops, and other products can help you and your team create
better software and have more fun. For more information, as well as the latest Pragmatic
titles, please visit us at http://pragprog.com.

The team that produced this book includes:


Fahmida Rashid (editor)
Potomac Indexing, LLC (indexer)
Molly McBeath (copyeditor)
David J Kelly (typesetter)
Janet Furlow (producer)
Juliet Benda (rights)
Ellie Callahan (support)

Copyright © 2013 The Pragmatic Programmers, LLC.


All rights reserved.

No part of this publication may be reproduced, stored in a retrieval system, or


transmitted, in any form, or by any means, electronic, mechanical, photocopying,
recording, or otherwise, without the prior consent of the publisher.

Printed in the United States of America.


ISBN-13: 978-1-937785-47-5
Encoded using the finest acid-free high-entropy binary digits.
Book version: P1.0—October 2013

Download from Wow! eBook <www.wowebook.com>


Contents
Acknowledgments . . . . . . . . . . . vii

Preface . . . . . . . . . . . . . . ix

1. Patterns and Functional Programming . . . . . . 1


1.1 What Is Functional Programming? 3
1.2 Pattern Glossary 4

2. TinyWeb: Patterns Working Together . . . . . . . 9


2.1 Introducing TinyWeb 9
2.2 TinyWeb in Java 9
2.3 TinyWeb in Scala 20
2.4 TinyWeb in Clojure 28

3. Replacing Object-Oriented Patterns . . . . . . . 39


3.1 Introduction 39
Pattern 1. Replacing Functional Interface 40
Pattern 2. Replacing State-Carrying Functional Interface 47
Pattern 3. Replacing Command 54
Pattern 4. Replacing Builder for Immutable Object 62
Pattern 5. Replacing Iterator 72
Pattern 6. Replacing Template Method 83
Pattern 7. Replacing Strategy 92
Pattern 8. Replacing Null Object 99
Pattern 9. Replacing Decorator 109
Pattern 10. Replacing Visitor 113
Pattern 11. Replacing Dependency Injection 128

4. Functional Patterns . . . . . . . . . . 137


4.1 Introduction 137
Pattern 12. Tail Recursion 138
Pattern 13. Mutual Recursion 146

Download from Wow! eBook <www.wowebook.com>


Contents • vi

Pattern 14. Filter-Map-Reduce 155


Pattern 15. Chain of Operations 159
Pattern 16. Function Builder 167
Pattern 17. Memoization 182
Pattern 18. Lazy Sequence 186
Pattern 19. Focused Mutability 196
Pattern 20. Customized Control Flow 206
Pattern 21. Domain-Specific Language 218

5. The End . . . . . . . . . . . . . 229

Bibliography . . . . . . . . . . . . 231

Index . . . . . . . . . . . . . . 233

Download from Wow! eBook <www.wowebook.com>


Acknowledgments
I’d like to thank my parents, without whom I would not exist.

Thanks also go to my wonderful girlfriend, who put up with many a night


and weekend listening to me mutter about code samples, inconsistent tenses,
and run-on sentences.

This book would have suffered greatly without a great group of technical
reviewers. My thanks to Rod Hilton, Michajlo “Mishu” Matijkiw, Venkat Sub-
ramaniam, Justin James, Dave Cleaver, Ted Neward, Neal Ford, Richard
Minerich, Dustin Campbell, Dave Copeland, Josh Carter, Fred Daoud, and
Chris Smith.

Finally, I’d like to thank Dave Thomas and Andy Hunt. Their book, The
Pragmatic Programmer, is one of the first books I read when I started my
career. It made a tremendous impact, and I’ve still got my original dog-eared,
fingerprint-covered, bruised and battered copy. In the Pragmatic Bookshelf,
they’ve created a publisher that’s truly dedicated to producing high-quality
technical books and supporting the authors who write them.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Preface
This book is about patterns and functional programming in Scala and Clojure.
It shows how to replace, or greatly simplify, many of the common patterns
we use in object-oriented programming, and it introduces some patterns
commonly used in the functional world.

Used together, these patterns let programmers solve problems faster and in
a more concise, declarative style than with object-oriented programming alone.
If you’re using Java and want to see how functional programming can help
you work more efficiently, or if you’ve started using Scala and Clojure and
can’t quite wrap your head around functional problem-solving, this is the
book for you.

Before we dig in, I’d like to start off with a story. This story is true, though
some names have been changed to protect the not-so-innocent.
A Tale of Functional Programming
by: Michael Bevilacqua-Linn, software firefighter

The site isn’t down, but an awful lot of alarms are going off. We trace the problems to changes
someone made to a third-party API we use. The changes are causing major data problems on
our side; namely, we don’t know what the changes are and we can’t find anyone who can tell
us. It also turns out the system that talks to the API uses legacy code, and the only guy who
knows how to work on it happens to be away on vacation. This a big system: 500,000-lines-of-
Java-and-OSGI big.

Support calls are flooding in, lots of them. Expensive support calls from frustrated customers.
We need to fix the problem quickly. I start up a Clojure REPL and use it to poke around the
problem API.

My boss pokes his head into my office. “How’s it going?” he asks. “Working on it,” I say. Ten
minutes later, my grandboss pokes his head into my office. “How’s it going?” he asks. “Working
on it,” I say. Another ten minutes pass by when my great-grandboss pokes his head into my
office. “How’s it going?” he asks. “Working on it,” I say. I get a half hour of silence before the CTO
pokes his head into my office. “Working on it,” I say before he opens his mouth.

An hour passes, and I figure out what’s changed. I whip up a way to keep the data clean until
the legacy developer gets back and can put together a proper fix. I hand my little program off

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Preface •x

to the operations team, which gets it up and running in a JVM, somewhere safe. The support
calls stop coming in, and everyone relaxes a bit.

A week or so later at an all-hands meeting, the great-grandboss thanks me for the Java program
I wrote that saved the day. I smile and say, “That wasn’t Java.”

The REPL, Clojure’s interactive programming environment, helped a lot in


this story. However, lots of languages that aren’t particularly functional have
similar interactive programming environments, so that’s not all there is to it.

Two of the patterns that we’ll see in this book, Pattern 21, Domain-Specific
Language, on page 218, and Pattern 15, Chain of Operations, on page 159,
contributed greatly to this story’s happy ending.

Earlier on, I had written a small instance of domain-specific language for


working with these particular APIs that helped me explore them very quickly
even though they’re very large and it was difficult to figure out where the
problem might lie. In addition, the powerful data transformation facilities that
functional programming relies on, such as the examples we’ll see in Pattern
15, Chain of Operations, on page 159, helped me quickly write code to clean
up the mess.

How This Book Is Organized


We’ll start with an introduction to patterns and how they relate to functional
programming. Then we’ll take a look at an extended example, a small web
framework called TinyWeb. We’ll first show TinyWeb written using classic
object-oriented patterns in Java. We’ll then rewrite it, piece by piece, to a
hybrid style that is object oriented and functional, using Scala. We’ll then
write in a functional style using Clojure.

The TinyWeb extended example serves a few purposes. It will let us see how
several of the patterns we cover in this book fit together in a comprehensive
manner. We also use it to introduce the basics of Scala and Clojure. Finally,
since we’ll transform TinyWeb from Java to Scala and Clojure bit by bit, it
gives us a chance to explore how to easily integrate Java code with Scala and
Clojure.

The remainder of the book is organized into two sections. The first, Chapter
3, Replacing Object-Oriented Patterns, on page 39, describes functional
replacements for object-oriented patterns. These take weighty object-oriented
patterns and replace them with concise functional solutions.

Peter Norvig, author of the classic Lisp text Paradigms of Artificial Intelligence
Programming: Case Studies in Common Lisp [Nor92], current director of
research at Google, and all-around very smart guy, pointed out in Design

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Pattern Template • xi

Patterns in Dynamic Languages that expressive languages like Lisp could turn
classic object-oriented patterns invisible.1

Unfortunately, not many people in the mainstream software development


world seem to have read Norvig, but when we can replace a complicated pat-
tern with something simpler, it makes sense that we should. It makes our
code more concise, easier to understand, and easier to maintain.

The second section, Chapter 4, Functional Patterns, on page 137, describes


patterns that are native to the functional world. These patterns run the gamut
from tiny—patterns consisting of a line or two of code—to very large—ones
that deal with entire programs.

Sometimes these patterns have first-class language support, which means


that someone else has done the hard work of implementing them for us. Even
when they don’t, we can often use an extremely powerful pattern, Pattern 21,
Domain-Specific Language, on page 218, to add it. This means that functional
patterns are more lightweight than object-oriented patterns. You still need
to understand the pattern before you can use it, but the implementation
becomes as simple as a few lines of code.

Pattern Template
The patterns are laid out using the following format, with some exceptions.
For example, a pattern that doesn’t have any other common name would not
have the Also Known As subsection, and the Functional Replacement subsec-
tions only apply to the patterns in Chapter 3, Replacing Object-Oriented Pat-
terns, on page 39.

Intent
The Intent subsection provides a quick explanation of the intent of this pattern
and the problem it solves.

Overview
Here is where you’ll find a deeper motivation for the pattern and an explanation
of how it works.

Also Known As
This subsection lists other common names for the pattern.

1. http://norvig.com/design-patterns/

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Preface • xii

Functional Replacement
Here you’ll find how to replace this pattern with functional programming
techniques—sometimes object-oriented patterns can be replaced with basic
functional language features and sometimes with simpler patterns.

Example Code
This subsection contains samples of the pattern—for object-oriented patterns,
we first show a sketch of the object-oriented solution using either class dia-
grams or a sketch of the Java code before showing how to replace them in
Clojure and Scala. Functional patterns will be shown in Clojure and Scala
only.

Discussion
This area provides a summary and discussion of interesting points about the
pattern.

For Further Reading


Look here for a list of references for further information on the pattern.

Related Patterns
This provides a list of other patterns in this book that are related to the current
one.

Why Scala and Clojure


Many of the patterns in this book can be applied using other languages with
functional features, but we will focus on Clojure and Scala for our examples.
We focus on these two languages for quite a few reasons, but first and foremost
because they’re both practical languages suitable for coding in production
environments.

Both Scala and Clojure run on a Java virtual machine (JVM), so they interop-
erate well with existing Java libraries and have no issues being dropped into
the JVM infrastructure. This makes them ideal to run alongside existing Java
codebases. Finally, while both Scala and Clojure have functional features,
they’re quite different from each other. Learning to use both of them exposes
us to a very broad range of functional programming paradigms.

Scala is a hybrid object-oriented/functional language. It’s statically typed


and combines a very sophisticated type system with local type inference,
which allows us to often omit explicit type annotations in our code.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


How to Read This Book • xiii

Clojure is a modern take on Lisp. It has Lisp’s powerful macro system and
dynamic typing, but Clojure has added some new features not seen in older
Lisps. Most important is its unique way of dealing with state change by using
reference types, a software transactional memory system, and efficient
immutable data structures.

While Clojure is not an object-oriented language, it does give us some good


features that are common in object-oriented languages, just not in the way
we may be familiar with. For instance, we can still get polymorphism through
Clojure’s multimethods and protocols, and we can get hierarchies through
Clojure’s ad hoc hierarchies.

As we introduce the patterns, we’ll explore both of these languages and their
features, so this book serves as a good introduction to both Scala and Clojure.
For further detail on either language, my favorite books are Programming
Clojure [Hal09] and The Joy of Clojure [FH11] for Clojure, and Programming
Scala: Tackle Multi-Core Complexity on the Java Virtual Machine [Sub09] and
Scala In Depth [Sue12] for Scala.

How to Read This Book


The best place to start is with Chapter 1, Patterns and Functional Programming,
on page 1, which goes over the basics of functional programming and its
relation to patterns. Next, Chapter 2, TinyWeb: Patterns Working Together,
on page 9, introduces basic concepts in Scala and Clojure and shows how
several of the patterns in this book fit together.

From there you can jump around, pattern by pattern, as needed. The patterns
covered earlier in Chapter 3, Replacing Object-Oriented Patterns, on page 39,
and Chapter 4, Functional Patterns, on page 137, tend to be more basic than
later ones, so they’re worth reading first if you have no previous functional
experience.

A quick summary of each pattern can be found in Section 1.2, Pattern Glos-
sary, on page 4, for easy browsing. Once you’re through the introduction,
you can use it to look up a pattern that solves the particular problem you
need to solve.

However, if you are completely new to functional programming, you should


start with Pattern 1, Replacing Functional Interface, on page 40, Pattern 2,
Replacing State-Carrying Functional Interface, on page 47, and Pattern 12,
Tail Recursion, on page 138.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Preface • xiv

Online Resources
As you work through the book, you can download all the included code files
from http://pragprog.com/titles/mbfpp/source_code. On the book’s home page at
http://pragprog.com/book/mbfpp, you can find links to the book forum and to report
errata. Also, for ebook buyers, clicking on the box above the code extracts
downloads the code for that extract for you.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


CHAPTER 1

Patterns and Functional Programming


Patterns and functional programming go together in two ways. First, many
object-oriented design patterns are simpler to implement with functional
programming. This is true for several reasons. Functional languages give us
a concise way of passing around a bit of computation without having to create
a new class. Also, using expressions rather than statements lets us eliminate
extraneous variables, and the declarative nature of many functional solutions
lets us do in a single line of code what might take five lines in the imperative
style. Some object-oriented patterns can even be replaced with a straightfor-
ward application of functional language features.

Second, the functional world also has its own set of useful patterns. These
patterns focus on writing code that avoids mutability and favors a declarative
style, which helps us write simpler, more maintainable code. The two main
sections of this book cover these two sets of patterns.

You may be surprised to see the first set. Don’t the patterns we know and
love extend across languages? Aren’t they supposed to provide common
solutions to common problems regardless of what language you are using?
The answer to both questions is yes, so long as the language you are using
looks something like Java or its ancestor, C++.

With the emergence of more expressive language features, many of these


patterns fade away. Classic Java itself has a great example of a language
feature replacing a pattern: foreach. The introduction of foreach loops to Java 1.5
reduced the usefulness of the explicit Iterator pattern described in Design
Patterns: Elements of Reusable Object-Oriented Software [GHJV95], even though
foreach loops use it behind the scenes.

That’s not to say that foreach loops are exactly equivalent to the Iterator. A
foreach won’t replace an Iterator in all cases. The problems they do address

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 1. Patterns and Functional Programming •2

are solved in a simpler way. Developers prefer the built-in foreach loops for the
common-sense reasons that they are less work to implement and are less
error prone.

Many functional language features and techniques have a similar effect on


coding projects. While they may not be the exact equivalent to a pattern, they
often provide developers with a built-in alternative that solves the same
problem. Similar to the foreach-Iterator example, other language features give
programmers techniques that are less work and often produce code that is
more concise and easier to understand than the original.

Adding functional features and techniques adds more tools to our program-
ming toolbox, just as Java 1.5 did with its foreach loop but on a grander scale.
These tools often complement the tools we already know and love from the
object-oriented world.

The second set of patterns we cover in this book, native functional patterns,
describes the patterns that evolved out of the functional style. These functional
patterns differ from the object-oriented patterns you may be familiar with in
a few key ways. The first, and most obvious, is that functions are the primary
unit of composition, just as objects are in the object-oriented world.

Another key difference lies in the patterns’ granularity. The patterns from
Design Patterns: Elements of Reusable Object-Oriented Software [GHJV95] (one
of the original drivers of the software patterns movement) are generally tem-
plates that define a few classes and specify how they fit together. Most of
them are medium size. They often don’t concern themselves either with very
small issues that encompass just a few lines of code or with very large issues
that encompass entire programs.

The functional patterns in this book cover a much broader range, as some of
them can be implemented in a line or two of code. Others tackle very big
problems, such as creating new, miniature programming languages.

The range is in line with the book that started the patterns movement in
general, A Pattern Language [AIS77]. This book on architectural patterns
starts off with the very big “1—Independent Regions” pattern, which outlines
why the planet should be organized into political entities of about 10,000
people, and goes all the way down to “248—Soft Tile and Brick,” which explains
how to make your own bricks.

Before we dig into the various patterns in this book, let’s spend some time
getting familiar with functional programming itself.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


What Is Functional Programming? •3

1.1 What Is Functional Programming?


At its core, functional programming is about immutability and about compos-
ing functions rather than objects. Many related characteristics fall out of this
style.

Functional programs do the following:

Have first-class functions: First-class functions are functions that can be


passed around, dynamically created, stored in data structures, and
treated like any other first-class object in the language.

Favor pure functions: Pure functions are functions that have no side effects.
A side effect is an action that the function does that modifies state outside
the function.

Compose functions: Functional programming favors building programs from


the bottom up by composing functions together.

Use expressions: Functional programming favors expressions over statements.


Expressions yield values. Statements do not and exist only to control the
flow of a program.

Use Immutability: Since functional programming favors pure functions, which


can’t mutate data, it also makes heavy use of immutable data. Instead of
modifying an existing data structure, a new one is efficiently created.

Transform, rather than mutate, data: Functional programming uses functions


to transform immutable data. One data structure is put into the function,
and a new immutable data structure comes out. This is in explicit contrast
with the popular object-oriented model, which views objects as little
packets of mutable state and behavior.

A focus on immutable data leads to programs that are written in a more


declarative style, since we can’t modify a data structure piece by piece. Here’s
an iterative way to filter the odd numbers out of a list, written in Java. Notice
how it relies on mutation to add odd numbers to filteredList one at a time.
JavaExamples/src/main/java/com/mblinn/mbfpp/intro/FilterOdds.java
public List<Integer> filterOdds(List<Integer> list) {
List<Integer> filteredList = new ArrayList<Integer>();
for (Integer current : list) {
if (isOdd(current)) {
filteredList.add(current);
}
}
return filteredList;
}

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 1. Patterns and Functional Programming •4

private boolean isOdd(Integer integer) {


return 0 != integer % 2;
}

And here’s a functional version, written in Clojure.


(filter odd? list-of-ints)

The functional version is obviously much shorter than the object-oriented


version. As mentioned previously, this is because functional programming is
declarative. That is, it specifies what should be done rather than how to do
it. For many problems we encounter in programming, this style lets us work
at a higher level of abstraction.

However, other problems are hard, if not impossible, to solve using strict
functional programming techniques. A compiler is a pure function. If you put
a program in, you expect to get the same machine code out every time. If you
don’t, it’s probably a compiler bug. Google’s search engine, however, is not a
pure function. If we got the same results from a Google search query every
time, we’d be stuck with a late 1990s view of the Web, which would be quite
tragic.

For this reason, functional programming languages tend to lie on a spectrum


of strictness. Some are more functionally pure than others. Of the two lan-
guages we’re using in this book, Clojure is purer on the functional spectrum;
at least, it is if we avoid its Java interoperability features.

For example, in idiomatic Clojure, we don’t mutate data as we do in Java.


Instead, we rely on an efficient set of immutable data structures, a set of ref-
erence types, and a software transactional memory system. This allows us to
get the benefits of mutability without the dangers. We’ll introduce these
techniques in Section 2.4, TinyWeb in Clojure, on page 28.

Scala has more support for mutable data, but immutable data is preferred.
For instance, Scala has both mutable and immutable versions of its collections
library, but the immutable data structures are imported and used by default.

1.2 Pattern Glossary


Here is where we introduce all of the patterns we cover in the book and give
a brief overview of each. This is a great list to skim if you already have a
specific problem you need to solve in a functional way.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Pattern Glossary •5

Replacing Object-Oriented Patterns


This section shows how to replace common object-oriented patterns with
functional language features. This generally cuts down on the amount of code
we have to write while giving us a more concise code to maintain.

Pattern 1, Replacing Functional Interface, on page 40


Here we replace common types of functional interfaces, such as Runnable or
Comparator, with native functional features.

This section introduces two basic types of functional features. The first type,
higher-order functions, allows us to pass functions around as first-class data.
The second, anonymous functions, allows us to write quick one-off functions
without giving them a name. These features combine to let us replace most
instances of Functional Interface very concisely.

Pattern 2, Replacing State-Carrying Functional Interface, on page 47


With this pattern we replace instances of Functional Interface that need to
carry around some bit of state—we introduce another new functional feature,
closures, which lets us wrap up a function and some state to pass around.

Pattern 3, Replacing Command, on page 54


Replacing Command encapsulates an action in an object—here we’ll take a
look at how we can replace the object-oriented version using the techniques
introduced in the previous two patterns.

Pattern 4, Replacing Builder for Immutable Object, on page 62


Here we carry data using the classic Java convention, a class full of getters
and setters—this approach is intimately tied up with mutability. Here we’ll
show how to get the convenience of a Java Bean along with the benefits of
immutability.

Pattern 5, Replacing Iterator, on page 72


Replacing Iterator gives us a way to access items in a collection sequential-
ly—here we’ll see how we can solve many of the problems we’d solve with
Iterator using higher-order functions and sequence comprehensions, which
give us solutions that are more declarative.

Pattern 6, Replacing Template Method, on page 83


This pattern defines the outline of an algorithm in a superclass, leaving
subclasses to implement its details. Here we’ll see how to use higher-order
functions and function composition to replace this inheritance-based pattern.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 1. Patterns and Functional Programming •6

Pattern 7, Replacing Strategy, on page 92


In this pattern we define a set of algorithms that all implement a common
interface. This allows a programmer to easily swap out one implementation
of an algorithm for another.

Pattern 8, Replacing Null Object, on page 99


In this pattern we discuss how to replace Null Object and talk about other
types of null handling—in Scala, we take advantage of the type system using
Option. In Clojure, we rely on nil and some language support to make it more
convenient to deal with.

Pattern 9, Replacing Decorator, on page 109


Replacing Decorator adds new behavior to an object without changing the
original class. Here we’ll see how to achieve the same effect with function
composition.

Pattern 10, Replacing Visitor, on page 113


Replacing Visitor makes it easy to add operations to a data type but difficult
to add new implementations of the type. Here we show solutions in Scala and
Clojure that make it possible to do both.

Pattern 11, Replacing Dependency Injection, on page 128


This pattern injects an object’s dependencies into it, rather than instantiating
them inline—this allows us to swap out their implementations. We’ll explore
Scala’s Cake pattern, which gives us a DI-like pattern.

Introducing Functional Patterns

Pattern 12, Tail Recursion, on page 138


Tail Recursion is functionally equivalent to iteration and provides a way to
write a recursive algorithm without requiring a stack frame for each recursive
call. While we’ll prefer more declarative solutions throughout the book,
sometimes the most straightforward way to solve a problem is more iterative.
Here we’ll show how to use Tail Recursion for those situations.

Pattern 13, Mutual Recursion, on page 146


Mutual Recursion is a pattern where recursive functions call one another. As
with Tail Recursion, we need a way to do this without consuming stack frames
for it to be practical. Here we’ll show how to use a feature called trampolining
to do just that.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Pattern Glossary •7

Pattern 14, Filter-Map-Reduce, on page 155


Filter, map, and reduce are three of the most commonly used higher-order
functions. Used together, they’re a very powerful tool for data manipulation
and are the inspiration for the popular MapReduce data-processing paradigm.
In this pattern, we’ll see how they can be used on a smaller scale.

Pattern 15, Chain of Operations, on page 159


Functional programming eschews mutability; so instead of mutating a data
structure, we take one immutable data structure, operate on it, and produce
a new one. Chain of Operations examines the differing ways to do so in Scala
and Clojure.

Pattern 16, Function Builder, on page 167


Higher-order functions can create other functions using the Function Builder
pattern. Here we’ll show some common instances of the pattern that are built
into many functional languages, and we’ll explore a few custom ones.

Pattern 17, Memoization, on page 182


This pattern caches the results of a pure function invocation to avoid having
to do an expensive computation more than once.

Pattern 18, Lazy Sequence, on page 186


Lazy Sequence is a pattern where a sequence is realized bit by bit only as it’s
needed. This allows us to create infinitely long sequences and to easily work
with streams of data.

Pattern 19, Focused Mutability, on page 196


Focused Mutability makes a small critical section of code use mutable data
structures to optimize performance. The need for this is less common than
you might think. Clojure and Scala, backed by the JVM, provide very efficient
mechanisms for working with immutable data, so immutability is rarely the
bottleneck.

Pattern 20, Customized Control Flow, on page 206


With most languages, it’s impossible to add a new way of doing control flow
to the language without modifying the language itself. Functional languages,
however, usually provide a way to create custom control abstractions tailored
for specific uses.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 1. Patterns and Functional Programming •8

Pattern 21, Domain-Specific Language, on page 218


The Domain-Specific Language pattern allows us to create a language that
is purpose-built for solving a specific problem. Using a well-designed imple-
mentation of domain-specific language is the ultimate solution for often-solved
problems, as it lets us program close to the problem domain. This reduces
the amount of code we have to write and the mental friction in transforming
our thoughts into code.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


CHAPTER 2

TinyWeb: Patterns Working Together


2.1 Introducing TinyWeb
We’ll start our journey with a look at an example of a program that makes
heavy use of classic object-oriented patterns, a small web framework called
TinyWeb. After introducing TinyWeb, we’ll see how to rewrite it in a hybrid
object-oriented and functional style using Scala. Finally, we’ll move on to a
more fully functional style in Clojure.

Let’s focus on a few goals for this example. The first is to see several patterns
working together in one codebase before we go into them in more detail.

The second is to introduce basic Scala and Clojure concepts for those unfa-
miliar with either, or both, of the languages. A full introduction to the lan-
guages is beyond the scope of this book, but this section gives you enough
of the basics to understand the majority of the remaining code.

Finally, we’ll work existing Java code into a Scala or Clojure codebase. We’ll
do this by taking the Java version of TinyWeb and transforming it into Scala
and Clojure piece by piece.

TinyWeb itself is a small model-view-controller (MVC) web framework. It’s far


from complete, but it should feel familiar to anyone who has worked with any
of the popular frameworks, such as Spring MVC. There’s one little twist to
TinyWeb: since this is a book on functional programming, we’re going to do
our best to work with immutable data, which can be quite challenging in
Java.

2.2 TinyWeb in Java


The Java version of TinyWeb is a basic MVC web framework written in a
classic object-oriented style. To handle requests we use a Controller implemented
using the Template method, which we cover in detail in Pattern 6, Replacing

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 2. TinyWeb: Patterns Working Together • 10

Template Method, on page 83. Views are implemented using the Strategy
pattern, covered in Pattern 7, Replacing Strategy, on page 92.

Our framework is built around core pieces of data objects, HttpRequest and
HttpResponse. We want these to be immutable and easy to work with, so we are
going to build them using the Builder pattern discussed in Pattern 4,
Replacing Builder for Immutable Object, on page 62. Builder is a standard way
of getting immutable objects in Java.

Finally, we’ve got request filters that run before a request is handled and that
do some work on the request, such as modifying it. We will implement these
filters using the Filter class, a simple example of Pattern 1, Replacing Functional
Interface, on page 40. Our filters also show how to handle changing data using
immutable objects.

The whole system is summarized in the following figure.

Figure 1—A TinyWeb Overview. A graphical overview of TinyWeb

We’ll start off with a look at our core data types, HttpRequest and HttpResponse.

HttpRequest and HttpResponse


Let’s dig into the code, starting with HttpResponse. In this example we’ll only
need a body and a response code in our response, so those are the only
attributes we’ll add. The following code block shows how we can implement
the class. Here we use the fluent builder of the type made popular in the Java
classic, Effective Java [Blo08].

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


TinyWeb in Java • 11

JavaExamples/src/main/java/com/mblinn/oo/tinyweb/HttpResponse.java
package com.mblinn.oo.tinyweb;

public class HttpResponse {


private final String body;
private final Integer responseCode;

public String getBody() {


return body;
}

public Integer getResponseCode() {


return responseCode;
}

private HttpResponse(Builder builder) {


body = builder.body;
responseCode = builder.responseCode;
}

public static class Builder {


private String body;
private Integer responseCode;

public Builder body(String body) {


this.body = body;
return this;
}

public Builder responseCode(Integer responseCode) {


this.responseCode = responseCode;
return this;
}

public HttpResponse build() {


return new HttpResponse(this);
}

public static Builder newBuilder() {


return new Builder();
}
}
}

This approach encapsulates all mutability inside of a Builder object, which then
builds an immutable HttpResponse. While this gives us a clean way of working
with immutable data, it’s quite verbose. For example, we could create a simple
test request using this code:

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 2. TinyWeb: Patterns Working Together • 12

HttpResponse testResponse = HttpResponse.Builder.newBuilder()


.responseCode(200)
.body("responseBody")
.build();

Without using Builder we’d need to pass all of our arguments in the construc-
tor. This is okay for our small example, but this practice grows unwieldy when
working with larger classes. Another option would be to use a Java Bean–style
class with getters and setters, but that would require mutability.

Let’s move on and take a quick look at HttpRequest. Since the class is similar
to HttpResponse (though it lets us set a request body, headers, and a path), we
won’t repeat the code in full. One feature is worth mentioning, though.

In order to support request filters that “modify” the incoming request, we


need to create a new request based off the existing one, since our request
objects aren’t mutable. We’ll use builderFrom() to do so. This method takes an
existing HttpRequest and uses it to set starting values for a new builder. The
code for builderFrom() follows:
JavaExamples/src/main/java/com/mblinn/oo/tinyweb/HttpRequest.java
public static Builder builderFrom(HttpRequest request) {
Builder builder = new Builder();
builder.path(request.getPath());
builder.body(request.getBody());

Map<String, String> headers = request.getHeaders();


for (String headerName : headers.keySet())
builder.addHeader(headerName,
headers.get(headerName));

return builder;
}

This may seem wasteful, but the JVM is a miracle of modern software engi-
neering. It’s able to garbage-collect short-lived objects very efficiently, so this
style of programming performs admirably well in most domains.

Views and Strategy


Let’s continue our tour of TinyWeb with a look at view handling. In a fully
featured framework, we’d include some ways to plug template engines into
our view, but for TinyWeb we’ll just assume we’re generating our response
bodies entirely in code using string manipulation.

First we’ll need a View interface, which has a single method, render(). render()
takes in a model in the form of a Map<String, List<String>>, which represents the

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


TinyWeb in Java • 13

Immutability: Not Just for Functional Programmers


The experienced object-oriented programmer might grumble about extra effort to get
immutable objects, especially if we’re doing it “just to be functional.” However,
immutable data doesn’t just fall out of functional programming; it’s a good practice
that can help us write cleaner code.

A large class of software bugs boil down to one section of code modifying data in
another section in an unexpected way. This type of bug becomes even more heinous
in the multicore world we all live in now. By making our data immutable, we can
avoid this class of bugs altogether.

Using immutable data is an oft-repeated bit of advice in the Java world; it’s mentioned
in Effective Java [Blo08]—Item 15: Minimize Mutability, among other places, but it is
rarely followed. This is largely due to the fact that Java wasn’t designed with
immutability in mind, so it takes a lot of programmer effort to get it.

Still, some popular, high-quality libraries, such as Joda-Time and Google’s collections
library, provide excellent support for programming with immutable data. The fact
that both of these popular libraries provide replacements for functionality available
in Java’s standard library speaks to the usefulness of immutable data.

Thankfully, both Scala and Clojure have much more first-class support for immutable
data, to the extent that it’s often harder to use mutable data than immutable.

model attributes and values. We’ll use a List<String> for our values so that a
single attribute can have multiple values. It returns a String representing the
rendered view.

The View interface is in the following code:


JavaExamples/src/main/java/com/mblinn/oo/tinyweb/View.java
package com.mblinn.oo.tinyweb;

import java.util.List;
import java.util.Map;

public interface View {


public String render(Map<String, List<String>> model);
}

Next we need two classes that are designed to work together using the Strat-
egy pattern: StrategyView and RenderingStrategy.

RenderingStrategy is responsible for doing the actual work of rendering a view


as implemented by the framework user. It’s an instance of a Strategy class from
the Strategy pattern, and its code follows:

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 2. TinyWeb: Patterns Working Together • 14

JavaExamples/src/main/java/com/mblinn/oo/tinyweb/RenderingStrategy.java
package com.mblinn.oo.tinyweb;

import java.util.List;
import java.util.Map;

public interface RenderingStrategy {

public String renderView(Map<String, List<String>> model);

Now let’s examine the class that delegates to RenderingStrategy, StrategyView. This
class is implemented by the framework and takes care of properly handing
exceptions thrown out of the RenderingStrategy. Its code follows:
JavaExamples/src/main/java/com/mblinn/oo/tinyweb/StrategyView.java
package com.mblinn.oo.tinyweb;

import java.util.List;
import java.util.Map;

public class StrategyView implements View {

private RenderingStrategy viewRenderer;

public StrategyView(RenderingStrategy viewRenderer) {


this.viewRenderer = viewRenderer;
}

@Override
public String render(Map<String, List<String>> model) {
try {
return viewRenderer.renderView(model);
} catch (Exception e) {
throw new RenderingException(e);
}
}
}

To implement a view, the framework user creates a new subclass of Render-


ingStrategy with the right view-rendering logic, and the framework injects it into
StrategyView.

In this simple example, StrategyView plays a minimal role. It simply swallows


exceptions and wraps them in RenderingException so that they can be handled
properly at a higher level. A more complete framework might use StrategyView
as an integration point for various rendering engines, among other things,
but we’ll keep it simple here.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


TinyWeb in Java • 15

Controllers and Template Method


Next up is our Controller. The Controller itself is a simple interface with a single
method, handleRequest(), which takes an HttpRequest and returns an HttpResponse.
The code for the interface follows:
JavaExamples/src/main/java/com/mblinn/oo/tinyweb/Controller.java
package com.mblinn.oo.tinyweb;

public interface Controller {


public HttpResponse handleRequest(HttpRequest httpRequest);
}

We’ll use the Template Method pattern so that users can implement their
own controllers. The central class for this implementation is TemplateController,
which has an abstract doRequest(), as shown in the following code:
JavaExamples/src/main/java/com/mblinn/oo/tinyweb/TemplateController.java
package com.mblinn.oo.tinyweb;

import java.util.List;
import java.util.Map;

public abstract class TemplateController implements Controller {


private View view;
public TemplateController(View view) {
this.view = view;
}

public HttpResponse handleRequest(HttpRequest request) {


Integer responseCode = 200;
String responseBody = "";

try {
Map<String, List<String>> model = doRequest(request);
responseBody = view.render(model);
} catch (ControllerException e) {
responseCode = e.getStatusCode();
} catch (RenderingException e) {
responseCode = 500;
responseBody = "Exception while rendering.";
} catch (Exception e) {
responseCode = 500;
}

return HttpResponse.Builder.newBuilder().body(responseBody)
.responseCode(responseCode).build();
}
protected abstract Map<String, List<String>> doRequest(HttpRequest request);
}

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 2. TinyWeb: Patterns Working Together • 16

To implement a controller, a user of the framework extends TemplateController


and implements its doRequest() method.

Both the Template Method pattern we used for our controllers and the
Strategy pattern we used for our views support similar tasks. They let some
general code, perhaps in a library or framework, delegate out to another bit
of code intended to perform a specific task. The Template Method pattern
does it using inheritance, while the Strategy pattern does it using composition.

In the functional world, we’ll rely heavily on composition, which also happens
be good practice in the object-oriented world. However, it’ll be a composition
of functions rather than a composition of objects.

Filter and Functional Interface


Finally, let’s examine Filter. The Filter class is a Functional Interface that lets
us perform some action on HttpRequest before it’s processed. For instance, we
may want to log some information about the request or even add a header.
It has a single method, doFilter(), takes HttpRequest, and returns a filtered instance
of it.

If an individual Filter needs to do something that modifies a request, it simply


creates a new one based on the existing request and returns it. This lets us
work with an immutable HttpRequest but gives us the illusion that it can be
changed.

The code for Filter follows:


JavaExamples/src/main/java/com/mblinn/oo/tinyweb/Filter.java
package com.mblinn.oo.tinyweb;

public interface Filter {


public HttpRequest doFilter(HttpRequest request);
}

Now that we’ve seen all of the pieces of TinyWeb, let’s see how they fit
together.

Tying It All Together


To tie it all together, we’ll use the main class, TinyWeb. This class takes two
constructor arguments. The first is a Map, where the keys are Strings represent-
ing request paths and the values are Controller objects. The second argument
is a list of Filters to run on all requests before they are passed to the appropriate
controller.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


TinyWeb in Java • 17

The TinyWeb class has a single public method, handleRequest(), which takes
HttpRequest. The handleRequest() method then runs the request through the filters,
looks up the appropriate controller to handle it, and returns the resulting
HttpResponse. The code is below:

JavaExamples/src/main/java/com/mblinn/oo/tinyweb/TinyWeb.java
package com.mblinn.oo.tinyweb;

import java.util.List;
import java.util.Map;

public class TinyWeb {


private Map<String, Controller> controllers;
private List<Filter> filters;

public TinyWeb(Map<String, Controller> controllers, List<Filter> filters) {


this.controllers = controllers;
this.filters = filters;
}

public HttpResponse handleRequest(HttpRequest httpRequest) {

HttpRequest currentRequest = httpRequest;


for (Filter filter : filters) {
currentRequest = filter.doFilter(currentRequest);
}

Controller controller = controllers.get(currentRequest.getPath());

if (null == controller)
return null;

return controller.handleRequest(currentRequest);
}
}

A full-featured Java web framework wouldn’t expose a class like this directly
as its framework plumbing. Instead it would use some set of configuration
files and annotations to wire things together. However, we’ll stop adding to
TinyWeb here and move on to an example that uses it.

Using TinyWeb
Let’s implement an example program that takes an HttpRequest with a comma-
separated list of names as its value and returns a body that’s full of friendly
greetings for those names. We’ll also add a filter that logs the path that was
requested.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 2. TinyWeb: Patterns Working Together • 18

We’ll start by looking at GreetingController. When the controller receives an


HttpRequest, it picks out the body of the request, splits it on commas, and treats
each element in the split body as a name. It then generates a random
friendly greeting for each name and puts the names into the model under the
key greetings. The code for GreetingController follows:
JavaExamples/src/main/java/com/mblinn/oo/tinyweb/example/GreetingController.java
package com.mblinn.oo.tinyweb.example;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import com.mblinn.oo.tinyweb.HttpRequest;
import com.mblinn.oo.tinyweb.TemplateController;
import com.mblinn.oo.tinyweb.View;

public class GreetingController extends TemplateController {


private Random random;
public GreetingController(View view) {
super(view);
random = new Random();
}

@Override
public Map<String, List<String>> doRequest(HttpRequest httpRequest) {
Map<String, List<String>> helloModel =
new HashMap<String, List<String>>();
helloModel.put("greetings",
generateGreetings(httpRequest.getBody()));
return helloModel;
}

private List<String> generateGreetings(String namesCommaSeperated) {


String[] names = namesCommaSeperated.split(",");
List<String> greetings = new ArrayList<String>();
for (String name : names) {
greetings.add(makeGreeting(name));
}
return greetings;
}

private String makeGreeting(String name) {


String[] greetings =
{ "Hello", "Greetings", "Salutations", "Hola" };
String greetingPrefix = greetings[random.nextInt(4)];
return String.format("%s, %s", greetingPrefix, name);
}
}

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


TinyWeb in Java • 19

Next up, let’s take a look at GreetingRenderingStrategy. This class iterates through
the list of friendly greetings generated by the controller and places each into
an <h2> tag. Then it prepends the greetings with an <h1> containing "Friendly
Greetings:", as the following code shows:

JavaExamples/src/main/java/com/mblinn/oo/tinyweb/example/GreetingRenderingStrategy.java
package com.mblinn.oo.tinyweb.example;

import java.util.List;
import java.util.Map;

import com.mblinn.oo.tinyweb.RenderingStrategy;

public class GreetingRenderingStrategy implements RenderingStrategy {

@Override
public String renderView(Map<String, List<String>> model) {
List<String> greetings = model.get("greetings");
StringBuffer responseBody = new StringBuffer();
responseBody.append("<h1>Friendly Greetings:</h1>\n");
for (String greeting : greetings) {
responseBody.append(
String.format("<h2>%s</h2>\n", greeting));

}
return responseBody.toString();
}

Finally, let’s look at an example filter. The LoggingFilter class just logs out the
path of the request it’s being run on. Its code follows:
JavaExamples/src/main/java/com/mblinn/oo/tinyweb/example/LoggingFilter.java
package com.mblinn.oo.tinyweb.example;

import com.mblinn.oo.tinyweb.Filter;
import com.mblinn.oo.tinyweb.HttpRequest;

public class LoggingFilter implements Filter {

@Override
public HttpRequest doFilter(HttpRequest request) {
System.out.println("In Logging Filter - request for path: "
+ request.getPath());
return request;
}

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 2. TinyWeb: Patterns Working Together • 20

Wiring up a simple test harness that connects everything together into a


TinyWeb, throws an HttpRequest at it, and then prints the response to the console
gets us the following output. This indicates that everything is working properly:
In Logging Filter - request for path: greeting/
responseCode: 200
responseBody:
<h1>Friendly Greetings:</h1>
<h2>Hola, Mike</h2>
<h2>Greetings, Joe</h2>
<h2>Hola, John</h2>
<h2>Salutations, Steve</h2>

Now that we’ve seen the TinyWeb framework in Java, let’s take a look at how
we’ll use some of the functional replacements for the object-oriented patterns
we’ll explore in this book. This will give us a TinyWeb that’s functionally
equivalent but written with fewer lines of code and in a more declarative,
easier-to-read style.

2.3 TinyWeb in Scala


Let’s take TinyWeb and transform it into Scala. We’ll do this a bit at a time
so we can show how our Scala code can work with the existing Java code.
The overall shape of the framework will be similar to the Java version, but
we’ll take advantage of some of Scala’s functional features to make the code
more concise.

Step One: Changing Views


We’ll start with our view code. In Java, we used the classic Strategy pattern.
In Scala, we’ll stick with the Strategy pattern, but we’ll use higher-order
functions for our strategy implementations. We’ll also see some of the benefits
of expressions over statements for control flow.

The biggest change we’ll make is to the view-rendering code. Instead of using
Functional Interface in the form of RenderingStrategy, we’ll use a higher-order
function. We go over this replacement in great detail in Pattern 1, Replacing
Functional Interface, on page 40.

Here’s our modified view code in its full functional glory:


ScalaExamples/src/main/scala/com/mblinn/mbfpp/oo/tinyweb/stepone/View.scala
package com.mblinn.mbfpp.oo.tinyweb.stepone
import com.mblinn.oo.tinyweb.RenderingException

trait View {
def render(model: Map[String, List[String]]): String
}

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


TinyWeb in Scala • 21

class FunctionView(viewRenderer: (Map[String, List[String]]) => String)


extends View {
def render(model: Map[String, List[String]]) =
try
viewRenderer(model)
catch {
case e: Exception => throw new RenderingException(e)
}
}

We start off with our View trait. It defines a single method, render(), which takes
a map representing the data in our model and returns a rendered String.
trait View {
def render(model: Map[String, String]): String
}

Next up, let’s take a look at the body of FunctionView. The code below declares
a class that has a constructor with a single argument, viewRenderer, which sets
an immutable field of the same name.
class FunctionView(viewRenderer: (Map[String, String]) => String) extends View {
«classBody»
}

The viewRenderer function parameter has a rather strange-looking type annota-


tion, (Map[String, String]) => String. This is a function type. It says that viewRenderer
is a function that takes a Map[String, String] and returns a String, just like the
renderView() on our Java RenderingStrategy.

Next, let’s take a look at the render() method itself. As we can see from the code
below, it takes in a model and runs it through the viewRender() function.
def render(model: Map[String, String]) =
try
viewRenderer(model)
catch {
case e: Exception => throw new RenderingException(e)
}

Notice how there’s no return keyword anywhere in this code snippet? This
illustrates another important aspect of functional programming. In the func-
tional world, we program primarily with expressions. The value of a function
is just the value of the last expression in it.

In this example, that expression happens to be a try block. If no exception is


thrown, the try block takes on the value of its main branch; otherwise it takes
on the value of the appropriate case clause in the catch branch.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 2. TinyWeb: Patterns Working Together • 22

If we wanted to supply a default value rather than wrap the exception up into
a RenderException, we can do so just by having the appropriate case branch take
on our default, as illustrated in the following code:
try
viewRenderer(model)
catch {
case e: Exception => ""
}

Now when an exception is caught, the try block takes on the value of the
empty string.

Step Two: A Controller First Cut


Now let’s take a look at transforming our controller code into Scala. In Java
we used the Controller interface and the TemplateController class. Individual con-
trollers were implemented by subclassing TemplateController.

In Scala, we rely on function composition just like we did with our views by
passing in a doRequest() function when we create a Controller:
ScalaExamples/src/main/scala/com/mblinn/mbfpp/oo/tinyweb/steptwo/Controller.scala
package com.mblinn.mbfpp.oo.tinyweb.steptwo

import com.mblinn.oo.tinyweb.HttpRequest
import com.mblinn.oo.tinyweb.HttpResponse
import com.mblinn.oo.tinyweb.ControllerException
import com.mblinn.oo.tinyweb.RenderingException

trait Controller {
def handleRequest(httpRequest: HttpRequest): HttpResponse
}

class FunctionController(view: View, doRequest: (HttpRequest) =>


Map[String, List[String]] ) extends Controller {

def handleRequest(request: HttpRequest): HttpResponse = {


var responseCode = 200;
var responseBody = "";

try {
val model = doRequest(request)
responseBody = view.render(model)
} catch {
case e: ControllerException =>
responseCode = e.getStatusCode()
case e: RenderingException =>
responseCode = 500
responseBody = "Exception while rendering."

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


TinyWeb in Scala • 23

case e: Exception =>


responseCode = 500
}

HttpResponse.Builder.newBuilder()
.body(responseBody).responseCode(responseCode).build()
}
}

This code should look fairly similar to our view code. This is a fairly literal trans-
lation of Java into Scala, but it’s not terribly functional because we’re using the
try-catch as a statement to set the values of responseCode and responseBody.

We’re also reusing our Java HttpRequest and HttpResponse. Scala provides a more
concise way to create these data-carrying classes, called case classes.
Switching over to use the try-catch as a statement, as well as using case
classes, can help cut down on our code significantly.

We’ll make both of these changes in our next transformation.

Immutable HttpRequest and HttpResponse


Let’s start by switching over to case classes instead of using the Builder pat-
tern. It’s as simple as the code below:
ScalaExamples/src/main/scala/com/mblinn/mbfpp/oo/tinyweb/stepthree/HttpData.scala
package com.mblinn.mbfpp.oo.tinyweb.stepthree

case class HttpRequest(headers: Map[String, String], body: String, path: String)


case class HttpResponse(body: String, responseCode: Integer)

We can create new HttpRequest and HttpResponse objects easily, as the following
REPL output shows:
scala> val request = HttpRequest(Map("X-Test" -> "Value"), "requestBody", "/test")
request: com.mblinn.mbfpp.oo.tinyweb.stepfour.HttpRequest =
HttpRequest(Map(X-Test -> Value),requestBody,/test)

scala> val response = HttpResponse("requestBody", 200)


response: com.mblinn.mbfpp.oo.tinyweb.stepfour.HttpResponse =
HttpResponse(requestBody,200)

At first glance, this might seem similar to using a Java class with constructor
arguments, except that we don’t need to use the new keyword. However, in
Pattern 4, Replacing Builder for Immutable Object, on page 62, we dig deeper
and see how Scala’s ability to provide default arguments in a constructor,
the natural immutability of case classes, and the ability to easily create a new
instance of a case class from an existing instance lets them satisfy the intent
of the Builder pattern.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 2. TinyWeb: Patterns Working Together • 24

Let’s take a look at our second change. Since a try-catch block in Scala has a
value, we can use it as an expression rather than as a statement. This might
seem a bit odd at first, but the upshot is that we can use the fact that Scala’s
try-catch is an expression to simply have the try-catch block take on the value of
the HttpResponse we’re returning. The code to do so is below:
ScalaExamples/src/main/scala/com/mblinn/mbfpp/oo/tinyweb/stepthree/Controller.scala
package com.mblinn.mbfpp.oo.tinyweb.stepthree
import com.mblinn.oo.tinyweb.ControllerException
import com.mblinn.oo.tinyweb.RenderingException

trait Controller {
def handleRequest(httpRequest: HttpRequest): HttpResponse
}
class FunctionController(view: View, doRequest: (HttpRequest) =>
Map[String, List[String]] ) extends Controller {
def handleRequest(request: HttpRequest): HttpResponse =
try {
val model = doRequest(request)
val responseBody = view.render(model)
HttpResponse(responseBody, 200)
} catch {
case e: ControllerException =>
HttpResponse("", e.getStatusCode)
case e: RenderingException =>
HttpResponse("Exception while rendering.", 500)
case e: Exception =>
HttpResponse("", 500)
}
}

This style of programming has a couple of benefits. First, we’ve eliminated a


couple of extraneous variables, responseCode and responseBody. Second, we’ve
reduced the number of lines of code a programmer needs to scan to under-
stand which HttpRequest we’re returning from the entire method to a single line.

Rather than tracing the values of responseCode and responseBody from the top of
the method through the try block and finally into the HttpResponse, we only
need to look at the appropriate piece of the try block to understand the final
value of the HttpResponse. These changes combine to give us code that’s more
readable and concise.

Tying It Together
Now let’s add in the class that ties it all together, TinyWeb. Like its Java coun-
terpart, TinyWeb is instantiated with a map of Controllers and a map of filters.
Unlike Java, we don’t define a class for filter; we simply use a list of higher-
order functions!

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


TinyWeb in Scala • 25

Also like the Java version, the Scala TinyWeb has a single method, handleRequest(),
which takes in an HttpRequest. Instead of returning an HttpResponse directly, we
return an Option[HttpResponse], which gives us a clean way of handling the case
when we can’t find a controller for a particular request. The code for the Scala
TinyWeb is below:

ScalaExamples/src/main/scala/com/mblinn/mbfpp/oo/tinyweb/stepfour/Tinyweb.scala
package com.mblinn.mbfpp.oo.tinyweb.stepfour
class TinyWeb(controllers: Map[String, Controller],
filters: List[(HttpRequest) => HttpRequest]) {

def handleRequest(httpRequest: HttpRequest): Option[HttpResponse] = {


val composedFilter = filters.reverse.reduceLeft(
(composed, next) => composed compose next)
val filteredRequest = composedFilter(httpRequest)
val controllerOption = controllers.get(filteredRequest.path)
controllerOption map { controller => controller.handleRequest(filteredRequest) }
}
}

Let’s take a look at it in greater detail starting with the class definition.
class TinyWeb(controllers: Map[String, Controller],
filters: List[(HttpRequest) => HttpRequest]) {
«classBody»
}

Here we’re defining a class that takes two constructor arguments, a map of
controllers and a list of filters. Note the type of the filters argument,
List[(HttpRequest) => HttpRequest]. This says that filters is a list of functions from
HttpRequest to HttpRequest.

Next up, let’s look at the signature of the handleRequest() method:


def handleRequest(httpRequest: HttpRequest): Option[HttpResponse] = {
«functionBody»
}

As advertised, we’re returning an Option[HttpResponse] instead of an HttpResponse.


The Option type is a container type with two subtypes, Some and None. If we’ve
got a value to store in it, we can store it in an instance of Some; otherwise we
use None to indicate that we’ve got no real value. We’ll cover Option in greater
detail in Pattern 8, Replacing Null Object, on page 99.

Now that we’ve seen the TinyWeb framework, let’s take a look at it in action.
We’ll use the same example from the Java section, returning a list of friendly
greetings. However, since it’s Scala, we can poke at our example in the REPL
as we go. Let’s get started with our view code.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 2. TinyWeb: Patterns Working Together • 26

Using Scala TinyWeb


Let’s take a look at using our Scala TinyWeb framework.

We’ll start by creating a FunctionView and the rendering function we’ll compose
into it. The following code creates this function, which we’ll name greetingViewRen-
derer(), and the FunctionView that goes along with it:

ScalaExamples/src/main/scala/com/mblinn/mbfpp/oo/tinyweb/example/Example.scala
def greetingViewRenderer(model: Map[String, List[String]]) =
"<h1>Friendly Greetings:%s".format(
model
getOrElse("greetings", List[String]())
map(renderGreeting)
mkString ", ")

private def renderGreeting(greeting: String) =


"<h2>%s</h2>".format(greeting)

def greetingView = new FunctionView(greetingViewRenderer)

We’re using a couple of new bits of Scala here. First, we introduce the map()
method, which lets us map a function over all the elements in a sequence
and returns a new sequence. Second, we’re using a bit of syntactic sugar that
Scala provides that allows us to treat any method with a single argument as
an infix operator. The object on the left side of the operator is treated as the
receiver of the method call, and the object on the right is the argument.

This bit of syntax means that we can omit the familiar dot syntax when
working in Scala. For instance, the two usages of map() below are equivalent:
scala> val greetings = List("Hi!", "Hola", "Aloha")
greetings: List[java.lang.String]

scala> greetings.map(renderGreeting)
res0: List[String] = List(<h2>Hi!</h2>, <h2>Hola</h2>, <h2>Aloha</h2>)

scala> greetings map renderGreeting


res1: List[String] = List(<h2>Hi!</h2>, <h2>Hola</h2>, <h2>Aloha</h2>)

Now let’s take a look at our controller code. Here we create the handleGreetingRe-
quest() function to pass into our Controller. As a helper, we use makeGreeting(),
which takes in a name and generates a random friendly greeting.

Inside of handleGreetingRequest() we create a list of names by splitting the request


body, which returns an array like in Java, converting that array into a Scala
list and mapping the makeGreeting() method over it. We then use that list as the
value for the "greetings" key in our model map:

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


TinyWeb in Scala • 27

Scala Functions and Methods


Since Scala is a hybrid language, it’s got both functions and methods. Methods are
defined using the def keyword, as we do in the following code snippet:

scala> def addOneMethod(num: Int) = num + 1


addOneMethod: (num: Int)Int

We can create a function and name it by using Scala’s anonymous function syntax,
assigning the resulting function to a val, like we do in this code snippet:

scala> val addOneFunction = (num: Int) => num + 1


addOneFunction: Int => Int = <function1>

We can almost always use methods as higher-order functions. For instance, here we
pass both the method and the function version of addOne() into map().

scala> val someInts = List(1, 2, 3)


someInts: List[Int] = List(1, 2, 3)

scala> someInts map addOneMethod


res1: List[Int] = List(2, 3, 4)

scala> someInts map addOneFunction


res2: List[Int] = List(2, 3, 4)

Since method definitions have a cleaner syntax, we use them when we need to define
a function, rather than using the function syntax. When we need to manually convert
a method into a function, we can do so with the underscore operator, as we do in the
following REPL session:

scala> addOneMethod _
res3: Int => Int = <function1>

The need to do this is very rare, though; for the most part Scala is smart enough to
do the conversion automatically.

ScalaExamples/src/main/scala/com/mblinn/mbfpp/oo/tinyweb/example/Example.scala
def handleGreetingRequest(request: HttpRequest) =
Map("greetings" -> request.body.split(",").toList.map(makeGreeting))

private def random = new Random()


private def greetings = Vector("Hello", "Greetings", "Salutations", "Hola")
private def makeGreeting(name: String) =
"%s, %s".format(greetings(random.nextInt(greetings.size)), name)

def greetingController = new FunctionController(greetingView, handleGreetingRequest)

Finally, let’s take a look at our logging filter. This function simply writes the
path that it finds in the passed-in HttpRequest to the console and then returns
the path unmodified:

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 2. TinyWeb: Patterns Working Together • 28

ScalaExamples/src/main/scala/com/mblinn/mbfpp/oo/tinyweb/example/Example.scala
private def loggingFilter(request: HttpRequest) = {
println("In Logging Filter - request for path: %s".format(request.path))
request
}

To finish up the example, we need to create an instance of TinyWeb with the


controller, the view, and the filter we defined earlier, and we need to create a
test HttpResponse:
ScalaExamples/src/main/scala/com/mblinn/mbfpp/oo/tinyweb/example/Example.scala
def tinyweb = new TinyWeb(
Map("/greeting" -> greetingController),
List(loggingFilter))
def testHttpRequest = HttpRequest(
body="Mike,Joe,John,Steve",
path="/greeting")

We can now run the test request through TinyWeb’s handleRequest() method in
the REPL and view the corresponding HttpResponse:
scala> tinyweb.handleRequest(testHttpRequest)
In Logging Filter - request for path: /greeting
res0: Option[com.mblinn.mbfpp.oo.tinyweb.stepfour.HttpResponse] =
Some(HttpResponse(<h1>Friendly Greetings:<h2>Mike</h2>, <h2>Nam</h2>, <h2>John</h2>,
200))

That wraps up our Scala version of TinyWeb. We’ve made a few changes to
the style that we used in our Java version. First, we replaced most of our
iterative code with code that’s more declarative. Second, we’ve replaced our
bulky builders with Scala’s case classes, which give us a built-in way to
handle immutable data. Finally, we’ve replaced our use of Functional Interface
with plain old functions.

Taken together, these small changes save us quite a bit of code and give us
a solution that’s shorter and easier to read. Next up, we’ll take a look at
TinyWeb in Clojure.

2.4 TinyWeb in Clojure


Now let’s take TinyWeb and translate it into Clojure. This is going to be a
bigger leap than the translation from Java to Scala, so we’ll take it slowly.

The most obvious difference between Clojure and Java is the syntax. It’s very
different than the C-inspired syntax found in most modern programming
languages. This isn’t incidental: the syntax enables one of Clojure’s most
powerful features, macros, which we’ll cover in Pattern 21, Domain-Specific
Language, on page 218.

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


TinyWeb in Clojure • 29

A Gentle Introduction to Clojure


For now let’s just have a gentle introduction. Clojure uses prefix syntax, which
just means that the function name comes before the function arguments in
a function call. Here we call the count function to get the size of a vector, one
of Clojure’s immutable data structures:
=> (count [1 2 3 4])
4

Like Scala, Clojure has excellent interoperability with existing Java code.
Calling a method on a Java class looks almost exactly like calling a Clojure
function; you just need to prepend the method name with a period and put
it before the class instance rather than after. For instance, this is how we call
the length() method on an instance of a Java String:
=> (.length "Clojure")
7

Instead of organizing Clojure code into objects and methods in Java or into
objects, methods, and functions in Scala, Clojure code is organized into
functions and namespaces. Our Clojure version of TinyWeb is based on
models, views, controllers, and filters, just like the Java and Scala versions;
however, these components will take quite a different form.

Our views, controllers, and filter codes are simply functions, and our models
are maps. To tie everything together, we use a function named TinyWeb,
which takes in all our components and returns a function that takes in an
HTTP request, runs it through the filters, and then routes it to the proper
controller and view.

Controllers in Clojure
Let’s start our look at the Clojure code with the controllers. Below, we implement
a simple controller that takes the body of an incoming HTTP request and uses it
to set a name in a model. For this first iteration, we’ll use the same HttpRequest as
our Java code. We’ll change it to be more idiomatic Clojure later on:
ClojureExamples/src/mbfpp/oo/tinyweb/stepone.clj
(ns mbfpp.oo.tinyweb.stepone
(:import (com.mblinn.oo.tinyweb HttpRequest HttpRequest$Builder)))
(defn test-controller [http-request]
{:name (.getBody http-request)})
(def test-builder (HttpRequest$Builder/newBuilder))
(def test-http-request (.. test-builder (body "Mike") (path "/say-hello") build))
(defn test-controller-with-map [http-request]
{:name (http-request :body)})

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Chapter 2. TinyWeb: Patterns Working Together • 30

Let’s take a look at this code piece by piece, starting with the namespace
declaration.
ClojureExamples/src/mbfpp/oo/tinyweb/stepone.clj
(ns mbfpp.oo.tinyweb.stepone
(:import (com.mblinn.oo.tinyweb HttpRequest HttpRequest$Builder)))

Here we define a namespace called mbfpp.oo.tinyweb.stepone. A namespace is


simply a collection of functions that form a library that can be imported in
full or in part by another namespace.

As part of the definition, we import a couple of Java classes, HttpRequest and


HttpRequest$Builder. The second one might look a little strange, but it’s just the
full name for the static inner Builder class we created as part of our HttpRequest.
Clojure doesn’t have any special syntax for referring to static inner classes,
so we need to use the full class name.

The keyword :import is an example of a Clojure keyword. A keyword is just an


identifier that provides very fast equality checks and is always prepended
with a colon. Here we’re using the :import keyword to indicate what classes
should be imported into the namespace we’ve just declared, but keywords
have many other uses. They’re often used as keys in a map, for instance.

Now let’s take a look at our controller, which takes an HttpRequest from the
original Java solution and produces a Clojure map as a model:
ClojureExamples/src/mbfpp/oo/tinyweb/stepone.clj
(defn test-controller [http-request]
{:name (.getBody http-request)})

Here we call the getBody() method on the HttpRequest to get the body of the
request, and we use it to create a map with a single key-value pair. The key
is the keyword :name, and the value is the String body of the HttpRequest.

Before we move on, let’s look at Clojure maps in greater detail. In Clojure, it’s
common to use maps to pass around data. The syntax for creating a map in
Clojure is to enclose key-value pairs inside curly braces. For instance, here
we’re creating a map with two key-value pairs. The first key is the keyword
:name, and the value is the String "Mike". The second is the keyword :sex, and the
value is another keyword, :male>:
=> {:name "Mike" :sex :male}
{:name "Mike" :sex :male}

Maps in Clojure are functions of their keys. This means that we can call a map
as a function, passing a key we expect to be in the map, and the map will return
the value. If the key isn’t in the map, nil is returned, as the code below shows:

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


TinyWeb in Clojure • 31

=> (def test-map {:name "Mike"})


#'mbfpp.oo.tinyweb.stepone/test-map
=> (test-map :name)
"Mike"
=> (test-map :orange)
nil

Keywords in Clojure are also functions. When they are passed a map, they
will look themselves up in it, as in the following snippet, which shows the
most common way to look up a value from a map:
=> (def test-map {:name "Mike"})
#'mbfpp.oo.tinyweb.stepone/test-map
=> (:name test-map)
"Mike"
=> (:orange test-map)
nil

Now let’s create some test data. Below, we create an HttpRequest$Builder and use
it to create a new HttpRequest:
ClojureExamples/src/mbfpp/oo/tinyweb/stepone.clj
(def test-builder (HttpRequest$Builder/newBuilder))
(def test-http-request (.. test-builder (body "Mike") (path "/say-hello") build))

This code features two more Clojure/Java interop features. First, the forward
slash lets us call a static method or reference a static variable on a class. So
the snippet (HttpRequest$Builder/newBuilder) is calling the newBuilder() method on the
HttpRequest$Builder class. As another example, we can use this syntax to parse
an integer from a String using the parseInt() method on the Integer class:
=> (Integer/parseInt "42")
42

Next up is the .. macro, a handy interop feature that makes calling a series
of methods on a Java object easy. It works by taking the first argument to ..
and threading it through calls to the rest of the arguments.

The snippet (.. test-builder (body "Mike") (path "/say-hello") build) first calls the body()
method on test-builder with the argument "Mike". Then it takes that result and
calls the path() method on it with the argument "say-hello" and finally calls build()
on that result to return an instance of HttpResult.

Here’s another example of using the .. macro to uppercase the string "mike"
and then take the first character of it:
=> (.. "mike" toUpperCase (substring 0 1))
"M"

Download from Wow! eBook <www.wowebook.com> report erratum • discuss


Another Random Document on
Scribd Without Any Related Topics
Stück Land, so schwer es mir auch wurde, mit einem hölzernen
Spaten um, teilte es in zwei Hälften und übergab die Körner der
ernährenden Mutter Erde; den dritten Teil derselben behielt ich indes
aus Vorsorge zurück, falls ich die Jahreszeit nicht richtig gewählt
haben sollte. Der folgende Monat war ein außerordentlich trockener
und ließ meine Saat kaum zum Aufkeimen kommen; ja, ich mußte
ganz auf eine Ernte verzichten, da sich die Keime vor der
wiederkehrenden Regenzeit nicht bis zur Reife entwickeln konnten.
Ich suchte nun einen feuchteren Boden auf, grub ihn um und säete
den zurückbehaltenen Rest der Körner im Februar, kurz vor dem
Eintritt der nassen Jahreszeit. Die regnerischen Monate März und
April waren meiner Pflanzung, auf die ich meine letzten Hoffnungen
gegründet hatte, so günstig, daß ich etwa ein Liter von jeder
Gattung erntete.
Die Jahreszeiten wechselten unter dem Himmel meiner Insel nicht
mit so angenehmen Übergängen wie in der Heimat, sondern sie
schieden sich nur in zwei Perioden, in eine trockene und eine nasse:
von Mitte Februar bis Mitte April Regen, von Mitte April bis Mitte
August trockene Zeit; von Mitte August bis Mitte Oktober Regen, von
Mitte Oktober bis Mitte Februar Trockenheit.
Die gezwungene Zurückgezogenheit in den Regenmonaten
benutzte ich zu allerhand nützlichen Beschäftigungen. So versuchte
ich unter anderm auch, einen Korb zu flechten, und wurde in dieser
Arbeit durch Erinnerungen aus frühester Kindheit unterstützt. Wie
hätte ich vorher ahnen können, daß die Besuche bei unserm
Nachbar Korbflechter, in dessen Werkstatt ich ein täglicher Gast
gewesen, mir später nützlich sein würden? Die ersten Zweige, mit
denen ich meine Arbeit beginnen wollte, zeigten sich freilich recht
spröde. Meine Blicke lenkten sich unwillkürlich auf die jungen
Stecklinge um die Hütte; diese versprachen besseres Flechtmaterial.
Ich fand sie wirklich so geschmeidig wie Weidenruten, und es ward
meinen Künstlerhänden nicht schwer, die verschiedensten Körbe zu
mannigfachen Zwecken herzustellen.
Meine häuslichen Verhältnisse hatten sich immer behaglicher
gestaltet, nur noch ein einziges Gerät vermißte ich schmerzlich: ein
Kochgeschirr. Zwar besaß ich einen Kessel; allein dieser war von so
bedeutender Größe, daß ich darin weder ein kleines Stück Fleisch
kochen, noch weniger mir Fleischbrühe bereiten konnte. Wie ließ
sich diesem Übelstand abhelfen? Ich dachte so: wenn es mir
gelänge, Thonerde zu finden, so könnte wohl die Glut der tropischen
Sonne meine Töpferarbeiten trocknen. Ach! – meine Töpferarbeiten!
Ich will hier nicht erzählen, wie viel ungeschickte Versuche ich
machte, welche ungeheuerlichen Formen sich die Mutter Erde unter
meinen Händen gefallen lassen mußte, wie oft meine Gefäße in der
großen Sonnenhitze zerbröckelten oder beim Fortschaffen
zerbrachen. Erst nach zwei Monaten hatte ich endlich zwei
Erzeugnisse zusammengebracht, die nicht einmal mit den
schlechtesten Schiffskrügen nur annähernd verglichen werden
konnten. Weniger mißlangen meine Versuche im Anfertigen kleinerer
Gefäße, z. B. der Teller, Töpfe, Krüge, kurz aller Gerätschaften, die
sich mit der Hand formen ließen. Dabei kam mir auch die günstige
Witterung zu statten; die Sonne meinte es in diesen Tagen überaus
gut, so daß mein Töpfergeschirr in erwünschter Weise Härte
gewann.
Mittels meiner fortschreitenden Töpferkünste hatte ich mir Gefäße
zum Aufbewahren von allerlei Lebensmitteln beschafft, aber noch
immer fehlten mir solche, welche auch das Feuer auszuhalten
vermochten. Da ich weder einen Begriff von der Einrichtung eines
Ofens, noch von der Glasur hatte, mit der die Töpfer ihre Waren
überziehen, so beschränkte ich mich darauf, drei Krüge dicht
nebeneinander zu stellen; auf diese setzte ich kleinere Geschirre,
und um die so aufgetürmte Pyramide zündete ich dann ein tüchtiges
Feuer an, welches die Sandbestandteile der Thonerde schmelzen
sollte. Die Töpfe nahmen nach Verlauf von fünf bis sechs Stunden
eine hochrote Farbe an. So wurde ich schließlich der glückliche
Besitzer von drei leidlichen Krügen nebst zwei irdenen Töpfen, die
sich auch als feuerfest erwiesen.
Von meiner Insel blieb noch mancher Teil zu durchstreifen übrig.
Deshalb nahm ich eines Tages meine Flinte samt der nötigen
Munition, ein Beil, zwei Zwiebäcke sowie ein Päckchen Rosinen mit
und machte mich in Begleitung meines Hundes auf den Weg. Am
Ende des Thales angelangt, in welchem meine Villa lag, sah ich
westwärts auf das Meer und, da die Luft äußerst rein und
durchsichtig war, fern am Horizont einen nebligen Streifen, der von
West nach West-Süd-West verlief und eine Ausdehnung von fünf bis
sechs Stunden haben mochte. Zwar wußte ich nicht, ob ich die Küste
einer Insel oder die des amerikanischen Festlandes erblickte;
vielleicht war ich auf dem rechten Wege, als ich vermutete, daß die
spanischen Kolonien nicht allzu entfernt von jenem Küstenstriche
lägen, und daß sich doch wohl ein Schiff in diesen Gewässern sehen
lassen müsse. Möglicherweise konnten aber auch dort jene wilden,
menschenfressenden Völkerschaften hausen, die unter dem Namen
»Kannibalen« weithin gefürchtet sind.
Unter solcherlei Gedanken schritt ich über Ebenen und Wiesen, die
mit Pflanzen und Blumen prächtig geschmückt und auch mit
Sträuchern besetzt waren. Auf den Bäumen hatten sich Scharen von
Tauben niedergelassen, deren Gegirr von dem schrillen Geschrei
buntgefiederter Papageien übertönt ward. Solch einen schmucken
Papagei mußte ich haben, und in der That gelang es mir, einen
jungen Vogel dieser Art zu fangen, indem ich ihn durch einen Wurf
mit meinem Wanderstab so gut traf, daß er betäubt vom Aste
herabfiel. Ich hob ihn auf, er kam allmählich wieder zu sich, und ich
nahm ihn mit mir.
In den Niederungen sah ich außerdem Tiere, welche ich für Hasen
hielt; wieder andere mochten Füchse sein; aber ich ließ meine Flinte
in Ruhe, denn Ziegen, Tauben und Schildkröten lieferten so leckeres
Fleisch, und ich besaß an Rosinen eine so schmackhafte Zukost, daß
selbst der beste Markt von London nichts Besseres geliefert haben
würde.
Auf meiner Entdeckungsreise durch die Insel rückte ich täglich nur
zwei bis drei Meilen vor, doch machte ich nach links und rechts
manche Abstecher, bis ich ermüdet an einem solchen Platze
anlangte, welcher mir zum Nachtlager geeignet schien. Zum Bett
mußten entweder die breiten Äste eines Baumes oder der harte
Boden der Erde dienen. Als ich an das Ufer des Meeres kam, sah ich
zu meiner Überraschung, daß die Küste meines Königreichs viel
angenehmer und von Tieren mehr bevölkert war als der
entgegengesetzte Strand. Zahlreiche Schildkröten sonnten sich hier
im Sande, und Seevögel marschierten mit stolzer Würde umher.

Schildkröten und Fetttaucher auf der Insel.


Trotz alledem verspürte ich keine Lust, meine Wohnung in diese
Gegend zu verlegen. Indessen setzte ich meine Reise noch etwa
zwölf Stunden gegen Osten weiter fort. Den äußersten Grenzpunkt
meiner Wanderungen bezeichnete ein eingerammter Pfahl, der mir
später einmal als Erkennungszeichen dienen sollte. Dann wandte ich
mich gegen Westen, um auf einem andern Wege nach Hause
zurückzukehren. Nachdem ich etwa drei Meilen zurückgelegt hatte,
befand ich mich in einem Thalkessel, der rings von hohen, dicht mit
Waldung gekrönten Bergen umsäumt war, so daß ich mich beim
weiteren Fortschreiten, um mich zurecht zu finden, nach dem Stande
der Sonne richten mußte.
Während der drei Tage, die ich in diesem Thale verweilte, hing
aber der Himmel voll trüber Wolken, und ich wußte oft nicht, wohin
ich mich wenden sollte, ob nach Ost, West, Süd oder Nord. So sah
ich mich denn genötigt, nach meinem Pfahl zurückzukehren und von
da aus den Heimweg anzutreten.
Unterwegs fing mein Hund eine junge Ziege ein. Eiligst sprang ich
hinzu, um sie seinem scharfen Gebiß zu entreißen, was mir auch
glückte. Bald war dem Tiere ein Halsband übergeworfen, ein Strick
durchgezogen, und weiter ging nun die Wanderung, bis wir endlich,
jedoch erst nach mehreren Tagemärschen, durch die sengende
Sonnenglut aufs äußerste ermattet, in meinem Wohnsitze ankamen.
Ich empfand wirklich eine große Freude, wieder daheim zu sein! Wie
sanft schlief ich nach einer Abwesenheit von mehr als einem Monate
zum erstenmal wieder in meiner Hängematte.
Das nächste, wofür ich Sorge zu tragen hatte, war, meinem
Papagei, welcher sich an mich bereits etwas gewöhnt hatte, einen
Käfig zu bauen, sowie die Ziege, welcher ich einstweilen in meinem
Lusthause ihren Aufenthalt angewiesen, nach Hause zu schaffen, um
das ausgehungerte Tierchen mit frischem Futter zu versorgen.
Ich fand es angebunden an derselben Stelle, wo ich es verlassen
hatte, und es folgte mir wie ein zahmes Haustier Schritt für Schritt,
indem es fortwährend aus meiner Hand das Futter fraß, mit dem ich
es lockte.
Wieder war der 30. September gekommen, und wieder hatte ich
unter inbrünstigem Gebet den Jahrestag meiner Strandung
begangen. Zwei Jahre lebte ich nun schon auf dem Eilande als
dessen alleiniger Bewohner, mein eigner König und mein einziger
Unterthan; – zwei Jahre reich an Prüfungen und Erfahrungen! Und
doch hatte sich mir nicht einmal ein Strahl von Hoffnung gezeigt,
diese einsame Insel verlassen zu können. Indessen dankte ich Gott
für die unendliche Güte, mit welcher er mein armseliges Dasein
fristete und meine Einsamkeit mir erträglich erscheinen ließ.
Wenn ich in der ersten Zeit meines Verlassenseins hinausstreifte
auf die Ebenen und Berge, sei es, um ein Tier auf der Jagd zu
erlegen, oder sei es, um auf Entdeckungen auszugehen, da
begleitete mich der stete Gedanke an mein Unglück und meine oft
trostarme Lage. Ich kam mir vor wie ein Gefangener, der,
eingeschlossen durch die endlosen Riegel und riesigen Schlösser des
Ozeans, in einer Wüstenei, ohne Hoffnung auf Befreiung, ein
erbärmliches Dasein fristet, und aufgelöst in Schmerz und Betrübnis
rang ich die Hände und weinte bitterlich.
Jetzt war es anders! Neue Gedanken, geschöpft aus der Heiligen
Schrift, dem Buche der Bücher, gaben meinem Geiste eine heilsame
Richtung, und ich gewann meine ganze Seelenstärke wieder, wenn
meine Augen auf die Worte des Trostes fielen. Ich fand Beruhigung
in dem Gedanken, daß ich in meinem gegenwärtigen Zustande der
Vereinsamung glücklicher sein könnte, als ich es vielleicht in irgend
einer andern Lebensstellung geworden wäre. Ich dankte dann Gott
dafür, daß er mich auf dieses Eiland geführt hatte. Dann wieder
schien mir jener Gedanke zu weitgehend. »Solltest du wirklich so
zwiespältig im Gemüte sein«, sagte ich zu mir selbst, »Gott für die
Versetzung in eine Lage zu danken, aus welcher erlöst zu werden ein
verzeihlicher und natürlicher Wunsch ist?« Jedenfalls dankte ich Gott
doch innig dafür, daß ich jetzt endlich zur Selbsterkenntnis
hinsichtlich der begangenen Fehler gelangt war.
Nun trat ich in das dritte Jahr meines Insellebens. In meine
täglichen Beschäftigungen hatte ich eine gewisse Regelmäßigkeit
gebracht. Zunächst verwandte ich auf die Erfüllung meiner religiösen
Pflichten, insbesondere auf das Lesen in der Bibel täglich eine
bestimmte Zeit; dann jagte ich, wenn das Wetter schön war,
ungefähr drei Stunden des Morgens. Kam ich nach Hause zurück, so
hatte ich die mitgebrachten Lebensmittel wohl aufzubewahren oder
zuzubereiten. Die Hitze während der mittleren Tageszeit gestattete
keinen Ausflug, und ich überließ mich dann gewöhnlich der Ruhe.
Manchmal arbeitete ich auch des Morgens und ging des Abends auf
die Jagd.
Ende November war herangekommen, und ich konnte bereits
meiner Gersten- und Reisernte entgegensehen. Aber wie groß war
mein Schrecken, als ich bei einer Besichtigung meines kleinen
Ackerfeldes gewahr wurde, daß die Ziegen alle jungen saftigen
Halme abgefressen hatten. Es galt nun, schleunigst weiteren
Verwüstungen vorzubeugen. Ich umgab mein Zelt mit einer dichten
Umzäunung, worüber ich nahe an drei Wochen zubrachte. Ferner
schoß ich auf die Tiere, welche sich am Tage heranwagten, und ließ
während der Nacht meinen Hund Wache halten, so daß sich endlich
die abgeschreckten Eindringlinge fern hielten.
Gleichwie die behaarten Vierfüßler sich zu den kräftig
emporsprossenden Halmen hingezogen fühlten, hatten es die
gefiederten Zweifüßler auf die Körner abgesehen. Als ich eines Tages
nach dem Stande meiner Feldfrüchte sah, wimmelte die ganze
Umgebung von zahlreichen verschiedenartigen Vögeln. Ich schoß
unter den dicksten Haufen, und sofort erhob sich mit wirrem
Schreien mitten aus dem Kornfeld eine wahre Wolke von Vögeln, die
ich vorher gar nicht bemerkt hatte.
Meine Ernteaussichten schienen nach solchen Betrachtungen
trostloser Natur zu sein; doch durfte ich um keinen Preis den Rest
meines Getreides der Vernichtung überlassen.
Während ich nun neben meinem Felde stand und die Flinte von
neuem lud, saßen die durch meinen ersten Schuß aufgescheuchten
Vögel auf den nächsten Bäumen und schienen nur auf meine
Entfernung zu harren. Als ich mich etwas entfernte, fielen die
gefräßigen Tiere von neuem über die Körner her. Ihre für mich so
verderbliche Eilfertigkeit versetzte mich derart in einen
unverständigen Zorn, daß ich nicht einmal wartete, bis alle
herangekommen sein würden, sondern sogleich unter die ersten
schoß, wodurch drei der kleinen Räuber getötet wurden. Dann
vollführte ich an ihnen eine Art Strafgericht; gleichwie man
anderwärts die Diebe aufhängt, so hing ich auch die Vögel auf, damit
sie ihren lüsternen Genossen als warnendes Beispiel dienten.
Die Wirkung war auffallend: keines der Tiere wagte sich mehr auf
mein Feld, ja sie verließen sogar allesamt jenen Teil der Insel, auf
dem es ihnen nicht mehr geheuer zu sein schien. Nach diesem
Säuberungszug hatte ich die Freude, gegen das Ende des Dezember,
zur Zeit der zweiten Reife, mein Korn einernten zu können. Ich
sammelte die abgemähten Ähren in einen großen Korb und körnte
sie einzeln mit den Händen aus. Das Liter Samen hatte mir nach
oberflächlicher Schätzung zwei Scheffel Reis sowie einen halben
Scheffel Gerste eingetragen, und ich beschloß, den ganzen Ertrag an
Körnern für die nächste Aussaat aufzubewahren. Inzwischen
versuchte ich, zur passenden Umgrabung des Ackerbodens mir einen
Spaten zu fertigen, was mich eine ganze Woche Zeit kostete. Ein
besonderes Meisterwerk war mir mit diesem Spaten allerdings nicht
gelungen, denn er wurde mir vermöge seiner Schwerfälligkeit oft
recht unbequem; indes empfand ich doch ein Gefühl der
Befriedigung darüber, daß sich meine Einrichtungen abermals um
einen Schritt weiter vervollkommnet hatten. Die Getreidekörner
wurden auf den geräumigen Feldern ganz nahe an meiner Wohnung
in die Erde gebracht, wobei ich für den Reis die feuchteste Stelle
aussuchte, da, wie ich bemerkt hatte, derselbe nur auf nassem
Boden eine einträgliche Ernte versprach.
Ich umzäunte die Felder mit einem starken Gehege und durfte nun
hoffen, am Ende des Jahres eine grüne und schattige Hecke zu
haben, welche nur hier und da einmal ausgeputzt zu werden
brauchte.
Während der inzwischen eingetretenen Regenzeit hielt ich mich
meist im Innern meiner Hütte auf und beschäftigte mich mit
mancherlei häuslichen Verrichtungen. Empfand ich hin und wieder
das Bedürfnis, mich von meinen anstrengenden Arbeiten zu erholen,
dann unterhielt ich mich mit meinem munteren Hausgenossen, dem
Papagei, und lehrte diesen sprechen; bald konnte das gelehrige Tier
seinen Namen nachplappern und wiederholte mit deutlicher Stimme:
»Poll! Poll!« Das war der erste artikulierte, wie von einer
Menschenstimme kommende Laut, den ich auf dem Eilande in
meiner Einsamkeit, fern von allen menschlichen Wesen, vernahm.
Wie Robinson die Halme niedermäht.
Siebentes Kapitel.
Robinson als Bäcker und
Schiffbauer.
Robinson macht sich einen Mörser und ein Sieb. – Ernte. – Brotbacken. –
Vergebliche Anstrengungen wegen der Schaluppe. – Robinson baut ein Boot;
vereitelte Hoffnungen. – Rückblicke auf das dreijährige Inselleben. – Trauriger
Zustand der Kleider. – Robinson wird Schneider.
Von allen bekannten Handwerken war mir bis zu dieser Zeit
meines Lebens keines so wildfremd geblieben, wie das eines
Steinmetzen, und doch mußte ich darauf sinnen, mir einen Mörser
oder ein andres geeignetes Werkzeug zu schaffen, um das Getreide
in Mehl zu verwandeln. Lange Zeit suchte ich vergebens nach einem
Steinblock, der sich mörserartig aushöhlen ließe; dann entschloß ich
mich endlich, einen harten Holzblock aus meinem Forst zu holen.
Mit unsäglicher Anstrengung fällte ich einen dicken Baumstamm,
hieb am unteren Ende ein amboßähnliches Stück ab, rundete es
ringsum mit meiner Axt und höhlte es durch Feuer aus, wie es die
wilden Eingebornen Brasiliens mit ihren kleinen Seefahrzeugen
(Kanoes) thun. Als Stampfe diente mir eine wuchtige Keule aus
demselben harten Holze.
Aber auch für ein Sieb mußte gesorgt werden, um das durch
Stampfen gewonnene Mehl durchzuschütten und es von der Kleie zu
sichten. Hier war guter Rat teuer, denn ich hatte weder Kanevas
noch Bastgeflechte. Aber unter den Matrosensachen, die ich vom
Wrack gerettet hatte, befanden sich etliche Halstücher von Kattun
und Musselin; aus diesen verfertigte ich drei kleine Siebe, die ich
auch ziemlich brauchbar fand.
Die Zeit der Ernte nahte heran. Mit meinen Körben schritt ich
hinaus aufs Feld und überschaute den Früchtereichtum des Bodens.
Dann schnitt ich die Ähren, sammelte sie in Garbenbüscheln in die
Körbe und trug die segenschwere Last nach Hause. Hier ließ ich alles
so stehen, wie ich es eingeheimst hatte, bis ich Zeit und Mittel finden
konnte, das Getreide auszukörnen; denn ich hatte weder eine Tenne
noch einen Dreschflegel.
Im ganzen brachte ich 20 Scheffel Gerste und ebensoviel Reis in
mein Kornmagazin, weshalb es sich als notwendig herausstellte, das
letztere besser einzurichten. Aus Erfahrung wußte ich jetzt, daß ich
jährlich zweimal säen und ernten könne; die Entscheidung darüber,
was in Zukunft für mich und meinen Hausstand am zweckmäßigsten
sein würde, wollte ich von der Größe meines diesmaligen Verbrauchs
abhängig sein lassen.
Zunächst nahm ich meine Ähren, rieb sie aus, stampfte die Körner
in meinem Mörser und siebte sie durch die Matrosenhalstücher. Zum
Brotbacken braucht man aber bekanntlich einen Ofen, und die Not
macht erfinderisch. Ich baute mir große irdene Gefäße zusammen,
die wohl breit, aber nicht zu tief waren; dann härtete ich diese mehr
pfannenartigen Gefäße im Feuer. Wollte ich nun Brot backen, so
zündete ich ein tüchtiges Feuer auf meinem Herde an, den ich mit
rotgebrannten Steinen eigner Fabrik gepflastert hatte. Sobald das
Holz hierauf zu glühender Kohle ausgebrannt war, breitete ich
dieselbe derart auf dem Boden aus, daß die Steine gehörig
durchhitzt wurden. Dann zog ich die Kohlen zurück, fegte die Asche
weg, legte meine Brote oder vielmehr flachen Kuchen an deren
Stelle, bedeckte dieselben mit den beiden irdenen Gefäßen und
häufte ringsumher glühende Kohlen und Asche, um die Hitze noch
zu verstärken. So bereitete ich meine Brote ebenso gut, als wären
sie im besten Ofen der Welt gebacken worden; ja, ich versuchte
mich sogar im Backen verschiedener Arten von Kuchen und
Reispuddings, die in meinen einförmigen Speisezettel eine
angenehme Abwechselung brachten.
Bei all dieser mich sehr in Anspruch nehmenden Arbeit
beschäftigten sich doch meine Gedanken wiederholt mit jenem
Küstenlande, welches ich auf meiner letzten Entdeckungsreise
deutlich als dunklen Streifen am Horizont wahrgenommen hatte. Im
Glauben, daß jenes Land zum amerikanischen Festlande gehöre,
flogen meine Wünsche über die weite Meeresfläche und regten mit
aller Gewalt in mir die Sehnsucht an, dorthin zu gelangen.
Indes empfand ich die Wahrheit des alten Spruches: »Das Wasser
hat keine Balken.« Ich wünschte mir lebhaft meinen treuen Xury und
das Boot mit den lateinischen Segeln zurück, mit dem ich eine so
weite und gefahrvolle Reise längs der afrikanischen Küste
zurückgelegt hatte; ohne Bedenken hätte ich mich dann von neuem
dem unsicheren Elemente anvertraut.
Da fiel mir eines Tages die Schaluppe unsres Schiffes ein, welche
weit auf die Küste geworfen worden war. Flugs machte ich mich auf,
um zu untersuchen, in welcher Verfassung sie sich befände. Ich traf
sie auch noch an der nämlichen Stelle, wo sie zuerst gelegen hatte,
aber in umgekehrter Lage, denn die Gewalt der Fluten und der
Stürme hatte sie auf eine sehr hohe Sandbank geworfen und aufs
Trockene gesetzt. Es kam zunächst darauf an, die Schaluppe wieder
umzukehren und flott zu machen. Nach vielen vergeblichen Mühen
und Anstrengungen kam ich auf den Einfall, den Sand unter dem
Boote wegzugraben, um es von selbst herabgleiten zu lassen und
den Abrutsch durch untergeschobene Walzen und Stützen zu lenken.
Aber auch hierdurch gelang es mir nicht, die Schaluppe vorwärts zu
schieben und ins Wasser gelangen zu lassen, deshalb gab ich nach
einer fruchtlosen Arbeit während drei bis vier Wochen die ganze
Sache auf.
So sehr auch meine Hoffnungen vereitelt waren, so wurden doch
meine Begierde und mein Mut nur verstärkt, und ich faßte den
Entschluß, selbst ein Kanoe aus einem Baumstamm zu bauen. Ich
hielt dies nicht nur für möglich, sondern sogar für leicht, zumal ich
über viel mehr Hilfsmittel verfügte als die Neger oder Indianer.
Freilich hätte ich auch überlegen sollen, daß ich Vereinsamter mit
ganz andern Schwierigkeiten zu kämpfen haben würde als die
Indianer, die einander beistehen. Was half es mir am Ende, falls ich
auch das schönste Kanoe von ganz Amerika zustande brächte, wenn
ich es nicht ins Meer zu schaffen vermöchte?
Man sollte denken, daß die Erfahrungen, die ich vordem mit der
aufs Trockene gelegten Schaluppe gemacht hatte, mir hinsichtlich
der Möglichkeit, das Boot in das Wasser zu bringen, einen
handgreiflichen Wink gegeben hätten: nichts von alledem! Meine
unstäten Gedanken verschmolzen sich schon so sehr mit der
Meerfahrt, daß ich die Sache möglichst ungeschickt anfing. Aber
stets beschwichtigte ich alle Befürchtungen mit der thörichten
Tröstung: »Laß nur gut sein, Robinson! Erst das Boot fertig, das
übrige wird sich finden!«
Kurz, mein Eigensinn siegte über den Verstand. Ich fand auch
einen prächtigen Baum, der mir für meinen Zweck ganz wie
geschaffen schien. Zwanzig Tage brachte ich dazu, den Riesen zu
fällen, und vierzehn Tage mußte ich darauf verwenden, Äste und
Krone abzuhauen. Dann kostete es fast einen ganzen Monat Zeit,
dem Stamme jene bauchförmige äußere Gestalt des Bootes zu
geben, damit er auf dem Wasser schwimmen könne, ohne sich zur
Seite zu neigen. Weiterhin brauchte ich noch drei Monate, um das
Innere auszuhöhlen, und zwar bediente ich mich dazu nicht des
Feuers nach Art der Indianer, sondern nur des Beiles und des
Meißels.
Als ich mit meiner Arbeit zu Ende war, empfand ich eine wahrhafte
Freude an meiner Schöpfung, denn ich hatte in der That noch nie
einen so großen, aus einem einzigen Baumstamm gehauenen
Ruderkahn gesehen, groß genug, um mehr als zwanzig Mann zu
fassen, und demzufolge auch mich samt meinen Habseligkeiten zu
tragen. Das Boot hatte unzählige Axt- und Hammerschläge,
manchen Schweißtropfen gekostet, und wäre es mir gelungen,
dasselbe flott zu machen, wer weiß, ob ich nicht die unüberlegteste
Reise gewagt hätte, wie sie nur je ein wagehalsiger Abenteurer
unternehmen konnte.
Mein neues Fahrzeug lag zwar nicht weit vom Meere entfernt;
aber das große Hindernis bestand darin, daß das Ufer zum Meere
bergan lief. Ich ließ indes den Mut nicht sinken, sondern versuchte,
die Anhöhe wegzuräumen und das Land nach der Küste zu abfällig
zu machen. Als der Weg so ziemlich geebnet war, befand ich mich
um nichts gefördert, denn das Kanoe rückte äußerst wenig von der
Stelle, so wenig wie vordem die Schaluppe. Hierauf maß ich die
Entfernung ab, welche zwischen meinem Boote und dem Meere lag,
sowie die Tiefe des Bodens und die erforderliche Breite, um einen
genügend breiten und tiefen Kanal bis zum Meere zu bauen und in
diesem Bassin mein Boot hinabzuführen. Indem ich den
Kraftaufwand hinsichtlich solch kolossaler Bauten veranschlagte –
denn der Kanal hätte sehr viel Tiefe haben müssen – und damit die
mir zu Gebote stehenden Arbeitsmittel, d. h. meine zwei rüstigen
Arme, in Vergleich brachte, erlangte ich als Ergebnis meines
Voranschlags die Überzeugung, daß recht gut zehn bis zwölf Jahre
vergehen könnten, ehe ich ans Ziel meiner Wünsche kommen
konnte.
Dieses erfüllte mich mit großer Betrübnis; ich sah jetzt, leider zu
spät, ein, wie thöricht es ist, ein Werk zu beginnen, wenn man sich
vorher nicht Klarheit darüber verschafft, ob der Größe des
Unternehmens gemäß auch die zur Verfügung stehenden Mittel zur
Ausführung hinreichen.
Mitten unter dieser Arbeit hatte ich mein viertes Jahr auf dem
Eiland zurückgelegt. Ich feierte den Jahrestag meiner Ankunft, wie in
früheren Jahren, durch ernste und gottergebene Betrachtungen, die
mir reichen Trost einflößten.
An eben demselben Jahrestage, an welchem ich meinen Eltern
entlief, um mich in Hull einzuschiffen, ward ich durch den Seeräuber
von Saleh gefangen genommen und zu Sklavendiensten gezwungen.
An dem nämlichen Tage, als ich aus dem Schiffbruch auf der Reede
von Yarmouth gerettet ward, entfloh ich glücklich aus Saleh. Am 30.
September 1659 endlich, an meinem 26. Geburtstage, wurde ich
wunderbar gerettet und auf diese Insel verschlagen.
Der erste meiner Vorräte, welcher mir nach der Tinte ausging, war
der Schiffszwieback, und obgleich ich mit demselben höchst
haushälterisch umgegangen war, so hatte ich ihn dennoch schon ein
Jahr vor meiner Kornernte gänzlich aufgezehrt, was mich allerdings
etwas in Verlegenheit versetzte.
Mit meiner Kleidung sah es gleichfalls recht windig aus, denn seit
längerer Zeit besaß ich nichts weiter als wenige Matrosenhemden,
die meine Haut vor den stechenden Sonnenstrahlen schützten. Bei
einer Durchsuchung meiner Kisten fand ich jedoch etliche taugliche
Kleidungsstücke sowie ein paar große Überröcke. Fast mußte ich
über den Fund dieser letzteren lächeln, denn ich hätte es in
denselben vor Hitze nicht aushalten können, und doch wußte ich
auch hieraus etwas Brauchbares zu schaffen. Da sich nämlich alle
meine Jacken in einem Zustande bedenkenerregender Zerfahrenheit
befanden, so lag es sehr nahe, mich auch einmal als ehrsamen
Kleiderkünstler zu versuchen, und ich fertigte nun drei Jacken, die
ich ziemlich lange tragen zu können hoffte. War aber schon das
Fabrikat derjenigen Kleidungsstücke, die meinen Oberkörper
bedecken sollten, in einer Weise ausgefallen, die selbst das Mitleid
nachsichtiger Leute herausforderte, so legten meine Versuche
hinsichtlich der Beinkleider ein noch glänzenderes Zeugnis
bejammernswürdiger Unbeholfenheit ab.
Ich muß hier nachträglich erwähnen, daß ich die Häute aller
getöteten vierfüßigen Tiere aufbewahrte und auf Stäben an der
Sonne trocknen ließ. Einige derselben waren so hart geworden, daß
sie zu nichts mehr taugten; andre aber, die nicht bis zu jener Steife
zusammengedörrt waren, leisteten mir leidlich gute Dienste.
Das erste, was ich mir nun verfertigte, war eine neue große
Kopfbedeckung aus Ziegenfell, an welchem ich die Haar außerhalb
ließ, um mich so besser gegen den Regen zu schützen.
Noch etwas andres stellte sich mir als unentbehrlich heraus,
nämlich ein Regen- oder Sonnenschirm. Denn da ich meist im
Freien weilen mußte, so quälte mich die Hitze der tropischen Sonne
äußerst empfindlich. Lange Zeit währte es, bis ich etwas Taugliches
zustande brachte. Die Hauptschwierigkeit bestand darin, den Schirm
so zu verfertigen, daß ich ihn zusammenlegen konnte; im andern
Falle hätte ich ihn stets aufgespannt tragen müssen, was sicherlich
die Bequemlichkeit nicht sehr vermehrt haben würde. Ich bedeckte
dieses tragbare Wetterdach mit Ziegenfellen, deren Haare ich nach
auswärts kehrte; so schützte ich mich, so gut es gehen wollte,
gegen den Regen wie gegen die Sonnenstrahlen. Bedurfte ich seiner
nicht mehr, so klappte ich den Schirm zusammen.
Vor der Hand hatte ich nun so ziemlich alle Bedürfnisse befriedigt,
die sich in meiner Einsamkeit überhaupt einstellen konnten; aber nie
schweigen die Wünsche des Menschen still. Ich wollte mit dem
gewonnenen Nützlichen auch das Angenehme verbinden, und was
konnte mir da wohl näher liegen als der Besitz – einer
Tabakspfeife? Hatte ich mich doch in der Töpferei hinlänglich
erprobt, daß mir die Fabrikation eines Pfeifenkopfes nur leichtes
Spiel schien; auf künstlerische Verzierung dieses Thonstückes mußte
ich freilich immer noch Verzicht leisten. Ein ausgehöhltes Rohr
herzurichten, machte wenig Kopfzerbrechen, und so konnte ich nun
mit meinem edlen Kraute das Inselreich durchdampfen.
Ich kann nicht sagen, daß mir in fünf Jahren etwas
Ungewöhnliches begegnet sei, denn ich lebte in derselben Lage, an
dem nämlichen Orte, auf die gleiche Weise wie früher. Ich baute
mein Korn, buk Brot, erntete Trauben ein und sorgte immer für
einen ausreichenden Vorrat hinsichtlich aller nötigen Nahrungsmittel;
oft ging ich auf die Jagd, schoß Vögel und Ziegen, fing auch, um
eine sehr schmackhafte Suppe zu haben, dann und wann eine
Schildkröte und angelte Fische. Daß ich auch die ehrsamen Gewerke
eines Zimmermanns, Töpfers, Korbflechters, selbst des Schneiders in
Ehren hielt, habe ich bereits erwähnt.
Während dieser fünf Jahre richtete ich mein Hauptaugenmerk
darauf, mir eine andre Barke zu bauen, diesmal aber die Sache
klüger anzufangen als vorher. Zwar fand ich auch jetzt nicht näher
am Strande einen für mein Vorhaben tauglichen Baum; denn die
Baumregion begann erst eine ziemliche Strecke vom Ufer. Da
schlenderte ich eines Tages ungefähr eine halbe Stunde
landeinwärts, längs dem Ufer jenes Baches hin, wo ich mit den
Flößen gelandet war. Dort fand ich endlich, etwa zehn Schritt vom
Wasser, was ich suchte. Ich fällte den Baum, handhabte dann
unablässig Beil und Meißel und hatte schließlich die Freude, meine
Piroge fertig zu sehen. Nun grub ich einen Kanal, schaffte unter
manchem Schweißtropfen mein Kanoe von der Werft auf das Wasser
und flößte es nach dem Meere hinab in die Bucht.

Robinsons Tabakspfeife.
Obgleich ich nicht weniger als zwei Jahre mit meinen
Schiffszimmerarbeiten zugebracht hatte, so entsprach doch die
Größe der Barke nicht dem Zwecke, welchen ich bei Erbauung der
ersteren verfolgte, nämlich dem, mit derselben das
gegenüberliegende Festland zu erreichen, welches nach meiner
Schätzung wohl vierzig englische Meilen entfernt lag. Dennoch
empfand ich eine nicht zu beschreibende Freude, als ich mein
selbsterbautes Fahrzeug so sicher und leicht auf den Wellen
dahingleiten sah, und wenn ich auch auf den Wunsch verzichten
mußte, jenes ferne Küstenland zu erreichen, so schien mir mein Boot
doch hinlänglich fest, um in demselben eine Rundreise um mein
Eiland unternehmen zu können. Zu diesem Zwecke pflanzte ich
einen kleinen Mast auf meinen Ruderkahn und brachte ein Segel
zustande, das ich aus mehreren Stück Leinwand
zusammenschneiderte. Ebenso sorgte ich an beiden Seiten für
Kästchen und sonstige Behältnisse, um darin Lebensmittel, Pulver
und Blei aufzubewahren und so gegen den Regen und den Gischt
des Meeres gesichert zu sein. Im Innern des Bootes machte ich der
ganzen Länge nach eine Höhlung, legte meine Flinte hinein und
nagelte zum Schutze gegen die Nässe Leinwand darüber. Außerdem
befestigte ich noch meinen Schirm am Hinterteile der Barke, zum
Schutze gegen die brennenden Sonnenstrahlen, setzte ein
Steuerruder sowie einen Anker in Bereitschaft und versuchte mich
zunächst in kleinen Lustfahrten in der Nähe meiner Besitzung.
Nachdem ich die Tauglichkeit meines Bootes durch solche Ausflüge
auf dem Wasser erprobt hatte, konnte ich doch der Begierde, den
ganzen Umfang meines kleinen Königreichs kennen zu lernen, nicht
länger widerstehen. Ich brachte in mein Kanoe eine hinlängliche
Menge Proviant, nämlich zwei Dutzend Brote oder vielmehr
Gerstenkuchen, einen Topf mit Reis, eine Ziegenhälfte und ein
Fläschchen Rum; auch nahm ich Pulver und Blei mit, sowie zwei
Überröcke, die mir in kühlen Nächten teils als Matratzen, teils als
Decke dienen sollten.
So ausgerüstet begab ich mich am 6. November des sechsten
Jahres meines Insellebens an Bord und stach in See. Indessen sollte
diese Seefahrt eine andre Wendung nehmen, als ich gedacht hatte.
Nachdem ich eine Strecke hinausgefahren und an die östliche Küste
gelangt war, bemerkte ich eine Kette von Felsen, die meilenweit ins
Meer hinausragten und von denen einige Klippen über, andre unter
der Wasserfläche vorschoben. Am Ende des Riffs breitete sich noch
eine Sandbank von einer halben Stunde in derselben Richtung aus,
so daß ich einen großen Umweg zu machen hatte, wenn ich die
Spitze umsegeln wollte.
Diese Entdeckung kam mir sehr ungelegen, und da mir die Fahrt
denn doch etwas gefährlich schien, steuerte ich in meine Bucht
zurück und legte meine Barke vor Anker. Hierauf griff ich zur Flinte,
stieg ans Land und erklomm einen Hügel, von wo ich das ganze
Felsenriff überschauen konnte.
Ich bemerkte eine heftige Strömung, die in der Richtung nach
Osten ganz nahe an der äußersten Spitze der Sandbank hinlief.
Dieser Umstand konnte für mich sehr gefährlich werden; denn wenn
mich der Strom packte und mit sich fortriß, so mußte ich der Insel
vielleicht auf immer lebewohl sagen. Von der Südseite ließ sich ein
ähnlicher Strom in der Richtung nach Ost-Nordost wahrnehmen,
jedoch in einer größeren Entfernung vom Ufer. Dann sah ich eine
ziemlich genau angedeutete Sandbank, die gegen die Küste verlief.
Diesen Beobachtungen zufolge mußte ich meinen Kurs so nahe an
der ersten Sandbank halten, als es ohne Gefahr, zu stranden, irgend
anging.
Ein steifer Wind aus Ost-Südost sauste gerade dem
nordöstlichsten Strom entgegen und drängte das Wasser in heftiger
Brandung an das Riff und die Spitze der Landzunge. Deshalb konnte
ich mich nicht auf das Meer wagen. Wegen der Brandung war es
doch zu gefährlich, mich nahe am Lande zu halten, und die
Strömung legte mir anderseits die Notwendigkeit auf, mich nicht weit
vom Lande zu entfernen. Aus diesem Grunde blieb ich ruhig in
meiner Bucht zwei Tage vor Anker liegen.
Robinsons Nachtruhe.
Achtes Kapitel.
Robinsons unglückliche
Bootfahrt.
Gefährliche Seereise. – In die See hinausgetrieben. – Sehnsuchtsvolle
Betrachtungen. – Die beiden Strömungen und glückliche Landung. – Des Papageis
Ruf. – Robinsons »Familie«. – Ziegenfang und Ziegenpark. – Schneiderkünste. –
Neue Beobachtungen. – Rückblicke.
Am Morgen des dritten Tages legte sich der Wind, das Meer wurde
ruhig, und nun erst begann ich meine Seefahrt. Mein Schicksal möge
unerfahrenen und wagehalsigen Schiffern zur Warnung dienen!
Kaum hatte ich die Spitze der Sandbank erreicht, von dem Ufer nur
um die Länge meiner Barke entfernt, als ein Strom gleich einer
Mühlschleuse mich mit überwältigender Heftigkeit packte. Alle Mühe,
dagegen anzukämpfen, erwies sich als umsonst; immer weiter trieb
mich die Strömung von der Sandbank, die mir zur Linken lag. Weder
Segel noch Ruder konnte ich mit Erfolg gebrauchen. Wurde ich von
der Strömung etwa in die See hinausgeworfen, so schien mein
Untergang unvermeidlich, insbesondere wegen des Mangels an
Lebensmitteln. Denn die am ersten Tage in die Barke geschafften
Vorräte nebst einer noch am Meeresufer von mir gefangenen
Schildkröte konnten nicht ausreichen, wenn ich weit hinaus auf den
unermeßlichen Ozean getrieben wurde, vielleicht viele Meilen von
der Küste entfernt.
Jetzt gedachte ich meiner einsamen und verlassenen Insel, die mir
nun wie ein behaglicher und reizender Ort erschien. »Glückliche
Einöde!« klagte ich, »werde ich dich jemals wiedersehen? Nie wollte
ich dich wieder verlassen!« So erkannte ich, als mir meine Besitzung
schon verloren schien, erst ihren vollen Wert. Ich ruderte aus allen
Kräften und blieb möglichst in derselben Richtung, in welcher die
Strömung die Sandbank treffen konnte. Plötzlich erhob sich ein
Welcome to Our Bookstore - The Ultimate Destination for Book Lovers
Are you passionate about books and eager to explore new worlds of
knowledge? At our website, we offer a vast collection of books that
cater to every interest and age group. From classic literature to
specialized publications, self-help books, and children’s stories, we
have it all! Each book is a gateway to new adventures, helping you
expand your knowledge and nourish your soul
Experience Convenient and Enjoyable Book Shopping Our website is more
than just an online bookstore—it’s a bridge connecting readers to the
timeless values of culture and wisdom. With a sleek and user-friendly
interface and a smart search system, you can find your favorite books
quickly and easily. Enjoy special promotions, fast home delivery, and
a seamless shopping experience that saves you time and enhances your
love for reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!

ebookgate.com

You might also like