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

Functional Programming Patterns in Scala and Clojure 1st Edition Michael Bevilacqua-Linn instant download

The document is about 'Functional Programming Patterns in Scala and Clojure' by Michael Bevilacqua-Linn, which focuses on transitioning from object-oriented programming to functional programming using patterns. It includes examples and patterns that simplify common object-oriented practices, making programming more efficient and concise. The book is structured to guide programmers through practical applications in Scala and Clojure, emphasizing the benefits of functional programming.

Uploaded by

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

Functional Programming Patterns in Scala and Clojure 1st Edition Michael Bevilacqua-Linn instant download

The document is about 'Functional Programming Patterns in Scala and Clojure' by Michael Bevilacqua-Linn, which focuses on transitioning from object-oriented programming to functional programming using patterns. It includes examples and patterns that simplify common object-oriented practices, making programming more efficient and concise. The book is structured to guide programmers through practical applications in Scala and Clojure, emphasizing the benefits of functional programming.

Uploaded by

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

Functional Programming Patterns in Scala and

Clojure 1st Edition Michael Bevilacqua-Linn pdf


download

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

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


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


Other documents randomly have
different content
DE SCHORPIOENSPINNEN (P e d i p a l p i ).
Men kent ± 30 soorten van deze zeer zonderlinge Spinachtigen, uitsluitend bewoners van
de tropische gewesten der Oude en der Nieuwe Wereld. Evenals de Echte Spinnen
hebben zij tweeledige kaaksprieten met klauwvormig eindlid, dat vermoedelijk in
gemeenschap staat met een gifklier. De naam Pedipalpi beteekent, „tasterpooten” en
doelt op de groote lengte en de veelledigheid van den voet der achterste kaken (of
voorste pooten), die aan een „zweep” van een spriet herinnert. Het 11- of 12-ledige
achterlijf, hoewel „zittend”, is door een insnoering van het ongelede kopborststuk
gescheiden.—Bij de D r a a d s c h o r p i o e n e n (Thelyphonidae) zijn de drie laatste
achterlijfsleden smal en vormen een korte buis, die in een lange, veelledige draad met
een stinkklier eindigt. De zweep is betrekkelijk kort en 8-ledig. De kaaktasters zijn dik,
gedrongen en aan ’t einde schaarvormig. De afgebeelde soort bewoont Java en Timor en
is zonder den staart 32 mM. lang.—De Z w e e p s c h o r p i o e n e n (Phrynidae) hebben
een meer spinachtig voorkomen, missen den staartdraad, maar hebben een buitengewoon
lange, veelledige zweep. De lange kaaktasters eindigen niet in een schaar, maar in een
door stekels omgeven klauw. De afgebeelde soort leeft op San-Domingo en wordt hier
soms in het vandaar uitgevoerde verfhout gevonden.
L a n g s t a a r t i g e D r a a d s c h o r p i o e n (Thelyphonus caudatus). Ware grootte.
VIJFDE ORDE.
DE BASTAARDSPINNEN (O p i l i o n e s ).
De tot dusver besprokene Spinachtigen
komen alleen den bewoner van Zuid-
Europa en van andere warme landen
onder de oogen, en dan nog slechts bij
uitzondering en bij toeval, daar zij
nachtwandelaars zijn. De
B a s t a a r d s p i n n e n (Phalangina of
Opiliones) leiden een minder verborgen
leven en zijn over den gematigden
aardgordel en geheel Amerika verbreid.
De buitengewoon lang- en dunpootige
dieren, die bij ons, zoowel als in
noordelijker en zuidelijker deelen van
Europa hun klein, eivormig lichaam
zwevend houden, wanneer zij een L a n g a r m i g e T a r a n t e l s c h o r p i o e n (Phrynus
boomstam of een muur bestijgen, of lunatus). Ware grootte.—a) Voorste deel van het
over den bodem loopen, daarentegen kopborststuk vergroot om de rangschikking der oogen te
bij het rusten op den buik liggen en de toonen.
pooten ver uitstrekken, zijn aan
iedereen onder den naam van
H o o i w a g e n s bekend. Liefhebbers van een vreemdsoortige versnapering zeggen, dat
de romp van deze diertjes zoo zoet smaakt als een hazelnoot. Bij het vangen van dit wild
zijn zij in de gelegenheid om op te merken, hoe licht de dunne pooten van de vleezige
heup los geraken en hoe zij uren lang voortgaan met krampachtige bewegingen te
maken, als waren zij nog in leven. In donkere hoeken van huizen, maar ook in de vrije
natuur overal, niet uitsluitend op zeer verborgen plaatsen, ziet men deze dieren over dag
rusten, of nu en dan traag van plaats veranderen, als liepen zij op stelten. Zoodra de
nacht begint, ontwaken zij uit haar droomenden toestand; dartel stoeiend, trachten zij
elkander een beentje te lichten; de lange pooten geraken verward; de eigenaars van deze
lichaamsdeelen behouden met moeite het evenwicht en hun plaats. Intusschen worden
meer ernstige bezigheden niet verzuimd. Als een Kat bespringt de Hooiwagen zijn buit,
die uit kleine Insecten en Spinnen bestaat.

De H o o i w a g e n s (Phalangidae), waarvan men ongeveer 100 soorten onderscheidt,


die bijna alle de Oude Wereld bewonen, stemmen in de volgende opzichten overeen. Het
dikke, eivormige lichaam is straalsgewijs door de lange pooten omgeven. Nagenoeg op
’t midden van het kopborststuk staan de beide oogen; het bolle achterlijf is (niet altijd
duidelijk) in 6 ringen verdeeld. Twee ademgaten onder de heupen van de achterpooten
stellen het tracheeënstelsel, waardoor de ademhaling geschiedt, met de buitenwereld in
gemeenschap. De 3-ledige kaaksprieten zijn naar beneden gericht; hunne beide laatste
leden vormen een kleine schaar. De kaaktasters bestaan uit 6 draadvormige leden en
eindigen in den regel in één fijnen klauw, evenals de beide pootvormige kaken, die
overigens weinig verschillen van de 3 paar volgende, tweeklauwige ledematen. Bij geen
der overige Arthropoden vindt men pooten van zulk een lengte. De koude schijnt de
Hooiwagens weinig te deren; zelfs op hooge bergen komen zij voor: de G l e t s c h e r -
h o o i w a g e n (Opilio glacialis) wordt in de Zwitsersche Alpen nog op een hoogte van
3344 M. gevonden.

De meest algemeen verbreide soort, de G e w o n e H o o i w a g e n (Opilio parietinum,


fig. 4), is op de heup, de dij en het kopborststuk met fijne doorntjes bezet. De
lichtbruinachtige rugzijde vertoont een nagenoeg ruitvormige, zwartbruine teekening; de
buikzijde is witachtig. Het lichaam wordt 8 à 10 mM. lang. Zeer gretig heeft men deze
Spin de wijfjes van de Roodbruine Sparrelootgallen-bladluis (Chermes coccineus, C.
strobilobius) zien grijpen; zij perste hare slachtoffers de eieren uit het lichaam en vrat
deze op, waarna zij de overige, hardere deelen liet liggen. Naar het schijnt, duurt de
ontwikkeling van deze soort 3 jaren, waarin verscheidene vervellingen voorkomen.

Behalve de Hooiwagens onderscheidt men nog een zestal andere familiën (met 150
soorten) van Bastaardspinnen. De zonderlingste vormen treft men aan in het Zuid-
Amerikaansche geslacht Gonyleptes. Het achterlijf is bij deze zoo goed als geheel onder
het stevig gepantserde kopborststuk verborgen. Daarachter steken de ver uiteenwijkende,
breede en zeer lange achterpooten uit, die een bijzonder dikke heup hebben en met
krachtige doornen gewapend zijn. Alleen de mannetjes vertoonen deze afwijkingen; bij
de wijfjes is achter het rugschild van ’t kopborststuk een deel van het achterlijf zichtbaar.
De bruinroode Gonyleptes curvipes bewoont Brazilië en Chili en blijft over dag
verscholen achter boomschors, onder omgehouwen boomstammen, in gaten van den
grond en dergelijke schuilhoeken, waar andere duisterlingen haar tot voedsel dienen.
ZESDE ORDE.
DE ECHTE SPINNEN (A r a n e i n a ).
In ’t oog vallende eigenaardigheden van de Spinnen zijn haar arglistig loeren op buit van
uit een verborgen hinderlaag en de alles behalve vriendschappelijke betrekking, waarin
zij, vooral het mannetje en het wijfje, tot elkander staan. Om de hevigste openbaring van
vijandschap tusschen twee menschen aan te duiden, vergelijkt men hen met Spinnen.
Daar hare uitwendige kenteekenen al even weinig innemend zijn als de beide reeds
genoemde karaktertrekken, worden de Spinnen door de meeste menschen gemeden en
verafschuwd, hoewel zij in vele opzichten onze bewondering verdienen. Haar
lichaamsbouw is niet minder merkwaardig dan die der overige Arthropoden; haar arbeid
heeft evenveel aanspraak op onze waardeering. Reeds door de ouden werd dit erkend.
Volgens een Grieksche sage had A r a c h n e , de dochter van den purperverwer
I d m o n , die van P a l l a s - A t h e n e de weefkunst had geleerd, de onbescheidenheid
om aan haar goddelijke leermeesteres een wedstrijd voor te stellen. Te vergeefs werd dit
waagstuk haar ontraden door de godin, die de gedaante van een oude vrouw had
aangenomen. A r a c h n e bleef bij haar voornemen en vervaardigde een kunstig weefsel,
dat de minnarijen der goden voorstelde. Toen A t h e n e , hierover vertoornd, het weefsel
verscheurde, hing A r a c h n e uit wanhoop zich op. De godin riep haar in ’t leven terug
in de gestalte—van een Spin, opdat zij naar welgevallen zou kunnen hangen.—Koning
Salomo stelde de Spin tot voorbeeld aan zijne hovelingen wegens haar vlijt,
kunstvaardigheid, schranderheid, matigheid en deugd.
K r u i s s p i n (Epeira diadema):—1) Wijfje. 2) Mannetje. 3) Spinpijpje. 4) Spintepels met de aarsopening
(boven) en het „zeefje” (onder). 5) Kaaksprieten en oogen. 6) Linker kaakspriet, waarvan het grondlid
overlangs doorgesneden is om de gifklier in haar geheel te toonen. 7) Top van het voetlid.—3–7 sterk vergr.

Bij alle Echte Spinnen is zoowel het a c h t e r l ij f als het kopborststuk o n g e l e e d ;


beide afdeelingen zijn door een dunnen steel verbonden. Als pareltjes in ’t goud, zijn aan
de bovenzijde van ’t kopborststuk de enkelvoudige oogen geplaatst, die door hun aantal,
rangschikking, afstand, grootte en richting betrouwbare kenmerken voor de
onderscheiding der talrijke geslachten opleveren. Bij de meeste Spinnen komen 8, bij
sommige 6, bij enkele 2 en bij eenige bewoners van donkere holen in ’t geheel geen
oogen voor. Elke kaakspriet (fig. 5) bestaat uit een dik, aan de binnenzijde gegroefd
grondlid en een klauwvormig eindlid, dat in deze groeve teruggeslagen kan worden en,
als een giftand van een Slang, doorboord is; dit kanaal staat in gemeenschap met een
gifklier in den vorm van een langwerpigen, blinden zak (fig. 6). Bij een beet met de
beide kaaksprieten storten dus 2 gifklieren venijn in de wonde. Kleine dieren worden er
bijna onmiddellijk door gedood, doch ook voor groote dieren en zelfs voor den mensch
is het gif van eenige soorten van Spinnen gevaarlijk. Aan weerszijden van de mondspleet
komen de heupleden van het volgende paar ledematen, de kaken, voor; hunne 5 overige
leden vormen den kaaktaster. Het eindlid, dat bij het wijfje altijd een (meestal getande)
klauw draagt, is bij het mannetje vervormd tot een voor deze orde karakteristiek
voortplantingsorgaan. Het volgende paar kaken eindigt, evenals de 3 paar eigenlijke
pooten, in 2 kamvormig getande klauwen (fig. 7) en komt er ook in andere opzichten
(o.a. door de verdeeling in 7 leden) zoozeer mede overeen, dat men het gewoonlijk als
een paar pooten beschouwt en aan de Spinnen 4 paar bewegingsorganen toeschrijft. Aan
den voet van de beide groote klauwen bevindt zich (fig. 7) een kleine, slechts bij enkele
Spinnen ontbrekende „voorklauw” van gelijken vorm.

Onmiddellijk vóór de min of meer buisvormige aarsopening zijn de wonderbaarlijke


spinorganen gelegen, die de tweede eigenaardigheid van de geheele orde vormen. Door
klieren van zeer verschillend maaksel, die zich tusschen de ingewanden bevinden, wordt
een vloeistof bereid, die in aanraking met de lucht verhardt tot een taaie (droge of
kleverige) draad. De spinstof ontwijkt uit de talrijke, microscopisch fijne gaatjes,
waarmede de zoogenaamde „spintepels” (fig. 4) bij wijze van een zeef bezaaid zijn. De
meeste Spinnen hebben 3 paar van deze organen: voorste (onderste), middelste en
achterste (bovenste). Die van het middelste paar vallen weinig in ’t oog, daar zij altijd
klein en éénledig zijn; de voorste en achterste zijn grooter en dikwijls 2- of 3-ledig. Vóór
de voorste spintepels vindt men nog het zoogenaamde „zeefje” (cribellum), een met
talrijke spinpijpjes bezet veld, dat door een hoornachtigen rand omgeven is. Door
spierwerking kunnen de spintepels naar voren en naar achteren, naar buiten en naar
binnen bewogen, uitgestulpt en teruggetrokken worden. Bij sommige Spinnen komt een
paar veelledige spintepels voor, die als staartjes voorbij de spits van het achterlijf
uitsteken; deze spelen waarschijnlijk een rol bij het rangschikken der draden, doch
vormen er zelf geen. De e i g e n l ij k e , kegelvormige of cilindrische spintepels bestaan
uit twee deelen: het onderste en grootste is behaard en door een hoornachtigen ring
omgeven; het bovenste is een eenigszins bol vlak, dat als een borstel met een groot
aantal uitsteeksels van eigenaardigen vorm, de spinborstels of spinpijpjes (fig. 3) bezet
is. Hun wijdte en rangschikking loopen zeer uiteen. Zij zijn niet slechts bij verschillende
soorten van Spinnen, maar ook aan de verschillende spintepels van hetzelfde dier in
ongelijk aantal aanwezig. Het talrijkst zijn zij bij de Kruisspinnen, die er ongeveer 1000
hebben; bij Tegenaria zijn er slechts 400, bij Segestria senoculata ongeveer 100 en bij
verscheidene kleinere soorten nog minder. Bij het spinnen van een draad worden niet
altijd alle spinpijpjes gelijktijdig gebruikt; de Spin kan naar verkiezing enkele of
verscheidene van deze organen laten werken, al naar het doel waarvoor de draad
bestemd is.

De hardheid van de chitinelaag, die het lichaam van de Spin bedekt, is zeer ongelijk; bij
de inheemsche soorten is zij over ’t algemeen zachter dan bij verscheidene
buitenlandsche, waaronder er zijn met een zeer harde schaal. Na de klauwen hebben
altijd het rugschild en het borstschild van het kopborststuk de grootste hardheid. De
oppervlakte is niet meer of minder dicht bekleed met lange, borstelige of korte
fluweelachtige haren, soms ook met stekels; niet zelden verhoogt dit kleed in niet
geringe mate het afschrikwekkend voorkomen van de Spinnen. Sombere kleuren hebben
bij haar gewoonlijk de overhand; niet zelden echter zijn zij lichter en bont van kleur en
teekening. Voor de onderscheiding der soorten zijn deze verschijnselen niet zeer
geschikt.

Daar de Spinnen van roof, n.l. van allerlei Insecten, leven, is, evenals aan andere
roofdieren, gezelligheid haar vreemd; zij moeten hare soortgenooten mijden en in
sommige gevallen bestrijden. De uitzonderingen op dezen regel zijn zeldzaam en alleen
in Zuid-Afrika en Argentinië waargenomen.

De Spinnen zijn arme wevers; evenals deze, moeten zij weven, om in hun
levensonderhoud te voorzien; zij moeten echter spaarzaam zijn met de grondstof, omdat
deze bij goede voeding in ruime mate, bij schralen kost slechts in geringe hoeveelheid
beschikbaar is. De draad, die het lichaam verlaten heeft, kan er niet weer in
teruggetrokken worden. Soms zou men kunnen meenen, dat dit wel geschiedt, n.l. als de
Spin bij een draad naar boven klimt en deze daarbij steeds korter wordt; in dit geval
echter wordt de draad eenvoudig opgewikkeld en aan de pooten medegevoerd. Een nog
veel grooter onderscheid dan er bij verschillende soorten van Wespen wordt
waargenomen in de wijze van bouwen der nesten, merkt men bij de Spinnen op.
Sommige, zooals de van oudsher bekende Kruisspin, vervaardigen een wielvormig web,
andere, zooals de Gewone Huisspin, een dichter weefsel van trechtervormige gedaante,
nog andere buizen, zakken, enz., hieraan danken zij de namen Wiel-, Kruisnet-,
Trechter-, Zakspinners. Een groot aantal Spinnen vangen haar prooi niet in een web,
maar oefenen op een eerlijker wijze het roovershandwerk uit door het Insect, dat in de
nabijheid van haar schuilhoek komt, loopend te vervolgen of onverhoeds te bespringen.
Bovendien gebruiken de Spinnen hare draden als middel om van plaats te veranderen; zij
laten zich spinnend naar beneden zakken en kunnen ook, door de draad in
schommelende beweging te brengen, een voorwerp bereiken, dat niet onmiddellijk onder
haar uitgangspunt gelegen is. Wanneer de draad van hier losgerukt en door
luchtstroomingen medegevoerd wordt, zal zij een kleine Spin kunnen dragen; bij fraai
herfstweder ziet men sommige soorten op deze wijze door de lucht vliegen en zich over
een grooten afstand verplaatsen. Alle Spinnen zonder uitzondering, voor zoover zij
wijfjes zijn, gebruiken het product van hare spinklieren tot beschutting van de eieren.
Deze overigens zoo wreedaardige dieren leveren sterk sprekende bewijzen van
moederliefde en overtreffen in dit opzicht zelfs de Insecten, die het best voor hunne
jongen zorgen. De eieren worden meestal midden in den zomer gelegd; bij gunstige
temperatuur en vochtigheidstoestand van de lucht verlaat het jong 3 à 4 weken later het
ei. De meeste Springspinnen, Zak-, Trechter- en Wielspinners leggen in het laatst van
den zomer eieren en brengen het gewoonlijk lensvormige, soms halfbolvormige nestje
op een voor winterkwartier geschikte plaats. Van de leden dezer familiën overwinteren
slechts bij uitzondering enkele exemplaren; daarentegen verkeeren de nog niet
volwassen jongen van de overige soorten des winters op hunne gewone schuilplaatsen in
een toestand van verstijving. In het gunstige jaargetijde groeien zij tamelijk snel, hetgeen
door verscheidene vervellingen mogelijk wordt. Over ’t algemeen is men van oordeel,
dat bij de vierde vervelling de groei ophoudt en dat na dien tijd de vervanging van
verloren lichaamsdeelen niet meer voorkomt.

Het aantal bekende soorten van Spinnen bedraagt eenige duizenden en neemt nog steeds
toe. Zij zijn over de geheele aardoppervlakte verbreid; sommige soorten worden nog op
een hoogte van ongeveer 3125 M. boven den zeespiegel aangetroffen. Toch zijn warme
landen beter voor haar ter bewoning geschikt dan koudere, zooals blijkt uit de grootere
verscheidenheid van vormen, die deze orde in de tropische gewesten aanbiedt; hier leven
de grootste en fraaiste soorten. In het barnsteen zijn overblijfselen van een niet
onbelangrijk aantal uitgestorven soorten (ongeveer 250) gevonden. Reeds in de
steenkolenformatie bestond deze orde; twee soorten uit dit tijdperk zijn bekend.
Vo g e l s p i n (Mygale).

Tot het geslacht der M o o r d - , B o s c h - of Vo g e l s p i n n e n (Mygale), dat


uitsluitend in de warme landen van beide halfronden aangetroffen wordt, behooren
Spinnen, die een lichaamslengte van 5 of meer cM. kunnen bereiken, doch met hare
dikke, ruig behaarde pooten 18 cM. kunnen overspannen. Sommige reizigers hebben
haar beticht van het dooden en verslinden van kleine Vogels; Bates heeft werkelijk een
dergelijke Spin op heeterdaad betrapt. Of dit de G e w o n e Vo g e l s p i n (Mygale
avicularia) was, dan wel een andere der veel op elkander gelijkende soorten van
hetzelfde geslacht, is niet bekend. Over een diepen spleet van een dikken boomstam was
een stevig, wit weefsel uitgespannen, in welks beschadigd onderste gedeelte twee
vogeltjes (Vinken) hingen. Het eene was reeds gestorven, het andere lag onder het
lichaam van de Spin, onmiddellijk onder de spleet, en was den dood nabij. Nadat Bates
den roover verjaagd had, vond hij het vogeltje, dat weldra in zijne handen stierf, bedekt
met eene smerige, op speeksel gelijkende vloeistof. Naar deze mededeeling en de
gebrekkige houtgravure, die haar vergezelt, is de afbeelding vervaardigd; de Spin echter
is geteekend naar een in spiritus geconserveerd exemplaar van de genoemde soort. Bates
zegt uitdrukkelijk, dat het door hem waargenomen feit nieuw was voor de bewoners van
Amazonië, die de bedoelde, in hun vaderland volstrekt niet zeldzame Spinnen
A r a n h a s c a r a n g u e x e i r a s (Kreeftspinnen) noemen. Dat het niet de gewoonte
van alle Vogelspinnen kan zijn om zich met Vogels te voeden, blijkt uit hare
verblijfplaatsen, die vermoedelijk niet dikwijls door de gevleugelde bewoners der lucht
bezocht worden. Slechts weinige soorten leven op boomen en struiken, de meeste
bewonen gaten in muren, daken van huizen, op welker muren men ze soms ziet zitten,
ruimten onder steenen en holen in den grond. Dit laatste geldt o.a. van een dikke, bruine,
in West-Indië en Brazilië levende, 65 mM. lange soort [Mygale (Therephosa) Blondii],
die gemakkelijk herkend kan worden aan de gele strepen op de pooten. Zij bekleedt haar
scheef afhellende, ongeveer 63 cM. lange gang met een zijden behangsel en gaat tegen
den avond bij de opening op den loer liggen. Verschrikt vlucht zij diep in haar woning,
zoodra zware voetstappen naderen. Ook in Zuid-Afrika schijnen de onder steenen
wonende Moordspinnen veelvuldiger te zijn dan de op houtgewas levende. Met groote
behendigheid trachten zij springend te ontkomen aan de vervolging van ieder, die haar
wil vangen; altijd zijn zij gereed om met hare scherpe gifklauwen de grijpende vingers te
kwetsen.

De Indianen vreezen de Boschspin niet. Bates zag de kinderen, die voor hem Insecten
verzamelden, met een groot dier van deze soort spelen. Zij hadden het een draad om het
lichaam gebonden en liepen er mede door het huis als met een hondje.

In 1862 werd te Danzig bij het lossen van een uit Engeland afkomstig kolenschip een
levende Mygale avicularia gevonden en bijna een jaar lang in ’t leven gehouden. Zij
verslond Insecten, Pissebedden en Spinnen, maar ook Kikvorschen en rauw vleesch.

De Vogelspin is pekzwart en met zwartbruine haren bekleed; een koperkleurig rood vilt
bedekt het breede, platgedrukte eindlid van den poot, dat twee verborgene, ongetande
klauwen draagt; de voorste middeloogen zijn aanmerkelijk grooter dan de overige. De
leden van het soortenrijke geslacht Mygale onderscheiden zich door de X-vormige
rangschikking der 8 dicht bijeen geplaatste oogen, door stevige, lang en dicht behaarde
pooten en door twee gekromde haken aan het einde van het tweede scheenlid van de
voorpooten.

Bij Mygale en een gering aantal andere geslachten vindt men 4 longzakken, dus ook 4
ademgaten aan ’t voorste deel van den buik (alle overige leden der orde bezitten 2
longen), s l e c h t s v i e r spintepels, waarvan 2 zeer klein zijn, en naar voren gerichte
kaaksprieten, welker klauwlid b e n e d e n w a a r t s en niet binnenwaarts tegen het
grondlid wordt aangelegd. De Spinnen, die deze kenmerken gemeen hebben, worden
gezamenlijk V i e r l o n g i g e n (Tetrapneumones) genoemd. In Europa is deze groep
o.a. vertegenwoordigd door de M e t s e l s p i n n e n (Cteniza), waarvan 6 soorten het
Middellandsche Zee-gebied bewonen en door het geslacht Atypus (d.i. „afwijkend”, zoo
genoemd wegens het bezit van 6 spintepels), waarvan 3 soorten, behalve in Zuid-Europa,
ook, hoewel zelden, in Duitschland gevonden worden.

S a u v a g e ’ s M e t s e l s p i n (Cteniza fodiens) in haar woning (deze is sterk verkort


en overlangs doorgesneden voorgesteld).—a) Plaatsing der oogen (sterk vergroot).—b)
Deksel van binnen gezien.—c) Eieren.—Ware grootte (behalve a).

S a u v a g e ’ s M e t s e l s p i n (Cteniza fodiens), die hieronder in haar eigenaardige


woning is afgebeeld (deze moet men zich echter ruim 4-maal zoo lang denken), heeft
een roodbruin, bijna onbehaard lichaam en ziet er ongeveer uit als een Kelderspin. De
beide staartjes aan de spits van het achterlijf, die ook bij vele andere Spinnen
voorkomen, stellen de beide genoemde, tastervormige, geen draad voortbrengende
spintepels voor. Deze soort wordt vooral op Corsica gevonden; zij kiest tot verblijfplaats
een niet met gras begroeide, steile helling, die uit een samenpakkende grondsoort zonder
steentjes bestaat, waarin het regenwater dus niet kan blijven staan. Hier graaft hij in
horizontale richting een soms wel 63 cM. lange gang, zoo wijd, dat zij zich er met
gemak in kan bewegen; deze wordt van binnen bekleed met een zijden weefsel om het
instorten te verhoeden. Haar kunstigst werkstuk is echter het cirkelronde deurtje,
waarmede de gang gesloten wordt en dat in de opening past. Het is aan den buitenkant
plat en ruw en niet van de omgevende aarde te onderscheiden, overigens uit fijne klei en
spinsel samengesteld, van binnen met een sierlijk zijden weefsel bekleed, welks draden
langs een deel van den bovenrand overgaan in het bekleedsel van de gang en zoo een
hengsel vormen; het deurtje valt door zijn eigen zwaarte dicht, nadat men het geopend
heeft. De Spin verlaat haar woning niet anders dan ’s nachts om op roof uit te gaan; over
dag is zij in haar goed gesloten hol beveiligd tegen vijanden. Als een van deze de deur
wil openen, belet de Spin dit, door de klauwen van de achterpooten in het bekleedsel van
de gang, die van de voorpooten in de zijden binnenbedekking van het deurtje te slaan en
dit dus naar zich toe te trekken. De zwarte stipjes die in fig. b langs een deel van den
rand voorkomen, stellen de gaten voor, die met het genoemde doel in ’t weefsel zijn
aangebracht. Wanneer de Spin de deur niet meer gesloten kan houden, vlucht zij naar het
diepste deel van haar hol. Hier bevinden zich de eieren en later de jongen, die gedurende
het eerste levenstijdperk zorgvuldig door de moeder bewaakt worden. Wanneer de
Metselspin uit haar hol gehaald en aan de zonnestralen blootgesteld wordt, is zij na
korten tijd slap en als verlamd.

Alle Spinnen, die slechts door t w e e longen (sommige bovendien door luchtbuizen)
ademen—de T w e e l o n g i g e n (Dipneumones)—, hebben het klauwvormig eindlid
van de kaaksprieten in rust binnenwaarts gericht. Op grond van haar levenswijze kan
men ze verdeelen in G e v e s t i g d e of W e b s p i n n e n (Sedentariae) en
Z w e r v e n d e of J a c h t s p i n n e n (Vagaebundae). De laatstgenoemde maken geen
web en vangen loopend of springend haar buit; de eerstgenoemde wachten hem af op of
bij het web, dat zij vervaardigen, of de draden, die zij spannen, en worden, naar de wijze
van spinnen, in verscheidene familiën verdeeld.

De W i e l s p i n n e r s (Orbitelariae, Epeiridae) hebben een meestal rechtstandig web,


samengesteld uit draden, die, als de spaken van een wiel, straalsgewijs van een
middelpunt uitgaan, en andere, die als concentrische of spiraalwindingen de vorige
doorsnijden. In de nabijheid van dit vangnet of er midden in wachten zij geduldig, tot
een vliegend Insect er aan vastgehecht blijft. In het laatst van den zomer of in den herfst
hebben de meeste Spinnen door de laatste vervelling haar volledige ontwikkeling
bereikt. Kort na de paring bezwijken de mannetjes; de wijfjes brengen hare eierenzakjes,
die gewoonlijk door gele, eenigszins wollige vlokjes omgeven zijn, op een veilige plaats
en sterven vóór den aanvang van den winter. Alle Wielspinners hebben 8 oogen; de 4
grootste staan in ’t midden (middenoogen) en vormen een vierkant, tenzij de afstand
tusschen de 2 voorhoofdsoogen iets grooter is dan die, welke de kruinoogen
vaneenscheidt; de 4 overige (zijoogen) zijn aan weerszijden van de middenoogen en op
grooten afstand van deze, twee aan twee, eenigszins scheef en zeer dicht bij elkander
geplaatst (zoodat er dikwijls geen tusschenruimte overblijft). De pooten zijn tamelijk
dik; de voorste zijn langer dan die van het 2e paar, hoewel deze de volgende in lengte
overtreffen. Alle wijfjes (uitgezonderd die van het geslacht Tetragnatha) onderscheiden
zich door een dik, bolrond achterlijf en een sterk getanden tasterklauw.

Dit alles kan men het gemakkelijkst waarnemen bij de algemeen bekende G e w o n e
K r u i s s p i n (Epeira diadema). Aan de rugzijde van het vette, glanzige achterlijf ziet
men lichte vlekjes een kruis vormen op den lichter of donkerder bruinen, met meer of
minder grijs gemengden ondergrond; dit heeft aanleiding gegeven tot den naam. Andere
hier voorkomende, meestal zuiver witte vlekken en stippels, begrenzen een driehoekig
veld. Bij het aanmerkelijk kleinere, slechts 11 mM. lange mannetje zijn de schenen van
de 2e paar pooten verdikt. De Epeiren spinnen uit 6 tepels met zeer talrijke pijpjes.
De Gewone Kruisspin wordt in ’t grootste deel van Europa in tuinen, kreupelhout en ijle
naaldhoutbosschen gevonden; meestal vestigt zij zich op betrekkelijk geringen afstand
van den grond, bij voorkeur in de nabijheid van slooten, moerassen, meren, kortom op
plaatsen waar Vliegen en Muggen gewoonlijk in overvloed rondvliegen. In ’t begin van
Mei verlaten de jongen de eischaal; gedurende ongeveer 8 dagen blijven zij bijeen, of
liever komen telkens weer samen na zich verspreid te hebben; na de eerste vervelling
verlaten zij haar geboorteplaats. Langzamerhand, na verscheidene vervellingen
ontwikkelt zich de teekening, die het volwassen dier onder de fraaiste inheemsche
soorten een plaats verschaft. Zoodra de jonge Kruisspinnen zich verstrooid hebben, spint
ieder een web, dat natuurlijk wegens zijn geringe grootte minder de aandacht trekt dan
de wielvormige weefsels van 30 en meer cM. middellijn, welke men later ontmoet. De
plaats waar zij zich vestigen zal, wordt eerst na rijp beraad bepaald; voordat zij aan den
arbeid tijgt, loopt zij geruimen tijd op allerlei voorwerpen rond; dit is volstrekt noodig,
daar zij op deze plaats op een andere wijze te werk moet gaan dan op gene om de
buitendraden te spannen, die het drie- of vierhoekige raam begrenzen, waaraan het web
bevestigd is. Haar eerste werk bestaat in het vasthechten van den draad, dien zij zal
spinnen, door drukking met de spits van het achterlijf; in verreweg de meeste gevallen
geschiedt dit op een hoog gelegen plaats. Zij laat deze los en zakt langzamerhand door
haar eigen gewicht, hangend aan den steeds langer wordende, uit de spintepels
komenden draad, die vervolgens in strak gespannen toestand bevestigd wordt; het
tweede aanhechtingspunt is steeds lager gelegen dan het eerste. Groote zorgvuldigheid
vereischt het spinnen van den bovensten dwarsdraad, die als een strak gespannen touw
twee soms ver uiteenliggende punten verbindt. Wanneer het niet mogelijk is te voet van
het eene punt naar het andere te komen, schiet de Spin een draad uit, die door
luchtstroomingen naar het tweede aanhechtingspunt wordt vervoerd; soms laat zij zich,
onder aan een draad hangend, zoo lang heen en weer slingeren, totdat zij met de pooten
de gewenschte plaats bereiken kan. Indien de draad niet dadelijk de noodige spanning
heeft, wordt hij door korte zijdraden strak getrokken. Als het raam gereed is, verbindt de
Spin twee tegenovergestelde punten door aan het eene een draad te bevestigen, langs de
buitendraden naar het andere punt te loopen en intusschen den steeds langer wordende
nieuwen draad met den achterpoot van zich af te houden. Door tusschen het midden
dezer lijn en den omtrek heen en weer te gaan komen de spaken van het wiel tot stand,
waarbij de laatste verkregene steeds als weg dient bij het spinnen van de volgende. De
nu volgende arbeid, het verbinden van alle stralen door cirkels, levert geen bezwaar op.
In het middelveld, dat zich ongeveer zoo ver uitstrekt, als de Spin hare pooten kan
uitsteken, zijn deze draden droog, evenals de tot dusver gebruikte; verderop zijn zij bezet
met zeer talrijke, buitengewoon fijne, kleverige knobbeltjes en hierdoor in staat om
denzelfden dienst te doen als de lijmroeden bij het vogelvangen: zij houden de vliegende
Insecten vast, die er mede in aanraking komen. Men heeft uitgerekend, dat een web van
36 à 39 cM. middellijn ongeveer 120 000 van deze knobbeltjes bevat.
Het nu voltooide werkstuk levert een sterk sprekend bewijs van de buitengewone
kunstvaardigheid der Spin; de stralen en cirkels, hoewel minder zuiver van constructie
dan die van den met liniaal en passer uitgerusten teekenaar, vormen te zamen een
bewonderenswaardig geheel. Met lofwaardigen ijver is deze arbeid verricht; vooral na
een zachte regenbui wordt er gewoonlijk slechts één dag of één nacht aan besteed. Met
omlaag gericht kopborststuk troont op ’t middelveld de kunstenares. Soms acht zij het
verkieselijker aan den buitenkant van haar web onder een blad of op een andere
beschutte plaats haar hoofdkwartier te vestigen; steeds is dit plekje met het middelpunt
van het wiel verbonden door eenige sterk gespannen draden, die als telegraaf dienst
doen, van iedere beweging van het web terstond kennis geven. Zij geraken in trilling
door de onbesuisde Vlieg, die het ongeluk had met het net in aanraking te komen en bij
hare pogingen om zich te bevrijden hoe langer hoe meer in de draden verward geraakt.
Niet in eens, maar bij rukken schiet de Spin van uit de hinderlaag op haar slachtoffer toe;
zij is altijd voorzichtig, gaat nooit met blinde overhaasting te werk. Eerst begeeft zij zich
naar het middelpunt en van hier naar de plaats waar de Vlieg, door geweldig te spartelen
en te gonzen, hare krachten verspilt. Een beet met de gifkaken brengt haar spoedig tot
rust. De Spin zal, indien zij zeer hongerig is, onmiddellijk na de vangst den buit
verslinden, maar dezen, bij minder groote behoefte aan voedsel, met een breeden band
van draden omwikkelen. Als een pop in een cocon, blijft het goed ingepakte slachtoffer
voorloopig hangen; ter gelegener tijd bijt de Spin den opgespaarden voorraad los en
vervoert dezen naar haar schuilplaats; hier gaat zij op haar gemak aan ’t kauwen, waarna
de met speeksel tot een brijachtige massa verwerkte prooi opgezogen wordt. Als een
Wesp of een dergelijk onbruikbaar dier in het web geraakt, zal de Spin zelf door het stuk
bijten van eenige draden tot de bevrijding van de gevangene medewerken. Soms zit het
web vol van kleine Mugjes, die nagenoeg geen voedsel opleveren, maar door hun
donkere kleur en door het bedekken van de kleverige knobbeltjes der draden de
bruikbaarheid van het vangtoestel zoo zeer verminderen, dat de Spin zich genoodzaakt
ziet een ander web te vervaardigen. Onze Kruisspin heeft geen helpsters zooals sommige
van hare West-Indische verwanten, in welker web Darwin dikwijls kleinere spinnetjes
aantrof, die, naar hij vermoedt, op de gevangene Insecten azen, die wegens hun geringe
grootte door de eigenares van het web versmaad worden. Dat de Kruisspin haar weefsel
herstelt, wanneer het beschadigd is, wordt door sommige onderzoekers beweerd, door
andere betwist; waarschijnlijk geschiedt dit alleen op plaatsen, die zoo gunstig gelegen
zijn voor de vangst, dat de Spin geen lust gevoelt ze te verlaten.

De omstandigheden bepalen de wijze, waarop de Spin te werk gaat, zoowel bij het
aanleggen van het raam voor haar web als bij de behandeling en het verslinden van den
buit; evenals in deze gevallen, toont zij ook overleg bij de keuze van maatregelen, om
aan een dreigend gevaar te ontkomen. Haar gewone redmiddel is, zich te laten zakken
aan een draad; soms acht zij het blijven hangen in de lucht voldoende; soms echter daalt
zij tot op den bodem af en houdt zich dood; zoodra het gevaar geweken is, keert zij langs
den draad naar haar vroegere zitplaats terug. In andere gevallen van verontrusting blijft
zij stevig vastgehecht zitten op het middelveld van haar web, maar deelt hieraan zulk een
hevige, trillende beweging mede, dat men haar lichaam niet meer kan onderscheiden. In
den herfst zijn de Kruisspinnen volwassen. In een streek waar deze dieren talrijk zijn,
schat men het aantal wijfjes op 10 à 15 tegen 1 mannetje. Het mannetje heeft een eigen
web en toont gedurende de kortstondige spinnenvrijage een niet ongegronde vrees voor
zijn veel grootere wederhelft. In September of October legt het wijfje ongeveer 100 gele
eieren in een door haar gesponnen zakje, dat zij op een veilige plaats ophangt. De
omvang van haar achterlijf vermindert hierdoor zoo sterk, dat zij bijna onkenbaar wordt.
Zij sterft vóór den aanvang van den winter, maar blijft tot aan het einde van haar leven
hare eieren zorgvuldig bewaken. Zelden treft men in den winter onder boomschors of
mos Gewone Kruisspinnen aan; steeds zijn dit onvolwassene exemplaren, die later dan
gewoonlijk (Mei) de eischaal verlieten.

De U i t g e r e k t e O e v e r s p i n (Tetragnatha extensa) heeft vele eigenaardigheden,


waardoor zij zich van de overige Wielspinners onderscheidt; de opmerkelijkste zijn: het
langwerpige achterlijf en de zeer lange pooten; het rustende dier strekt de beide naast
elkander gelegde voorste paren regelrecht naar voren, de beide achterste paren op
dezelfde wijze naar achteren; ook de kaaksprieten steken ver vóór het kopborststuk uit.
De volwassen Spin is 15 à 19.5 mM. lang; de pooten en het voorste deel van ’t lichaam
zijn roodachtig geel; het achterlijf is van onderen meestal geelachtig wit, aan de zijden
zilverwit en van boven versierd met een roodbruin, bladvormig rugveld, dat door
donkere, ingekorven randen omgeven wordt. Tusschen halmen van riet, biezen of
grassen, bij moerassen, poelen en andere vochtige plaatsen, bij ons ook in tuinen, vindt
men haar loodrecht geplaatst wielvormig web en in het middenveld of tegen een
naburige bieshalm aangedrukt, de op buit loerende Spin. Deze is in ’t heetst van den
zomer volwassen; het mannetje toont in den paartijd geen vrees voor het wijfje. De
lichtgele eieren worden in een halfbolvormig zakje, door een vlokkig spinsel omhuld,
aan een stengel opgehangen. De jongen komen nog in ’t zelfde jaar uit, vliegen soms aan
„herfstdraden” door de lucht en zijn gedurende den winter dikwijls verscholen in holle
leden van rietstoppels.

In de warme landen van beide halfronden, in Amerika tot in den staat Ohio, leven
talrijke, tot verschillende geslachten behoorende soorten van Wielspinners, die zich
kenmerken door een hoornachtig, van achteren in twee lange, rechte of kromme doornen
eindigend rugschild op het achterlijf. Tot de meest verbreide behoort het geslacht der
D o o r n s p i n n e n (Gasteracantha), dat nog wel zonderlinger vormen omvat dan de
hierna afgebeelde T a n g v o r m i g e D o o r n s p i n (Gasteracantha arcuata), die op
Java gevonden wordt.
Sommige K r u i s n e t s p i n n e r s (Theridiidae—meer bepaaldelijk de Linyphiinae en
de Theridiinae) spinnen in de struiken of tusschen grashalmen een horizontaal,
dekenvormig web, welks draden elkander in alle richtingen kruisen. O n d e r dit nest
wonen in den paartijd de mannetjes en de wijfjes gezellig bijeen; in de overige tijden van
’t jaar leeft ieder afzonderlijk. Andere leden van dezelfde familie spinnen enkele draden
in verschillende richtingen, overlangs, overdwars, naar boven, naar onderen, of werpen
er een uit onder het loopen, maar vervaardigen geen echt web (Pachygnathinae); evenals
de zoogenaamde Jachtspinnen (Vagabundae), vangen zij hun prooi loopend of
springend. Bij de leden der eerstgenoemde afdeeling zijn er, die onder hun met een
troonhemel vergelijkbaar weefsel nog een klein, horizontaal, wielvormig web
vervaardigen en bovendien een klein, klokvormig broeinestje, waarin het wijfje één of
eenige eierenhoopjes bewaakt. Al deze Spinnen zijn gewoon om, aan de pooten, met
naar beneden gekeerden rug, o n d e r haar net hangend, haar buit af te wachten. De
meeste hebben een zeer bol, bijna kogelvormig achterlijf; de pooten zijn dun en lang; de
voorste steeds de langste.

T a n g v o r m i g e D o o r n s p i n (Gasteracantha arcuata). Bij het exemplaar op den boomstam


ziet men het spinveld als een glinsterend zwarte knobbel uitpuilen op het midden van de overdwars
gerimpelde onderzijde van het helder bloedroode achterlijf, dat, behalve de 2 lange, gekromde
doornen aan de achterhoeken nog 2 paar kortere stekels draagt, die, evenals de vlekken op den rug,
zwart zijn. Het voorste deel van ’t lichaam is behaard en glanzig zwart.—Ware grootte.

De B a l d a k ij n s p i n (Linyphia montana) bewoont zoowel vlakke als bergachtige


streken en wordt, ofschoon zeldzamer dan hare (vooral op heidegrond levende)
verwanten, ook in Nederland in dennebosschen gevonden. Zij bouwt haar nest in tuinen
tegen schuttingen of oude huizen, in holle wilgen, ook wel in bosschen, maar hier liever
tusschen lage heidestruiken dan in hooger opschietend struikgewas. Oorden, die gunstig
gelegen zijn voor de insectenvangst, vindt men dikwijls wijd en zijd met nesten
overdekt, die niet zelden op verschillende hoogten zoldersgewijs boven elkander
voorkomen; door den morgendauw bepareld, leveren zij een prachtig schouwspel op. In
Juni legt het wijfje omstreeks 100 eieren in een plat-rond nestje, dat zij onder
boomschors of op een andere beschutte plaats verbergt, met losse draden overspint en
met de bij Spinnen gewone moederliefde bewaakt. In Juni komen de jongen uit.

1, 2) O m k r a n s t e W e e f s p i n (Theridium redimitum):—1) Volwassen Spin: op den grond loopend, op


haar web zittend en van ter zijde gezien op een blad.—2) Eierenzakje aan een blad bevestigd, bewaakt door
de moeder.—3) Spin bezig met het leggen van eieren in het door haar gesponnen nestje, welks randen later
tot een bolvormig zakje worden bijeengevoegd.—4) G e w o n e H o o i w a g e n (Opilio parietinus).—1,
2, 4) Ware grootte. 3) Vergroot.

De genoemde soort komt in vorm ongeveer met de Oeverspin overeen, hoewel zij in rust
aan hare pooten een geheel andere richting geeft en veel kleiner is; haar lengte bedraagt
5 à 7 mM. Het kopborststuk is bruin, aan de zijden met donkerder randen; het achterlijf
prijkt op witten grond met een langwerpig, bruin schild, dat een donkerder, gehakkelden
zoom heeft; de buik is donkerbruin met 4 witte vlekken. De geelachtige pooten hebben
op de dij en de scheen en aan den achtervoet 2 zwartbruine ringen, één bovendien aan de
uiteinden der knieën en aan de leden der overige voeten.

De O m k r a n s t e W e e f s p i n (Theridium redimitum), die bij ons vrij algemeen,


vooral in tuinen, voorkomt, wordt hoogstens 5 mM. lang; dit kleine, vette spinnetje
bewoont allerlei laag groeiende kruiden en heesters; hier spint het (fig. 1) een paar
bladen aaneen door onregelmatig gerichte draden, waaraan de kleine diertjes blijven
hangen, die zijn voedsel uitmaken. De moeder bevestigt het kogelronde, blauwachtige
eierenzakje aan een blad (fig. 2), houdt er naast de wacht, totdat de jongen zijn
uitgekomen en gaat hiermede voort gedurende de weinige dagen van hun samenwoning.
Deze fraaie spinnetjes zijn zeer veranderlijk van kleur en teekening. In hun prille jeugd
doorschijnend en bijna wit, alleen op den rug van het achterlijf zwart gevlekt; hebben zij
tegen het einde van Juni, in Juli en in Augustus een bleekgele kleur aangenomen,
sommige effenkleurig, andere met een vlek op ’t achterlijf, die zuiver rozerood of
gedeeltelijk groenachtig, kringvormig of ovaal kan zijn. Bovendien zijn de rand en een
lijn over het midden van het kopborststuk, 6 paar ronde stippels op het achterlijf, de top
van de tasters en de scheenen zwart.—Alle Theridiën verraden in hare bewegingen meer
traagheid dan de meeste andere Spinnen en laten zich gemakkelijk grijpen.

Het beruchtste lid van deze familie is de Zuid-Europeesche M a l m i g n a t t e


(Latrodectus tredecimguttatus). Sedert 1786 heeft deze fraaie Spin in Toscane meer
algemeen de aandacht getrokken; zij wordt hier, vooral in Augustus, wegens haar
„giftigen” beet gevreesd. In Spanje werd zij eerst sedert 1830 meer algemeen bekend,
omdat zij zich toen in Catalonië in grooten getale vertoonde; dit geschiedde in 1833
nogmaals en wederom in 1841. Merkwaardigerwijze hebben deze zelfde jaren een
treurige herinnering achtergelaten wegens schade, door de Sprinkhanenzwermen
aangericht. Proefondervindelijk werd aangetoond, dat alle lichaamsdeelen van de
Malmignatte, zelfs de pooten en de onrijpe eieren, vergiftig zijn. In het jaar 1839 werden
door deze Spin aan den benedenloop van den Wolga 3000 Runderen gedood; in
sommige gewesten van Afrika bezwijken 33 percent van alle Kameelen aan haar beet.
Dat deze ook bij den mensch doodelijke gevolgen kan hebben, leeren berichten uit
Spanje, Italië en Rusland. De Malmignatte is 13 mM. lang, gitzwart van kleur en op het
bolvormige, van achteren eenigszins spits toeloopende achterlijf met 13 bloedroode
vlekken van verschillende grootte en kleur geteekend, waarvan 2 op de buikzijde
voorkomen. Zij houdt zich op tusschen steenen of in uithollingen van den bodem,
waarover zij enkele vangdraden spant, en schiet met voor niets terugdeinzende
stoutmoedigheid toe op de Insecten, die hierin verward geraken en door haar snel
werkend vergif schielijk overmeesterd worden, zelfs als zij de Spin in grootte
aanmerkelijk overtreffen. Vooral geldt dit van de Sprinkhanen, waarvan zij er vele
verdelgt. Het wijfje omspint hare talrijke eieren (dikwijls meer dan 200) met een
bolvormig, naar de eene zijde een weinig spits toeloopend, stevig hulsel van licht
koffiebruine kleur en 13 mM. middellijn.
H u i s s p i n (Tegenaria domestica):—a) Mannetje (hieronder, op vergroote schaal, de oogen van voren
gezien). b) Wijfje.—Ware grootte.

Algemeen bekend zijn de driehoekige spinnewebben, die in stallen, schuren, kerken en


in alle ruimten van huizen, die niet dikwijls een schoonmaakbeurt krijgen, de hoeken van
muren, vensters, nissen, enz. ontsieren door hun zwarte kleur, welke een gevolg is van
het stof, dat, er in is blijven hangen. De H u i s s p i n (Tegenaria domestica), die deze
vangwebben vervaardigt, is niet slechts over geheel Europa, maar ook over Noord-
Afrika verbreid, overwintert bij ons op jeugdigen leeftijd en is gemiddeld in Juni
volwassen; het mannetje heeft dan een lengte van 11, het wijfje van 17 à 19.5 mM.
bereikt. De okergele grondkleur van het lichaam vertoont een bruine teekening.
Donkerder zijn de rand van het kopborststuk, een streep over het midden van het
kopgedeelte en straalsgewijs gerichte lijnen met 3 maanvlekken aan weerszijden op het
borstgedeelte; de roestroode of bruingele streep over het midden van het achterlijf is aan
weerszijden vergezeld door een reeks van gele vlekken; de dicht bijeengeplaatste,
schuinsche strepen op de zijden zijn bruin. De okergele pooten hebben getakte, donkere
ringen.

Als de Huisspin haar nest begint te bouwen, drukt zij het spinveld op een afstand van
eenige cM. van den hoek tegen den eenen muur, wandelt naar den anderen, intusschen
een draad spinnend, die zij hier, ongeveer op denzelfden afstand van den hoek als
zooeven, vasthecht, na haar strak gespannen te hebben. Daar zij de buitenste en
belangrijkste draad is, wordt haar dikte achtereenvolgens verdubbeld en verdrievoudigd.
Door het aanhoudend heen-en-weer loopen langs dit samenstel van 3 draden en de steeds
korter wordende, die hieraan achtereenvolgens verder naar binnen in onderling
evenwijdige richting worden toegevoegd, ontstaat de „ketting”, die met de haar
kruisende, als „inslag” dienende dwarsdraden het vangweb vormen, dat in het midden
een weinig hol staat. Hiermede is echter het geheele kunstwerk nog niet voltooid. Voor
zich zelf weeft de Spin nu achter in den hoek een aan beide einden geopende buis,
waaraan, als aan een korten steel, het vroeger vervaardigde, driehoekige net vastgehecht
is. Daar zij zich bij voorkeur vestigt op plaatsen waar gaten en spleten in den muur
voorkomen, mondt de buis in zulk een gat uit, waarin de Spin bij naderend gevaar zich
verschuilt. In ’t voorste gedeelte van deze buis loert zij op buit; de op het net komende
Vlieg of Mug wordt onmiddellijk gegrepen en naar haar hinderlaag vervoerd, waar zij
het slachtoffer op haar gemak verslindt.

Iedere Spin moet spaarzaam zijn met de stof, waarvan zij haar web spint, omdat de
beschikbare voorraad afhangt van de hoeveelheid voedsel, die haar ten deel valt, en dus
geringer is bij een uitgehongerd dan bij een goed doorvoed exemplaar; daarom spint zij
niet, wanneer storm of regen haar arbeid onmiddellijk weder kunnen vernielen en dus
nutteloos maken. In verband hiermede zijn de Spinnen zeer gevoelig voor
weersveranderingen. Men heeft ze zelfs tot het voorspellen van een toekomstige
weersgesteldheid in staat geacht en deze trachten af te leiden uit het werken of rusten, te
voorschijn komen of zich verbergen van de Spinnen, uit haar houding in het web, uit de
meerdere of mindere stevigheid, die zij geven aan de buitendraden van haar nest, uit het
vervaardigen van nieuwe of het vergrooten van reeds bestaande weefsels, enz. Vooral op
de handelingen van de Kruisspin en de Huisspin heeft men acht gegeven. Als de
Kruisspin eenige van de buitendraden van haar web verscheurt en vervolgens een
schuilplaats opzoekt, als de Huisspin of een andere Trechterspin, enz. zich diep in haar
buisvormige woning begeeft, wordt in ’t eene geval op de ligging der bedoelde draden,
in ’t andere op de richting van de spits van het achterlijf gelet en hieruit afgeleid, dat er
weldra een hevige wind uit dien hoek zal waaien. Wanneer echter de Huisspin de draden
van het raam van haar web herstelt en een afwachtende houding aanneemt, als de
Huisspin en hare verwanten met buitenwaarts gericht kopgedeelte aan den ingang van
haar woning verschijnen en de pooten strekken, alsof zij zich gereed maken een prooi te
bespringen, verwacht men verbetering van de weersgesteldheid. Tot staving van de
bedoelde voorwetenschap der Spinnen wordt gewoonlijk gewezen op een gebeurtenis,
die in het jaar 1794 aan het Fransche leger, dat Holland trachtte te bezetten, de zege
verschafte. De Fransche bevelhebber Pichegru was van oordeel, dat hij tegen de door
onderwaterzettingen beschermde stellingen van het Hollandsche leger niets zou kunnen
uitrichten en stond op het punt onverrichter zake terug te keeren, toen hij van den te
Utrecht gevangen gehouden generaal-adjudant Quatremère d’Isjonval het op
waarnemingen aan Spinnen gegronde bericht ontving, dat men binnen 10 dagen op vorst
kon rekenen. Pichegru bleef, de voorspelde weersverandering had plaats en het
Fransche leger kon over het ijs tot Amsterdam doordringen. Nauwgezette
onderzoekingen hebben geleerd, dat men geen staat kan maken op dergelijke
voorspellingen, al komen zij toevalligerwijze een enkele maal uit. Het is mogelijk, dat de
Spin aan verschijnselen, die aan onze zintuigen ontgaan, een r e e d s i n g e t r e d e n
verandering van den toestand der atmosfeer opmerkt; stellig bezit zij echter geen
profetische gave, die haar in staat stelt om dagen van te voren over het komende weer te
oordeelen.

Spinrag—vooral dat van de Huisspin, daar dit het gemakkelijkst kan worden verkregen
—behoort ook tot het tallooze heir van middelen, die tot het bestrijden van
ziekteverschijnselen aangewend worden of werden; naar men beweert, helpt het tegen
afwisselende koorts. Algemeener bekend is de bloedstelpende werking van
spinnewebben, die op een wonde gelegd zijn; niet zelden echter heeft het toepassen van
dit middel, wegens den onvoldoende staat van zuiverheid waarin het verkeerde,
aanleiding gegeven tot verergering van de kwaal. Ook heeft men getracht spinrag als
zijde te verwerken; het ligt echter voor de hand, dat de productie van een dergelijke, van
een roofdier afkomstige grondstof, nooit voldoende zal kunnen zijn om hierop een
voordeel afwerpende industrie te gronden.

De G e w o n e L a b y r i n t s p i n (Agelena labyrinthica) leidt op opene plekken in


bosschen, op weiden en op zonnige berghellingen, die met laag groeiende planten en
struiken begroeid zijn, een soortgelijke levenswijze als de Huisspin. Zij is nog forscher
gebouwd dan deze (13 à 22 mM. lang), heeft dezelfde gestalte en is op het grijsgele
kopborststuk geteekend met 2 zwartbruine, overlangsche strepen, die in de nabijheid van
de zijoogen spits eindigen. Over het deels grijs, deels zwart gekleurde achterlijf loopt in
’t midden een streep van roodachtig grijze haren, van waar aan de zijden 5 à 6 schuins
naar voren gerichte strepen uitgaan, die eveneens uit roodachtig grijze haren bestaan. De
heup en de dij zijn geel, de overige leden van de pooten roodgeel. De oogen, die alle
ongeveer gelijke grootte hebben, zijn gerangschikt als bij de vorige soort; de kruinoogen
zijn echter verder achterwaarts verschoven en nader (bijna zoo dicht als de
voorhoofdsoogen) bij elkander gelegen. Omdat het eindlid van de bovenste spintepels
lang en omhoog gericht is, schijnt het dier een sterk ontwikkeld staartje te hebben. Bij
fraai weer wandelt de Labyrintspin dikwijls langs de grenzen van haar web, welks wijde
rand door draden van meer dan 30 cM. lengte met de omgeving verbonden is. Zij
beweegt zich flink en is zeer gretig naar buit. Zij verlaat haar nest niet licht, maar
herstelt het telkens weer, zoodra het op de een of andere plaats beschadigd werd. In Juli
en Augustus legt het wijfje een betrekkelijk gering aantal (60 à 70) groote eieren in een
uit verscheidene lagen bestaande buis, welks buitenste oppervlakte met aardkluitjes en
plantaardige overblijfselen saamgesponnen is. In de nabijheid van het nest opgehangen,
worden de eieren door de moeder met zorg bewaakt. Deze Spin bewoont een uitgestrekt
gebied; men vindt haar in Engeland, Zweden, Duitschland, Frankrijk, Hongarije en
zonder twijfel ook in Rusland.

De beide genoemde en eenige verwante geslachten worden onder den naam van
T r e c h t e r s p i n n e r s (Ageleninae) tot een onderfamilie vereenigd, die zich o.a.
kenmerkt door het bezit van een bijklauw met 8 à 5 tanden. Een andere afdeeling van de
familie der B u i s s p i n n e r s (Tubitelae) vormen de Z a k s p i n n e r s (Drassinae);
deze hebben een rolrond of langwerpig eivormig achterlijf en korte pooten, waaraan de
bijklauw meestal ontbreekt.

Van geen enkelen Zakspinner biedt de levenswijze zoovele merkwaardige


eigenaardigheden aan als van de G e w o n e W a t e r s p i n (Argyroneta aquatica); door
haar uiterlijk trekt zij volstrekt niet de aandacht. In tegenstelling van ’t geen bij de
overige Spinnen als regel geldt, is het mannetje bij deze soort forscher gebouwd (15
mM. lang) dan het wijfje (ruim 12 mM. lang). Bij beide heeft het bijna onbehaarde,
roestroodachtige kopborststuk aan de zijden en van achteren een bruine, om het
voorhoofd een zwartbruine tint; van voren is het met 3 zwarte, overlangsche strepen, van
achteren met zwarte stralen geteekend. Het olijfbruine achterlijf is met een teer waas van
witachtig grijze, fluweelachtige haren bedekt, waarop 2 reeksen van putjes in ’t oog
vallen.

Deze Spin leeft bijna voortdurend in ’t water en ademt door longen en tracheën te gelijk.
Op haar uiterlijk afgaande, zou men haar licht kunnen verwarren met andere soorten van
Spinnen, van welke zij zich echter aanmerkelijk onderscheidt door haar levenswijze. Zij
bewoont stilstaand of langzaam stroomend water, dat rijk is aan Mijten en kleine
Insecten, aan eendenkroos en verschillende andere waterplanten; hier zwemt zij en
bouwt er haar nest. Zij kan echter gedurende korten tijd buiten haar element leven. De
zwemmende Spin levert een verrassend schouwspel op, daar haar achterlijf omgeven is
door een dunne luchtlaag, die als een druppel kwikzilver glinstert (haar geslachtsnaam
beteekent „met zilver omspannen”). Deze luchtlaag verraadt de aanwezigheid van het
diertje, dat anders wegens zijn kleinheid licht onopgemerkt zou blijven; zij wordt niet
alleen door de fluweelachtige beharing vastgehouden, die het natworden van de huid
verhindert, maar bovendien door een soort van vernis van het omgevende water
gescheiden.

Wanneer deze kleine duikkunstenares een nest wil bouwen, begeeft zij zich naar den
waterspiegel en steekt, op den kop staande, met naar boven gerichten buik, de spits van
haar achterlijf boven de oppervlakte in de lucht, spreidt de spintepels uit en daalt
schielijk weer in ’t water af. Zoodoende neemt zij, zonder dat het zilveren omhulsel van
het achterlijf er bij te pas komt, een meer of minder groote, aan de spits van ’t lichaam
hangende luchtbel mede. Deze wordt zwemmend vervoerd naar de waterplant, die bij
een vroeger bezoek geschikt werd geoordeeld voor ’t bouwen van een woning en hier
vastgehecht. Dit vereischt natuurlijk het gebruik van spinstof, die, uit de spintepels
ontwijkend, als een soort van vernis, dat met de achterpooten wordt uitgestreken, de
lucht van het water scheidt, daar deze anders onmiddellijk weer naar boven zou stijgen.
Opnieuw gaat zij een luchtbel halen, die na doelmatige vergrooting van het reeds
aanwezige spinsel met de eerste samenvloeit; deze arbeid wordt voortgezet, totdat de
kleine, met de opening naar beneden gerichte duikerklok ongeveer de grootte van een
walnoot bereikt heeft. Verscheidene draden moeten natuurlijk gedurende het bouwen
gespannen worden om aan het nest de vereischte stevigheid te verschaffen. Andere, die
rondom den ingang zich in alle richtingen uitspreiden, dienen als valstrikken voor den
zwemmenden buit. Indien de Spin hare slachtoffers afwachtte, zou zij menigmaal honger
moeten lijden; zij gaat ze echter ook wel opzoeken en houdt zich niet strikt aan één
bepaalde wijze van jagen gelijk hare verwanten, die in de lucht vangwebben hebben.
Zoodra zij een prooi gegrepen heeft, kruipt zij bij den eersten den besten stengel omhoog
en verslindt het lekkere hapje in de lucht; soms kiest zij tot eetzaal haar duikerklok, of
hangt hierin het overschot voor toekomstig gebruik op, zoodra haar honger gestild is. In
de gevangenschap bevestigt de Waterspin haar duikerklok ook wel aan den wand van het
glas, waarin zij leeft.

G e w o n e W a t e r s p i n (Argyroneta aquatica), een weinig vergroot, met 2 nestjes.

Het wijfje legt eieren in een luchtbel, die, met een dubbele laag spinsel omkleed en tot
een min of meer platbol zakje vervormd, aan een waterplant of in de duikerklok
opgehangen en zorgvuldig bewaakt wordt.

De duikerklok dient ook tot winterkwartier. Bij voorkeur overwintert de Waterspin


echter in een ledig slakkenhuis, welks mond zij met een kunstvol weefsel afsluit. Naar
het schijnt, komt onze soort hoofdzakelijk in Noord- en Midden-Europa voor; reeds in
het noorden van Frankrijk is zij zeldzaam; in het zuiden vindt men haar niet.

Een groot aantal over verschillende geslachten verdeelde Zakspinnen leven verborgen
onder steenen, in mos, in spleten van muren en rotsen en achter schorsschilfers van oude
boomen. Op de laatstgenoemde plaats merkt men dikwijls wit zijden lichaampjes op, die
op hemdsknoopjes gelijken, in ’t midden een weinig uitpuilen en een vlakken rand
hebben; verscheidene soorten van Zakspinnen maken zulke eiernestjes; hun platte zijde
is vastgekleefd aan de binnenzijde van de schorsschilfers of tegen den ontschorsten
stam; ook vindt men ze wel in opgerolde bladen. Een van de meest verbreide soorten
dezer afdeeling, de A t l a s s p i n (Clubiona holosericea), wordt, behalve in tuinen, waar
zij de genoemde schuilhoeken bewoont, niet zelden ook in huizen gevonden.

De B u i s s p i n n e r s i.e.z. (Dysderinae) weven onder steenen, in spleten, rietstengels,


enz. buizen van dichte zijde en onderscheiden zich door het bezit van niet meer dan 6
oogen, van een rolrond, op korte, maar krachtige pooten rustend lichaam en van een
bijklauw met slechts één tand.

Zeer algemeen vindt men onder steenen, boomschors of mos, in gaten van muren, in
kelders en in stroodaken de 10 à 11 mM. lange K e l d e r s p i n (Segestria senoculata);
zij bewoont een middelmatig lange, witte, aan weerszijden geopende buis, van waar zij
in verschillende richtingen draden spant om Insecten te vangen. Aan den ingang dezer
buis zit zij op de loer, houdt de 6 voorste pooten naar voren gericht en het lichaam tegen
den wand gedrukt. Het in de vangdraden verschijnende slachtoffer wordt onmiddellijk
gegrepen en medegenomen naar het achterste deel van de buis. Koen en behendig valt zij
Insecten aan, die haar door grootte en kracht verre overtreffen; zelfs voor Wespen, die
door de meeste andere Spinnen gevreesd worden, deinst zij niet terug. In het midden van
den zomer verlaten de jongen het nagenoeg bolvormige eierenzakje en houden zich
aanvankelijk in het nest van de moeder op. De Kelderspin heeft een betrekkelijk slanke
gedaante; het langwerpig eivormige, glanzig zwartbruine kopborststuk is bijna dubbel
zoo lang als breed; het bruinachtig gele achterlijf is behaard en op den rug met een reeks
van 6 donkerbruine vlekken getooid.—Een van hare naaste verwanten is de op Cuba
onder steenen levende Nops Guanabacoae, die door het bezit van slechts 2 oogen een
merkwaardige uitzondering vormt op den voor alle overige Spinnen geldenden regel.

Onder den naam van K r a b s p i n n e n (Laterigradae, Thomisidae) vereenigt men een


vrij groot aantal door levenswijze en lichaamsvorm merkwaardige soorten, die vooral in
Europa en Noord-Amerika voorkomen, zonder in de overige werelddeelen geheel te
ontbreken. Duidelijk herinneren haar gestalte en beweging aan die der Kortstaartige
Kreeften of Krabben. Zij strekken n.l. hare pooten, waarvan de beide achterste paren
aanmerkelijk korter zijn dan de beide voorste, ver zijwaarts, drukken deze ledematen en
het platte lichaam stevig tegen het voorwerp, waarop zij zich bevinden en verplaatsen
zich met even groot gemak voor-, achter- en zijwaarts, kortom in iedere gewenschte
richting. Men ziet ze, loerend op buit, rondloopen op boomstammen en bladen, vooral
echter op bloemen, die druk bezocht worden door Insecten. Gewoonlijk spinnen zij
slechts enkele draden, voornamelijk tot regeling harer bewegingen, o.a. om zich er aan te
laten zakken. In den tijd van ’t eierenleggen vestigen verscheidene soorten zich tusschen
saamgesponnen bladen of in bloeiwijzen van schermbloemigen, duizendblad (Achillea)
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