You are on page 1of 54

Functional Python Programming

Discover the power of functional


programming generator functions lazy
evaluation the built in itertools library
and monads 2nd Edition Steven F. Lott
Visit to download the full and correct content document:
https://textbookfull.com/product/functional-python-programming-discover-the-power-of
-functional-programming-generator-functions-lazy-evaluation-the-built-in-itertools-libra
ry-and-monads-2nd-edition-steven-f-lott/
More products digital (pdf, epub, mobi) instant
download maybe you interests ...

Function Python programming discover the power of


functional programming generator functions lazy
evaluation the built in itertools library and monads
Second Edition Lott
https://textbookfull.com/product/function-python-programming-
discover-the-power-of-functional-programming-generator-functions-
lazy-evaluation-the-built-in-itertools-library-and-monads-second-
edition-lott/

Functional Python Programming: Use a functional


approach to write succinct, expressive, and efficient
Python code, 3rd Edition Lott

https://textbookfull.com/product/functional-python-programming-
use-a-functional-approach-to-write-succinct-expressive-and-
efficient-python-code-3rd-edition-lott/

Beginning Functional JavaScript: Uncover the Concepts


of Functional Programming with EcmaScript 8 2nd Edition
Srikanth Machiraju

https://textbookfull.com/product/beginning-functional-javascript-
uncover-the-concepts-of-functional-programming-with-
ecmascript-8-2nd-edition-srikanth-machiraju/

Mathematica Functional and procedural programming 2nd


Edition V. Aladjev

https://textbookfull.com/product/mathematica-functional-and-
procedural-programming-2nd-edition-v-aladjev/
Trends in Functional Programming Meng Wang

https://textbookfull.com/product/trends-in-functional-
programming-meng-wang/

Programming Scala: Scalability = Functional Programming


+ Objects, Third Edition Dean Wampler

https://textbookfull.com/product/programming-scala-scalability-
functional-programming-objects-third-edition-dean-wampler/

Introducing Erlang Getting Started in Functional


Programming 2nd Edition Simon St. Laurent

https://textbookfull.com/product/introducing-erlang-getting-
started-in-functional-programming-2nd-edition-simon-st-laurent/

Introducing Elixir Getting Started in Functional


Programming 2nd Edition Simon St. Laurent

https://textbookfull.com/product/introducing-elixir-getting-
started-in-functional-programming-2nd-edition-simon-st-laurent/

Functional Reactive Programming 1st Edition Stephen


Blackheath

https://textbookfull.com/product/functional-reactive-
programming-1st-edition-stephen-blackheath/
Functional Python
Programming
Second Edition

%JTDPWFSUIFQPXFSPGGVODUJPOBMQSPHSBNNJOHHFOFSBUPS
GVODUJPOTMB[ZFWBMVBUJPOUIFCVJMUJOJUFSUPPMTMJCSBSZBOE
NPOBET

Steven F. Lott

BIRMINGHAM - MUMBAI
Functional Python Programming
Second Edition
Copyright a 2018 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form
or by any means, without the prior written permission of the publisher, except in the case of brief quotations
embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented.
However, the information contained in this book is sold without warranty, either express or implied. Neither the
author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to
have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products
mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy
of this information.

Commissioning Editor: Merint Methew


Acquisition Editor: Sandeep Mishra
Content Development Editor: Priyanka Sawant
Technical Editor: Ketan Kamble
Copy Editor: Safis Editing
Project Coordinator: Vaidehi Sawant
Proofreader: Safis Editing
Indexer: Mariammal Chettiyar
Graphics: Jason Monteiro
Production Coordinator: Deepika Naik

First published: January 2015


Second edition: April 2018

Production reference: 1120418

Published by Packt Publishing Ltd.


Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.

ISBN 978-1-78862-706-1

XXXQBDLUQVCDPN
NBQUJP

Mapt is an online digital library that gives you full access to over 5,000 books and videos, as
well as industry leading tools to help you plan your personal development and advance
your career. For more information, please visit our website.

Why subscribe?
Spend less time learning and more time coding with practical eBooks and Videos
from over 4,000 industry professionals

Improve your learning with Skill Plans built especially for you

Get a free eBook or video every month

Mapt is fully searchable

Copy and paste, print, and bookmark content

PacktPub.com
Did you know that Packt offers eBook versions of every book published, with PDF and
ePub files available? You can upgrade to the eBook version at XXX1BDLU1VCDPN and as a
print book customer, you are entitled to a discount on the eBook copy. Get in touch with us
at TFSWJDF!QBDLUQVCDPN for more details.

At XXX1BDLU1VCDPN, you can also read a collection of free technical articles, sign up for a
range of free newsletters, and receive exclusive discounts and offers on Packt books and
eBooks.
About the author
Steven F. Lott has been programming since the '70s, when computers were large,
expensive, and rare. He's been using Python to solve business problems for over 10 years.
His other titles with Packt Publishing include Python Essentials, Mastering Object-Oriented
Python, Functional Python Programming, and Python for Secret Agents. Steven is currently a
technomad who lives in city along the east coast of the U.S. You can follow his technology
blog (slott-softwarearchitect).
About the reviewer
Yogendra Sharma is a developer with experience in architecture, design, and development
of scalable and distributed applications. He was awarded a bachelorbs degree from the
Rajasthan Technical University in computer science. With a core interest in microservices
and Spring, he also has hands-on experience in technologies such as AWS Cloud, Python,
J2EE, NodeJS, JavaScript, Angular, MongoDB, and Docker.

Currently, he works as an IoT and Cloud Architect at Intelizign Engineering Services Pune.

Packt is searching for authors like you


If you're interested in becoming an author for Packt, please visit BVUIPSTQBDLUQVCDPN and
apply today. We have worked with thousands of developers and tech professionals, just
like you, to help them share their insight with the global tech community. You can make a
general application, apply for a specific hot topic that we are recruiting an author for, or
submit your own idea.
Table of Contents
Copyright and Credits 3
Preface 1
Chapter 1: Understanding Functional Programming 8
Identifying a paradigm 9
Subdividing the procedural paradigm 10
Using the functional paradigm 11
Using a functional hybrid 14
Looking at object creation 15
The stack of turtles 16
A classic example of functional programming 17
Exploratory data analysis 20
Summary 21
Chapter 2: Introducing Essential Functional Concepts 22
First-class functions 23
Pure functions 23
Higher-order functions 24
Immutable data 25
Strict and non-strict evaluation 27
Recursion instead of an explicit loop state 29
Functional type systems 33
Familiar territory 33
Learning some advanced concepts 34
Summary 35
Chapter 3: Functions, Iterators, and Generators 36
Writing pure functions 37
Functions as first-class objects 39
Using strings 41
Using tuples and named tuples 42
Using generator expressions 44
Exploring the limitations of generators 46
Combining generator expressions 48
Cleaning raw data with generator functions 49
Using lists, dicts, and sets 50
Using stateful mappings 54
Using the bisect module to create a mapping 56
Using stateful sets 58
Table of Contents

Summary 58
Chapter 4: Working with Collections 60
An overview of function varieties 61
Working with iterables 61
Parsing an XML file 63
Parsing a file at a higher level 65
Pairing up items from a sequence 67
Using the iter() function explicitly 70
Extending a simple loop 71
Applying generator expressions to scalar functions 74
Using any() and all() as reductions 76
Using len() and sum() 79
Using sums and counts for statistics 79
Using zip() to structure and flatten sequences 82
Unzipping a zipped sequence 84
Flattening sequences 84
Structuring flat sequences 86
Structuring flat sequences – an alternative approach 88
Using reversed() to change the order 89
Using enumerate() to include a sequence number 90
Summary 91
Chapter 5: Higher-Order Functions 92
Using max() and min() to find extrema 93
Using Python lambda forms 97
Lambdas and the lambda calculus 98
Using the map() function to apply a function to a collection 99
Working with lambda forms and map() 100
Using map() with multiple sequences 101
Using the filter() function to pass or reject data 103
Using filter() to identify outliers 104
The iter() function with a sentinel value 105
Using sorted() to put data in order 106
Writing higher-order functions 108
Writing higher-order mappings and filters 108
Unwrapping data while mapping 110
Wrapping additional data while mapping 112
Flattening data while mapping 114
Structuring data while filtering 116
Writing generator functions 117
Building higher-order functions with callables 120
Assuring good functional design 121
Review of some design patterns 123

[ ii ]
Table of Contents

Summary 124
Chapter 6: Recursions and Reductions 126
Simple numerical recursions 127
Implementing tail-call optimization 128
Leaving recursion in place 129
Handling difficult tail-call optimization 130
Processing collections through recursion 131
Tail-call optimization for collections 132
Reductions and folding a collection from many items to one 134
Group-by reduction from many items to fewer 136
Building a mapping with Counter 137
Building a mapping by sorting 138
Grouping or partitioning data by key values 140
Writing more general group-by reductions 143
Writing higher-order reductions 144
Writing file parsers 146
Parsing CSV files 148
Parsing plain text files with headers 150
Summary 153
Chapter 7: Additional Tuple Techniques 154
Using tuples to collect data 155
Using named tuples to collect data 157
Building named tuples with functional constructors 160
Avoiding stateful classes by using families of tuples 161
Assigning statistical ranks 165
Wrapping instead of state changing 167
Rewrapping instead of state changing 168
Computing Spearman rank-order correlation 170
Polymorphism and type-pattern matching 171
Summary 178
Chapter 8: The Itertools Module 179
Working with the infinite iterators 180
Counting with count() 181
Counting with float arguments 182
Re-iterating a cycle with cycle() 184
Repeating a single value with repeat() 186
Using the finite iterators 187
Assigning numbers with enumerate() 188
Running totals with accumulate() 190
Combining iterators with chain() 191
Partitioning an iterator with groupby() 192
Merging iterables with zip_longest() and zip() 194
Filtering with compress() 194

[ iii ]
Table of Contents

Picking subsets with islice() 196


Stateful filtering with dropwhile() and takewhile() 197
Two approaches to filtering with filterfalse() and filter() 198
Applying a function to data via starmap() and map() 199
Cloning iterators with tee() 201
The itertools recipes 201
Summary 203
Chapter 9: More Itertools Techniques 205
Enumerating the Cartesian product 206
Reducing a product 206
Computing distances 208
Getting all pixels and all colors 210
Performance analysis 212
Rearranging the problem 214
Combining two transformations 215
Permuting a collection of values 216
Generating all combinations 218
Recipes 220
Summary 221
Chapter 10: The Functools Module 222
Function tools 223
Memoizing previous results with lru_cache 223
Defining classes with total ordering 225
Defining number classes 228
Applying partial arguments with partial() 230
Reducing sets of data with the reduce() function 231
Combining map() and reduce() 232
Using the reduce() and partial() functions 234
Using the map() and reduce() functions to sanitize raw data 235
Using the groupby() and reduce() functions 236
Summary 239
Chapter 11: Decorator Design Techniques 241
Decorators as higher-order functions 241
Using the functools update_wrapper() functions 246
Cross-cutting concerns 246
Composite design 247
Preprocessing bad data 249
Adding a parameter to a decorator 251
Implementing more complex decorators 253
Complex design considerations 254
Summary 258

[ iv ]
Table of Contents

Chapter 12: The Multiprocessing and Threading Modules 259


Functional programming and concurrency 260
What concurrency really means 261
The boundary conditions 261
Sharing resources with process or threads 262
Where benefits will accrue 263
Using multiprocessing pools and tasks 264
Processing many large files 264
Parsing log files – gathering the rows 266
Parsing log lines into namedtuples 267
Parsing additional fields of an Access object 270
Filtering the access details 273
Analyzing the access details 275
The complete analysis process 276
Using a multiprocessing pool for concurrent processing 277
Using apply() to make a single request 280
Using the map_async(), starmap_async(), and apply_async() functions 280
More complex multiprocessing architectures 281
Using the concurrent.futures module 282
Using concurrent.futures thread pools 282
Using the threading and queue modules 283
Designing concurrent processing 284
Summary 286
Chapter 13: Conditional Expressions and the Operator Module 287
Evaluating conditional expressions 288
Exploiting non-strict dictionary rules 289
Filtering true conditional expressions 291
Finding a matching pattern 292
Using the operator module instead of lambdas 293
Getting named attributes when using higher-order functions 295
Starmapping with operators 296
Reducing with operator module functions 298
Summary 299
Chapter 14: The PyMonad Library 301
Downloading and installing 301
Functional composition and currying 302
Using curried higher-order functions 304
Currying the hard way 306
Functional composition and the PyMonad * operator 307
Functors and applicative functors 308
Using the lazy List() functor 310
Monad bind() function and the >> operator 313
Implementing simulation with monads 314

[v]
Table of Contents

Additional PyMonad features 318


Summary 319
Chapter 15: A Functional Approach to Web Services 320
The HTTP request-response model 321
Injecting state through cookies 323
Considering a server with a functional design 324
Looking more deeply into the functional view 324
Nesting the services 325
The WSGI standard 326
Throwing exceptions during WSGI processing 329
Pragmatic WSGI applications 331
Defining web services as functions 331
Creating the WSGI application 332
Getting raw data 335
Applying a filter 337
Serializing the results 337
Serializing data into JSON or CSV formats 339
Serializing data into XML 340
Serializing data into HTML 341
Tracking usage 343
Summary 344
Chapter 16: Optimizations and Improvements 346
Memoization and caching 347
Specializing memoization 348
Tail recursion optimizations 350
Optimizing storage 352
Optimizing accuracy 353
Reducing accuracy based on audience requirements 353
Case study–making a chi-squared decision 354
Filtering and reducing the raw data with a Counter object 355
Reading summarized data 357
Computing sums with a Counter object 358
Computing probabilities from Counter objects 360
Computing expected values and displaying a contingency table 361
Computing the chi-squared value 363
Computing the chi-squared threshold 364
Computing the incomplete gamma function 365
Computing the complete gamma function 368
Computing the odds of a distribution being random 369
Functional programming design patterns 371
Summary 373
Other Books You May Enjoy 375

[ vi ]
Table of Contents

Index 378

[ vii ]
Preface
Functional programming offers a variety of techniques for creating succinct and expressive
software. While Python is not a purely functional programming language, we can do a
great deal of functional programming in Python.

Python has a core set of functional programming features. This lets us borrow many design
patterns and techniques from other functional languages. These borrowed concepts can lead
us to create succinct and elegant programs. Python's generator expressions, in particular,
negate the need to create large in-memory data structures, leading to programs that may
execute more quickly because they use fewer resources.

We canbt easily create purely functional programs in Python. Python lacks a number of
features that would be required for this. We donbt have unlimited recursion, for example,
we donbt have lazy evaluation of all expressions, and we donbt have an optimizing compiler.

There are several key features of functional programming languages that are available in
Python. One of the most important ones is the idea of functions being first-class
objects. Python also offers a number of higher-order functions. The built-in NBQ ,
GJMUFS , and GVODUPPMTSFEVDF functions are widely used in this role, and less-
obvious are functions such as TPSUFE , NJO , and NBY .

Webll look at the core features of functional programming from a Python point of view. Our
objective is to borrow good ideas from functional programming languages and use those
ideas to create expressive and succinct applications in Python.

Who this book is for


This book is for programmers who want to create succinct, expressive Python programs by
borrowing techniques and design patterns from functional programming languages. Some
algorithms can be expressed elegantly in a functional style; we cancand shouldcadapt
this to make Python programs more readable and maintainable.

In some cases, a functional approach to a problem will also lead to extremely high-
performance algorithms. Python makes it too easy to create large intermediate data
structures, tying up memory (and processor time.) With functional programming design
patterns, we can often replace large lists with generator expressions that are equally
expressive but take up much less memory and run much more quickly.
Preface

What this book covers


$IBQUFS, Understanding Functional Programming, introduces some of the techniques that
characterize functional programming. Webll identify some of the ways to map those features
to Python. Finally, webll also address some ways that the benefits of functional
programming accrue when we use these design patterns to build Python applications.

$IBQUFS, Introducing Essential Functional Concepts, delves into six central features of the
functional programming paradigm. Webll look at each in some detail to see how theybre
implemented in Python. Webll also point out some features of functional languages that
donbt apply well to Python. In particular, many functional languages have complex type-
matching rules required to support compiling and optimizing.

$IBQUFS, Functions, Iterators, and Generators, will show how to leverage immutable Python
objects, and generator expressions adapt functional programming concepts to the Python
language. Webll look at some of the built-in Python collections and how we can leverage
them without departing too far from functional programming concepts.

$IBQUFS, Working with Collections, shows how you can use a number of built-in Python
functions to operate on collections of data. This chapter will focus on a number of relatively
simple functions, such as BOZ and BMM , which will reduce a collection of values to a
single result.

$IBQUFS, Higher-Order Functions, examines the commonly-used higher-order functions


such as NBQ and GJMUFS . It also shows a number of other functions that are also
higher-order functions as well as how we can create our own higher-order functions.

$IBQUFS, Recursions and Reductions, teaches how to design an algorithm using recursion
and then optimize it into a high-performance GPS loop. Webll also look at some other
reductions that are widely used, including DPMMFDUJPOT$PVOUFS .

$IBQUFS, Additional Tuple Techniques, showcases a number of ways that we can use
immutable tuples (and namedtuples) instead of stateful objects. Immutable objects have a
much simpler interfacecwe never have to worry about abusing an attribute and setting an
object into some inconsistent or invalid state.

$IBQUFS, The Itertools Module, examines a number of functions in this standard library
module. This collection of functions simplifies writing programs that deal with collections
or generator functions.

[2]
Preface

$IBQUFS, More Itertools Techniques, covers the combinatoric functions in the itertools
module. These functions are somewhat less useful. This chapter includes some examples
that illustrate ill-considered use of these functions and the consequences of combinatoric
explosion.

$IBQUFS, The Functools Module, focuses on how to use some of the functions in this
module for functional programming. A few functions in this module are more appropriate
for building decorators, and they are left for $IBQUFS, Decorator Design Techniques. The
other functions, however, provide several more ways to design and implement function
programs.

$IBQUFS, Decorator Design Techniques, looks at how you can look at a decorator as a way
to build a composite function. While there is considerable flexibility here, there are also
some conceptual limitations: webll look at ways that overly-complex decorators can become
confusing rather than helpful.

$IBQUFS, The Multiprocessing and Threading Modules, points out an important


consequence of good functional design: we can distribute the processing workload. Using
immutable objects means that we canbt corrupt an object because of poorly-synchronized
write operations.

$IBQUFS, Conditional Expressions and the Operator Module, lists some ways to break out of
Pythonbs strict order of evaluation. There are limitations to what we can achieve here. Webll
also look at the operator module and how this can lead to slight clarification of some simple
kinds of processing.

$IBQUFS, The PyMonad Library, examines some of the features of the PyMonad library.
This provides some additional functional programming features. It also provides a way to
learn more about monads. In some functional languages, monads are an important way to
force a particular order for operations that might get optimized into an undesirable order.
Since Python already has strict ordering of f expressions and statements, the monad feature
is more instructive than practical.

$IBQUFS, A Functional Approach to Web Services, shows how we can think of web services
as a nested collection of functions that transform a request into a reply. Webll see ways to
leverage functional programming concepts for building responsive, dynamic web content.

$IBQUFS, Optimizations and Improvements, includes some additional tips on performance


and optimization. Webll emphasize techniques such as memoization, because theybre easy to
implement and cancin the right contextcyield dramatic performance improvements.

[3]
Preface

To get the most out of this book


This book presumes some familiarity with Python 3 and general concepts of application
development. We wonbt look deeply at subtle or complex features of Python; webll avoid
much consideration of the internals of the language.

Webll presume some familiarity with functional programming. Since Python is not a
functional programming language, we canbt dig deeply into functional concepts. Webll pick
and choose the aspects of functional programming that fit well with Python and leverage
just those that seem useful.

Some of the examples use exploratory data analysis (EDA) as a problem domain to show
the value of functional programming. Some familiarity with basic probability and statistics
will help with this. There are only a few examples that move into more serious data science.

Youbll need to have Python 3.6 installed and running. For more information on Python, visit
IUUQXXXQZUIPOPSH. The examples all make extensive use of type hints, which means
that the latest version of mypy must be installed as well.

Check out IUUQTQZQJQZUIPOPSHQZQJNZQZ for the latest version of mypy.

Examples in $IBQUFS, More Itertools Techniques, use PIL and Beautiful Soup 4. The Pillow
fork of the original PIL library works nicely; refer to IUUQTQZQJQZUIPOPSHQZQJ
1JMMPX and IUUQTQZQJQZUIPOPSHQZQJCFBVUJGVMTPVQ.

Examples in $IBQUFS, The PyMonad Library, use PyMonad; check out IUUQTQZQJ
QZUIPOPSHQZQJ1Z.POBE.

All of these packages should be installed using the following:


$ pip install pillow beautifulsoup4 PyMonad

Download the example code files


You can download the example code files for this book from your account at
XXXQBDLUQVCDPN. If you purchased this book elsewhere, you can visit
XXXQBDLUQVCDPNTVQQPSU and register to have the files emailed directly to you.

[4]
Preface

You can download the code files by following these steps:

1. Log in or register at XXXQBDLUQVCDPN.


2. Select the SUPPORT tab.
3. Click on Code Downloads & Errata.
4. Enter the name of the book in the Search box and follow the onscreen
instructions.

Once the file is downloaded, please make sure that you unzip or extract the folder using the
latest version of:

WinRAR/7-Zip for Windows


Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux

The code bundle for the book is also hosted on GitHub at IUUQTHJUIVCDPN
1BDLU1VCMJTIJOH'VODUJPOBM1ZUIPO1SPHSBNNJOH4FDPOE&EJUJPO. We also have other
code bundles from our rich catalog of books and videos available at IUUQTHJUIVCDPN
1BDLU1VCMJTIJOH. Check them out!

Conventions used
There are a number of text conventions used throughout this book.

$PEF*O5FYU: Indicates code words in text, database table names, folder names, filenames,
file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an
example: "Python has other statements, such as HMPCBM or OPOMPDBM, which modify the
rules for variables in a particular namespace."

[5]
Preface

A block of code is set as follows:


T
GPSOJOSBOHF  
JGOPSO
T O
QSJOU T

When we wish to draw your attention to a particular part of a code block, the relevant lines
or items are set in bold:
T
GPSOJOSBOHF  
JGOPSO
s += n
QSJOU T

Any command-line input or output is written as follows:


$ pip install pillow beautifulsoup4 PyMonad

Bold: Indicates a new term, an important word, or words that you see onscreen. For
example, words in menus or dialog boxes appear in the text like this. Here is an example:
"For our purposes, we will distinguish between only two of the many
paradigms: functional programming and imperative programming."

Warnings or important notes appear like this.

Tips and tricks appear like this.

Get in touch
Feedback from our readers is always welcome.

General feedback: Email GFFECBDL!QBDLUQVCDPN and mention the book title in the
subject of your message. If you have questions about any aspect of this book, please email
us at RVFTUJPOT!QBDLUQVCDPN.

[6]
Preface

Errata: Although we have taken every care to ensure the accuracy of our content, mistakes
do happen. If you have found a mistake in this book, we would be grateful if you would
report this to us. Please visit XXXQBDLUQVCDPNTVCNJUFSSBUB, selecting your book,
clicking on the Errata Submission Form link, and entering the details.

Piracy: If you come across any illegal copies of our works in any form on the Internet, we
would be grateful if you would provide us with the location address or website name.
Please contact us at DPQZSJHIU!QBDLUQVCDPN with a link to the material.

If you are interested in becoming an author: If there is a topic that you have expertise in
and you are interested in either writing or contributing to a book, please visit
BVUIPSTQBDLUQVCDPN.

Reviews
Please leave a review. Once you have read and used this book, why not leave a review on
the site that you purchased it from? Potential readers can then see and use your unbiased
opinion to make purchase decisions, we at Packt can understand what you think about our
products, and our authors can see your feedback on their book. Thank you!

For more information about Packt, please visit QBDLUQVCDPN.

[7]
1
Understanding Functional
Programming
Functional programming defines a computation using expressions and evaluation; often
these are encapsulated in function definitions. It de-emphasizes or avoids the complexity of
state change and mutable objects. This tends to create programs that are more succinct and
expressive. In this chapter, we'll introduce some of the techniques that characterize
functional programming. We'll identify some of the ways to map these features to Python.
Finally, we'll also address some ways in which the benefits of functional programming
accrue when we use these design patterns to build Python applications.

Python has numerous functional programming features. It is not a purely a functional


programming language. It offers enough of the right kinds of features that it confers the
benefits of functional programming. It also retains all the optimization power of an
imperative programming language.

We'll also look at a problem domain that we'll use for many of the examples in this book.
We'll try to stick closely to Exploratory Data Analysis (EDA) because its algorithms are
often good examples of functional programming. Furthermore, the benefits of functional
programming accrue rapidly in this problem domain.

Our goal is to establish some essential principles of functional programming. The more
serious Python code will begin in $IBQUFS, Introducing Some Functional Features.

We'll focus on Python 3.6 features in this book. However, some of the
examples might also work in Python 2.
Understanding Functional Programming Chapter 1

Identifying a paradigm
It's difficult to be definitive on the universe of programming paradigms. For our purposes,
we will distinguish between only two of the many
paradigms: functional programming and imperative programming. One important
distinguishing feature between these two is the concept of state.

In an imperative language, such as Python, the state of the computation is reflected by the
values of the variables in the various namespaces; some kinds of statements make a well-
defined change to the state by adding or changing (or even removing) a variable. A
language is imperative because each statement is a command, which changes the state
in some way.

Our general focus is on the assignment statement and how it changes the state. Python has
other statements, such as HMPCBM or OPOMPDBM, which modify the rules for variables in a
particular namespace. Statements such as EFG, DMBTT, and JNQPSU change the processing
context. Other statements such as USZ, FYDFQU, JG, FMJG, and FMTF act as guards to modify
how a collection of statements will change the computation's state. Statements such as GPS
and XIJMF, similarly, wrap a block of statements so that the statements can make repeated
changes to the state of the computation. The focus of all these various statement types,
however, is on changing the state of the variables.

Ideally, each assignment statement advances the state of the computation from an initial
condition toward the desired final outcome. This advancing the computation assertion can be
challenging to prove. One approach is to define the final state, identify a statement that will
establish this final state, and then deduce the precondition required for this final statement
to work. This design process can be iterated until an acceptable initial state is derived.

In a functional language, we replace the statecthe changing values of variablescwith a


simpler notion of evaluating functions. Each function evaluation creates a new object or
objects from existing objects. Since a functional program is a composition of functions, we
can design lower-level functions that are easy to understand, and then design higher-level
compositions that can also be easier to visualize than a complex sequence of statements.

Function evaluation more closely parallels mathematical formalisms. Because of this, we


can often use simple algebra to design an algorithm, which clearly handles the edge cases
and boundary conditions. This makes us more confident that the functions work. It also
makes it easy to locate test cases for formal unit testing.

[9]
Understanding Functional Programming Chapter 1

It's important to note that functional programs tend to be relatively succinct, expressive,
and efficient compared to imperative (object-oriented or procedural) programs. The benefit
isn't automatic; it requires a careful design. This design effort for functional programming is
often easier than for procedural programming.

Subdividing the procedural paradigm


We can subdivide imperative languages into a number of discrete categories. In this section,
we'll glance quickly at the procedural versus object-oriented distinction. What's important
here is to see how object-oriented programming is a subset of imperative programming. The
distinction between procedural and object-orientation doesn't reflect the kind of
fundamental difference that functional programming represents.

We'll use code examples to illustrate the concepts. For some, this will feel like reinventing
the wheel. For others, it provides a concrete expression of abstract concepts.

For some kinds of computations, we can ignore Python's object-oriented features and write
simple numeric algorithms. For example, we might write something like the following to
sum a range of numbers that share a common property:
T
GPSOJOSBOHF  
JGOPSO
T O
QSJOU T

The sum T includes only numbers that are multiples of three or five. We've made this
program strictly procedural, avoiding any explicit use of Python's object features. The
program's state is defined by the values of the variables T and O. The variable O takes on
values such that 1 d n < 10. As the loop involves an ordered exploration of values of O, we
can prove that it will terminate when O. Similar code would work in C or Java
language, using their primitive (non-object) data types.

We can exploit Python's Object-Oriented Programming (OOP) features and create a


similar program:
NMJTU
GPSOJOSBOHF  
JGOPSO
NBQQFOE O
QSJOU TVN N

[ 10 ]
Understanding Functional Programming Chapter 1

This program produces the same result but it accumulates a stateful collection object, N, as it
proceeds. The state of the computation is defined by the values of the variables N and O.

The syntax of NBQQFOE O and TVN N can be confusing. It causes some programmers to
insist (wrongly) that Python is somehow not purely object-oriented because it has a mixture
of the GVODUJPO and PCKFDUNFUIPE syntax. Rest assured, Python is purely object-
oriented. Some languages, such as C++, allow the use of primitive data types such as JOU,
GMPBU, and MPOH, which are not objects. Python doesn't have these primitive types. The
presence of prefix syntax, TVN N , doesn't change the nature of the language.

To be pedantic, we could fully embrace the object model, by defining a subclass of the MJTU
class. This new class will include a TVN method:
DMBTT4VNNBCMF@-JTU MJTU 
EFGTVN TFMG 
T
GPSWJOTFMG
T W
SFUVSOT

If we initialize the variable N with an instance of the 4VNNBCMF@-JTU class instead of the
MJTU method, we can use the NTVN method instead of the TVN N method. This kind
of change can help to clarify the idea that Python is truly and completely object-oriented.
The use of prefix function notation is purely syntactic sugar.

All three of these examples rely on variables to explicitly show the state of the program.
They rely on the assignment statements to change the values of the variables and advance
the computation toward completion. We can insert the BTTFSU statements throughout these
examples to demonstrate that the expected state changes are implemented properly.

The point is not that imperative programming is broken in some way. The point is that
functional programming leads to a change in viewpoint, which can, in many cases, be very
helpful. We'll show a function view of the same algorithm. Functional programming doesn't
make this example dramatically shorter or faster.

Using the functional paradigm


In a functional sense, the sum of the multiples of three and five can be defined in two parts:

The sum of a sequence of numbers


A sequence of values that pass a simple test condition, for example, being
multiples of three and five

[ 11 ]
Understanding Functional Programming Chapter 1

The sum of a sequence has a simple, recursive definition:


EFGTVNS TFR 
JGMFO TFR SFUVSO
SFUVSOTFR<> TVNS TFR<>

We've defined the sum of a sequence in two cases: the base case states that the sum of a
zero length sequence is 0, while the recursive case states that the sum of a sequence is the
first value plus the sum of the rest of the sequence. Since the recursive definition depends
on a shorter sequence, we can be sure that it will (eventually) devolve to the base case.

Here are some examples of how this function works:


>>> sumr([7, 11])
18
>>> 7+sumr([11])
18
>>> 18+sumr([])
0

The first example computes the sum of a list with multiple items. The second example
shows how the recursion rule works by adding the first item, TFR<>, to the sum of the
remaining items, TVNS TFR<> . Eventually, the computation of the result involves the
sum of an empty list, which is defined as zero.

The operator on the last line of the preceding example and the initial value of  in the base
case characterize the equation as a sum. If we change the operator to and the initial value
to , it would just as easily compute a product. We'll return to this simple idea of
generalization in the following chapters.

Similarly, a sequence of values can have a simple, recursive definition, as follows:


EFGVOUJM OGJMUFS@GVODW 
JGWOSFUVSO<>
JGGJMUFS@GVOD W SFUVSO<W> VOUJM OGJMUFS@GVODW 
FMTFSFUVSOVOUJM OGJMUFS@GVODW 

In this function, we've compared a given value, W, against the upper bound, O. If W reaches
the upper bound, the resulting list must be empty. This is the base case for the given
recursion.

[ 12 ]
Understanding Functional Programming Chapter 1

There are two more cases defined by the given GJMUFS@GVOD function. If the value of W is
passed by the GJMUFS@GVOD function, we'll create a very small list, containing one
element, and append the remaining values of the VOUJM function to this list. If the value
of W is rejected by the GJMUFS@GVOD function, this value is ignored and the result is
simply defined by the remaining values of the VOUJM function.

We can see that the value of W will increase from an initial value until it reaches O, assuring
us that we'll reach the base case soon.

Here's how we can use the VOUJM function to generate the multiples of three and five.
First, we'll define a handy MBNCEB object to filter values:
NVMU@@MBNCEBYYPSY

(We will use lambdas to emphasize succinct definitions of simple functions. Anything more
complex than a one-line expression requires the EFG statement.)

We can see how this lambda works from Command Prompt in the following example:
>>> mult_3_5(3)
True
>>> mult_3_5(4)
False
>>> mult_3_5(5)
True

This function can be used with the VOUJM function to generate a sequence of values,
which are multiples of three and five.

The VOUJM function for generating a sequence of values works as follows:


>>> until(10, lambda x: x%3==0 or x%5==0, 0)
[0, 3, 5, 6, 9]

We can use our recursive TVN function to compute the sum of this sequence of values.
The various functions such as TVN , VOUJM , and NVMU@@ are defined as simple
recursive functions. The values are computed without resorting to using intermediate
variables to store the state.

We'll return to the ideas behind this purely functional, recursive definition in several places.
It's important to note here that many functional programming language compilers can
optimize these kinds of simple recursive functions. Python can't do the same optimizations.

[ 13 ]
Understanding Functional Programming Chapter 1

Using a functional hybrid


We'll continue this example with a mostly functional version of the previous example to
compute the sum of multiples of three and five. Our hybrid functional version might look
like the following:
QSJOU TVN OGPSOJOSBOHF  JGOPSO

We've used nested generator expressions to iterate through a collection of values and
compute the sum of these values. The SBOHF  method is iterable and, consequently,
a kind of generator expression; it generates a sequence of values . The more
complex expression OGPSOJOSBOHF  JGOPSO is also an
iterable expression. It produces a set of values, . The
variable O is bound to each value, more as a way of expressing the contents of the set than
as an indicator of the state of the computation. The TVN function consumes the iterable
expression, creating a final object, 23.

The bound variable doesn't exist outside the generator expression. The
variable O isn't visible elsewhere in the program.

The JG clause of the expression can be extracted into a separate function, allowing us to
easily repurpose this for other rules. We could also use a higher-order function named
GJMUFS instead of the JG clause of the generator expression. We'll save this for $IBQUFS
, Higher-Order Functions.

The variable O in this example isn't directly comparable to the variable O in the first two
imperative examples. A GPS statement (outside a generator expression) creates a proper
variable in the local namespace. The generator expression does not create a variable in the
same way as a GPS statement does:
>>> sum(n for n in range(1, 10) if n%3==0 or n%5==0)
23
>>> n
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined

The variable O doesn't exist outside the binding in the generator expression. It doesn't
define the state of the computation.

[ 14 ]
Understanding Functional Programming Chapter 1

Looking at object creation


In some cases, it might help to look at intermediate objects as a history of the computation.
What's important is that the history of a computation is not fixed. When functions are
commutative or associative, then changes to the order of evaluation might lead to different
objects being created. This might have performance improvements with no changes to the
correctness of the results.

Consider this expression:


>>> 1+2+3+4
10

We are looking at a variety of potential computation histories with the same result. Because
the operator is commutative and associative, there are a large number of candidate
histories that lead to the same result.

Of the candidate sequences, there are two important alternatives, which are as follows:
>>> ((1+2)+3)+4
10
>>> 1+(2+(3+4))
10

In the first case, we fold in values working from left to right. This is the way Python works
implicitly. Intermediate objects 3 and 6 are created as part of this evaluation.

In the second case, we fold from right to left. In this case, intermediate objects 7 and 9 are
created. In the case of simple integer arithmetic, the two results have identical performance;
there's no optimization benefit.

When we work with something like the MJTU append, we might see some optimization
improvements when we change the association rules.

Here's a simple example:


>>> import timeit
>>> timeit.timeit("((([]+[1])+[2])+[3])+[4]")
0.8846941249794327
>>> timeit.timeit("[]+([1]+([2]+([3]+[4])))")
1.0207440659869462

In this case, there's some benefit to working from left to right.

[ 15 ]
Understanding Functional Programming Chapter 1

What's important for functional design is the idea that the operator (or BEE function)
can be used in any order to produce the same results. The operator has no hidden side
effects that restrict the way this operator can be used.

The stack of turtles


When we use Python for functional programming, we embark down a path that will
involve a hybrid that's not strictly functional. Python is not Haskell, OCaml, or Erlang. For
that matter, our underlying processor hardware is not functional; it's not even strictly
object-oriented, CPUs are generally procedural.

All programming languages rest on abstractions, libraries, frameworks and virtual


machines. These abstractions, in turn, may rely on other abstractions, libraries,
frameworks and virtual machines. The most apt metaphor is this: the world is carried on
the back of a giant turtle. The turtle stands on the back of another giant turtle. And that
turtle, in turn, is standing on the back of yet another turtle.

It's turtles all the way down.

- Anonymous

There's no practical end to the layers of abstractions.

More importantly, the presence of abstractions and virtual machines doesn't materially
change our approach to designing software to exploit the functional programming features
of Python.

Even within the functional programming community, there are both purer and less pure
functional programming languages. Some languages make extensive use of NPOBET to
handle stateful things such as file system input and output. Other languages rely on a
hybridized environment that's similar to the way we use Python. In Python, software can be
generally functional, with carefully chosen procedural exceptions.

Our functional Python programs will rely on the following three stacks of abstractions:

Our applications will be functionscall the way downcuntil we hit the objects
The underlying Python runtime environment that supports our functional
programming is objectscall the way downcuntil we hit the libraries
The libraries that support Python are a turtle on which Python stands

[ 16 ]
Another random document with
no related content on Scribd:
points into the second piece, and, holding the parts firmly with the
left hand, drive the nails into place.
68. Nailset.—Except in rough work, the nail should not be driven
entirely in with the hammer or the wood will be marred.
A nailset held as in Fig. 129 should be used to set the head of the
nail slightly below the surface of the wood—about one thirty-second
of an inch. A finger placed against the side of the nailset and allowed
to rest on the piece of wood aids greatly in guiding the set, which
otherwise might jump off the nail head when the blow is struck and
indent the wood.

Fig. 129. Fig. 130.

69. Withdrawing Nails.—Should it be necessary to withdraw a


nail, place a block of wood under the head
of the hammer, Fig. 130, to prevent marring the surface of the wood.
If the nail is a long one, the size of the block used should be
increased as the nail comes out, that the nail may not be bent.
70. The Screwdriver.—Patent ratchet and spiral screwdrivers
have come into quite common use among
workers in wood. The old style, Fig. 131, however, is much better
suited to elementary work than any of these special forms.

Fig. 131.

71. Screws.—Screws, like nails, are made entirely by machinery.


They are packed in pasteboard boxes and sold by the
gross. The size of a screw is designated by the length in inches and
the size of the wire from which it is made; thus, 1 inch No. 10 flat-
head bright screw.
The gage of wire for nails and the gage of wire for screws should
not be confused. Fig. 132 is a full-sized illustration of the gage used
for determining the size of wire for nails. The numbers apply to the
openings at the edge, not to the circular parts. The notch at No. 1 will
just slip over No. 1 wire. Fig. 135 is a full-sized illustration of a wire
gage for screws. The gage is slipped over the screw just below the
head.
Fig. 132.

Flathead screws are used for ordinary work. Roundhead screws


are used because they are more ornamental. Fig. 133. Either kind
may be made of steel or brass. Steel screws are often blued by
treating them with heat or an acid.
Fig. 133. Fig. 134.

72. Fastening with Screws.—Where two pieces of hard wood are


to be fastened with screws, a hole
just large enough to take in the shank of the screw must be bored in
the upper part. In the lower part, a hole should be bored just large
enough to take in the core of the screw snugly. Fig. 134. For flathead
screws, the hole should be countersunk so that the head may be
flush or sunk slightly below the surface of the wood. In soft woods,
the boring of a hole in the lower piece may be omitted.
Fig. 135.

73. Glue.—Nails are but seldom used in cabinet work to fasten


parts together; glue being used instead. Glue is
manufactured from the refuse parts of animals. Strippings of hide,
bone, horn, hoofs, etc., are boiled to a jelly; chemicals are added to
give it the light color. It is usually placed on the market in the form of
dry chips.
Glue pots are made double, the glue being placed in one part and
this placed in a larger one which contains water.

Fig. 136.

The glue is heated by the hot water and steam of the outer kettle.
Fig. 136.
To prepare glue, dissolve the dry chips in water. It is well to soak
them over night unless quite thin. If the glue chips are thin they may
be barely covered with water and the pot set in the outer kettle of
boiling water. Some kinds of glue require less water. The glue should
be stirred occasionally. It should be used while hot and should be
made thin enough to flow easily when applied with a brush. If the
wood is cold it will chill the glue. Best results are obtained by
warming the wood in an oven.
Prepared liquid glues, to be applied without heating, are common.
As these glues thicken with age, due to evaporation, they must be
thinned occasionally. In cold weather they chill and must be warmed
in hot water to bring them to a proper consistency.
Fig. 137.

74. Clamps.—Clamps are used in the making of a glue joint to


expel the glue from the surfaces of contact, forcing it
up into the pores of the wood or, if too much has been applied, out
on the sides of the joint. For holding small parts, the wooden hand-
screw is used, Fig. 137. To adjust this clamp, hold the handle of the
shoulder spindle firmly in the left hand and the handle of the end
spindle in the right hand; revolve them about an axis midway
between and parallel to the spindles until the approximate opening of
the jaw is obtained, Fig. 138. Place the clamp on the parts and screw
the shoulder spindle up tight, adjusting the end spindle when
necessary so that when it is tightened the jaws of the clamp shall be
parallel, Fig. 139. In taking off this clamp, the end spindle is the one
which must be released.

Fig. 138. Fig. 139.

Fig. 140 illustrates three kinds of bar clamps such as are used for
clamping wide frames and boards.
Fig. 140.

Fig. 141 illustrates a simple form of clamp which can be made by


the student himself. Two wedges to each clamp, driven in with the
hammer, supply the necessary pressure. Whenever finished
surfaces are to be clamped, blocks of wood must be placed between
them and the clamp jaws to prevent their being marred.
Fig. 141.

75. Gluing.—Where the end grain is to form part of a glue joint, it


is necessary to apply a glue size first.
This is done by filling the open grain of the end with a preliminary
coating of thin, hot glue.
Rubbed glue joints require no clamps. The edges are jointed
perfectly straight, glue is applied to each and they are then rubbed
together with as great pressure as is possible to expel the glue.
When this is properly done the pieces will hold together and may be
set away to dry. Fig. 142.
Fig. 142.
PART II.
SIMPLE JOINERY.

Chapter VIII.
Type Forms.

76. Joinery.—This term in its broader meaning refers to the art of


framing the finishing work of a house, such as doors
and windows; and to the construction of permanent fittings, such as
mantels, cupboards, linen presses, etc. Joinery as used herein refers
merely to the putting together of two or more parts, called the
members.
77. General Directions for Joinery:—Take into consideration the
direction of the grain in
planning the relative positions of the members. Make due allowance
where shrinkage is likely to be considerable.
As far as possible, plan to have the members join face to face.
Face sides are more likely to be true than are the other two surfaces
and therefore the joints are more likely to fit properly.
Make all measurements from a common starting point, as far as
practicable. Remember to keep the head of the gage, and the beam
of the trysquare against one or the other of the faces, unless there
should be special reasons for doing otherwise.
In practice it is sometimes advisable to locate the sides of a joint
by superposition rather than by measurement. Laying out by
superposition consists in placing one member upon another and
marking upon the second member the width, thickness or length of
the first. Fig. 143. Usually, it is found possible to locate and square
with knife and trysquare a line to represent one of the sides of the
joint. The first member is then held so that one of its arrises rests
upon this line, and a point is made with knife at the other arris. The
superimposed piece is then removed and a line made with knife and
try-square—not thru the mark of the knife point but inside, just
touching it.

Fig. 143. Fig. 144.

Where several members or parts are to be laid out, cut and fitted,
it is of the utmost importance that the work be done systematically.
System and power to visualize—that is, to see things in their proper
relation to one another in the finished piece—make it possible for
men to lay out and cut the members to the most intricate frames of
buildings before a single part has been put together. Lay out
duplicate parts and duplicate joints as suggested in Chapter VII,
Section 62. Where several joints of a similar size and kind are to be
fitted, mark the different parts to each joint with the same number or
letter as soon as fitted that no other member may be fitted to either
of these. Fig. 144. On small pieces, such as the stool, it is possible
to aid in visualizing by setting up the posts in the positions they are
to occupy relative to one another, marking roughly, as with a
penciled circle, the approximate location of the mortises, auger
holes, etc. The members may then be laid on the bench and
accurately marked without danger of misplacing the openings.
While the knife is used almost exclusively in laying out joints, there
are a few instances in which a pencil, if well sharpened and used
with slight pressure is preferable. To illustrate, suppose it is desired
to locate the ends of the mortises in the posts. Fig. 144. To knife
entirely across the surfaces of the four pieces and around the sides
of each as would be necessary to locate the ends of the mortises,
would injure the surfaces. Instead, pencil these lines and gage
between the pencil lines. Those parts of the pencil lines enclosed by
the gage lines—the ends of the mortises—may then be knifed, if
desired, to assist in placing the chisel for the final cut.
In sawing joints in hard wood, the saw should be made to cut
accurately to the line, Chapter II, Section 14. When working soft
wood, beginners are often permitted to leave a small margin—about
one thirty-second of an inch—between the knife and the saw kerf.
This margin is afterwards pared away with the chisel.

Fig. 145. Fig. 146.

78. Dado.—A dado, Fig. 145, is made by cutting a rectangular


groove entirely across one member into which the end
of another member fits. Dadoes are cut across the grain of the wood;
when similar openings are cut parallel to the grain, they are called
simply, grooves. Dadoes are used in the making of shelving, window
and door frames, etc.
79. Directions for Dado.—(1) Locate by means of the rule one
side of the dado and mark its position
with the point of the knife. (2) At this point, square a sharp line
across the piece with knife and trysquare. (3) By superposition,
locate and mark the second side. (4) Square these lines across the
edges of the piece a distance equal to the approximate depth of the
dado. (5) Set the gage for the required depth and gage between the
knife lines on the two edges. (6) Saw just far enough inside the knife
lines that the sides of the dado may be finished to the lines with the
chisel. Chapter II, Section 14. Saw down just to the gage lines,
watching both edges that the kerfs be not made too deep. (7) Chisel
out the waste until the bottom of the dado is smooth and true.
Chapter V, Section 47. Test the bottom as shown in Fig. 146. Two
brads are driven into a block having a straight edge until they project
a distance equal to the proposed depth of the dado. (8) Pare the
sides of the dado to the knife lines. Chapter V, Section 48. These
sides might be finished in another way, by setting a wide chisel in the
knife line and tapping it gently with a mallet. If care is taken the
successive settings of the chisel need not show.
Where the dado is to be cut on a piece narrow enough that the
saw may be made to follow the line accurately, it is considered better
practice to saw accurately to the line. Chapter II, Section 14.
80. Cross-Lap Joint.—Usually, stock for the two members of the
cross-lap joint can be best planed to width
and thickness in one piece. Place two sets of face marks on the
piece, so that there shall be one set of marks on each member after
they are separated. Two methods of making this joint are given. The
first is safer for beginners; the second, because the members cannot
be tried until the joints are completed, is an excellent test of one’s
ability. Fig. 147.
Fig. 147.

81. Directions for Cross-Lap Joint.—First Method: (1) Square


the two ends, measure from
each of these the desired length of each member, square knife lines
around, saw apart, finishing the ends square to the lines. (2)
Measure from one end of each member the required distance to the
nearer edge of the joint. Since the corresponding faces of the two
members must be on the same side of the piece when the parts are
put together, it will be necessary to lay off the groove of one member
on the face and of the other member on the side opposite the face. If
the joints are to be in the middle of each member but one
measurement need be made. Chapter VII, Section 62. (3) Square
sharp knife lines across at these points. (4) By superposition, locate
and knife the second edge of each joint. (5) If the joints are to be in
the middle of each member, before proceeding further, test to see
that the lines have been laid out properly. If the members are placed
side by side and the ends evened as in laying out in (2) above, the
lines will of necessity correspond. Turn one of the members end for
end and even the two ends; the lines ought still to correspond. If they
do not, points marked midway between the corresponding lines will
give the correct position for the new lines, Fig. 148. (6) Extend the
knife lines just made across the two adjoining surfaces of each
member. (7) Set the gage for the required depth and gage between
the knife lines on these surfaces. Tho the groove on one member is
laid out on the side opposite the face, do not make the mistake of
holding the head of the gage against other than the face. (8) Saw
accurately, Chapter II, Section 14, to the knife lines and to a depth
indicated by the gage lines. (9) Chisel out the waste stock. Chapter
V, Section 47. (10) Test as shown in Fig. 149. A well made cross-lap
joint is one in which the members can be put together with the
pressure of the hands and which will not fall apart of their own
weight. Fig. 150 shows the results of “forcing a fit.”

Fig. 148.

Fig. 149. Fig. 150.

82. Directions for Cross-Lap Joint.


—Second Method. The two members are to be planed to width and
thickness in one piece but are not to be separated until the grooves
have been laid out and cut. The grooves must be laid out by
measurement only, since superposition is impossible. The positions
of the grooves relative to the faces are, as in the first method, one on
the face and one on the side opposite. The gaging for both is done
from the faces.
83. Glue Joint.—Frequently it becomes necessary to glue
together a number of boards to make one wide
enough to meet the requirements of the work in hand. A table top is
a good illustration. A properly glued butt joint ought to be stronger
than the natural wood.
When the wood is of sufficient thickness, the joint may be
reinforced by means of dowels. The jointer should be used for
planing the edges. It is extremely difficult to prepare edges for glue
joints with the shorter planes. The jack plane should be used to
rough off the edges and prepare them for the jointer.

Fig. 151.

84. Directions for Glue Joint.—(1) If the boards are in the rough,
plane one surface of each true and
out of wind. (2) Pencil the face marks upon these surfaces and
indicate in some way the direction of the surface grain as well. Later,
it will be necessary to plane both pieces at once in surfacing over the
joints, and unless the parts are fitted with proper regard to the grain,
it will be impossible to plane one without roughing up the other. Then
too, the faces should be so selected that the warpage of one shall
counteract the warpage of the other. Fig. 151 shows the manner of
placing the pieces. Observe the rings of growth. Chapter 12. (3) Joint
one edge of each piece straight and square. The final plane strokes
must be taken the full length of the board and the plane-iron must be
set very shallow. Since the shrinkage is more at the ends than in the
middle, sometimes the middles of long boards are planed just a
shaving or two lower than the ends. (4) Place one of the boards in
the vise, jointed edge up, and place the other board in position on it.
Four tests are commonly used: First, placing the eye on a level with
the joint and looking toward the light, Fig. 152; second, tapping the
under board lightly to see if the top board “rocks”; third, sliding the
top board lengthwise slowly to “feel” for suction; fourth, holding a
straightedge as shown in Fig. 153 to see that the faces lie in the
same plane. (5) Glue the edges, Fig. 154. Work rapidly but carefully.
(6) Place the parts in the clamps and set away to dry; ten hours is
usually long enough. Keep the faces as even as possible in applying
the clamps. (7) When the glue has hardened the clamps may be
removed, the surplus glue scraped off and the parts treated as one
piece in squaring it up.

Fig. 152. Fig. 153.


Fig. 154.

85. Doweling.—Dowels are small wooden pins used in joining


parts together. Dowels can be bought ready made
in a variety of sizes. If desired short dowels may be made as follows:
(1) Select straight-grained strong wood—beech, birch or oak; waste
wood can usually be found that will do. (2) Split, not saw, these
pieces roughly to square prisms. The blocks from which they are to
be split should not be over eight or ten inches long to work well. (3)
Plane off the irregularities, roughly rounding the pieces to size. (4)
Point the ends slightly and drive the pieces thru a dowel plate. Fig.
155. The pegs should be driven thru the larger hole first. The holes
of the dowel plate are larger in diameter on one side of the plate than
on the other to give clearance to the peg as it is driven thru.

You might also like