SlideShare a Scribd company logo
Introducing Erlang Getting Started In Functional
Programming 2nd Edition St Laurent download
https://ebookbell.com/product/introducing-erlang-getting-started-
in-functional-programming-2nd-edition-st-laurent-55381340
Explore and download more ebooks at ebookbell.com
Here are some recommended products that we believe you will be
interested in. You can click the link to download.
Introducing Erlang Getting Started In Functional Programming 2 Early
Release Simon St Laurent
https://ebookbell.com/product/introducing-erlang-getting-started-in-
functional-programming-2-early-release-simon-st-laurent-5713014
Introducing Erlang Simon St Laurent
https://ebookbell.com/product/introducing-erlang-simon-st-
laurent-4081446
Introducing Erlang Simon St Laurent
https://ebookbell.com/product/introducing-erlang-simon-st-
laurent-170540754
Introducing Islam A Graphic Guide Graphic Guides 2nd Revised Edition
2nd Ziauddin Sardar
https://ebookbell.com/product/introducing-islam-a-graphic-guide-
graphic-guides-2nd-revised-edition-2nd-ziauddin-sardar-48359932
Introducing Comparative Politics 5th Edition Stephen Walter Orvis
https://ebookbell.com/product/introducing-comparative-politics-5th-
edition-stephen-walter-orvis-44864186
Introducing Financial Mathematics Theory Binomial Models And
Applications Chapman And Hallcrc Financial Mathematics Series 1st
Edition Mladen Victor Wickerhauser
https://ebookbell.com/product/introducing-financial-mathematics-
theory-binomial-models-and-applications-chapman-and-hallcrc-financial-
mathematics-series-1st-edition-mladen-victor-wickerhauser-44875460
Introducing Anthropology Laura Pountney Tomislav Maric
https://ebookbell.com/product/introducing-anthropology-laura-pountney-
tomislav-maric-46096168
Introducing Philosophy For Canadians A Text With Integrative Readings
1st Edition Robert C Solomon
https://ebookbell.com/product/introducing-philosophy-for-canadians-a-
text-with-integrative-readings-1st-edition-robert-c-solomon-46248138
Introducing Bronfenbrenner A Guide For Practitioners And Students In
Early Years Education 2nd Edition Nirn Hayes
https://ebookbell.com/product/introducing-bronfenbrenner-a-guide-for-
practitioners-and-students-in-early-years-education-2nd-edition-nirn-
hayes-46496164
Introducing Erlang Getting Started In Functional Programming 2nd Edition St Laurent
Introducing Erlang Getting Started In Functional Programming 2nd Edition St Laurent
Introducing Erlang Getting Started In Functional Programming 2nd Edition St Laurent
Simon St. Laurent
Introducing Erlang
Boston Farnham Sebastopol Tokyo
Beijing Boston Farnham Sebastopol Tokyo
Beijing
978-1-491-97330-1
[FILL IN]
Introducing Erlang
by Simon St. Laurent
Copyright © 2017 O’Reilly Media. All rights reserved.
Printed in the United States of America.
Published by O’Reilly Media, Inc. , 1005 Gravenstein Highway North, Sebastopol, CA 95472.
O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are
also available for most titles ( http://oreilly.com/safari ). For more information, contact our corporate/
institutional sales department: 800-998-9938 or corporate@oreilly.com .
Editor: Dawn Schanafelt
Production Editor: FILL IN PRODUCTION EDI‐
TOR
Copyeditor: FILL IN COPYEDITOR
Proofreader: FILL IN PROOFREADER
Indexer: FILL IN INDEXER
Interior Designer: David Futato
Cover Designer: Karen Montgomery
Illustrator: Rebecca Demarest
January -4712: Second Edition
Revision History for the Second Edition
2017-01-09: First Early Release
See http://oreilly.com/catalog/errata.csp?isbn=9781491973301 for release details.
The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Introducing Erlang, the cover image,
and related trade dress are trademarks of O’Reilly Media, Inc.
While the publisher and the author(s) have used good faith efforts to ensure that the information and
instructions contained in this work are accurate, the publisher and the author(s) disclaim all responsibil‐
ity for errors or omissions, including without limitation responsibility for damages resulting from the use
of or reliance on this work. Use of the information and instructions contained in this work is at your own
risk. If any code samples or other technology this work contains or describes is subject to open source
licenses or the intellectual property rights of others, it is your responsibility to ensure that your use
thereof complies with such licenses and/or rights.
Table of Contents
Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
1. Getting Comfortable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Installation 1
Firing It Up 2
First Steps: The Shell 2
Moving through Text 3
Moving through History 3
Moving through Files 3
Doing Something 4
Calling Functions 5
Numbers in Erlang 6
Working with Variables in the Shell 8
Seeing Your Bound Variables 9
Clearing Bound Variables in the Shell 9
2. Functions and Modules. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Fun with fun 11
Defining Modules 13
From Module to Fun 15
Functions and Variable Scope 16
Module Directives 16
Documenting Code 18
Documenting Modules 19
Documenting Functions 20
Documenting Your Application 22
iii
3. Atoms, Tuples, and Pattern Matching. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Atoms 25
Pattern Matching with Atoms 25
Atomic Booleans 27
Guards 28
Underscoring That You Don’t Care 30
Adding Structure: Tuples 32
Pattern Matching with Tuples 33
Processing Tuples 33
4. Logic and Recursion. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Logic Inside of Functions 37
Evaluating Cases 37
If This, Then That 40
Variable Assignment in case and if Constructs 42
The Gentlest Side Effect: io:format 43
Simple Recursion 44
Counting Down 45
Counting Up 46
Recursing with Return Values 47
5. Communicating with Humans. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Strings 53
Asking Users for Information 55
Gathering Terms 56
Gathering Characters 59
Reading Lines of Text 60
6. Lists. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
List Basics 65
Splitting Lists into Heads and Tails 67
Processing List Content 68
Creating Lists with Heads and Tails 70
Mixing Lists and Tuples 72
Building a List of Lists 73
7. Higher-Order Functions and List Comprehensions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Simple Higher-Order Functions 77
Creating New Lists with Higher-Order Functions 79
Reporting on a List 79
Running List Values Through a Function 80
Filtering List Values 81
iv | Table of Contents
Beyond List Comprehensions 81
Testing Lists 82
Splitting Lists 82
Folding Lists 83
8. Playing with Processes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
The Shell Is a Process 87
Spawning Processes from Modules 89
Lightweight Processes 92
Registering a Process 92
When Processes Break 94
Processes Talking Amongst Themselves 95
Watching Your Processes 97
Breaking Things and Linking Processes 101
9. Exceptions, Errors, and Debugging. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Flavors of Errors 109
Catching Runtime Errors as They Happen 110
Raising Exceptions with throw 112
Logging Progress and Failure 113
Debugging through a GUI 114
Tracing Messages 123
Watching Function Calls 126
10. Storing Structured Data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Mapping Your Data 129
From Tuples to Records 130
Setting Up Records 131
Creating and Reading Records 132
Using Records in Functions and Modules 134
Storing Records in Erlang Term Storage 136
Creating and Populating a Table 137
Simple Queries 143
A Key Feature: Overwriting Values 143
ETS Tables and Processes 144
Next Steps 146
Storing Records in Mnesia 146
Starting up Mnesia 147
Creating Tables 148
Reading Data 150
Query List Comprehensions 152
Table of Contents | v
11. Getting Started with OTP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Creating Services with gen_server 158
A Simple Supervisor 163
Packaging an Application 168
12. Next Steps Through Erlang. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Moving Beyond the Erlang Shell 173
Distributed Computing 174
Processing Binary Data 174
Input and Output 174
Testing, Analyzing, and Refactoring 174
Networking and the Web 175
Data Storage 175
Extending Erlang 176
Languages Built on Erlang 176
Community 176
Sharing the Gospel of Erlang 177
A. An Erlang Parts Catalog. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
B. OTP Templates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
vi | Table of Contents
Preface
Erlang has long been a mysterious dark corner of the programming universe, visited
mostly by developers who need extreme reliability or scalability and people who want
to stretch their brains.
Developed at Ericsson to serve on telephone switching equipment, it seemed like a
strangely special-purpose language until recently, when our computer and network
architectures came to look a lot more like massively parallel telephone-switching
equipment. Thanks to the rise of NoSQL data stores CouchDB and Riak, you may
already be using Erlang without realizing it, and Erlang is moving out into many
more fields.
Erlang provides a short path from discipline to resilience. The decisions made by the
creators of the language let the Erlang environment seamlessly scale and handle fail‐
ure in ways that other environments have to manage by adding ever more infrastruc‐
ture. In my utterly biased opinion, any application that needs to run for a long time
and scale to many interactions should be built in Erlang (or its more recent cousin
Elixir).
Exploring Erlang, if you come from pretty much any background other than func‐
tional programming, will require you to clear your mind of many techniques used in
other programming languages. Forget classes, forget variables that change values—
even forget the conventions of variable assignment.
Instead, you’re going to have to think about pattern matching, message passing, and
establishing pathways for data rather than telling it where to go. Erlang programming
can feel like making a key whose teeth set the tumblers on a lock just right for the key
to pass, or playing pachinko and watching the balls fall through a maze.
Sound strange? It is—but also enjoyable, powerful, and fun.
My first explorations of Erlang confused me and excited me at the same time. I’d had
some experience with what I’d called “invariant variables,” variables that can be bound
vii
to a value only once, in XSLT. That created a lot of headaches for me until I realized I
was coming at the problems all wrong, and then it suddenly made sense.
Who This Book Is For
This book is mostly for people who’ve been programming in other languages but
want to look around. Maybe you’re being very practical, and Erlang’s distributed
model and the resulting scale and resilience advantages appeal to you. Maybe you
want to see what this “functional programming” stuff is all about. Or maybe you’re
just going for a hike, taking your mind to a new place.
I suspect that functional programming is more approachable as a first language,
before you’ve learned to program in other paradigms. However, getting started in
Erlang—sometimes even just installing it—requires a fair amount of computing skill.
If you’re a complete newcomer to programming, welcome, but there will be a few
challenges along the way.
Who This Book Is Not For
This book is not for people in a hurry to get things done.
If you already know Erlang, you don’t likely need this book unless you’re looking for a
slow brush-up.
If you’re already familiar with functional languages, you may find the pacing of this
“Gentle Introduction” hopelessly slow. Definitely feel welcome to jump to another
book that moves faster if you get bored. Come back if you find the others go too fast,
and feel welcome to use this as a companion guide or reference with the other books.
What This Book Will Do For You
In Seven Languages in Seven Weeks, Bruce Tate suggests that “Erlang makes hard
things easy and easy things hard.” This book will get you through the “easy things
hard” part, and show you a bit of the promised land of “hard things easy.”
In practical terms, you’ll learn to write simple Erlang programs. You’ll understand
why Erlang makes it easier to build resilient programs that can scale up and down
with ease. Perhaps most importantly, you’ll be able to read other Erlang resources that
assume a fair amount of experience and make sense of them.
In more theoretical terms, you’ll get to know functional programming. You’ll learn
how to design programs around message-passing and recursion, creating process-
oriented programs focused more on data flow.
You’ll also be better prepared to read other books and conversations about Erlang.
viii | Preface
How This Book Works
This book tries to tell a story with Erlang. You’ll probably get the most out of it if you
read it in order at least the first time, though you’re always welcome to come back to
find whatever bits and pieces you need.
You’ll start by getting Erlang installed and running, and looking around its shell.
You’ll spend a lot of time in the shell, so get cozy. Next, you’ll start loading code into
the shell to make it easier to write programs, and you’ll learn how to call that code
and mix it up.
You’ll take a close look at numbers because they’re an easy place to get familiar with
Erlang’s basic structures. Then you’ll learn about atoms, pattern-matching, and
guards—the likely foundations of your program structure. After that you’ll learn
about strings, lists, and the recursion at the heart of much Erlang processing. Once
you’ve gone a few million recursions down and back, it’ll be time to look at processes,
a key part of Erlang that relies on the message-passing model to support concurrency
and resilience.
Once you have the foundation set, you can take a closer look at debugging and data
storage, and then get a quick look at a toolset that is likely at the heart of your long-
term development with Erlang: the Open Telecom Platform (OTP), which is about
much much more than telephones.
Some people want to learn programming languages through a dictionary. Here’s a list
of operators, here’s a list of control structures, these are the datatypes—and then
smash them together. Those lists are here, but they’re in Appendix A, not the main
flow of the book.
Many of the examples are built on the same foundation. While you will probably be
tired of falling objects by the end of the book, staying with a small set of examples
makes it easier to introduce new features rather than explaining endless projects.
The main point you should get from this book is that you can program in Erlang. If
you don’t get that, let me know!
Etudes for Erlang
While I was writing this book, J. David Eisenberg was developing a broad set of exer‐
cises to accompany it. They proved comprehensive enough to become a separate
project, which you can find (for free on the Web) at Chimera.
The etudes are structured to match this book, but hopefully will grow over time to
cover a larger scope than this book does. You’ll probably get the most out of them if
you explore them each time you finish a chapter, but they’re also great for general
review and to test your understanding.
Preface | ix
Why I Wrote This Book
I’m not an Erlang expert hoping to create more Erlang experts to get a lot of work
done.
I’m a writer and developer who encountered Erlang, thought it was the programming
language I’d been seeking for a long time, and felt compelled to share some of that.
I’m hoping that the path I followed will work for other people, probably with varia‐
tions, and that a book written from a beginner’s perspective (and vetted by experts)
would help more people find and enjoy Erlang.
Other Resources
This book may not be the best way for you to learn Erlang. It all depends on what you
want to learn and why.
If your primary interest in learning Erlang is to break out of a programming rut, you
should explore Bruce Tate’s wild tour of Seven Languages in Seven Weeks (Pragmatic
Publishers), which explores Ruby, Io, Prolog, Scala, Erlang, Clojure, and Haskell.
Erlang gets only (an excellent) 37 pages, but that might be what you want.
For an online experience (now also in print from No Starch Books) with more snark
and funnier illustrations, you should explore Fred Hebert’s Learn You Some Erlang for
Great Good!, at http://learnyousomeerlang.com/. While much longer than Tate’s telling,
it certainly moves faster and may feel more like an experienced programmer’s guide
to Erlang.
The two classic general books on Erlang are the similarly-titled Programming Erlang
(Pragmatic Publishers) by Erlang creator Joe Armstrong, and Erlang Programming
(O’Reilly) by Francesco Cesarini and Simon Thompson. They cover a lot of similar
and overlapping terrain, and both may be good places to start if this book moves too
slowly or you need more reference material. Erlang Programming goes further into
what you can do with Erlang, whereas Programming Erlang provides a lot of detail on
setting up an Erlang programming environment.
On the more advanced side, Erlang and OTP in Action (Manning) by Martin Logan,
Eric Merritt, and Richard Carlsson, opens with a high-speed 72-page introduction to
Erlang and then spends most of its time applying the Open Telecom Platform,
Erlang’s framework for building upgradeable and maintainable concurrent applica‐
tions. More recently, Designing for Scalability with Erlang/OTP (O’Reilly), by Fran‐
cesco Cesarini and Steve Vinoski, focuses squarely on building large and resilient
applications with Erlang’s OTP libraries.
At the end of each chapter of this book, you’ll find a note pointing to relevant infor‐
mation on the chapter’s content in other Erlang-focused books. Hopefully they’ll help
x | Preface
you move quickly among them if you use this book as a companion to the rest of the
growing Erlang library.
If you want to focus on connecting Erlang to the Web, you should definitely also
explore Building Erlang Web Applications (O’Reilly) by Zachary Kessin.
You’ll also want to visit the main Erlang website, http://www.erlang.org/, for updates,
downloads, documentation, and more.
Are You Sure You Want Erlang?
Though they’ve been obscure for a long time, there’s a crowd of functional languages
rising into greater popularity.
Five of them in particular—Clojure, Scala, F#, Haskell, and Elixir—may be more
appealing than Erlang if you have specific needs.
• Clojure and Scala run on the Java Virtual Machine (JVM), making them insanely
portable, and they have access to Java libraries as a result. ClojureScript does the
same with JavaScript, too. (Erjang makes it possible to run Erlang on the JVM,
but it’s not a core part of the language.)
• F# runs on the .NET Common Language Runtime (CLR), making it very
portable in the Microsoft ecosystem, and again, has access to .NET libraries.
• Haskell doesn’t run on a virtual machine, but also offers a stronger type system
and a different kind of discipline (and laziness).
• Elixir is built on the same foundations as Erlang, and works well with Erlang, but
has a Ruby-like syntax with strong support for metaprogramming.
Personally, I got my start with these concepts in XSLT. It’s a very different kind of lan‐
guage meant for a specific domain of document transformation, but many of the
same ideas flow through it.
You don’t, of course, have to decide if Erlang is your life’s dream now. You can learn
concepts in Erlang and apply them elsewhere if it turns out to be a better idea for
your work.
Erlang Will Change You
Before you go deeper, you should know that working in Erlang may irrevocably
change the way you look at programs. Its combination of functional code, process-
orientation, and distributed development may seem alien at first. However, once it
sinks in, Erlang can transform the way you solve problems, and potentially make it
difficult to return to other languages, environments, and programming cultures.
Preface | xi
Conventions Used in This Book
The following typographical conventions are used in this book:
Italic
Indicates new terms, URLs, email addresses, filenames, and file extensions.
Constant width
Used for program listings, as well as within paragraphs to refer to program ele‐
ments such as variable or function names, statements, and keywords.
Constant width bold
Shows commands or other text that should be typed literally by the user.
Constant width italic
Shows text that should be replaced with user-supplied values or by values deter‐
mined by context.
This icon signifies a tip, suggestion, or general note.
This icon indicates a warning or caution.
A Note on Erlang Syntax
Erlang’s syntax seems to be a sticking point for a lot of people. It doesn’t look like the
C family of languages. Punctuation is different and capitalization matters. Periods
even get used as conclusions rather than connectors!
To me, Erlang syntax mostly feels natural, and I’m especially happy that it’s different
from the other languages I typically use. I make a lot fewer mix-ups that way.
Rather than dwell on syntax, I’ve chosen just to present it as it is. Comparing it to
other languages doesn’t seem likely to be helpful, especially when different readers
may come from different programming backgrounds. Hopefully you will find Erlang
syntax as pleasant as I do. If you just can’t get past it, you may want to try Elixir
instead.
xii | Preface
Using Code Examples
The examples in this book are meant to teach basic concepts in small bites. While you
may certainly borrow code and reuse it as you see fit, you won’t be able to take the
code of this book and build a stupendous application instantly (unless perhaps you
have an unusual fondness for calculating the speeds of falling objects).
The examples in this book are deliberately simple and perhaps even stupid. They
aren’t designed to dazzle or to show off, but to let you figure out how pieces fit
together in the simplest possible way. You should, however, be able to figure out the
steps you need to take to build a great application.
You can download the code from the Examples link on the book’s page at http://
oreil.ly/introducing_erlang.
This book is here to help you get your job done. In general, you may use the code in
this book in your programs and documentation. You do not need to contact us for
permission unless you are reproducing a significant portion of the code. For example,
writing a program that uses several chunks of code from this book does not require
permission. Selling or distributing a CD-ROM of examples from O’Reilly books does
require permission. Answering a question by citing this book and quoting example
code does not require permission. Incorporating a significant amount of example
code from this book into your product’s documentation does require permission.
We appreciate, but do not require, attribution. An attribution usually includes the
title, author, publisher, and ISBN. For example: "Introducing Erlang, by Simon St.Lau‐
rent (O’Reilly). Copyright 2013 Simon St.Laurent, 9781449331764.”
If you feel your use of code examples falls outside fair use or the permission given
above, feel free to contact us at permissions@oreilly.com.
Help This Book Grow
While I hope that you will enjoy reading this book and learn from it, I also hope that
you can contribute to helping other readers learn Erlang here. You can help your fel‐
low readers in a number of ways:
• If you find specific technical problems, bad explanations, or things that can be
improved, please report them through the errata system.
• If you like (or don’t like) the book, please leave reviews. The most visible places to
do so are on Amazon.com (or its international sites) and at the O’Reilly page for
the book at http://oreil.ly/introducing_erlang. Detailed explanations of what
worked and what didn’t work for you (and the broader target audience of pro‐
grammers new to Erlang) are helpful to other readers and to me.
Preface | xiii
• If you find you have much more you want to say about Erlang, please consider
sharing it, whether on the Web, in a book of your own, in training classes, or in
whatever form you find easiest.
I’ll update the book for errata, and try to address issues raised in reviews. Even once
the book is “complete,” I may still add some extra pieces to it. If you purchased it as
an ebook, you’ll receive these updates for free at least up to the point where it’s time
for a whole new edition. I don’t expect that new edition declaration to come quickly,
however, unless the Erlang world changes substantially.
Hopefully this book will engage you enough to make you consider sharing.
Please Use It For Good
I’ll let you determine what “good” means, but think about it. Please try to use Erlang’s
power for projects that make the world a better place, or at least not a worse place.
Safari® Books Online
Safari Books Online is an on-demand digital library that deliv‐
ers expert content in both book and video form from the
world’s leading authors in technology and business.
Technology professionals, software developers, web designers, and business and crea‐
tive professionals use Safari Books Online as their primary resource for research,
problem solving, learning, and certification training.
Safari Books Online offers a range of plans and pricing for enterprise, government,
education, and individuals.
Members have access to thousands of books, training videos, and prepublication
manuscripts in one fully searchable database from publishers like O’Reilly Media,
Prentice Hall Professional, Addison-Wesley Professional, Microsoft Press, Sams, Que,
Peachpit Press, Focal Press, Cisco Press, John Wiley & Sons, Syngress, Morgan Kauf‐
mann, IBM Redbooks, Packt, Adobe Press, FT Press, Apress, Manning, New Riders,
McGraw-Hill, Jones & Bartlett, Course Technology, and hundreds more. For more
information about Safari Books Online, please visit us online.
How to Contact Us
Please address comments and questions concerning this book to the publisher:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
xiv | Preface
Sebastopol, CA 95472
800-998-9938 (in the United States or Canada)
707-829-0515 (international or local)
707-829-0104 (fax)
We have a web page for this book, where we list errata, examples, and any additional
information. You can access this page at http://oreil.ly/introducing_erlang.
To comment or ask technical questions about this book, send email to bookques‐
tions@oreilly.com.
For more information about our books, courses, conferences, and news, see our web‐
site at http://www.oreilly.com.
Find us on Facebook: http://facebook.com/oreilly
Follow us on Twitter: http://twitter.com/oreillymedia
Watch us on YouTube: http://www.youtube.com/oreillymedia
Acknowledgments
Many thanks to Zachary Kessin for interesting me in Erlang in the first place, and to
him and Francesco Cesarini for encouraging me to write this. Detailed feedback from
Steve Vinoski and Fred Hebert has made it possible, I hope, for this book to get read‐
ers started on the right track. J. David Eisenberg and Chuck Ha helped make it espe‐
cially possible for beginners to get started right, pointing out gaps and issues in my
prose.
In particular, thanks to my wife Angelika for encouraging me to finish this, to my son
Konrad for not throwing the printouts around too much, and to my daughter Sun‐
giva for understanding that after I told her the story about Ned and Ernie, adventur‐
ing snakes, I needed to go back downstairs and work on this.
Preface | xv
Introducing Erlang Getting Started In Functional Programming 2nd Edition St Laurent
CHAPTER 1
Getting Comfortable
Erlang has a funny learning curve for many people. It starts gently for a little while,
then gets much much steeper as you realize the discipline involved, and then goes
nearly vertical for a little while as you try to figure out how that discipline affects get‐
ting work done—and then it’s suddenly calm and peaceful with a gentle grade for a
long time as you reapply what you’ve learned in different contexts.
Before that climb, it’s best to get comfortable in the sunny meadows at the bottom of
the learning curve. Erlang’s shell, its command-line interface, is a cozy place to get
started and a good place to start figuring out what works and what doesn’t work in
Erlang. Its features will spare you headaches later, so settle in!
Installation
Erlang is officially available from http://www.erlang.org/download.html. For this edi‐
tion, I used Erlang/OTP 19, but any version of Erlang more recent than 17 should
work.
If you’re on Windows, it’s easy. Download the Windows binary file, run the installer,
and you’re set. If you are a brave beginner tackling your first programming language,
this is easily your best bet.
On Linux or Mac OS X, you may be able to download the source file and compile it.
If the compilation approach doesn’t work or isn’t for you, Erlang Solutions offers a
number of installs at http://www.erlang-solutions.com/section/132/download-erlang-
otp. Also, many different package managers (Debian, Ubuntu, MacPorts, brew, and so
on) include Erlang. It may not be the very latest version, but having Erlang running is
much better than not having Erlang running.
1
Erlang is increasingly part of the default installation on many sys‐
tems, including Ubuntu, largely thanks to the spread of CouchDB.
Firing It Up
On Mac OS X or Linux, go to the command line and type erl. On Windows, go to
the command line and type werl.
You’ll see something like the following code sample, likely with a cursor next to the
1> prompt.
Erlang R15B (erts-5.9) [source] [smp:2:2] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9 (abort with ^G)
1>
You’re in Erlang!
First Steps: The Shell
Before moving on to the excitement of programming Erlang, it’s always worth noting
how to quit. The shell suggests ^G, Ctrl-G, which will bring you to a mysterious (for
now) user switch command. (Ctrl-C will bring you to a menu.) The simplest way to
quit, allowing everything that might be running in the shell to exit normally, is q().
1> q().
ok
2> SimonMacBook:~ simonstl$
So what have you done here? You’ve issued a shell command, calling a function q that
itself calls the init:stop() function built into Erlang. The period after the command
tells Erlang you’re done with the line. It reports back with ok, prints a new line num‐
ber (it always does that after a period), and drops you back out to the regular com‐
mand line, in this case a bash shell on your laptop.
If you had left off the period after q(), the results would look a little different. You’d
have started a new line but the command count wouldn’t update, so the line would
still start with 1>. When this happens, you can just type . and press Enter to finish
your command.
1> q()
1> .
ok
2> SimonMacBook:~ simonstl$
Including the period at the end of the line will soon become second nature, but leav‐
ing it off can create a lot of confusion at the start.
2 | Chapter 1: Getting Comfortable
Quitting Erlang with q(). turns off everything Erlang is doing,
period. That’s fine when you’re working locally, but will become a
bad idea when you’re connecting to a remote shell. To quit the shell
without the risk of shutting down the Erlang runtime on another
system, try Ctrl-G and then entering q, followed by the Enter key.
Moving through Text
If you explore the shell, you’ll find that many things work the way they do in other
shells. The left and right arrow keys move you backward and forward through the
line you’re editing. Some of the key bindings echo the emacs text editor. Ctrl-A will
take you to the beginning of a line, while Ctrl-E will take you back to the end of the
line. If you get two characters in the wrong sequence, pressing Ctrl-T will transpose
them.
Like most Unix shells, pressing the Tab key will make the shell try to autocomplete
what you’ve written, though in this case it’s looking for module or function names
(you’ll see them soon), not filenames.
Also, as you type closing parentheses or square brackets, the cursor will highlight the
corresponding opening parenthesis or square bracket.
Moving through History
The up and down arrow keys run through the history, making it easy to reissue
commands.
When you use the up and down arrows, the history will be broken down by newlines,
not by periods, so if you left a period off in a prior command you’ll need to add it
again. If you want to see what’s in the history, try h(). You can also specify how much
history to keep around with history(N) and results(N). You can tell Erlang to exe‐
cute a given line again with e(N), and reference a given result value with v(N). Those
line numbers can be useful!
Moving through Files
The Erlang shell does understand filesystems to some extent because you may need to
move through them to reach the files that will become part of your program. The
commands have the same names as Unix commands but are expressed as functions.
The Erlang shell starts wherever you opened the shell, and you can figure out where
that is with pwd():
4> pwd().
/Users/simonstl
ok
5>
First Steps: The Shell | 3
To change directories, use the cd() command, but you’ll need to wrap the argument
not only in parentheses but in quotes, preferably double quotes.
5> cd(..).
* 1: syntax error before: '..'
5> cd("..").
/Users
ok
6> cd("simonstl").
/Users/simonstl
ok
7>
You can look around with the ls() command, which will list files in the current
directory if you give it no arguments, and list files in a specified directory if you give
it one argument.
Doing Something
One of the easiest ways to get started playing with Erlang is to use the shell as a calcu‐
lator. You can enter mathematical expressions and get useful results:
Eshell V5.9 (abort with ^G)
1> 2+2.
4
2> 27-14.
13
3> 35*42023943.
1470838005
4> 200/15.
13.333333333333334
5> 200 div 15.
13
6> 200 rem 15.
5
7> 3*(4+15).
57
The first three operators are addition(+), subtraction(-), and multiplication(*), which
work the same way whether you’re working with integer values or floating points. The
fourth, /, supports division where you expect a floating point (a number with a deci‐
mal part) result. If you want an integer result (and have integer arguments), use the
div operator instead, with rem to get the remainder, as shown on lines 5 and 6. Paren‐
theses let you modify the order in which operators are processed, as shown on line 7.
(The normal order of operations is listed in Appendix A.)
Erlang will accept integers in place of floats, but floats are not always welcome where
integers are used. If you need to convert a floating point number to an integer, you
can use the round() built-in function:
4 | Chapter 1: Getting Comfortable
8> round(200/15).
13
The round() function drops the decimal part of the number. If the decimal part was
greater than or equal to .5, it increases the integer part by 1, rounding up. If you’d
rather just drop the decimal part completely, use the trunc() function, which effec‐
tively always rounds down.
You can also refer to a previous result by its line number using v(). For example:
9> 4*v(8).
52
The result on line 8 was 13, and 4*13 is 52.
If you’re feeling adventurous, you can use negative numbers to reference prior results.
v(-1) is the previous result, v(-2) is the result before that, and so on.
Calling Functions
If you want to do more powerful calculations, Erlang’s math module offers pretty
much the classic set of functions supported by a scientific calculator. They return
floating point values. The constant pi is available as a function, math:pi(). Trigono‐
metric, logarithmic, exponential, square root, and (except on Windows) even the
Gauss error functions are readily available. (The trigonometric functions take their
arguments in radians, not degrees, so be ready to convert if necessary.) Using these
functions is a little verbose because of the need to prefix them with math:, but it’s still
reasonably sane.
For example, to get the sine of zero radians, you’d write:
1> math:sin(0).
0.0
Note that it’s 0.0, not just 0, indicating that the number is floating point.
To calculate the cosine of pi and 2pi radians, you’d write:
2> math:cos(math:pi()).
-1.0
3> math:cos(2*math:pi()).
1.0
To calculate 2 taken to the 16th power, you’d use:
4> math:pow(2,16).
65536.0
The full set of mathematical functions supported by Erlang’s math module is listed in
Appendix A.
Calling Functions | 5
Numbers in Erlang
Erlang recognizes two kinds of numbers: integers and floating-point numbers (often
called floats). It’s easy to think of integers as “whole numbers,” with no decimal part,
and floats as “decimal numbers,” with a decimal point and some value (even if it’s 0)
to the right of the decimal. 1 is an integer, 1.0 is a floating-point number.
However, it’s a little trickier than that. Erlang stores integers and floats in a very dif‐
ferent way. Erlang lets you store massive numbers as integers, but whether they’re big
or small, they are always precise. You don’t need to worry about their values being off
by just a little.
Floats, on the other hand, cover a wide range of numbers but with limited precision.
Erlang uses the 64-bit IEEE 754-1985 “double precision” representation. This means
that it keeps track of about 15 decimal digits plus an exponent. It can also represent
some large numbers—powers up to positive or negative 308 are available—but
because it tracks only a limited number of digits, results will vary a little more than
may seem convenient, especially when you want to do comparisons.
1> 3487598347598347598437583475893475843749245.0.
3.4875983475983474e42
2> 2343243.345435893850234543339545.
2343243.3454358936
3> 0.0000000000000000000000000000023432432432432234232324.
2.3432432432432235e-30
As you can see, some digits get left behind, and the overall magnitude of the number
represented with an exponent.
When you enter floating point numbers, you must always also have at least one num‐
ber to the left of the decimal point, even if it’s zero. Otherwise Erlang reports a syntax
error—it doesn’t understand what you’re doing.
4> .0000000000000000000000000000023432432432432234232324.
* 1: syntax error before: 23432432432432234232324
You can also write floats using the digits plus exponent notation:
7> 2.923e127.
2.923e127
8> 7.6345435e-231.
7.6345435e-231
Floats’ lack of precision can cause anomalous results. For example, the sine of zero is
zero, and the sine of pi is also zero. However, if you calculate this in Erlang, you won’t
quite get to zero with the float approximation Erlang provides for pi:
1> math:sin(0).
0.0
2> math:sin(math:pi()).
1.2246467991473532e-16
6 | Chapter 1: Getting Comfortable
If Erlang’s representation of pi went further, and its calculations went further, the
result for line 2 would be closer to zero.
If you need to keep track of money, integers are going to be a better bet. Use the
smallest available unit—cents for US dollars, for instance—and remember that those
cents are 1/100 of a dollar. (Financial transactions can go to much smaller fractions,
but you’ll still want to represent them as integers with a known multiplier.) For more
complex calculations, though, you’ll want to use floats, and just be aware that results
will be imprecise.
If you need to do calculations on integers using a base other than 10, you can use
Base#Value notation. For example, if you wanted to specify the binary value of
1010111, you could write:
3> 2#1010111.
87
Erlang reports back with the base 10 value of the number. Similarly, you can specify
hexadecimal numbers by using 16 instead of 2:
4> 16#cafe.
51966
Erlang lets you use either upper- or lower-case for hexdecimal numbers - 16#CAFE
and 16#CaFe also produce 51966. You aren’t limited to the traditional binary (base 2),
octal (base 8), and hexadecimal (base 16) choices. If you want to work in base 18, or
any base up to 36, you can:
5> 18#gaffe.
1743080
Why might you use base 36? It’s an extremely easy way to create
keys that look like a combination of letters and numbers, but
resolve neatly to numbers. The 6-digit codes airlines use to identify
tickets, like G6ZV1N, are easily treated as base 36. (However, they
usually leave out some digits and letters that are easily confused,
such as -0 and O, and 1 and l.)
To make any of these numbers negative just put a minus sign (-) in front of them.
This works with normal integers, Base#Value notation, and floats:
6> -1234.
-1234
7> -16#cafe.
-51966
8> -2.045234324e6.
-2045234.324
Numbers in Erlang | 7
Working with Variables in the Shell
The v() function lets you refer to the results of previous expressions, but it’s not
exactly convenient to keep track of result numbers, and the v() function works only
in the shell. It isn’t a general-purpose mechanism. A more reasonable solution stores
values with textual names, creating variables.
Erlang variable names begin with a capital letter or an underscore. Normal variables
start with a capital letter, whereas underscores start “don’t care” variables. For now,
stick with normal variables. You assign a value to a variable using a syntax that should
be familiar from algebra or other programming languages, here with N as the vari‐
able:
1> N=1.
1
To see the value of a variable, just type its name.
2> N.
1
To see Erlang protest at your rude behavior, try assigning the variable a new value:
3> N=2.
** exception error: no match of right hand side value 2
4> N=N+1.
** exception error: no match of right hand side value 2
What’s happening here? Erlang expects the righthand side of an expression, after the
=, to match the lefthand side. It’s willing to make that happen if a variable on the left
side isn’t bound yet, as was the case with N=1 in the first line. However, once the vari‐
able N is set to 1, Erlang interprets N=2 as 1=2, which it won’t accept. N=N+1 also evalu‐
ates to 1=2, and doesn’t work. Erlang’s single assignment model, where each variable
can be assigned a value only once in a given context, imposes discipline whose value
you will see in later chapters.
Erlang expressions work like algebra, where N never equals N+1. It just can’t happen
that way. However, once you’ve set N to 1, it’s fine to try expressions that also come to
one:
5> N=2-1.
1
6> N=15 div (3*5).
1
This will get much more important when you start to take advantage of Erlang’s pat‐
tern matching capabilities. You can also write the following:
7> 1=N.
1
8 | Chapter 1: Getting Comfortable
Erlang won’t attempt to bind any variables when they appear on the right side of the
equals sign, and this just effectively asks Erlang to compare 1 to 1. Try it with 2, how‐
ever, and Erlang complains that there isn’t a match; 2 does not equal 1:
8> 2=N.
** exception error: no match of right hand side value 1
You can also use bound variables in calculations, for example to create new bound
variables. Here’s one called Number:
9> Number=N*4+N.
5
10> 6*Number.
30
When you assign a value to a variable, you should make sure that all the calculations
are on the right side of the equals sign. Even though I know that M should be 6 when
2*M = 3*4, Erlang doesn’t:
11> 2*M=3*4.
* 1: illegal pattern
The shell will remember your variables until you quit or tell it to forget them. Code in
Erlang functions doesn’t forget, until the functions stop running.
Seeing Your Bound Variables
After a while poking around the shell using it as a calculator (try it!), you may find
you’ve forgotten what variables you’ve already bound. If you need a reminder, the b()
shell command can help:
11> b().
N = 1
Number = 5
ok
Clearing Bound Variables in the Shell
In the shell, and only in the shell, you can clear all variable bindings and you can clear
specific variable bindings. This may prove useful after an egregious typo or to reset
your console for new calculations, but it isn’t an option you’ll have in regular code.
To clear a specific variable, removing its binding and letting you set a new value, use
the f() function, giving the variable name as an argument:
12> f(N).
ok
13> b().
Number = 5
ok
Working with Variables in the Shell | 9
14> N=2.
2
To clear all the bound variables in the shell, just call f() with no arguments.
15> b().
N = 2
Number = 5
ok
16> f().
ok
17> b().
ok
They all disappeared.
Before moving on to the next chapter, which will introduce modules and functions,
spend some time playing in the Erlang shell. The experience, even at this simple level,
will help you move forward. Use variables, and see what happens with large integers.
Erlang supports large numbers very well. Try mixing numbers with decimal values
(floats) and integers in calculations, and see what happens. Nothing should be diffi‐
cult yet, though I suspect the idea of variables that don’t change values gives you a
hint of what’s to come.
You can learn more about installation and working with the shell in
Chapter 2 of Erlang Programming (O’Reilly); Chapters 2 and 6 of
Programming Erlang (Pragmatic); Section 2.1 of Erlang and OTP in
Action (Manning); and Chapter 1 of Learn You Some Erlang For
Great Good! (No Starch Press).
10 | Chapter 1: Getting Comfortable
CHAPTER 2
Functions and Modules
Like most programming languages, Erlang lets you define functions to help you rep‐
resent repeated calculations. While Erlang functions can become complicated, they
start out reasonably simple.
Fun with fun
You can create functions in the Erlang shell using the appropriately named fun. For
example, to create a function that calculates the velocity of a falling object based on
the distance it drops in meters, you could create the following:
1> FallVelocity = fun(Distance) -> math:sqrt(2 * 9.8 * Distance) end.
#Fun<erl_eval.6.111823515>
You can read that as a pattern match that binds the variable FallVelocity to a func‐
tion that takes an argument of Distance. The function returns (I like to read the -> as
yields) the square root of 2 times a gravitational constant for Earth of 9.8 m/s, times
Distance (in meters). Then the function comes to an end, and a period closes the
statement.
If you want to include multiple statements in a fun, separate them
with commas, like FallVelocity = fun(Distance) -> X = (2 *
9.8 * Distance), math:sqrt(X) end.
The return value in the shell, #Fun<erl_eval.6.111823515>, isn’t especially mean‐
ingful by itself, but it tells you that you’ve created a function and didn’t just get an
error. If you want a slightly more detailed sign that Erlang understood you, you can
use the b() shell command to see what it thinks:
11
2> b().
FallVelocity =
fun(Distance) ->
math:sqrt(2 * 9.8 * Distance)
end
ok
Conveniently, binding the function to the variable FallVelocity lets you use that
variable to calculate the velocity of objects falling to Earth:
3> FallVelocity(20).
19.79898987322333
4> FallVelocity(200).
62.609903369994115
5> FallVelocity(2000).
197.9898987322333
If you want those meters per second in miles per hour, just create another function.
You can copy and paste the earlier results into it (as I did here), or pick shorter num‐
bers:
6> Mps_to_mph = fun(Mps) -> 2.23693629 * Mps end.
#Fun<erl_eval.6.111823515>
7> Mps_to_mph(19.79898987322333).
44.289078952755766
8> Mps_to_mph(62.609903369994115).
140.05436496173314
9> Mps_to_mph(197.9898987322333).
442.89078952755773
I think I’ll stay away from 2000 meter drops. Prefer the fall speed in kilometers per
hour?
10> Mps_to_kph = fun(Mps) -> 3.6 * Mps end.
#Fun<erl_eval.6.111823515>
11> Mps_to_kph(19.79898987322333).
71.27636354360399
12> Mps_to_kph(62.609903369994115).
225.3956521319788
13> Mps_to_kph(197.9898987322333).
712.76363543604
You can also go straight to your preferred measurement by nesting the following calls:
14> Mps_to_kph(FallVelocity(2000)).
712.76363543604
However you represent it, that’s really fast, though air resistance will slow those down
a lot in reality.
This is handy for repeated calculations, but you probably don’t want to push this kind
of function use too far in the shell, as flushing your variables or quitting the shell ses‐
sion makes your functions vanish.
12 | Chapter 2: Functions and Modules
If you get an error that looks like ** exception error: no func
tion
clause matching erl_eval:'-inside-an-interpreted-fun-'(value),
check your capitalization. It may take a while to get used to capital‐
izing all your variables, including arguments in functions.
Defining Modules
Most Erlang programs define their functions in compiled modules rather than in the
shell. Modules are a more formal place to put programs, and they give you the ability
to store, encapsulate, share, and manage your code more effectively.
Each module should go in its own file, with an extension of .erl. You should use
name_of_module.erl, where name_of_module is the name you specify inside of the
module file. Example 2-1, which you can find in the examples archive at ch02/ex1-
drop, shows what a module, drop.erl, containing the functions previously defined
might look like.
Example 2-1. Module for calculating and converting fall velocities
-module(drop).
-export([fall_velocity/1, mps_to_mph/1, mps_to_kph/1]).
fall_velocity(Distance) -> math:sqrt(2 * 9.8 * Distance).
mps_to_mph(Mps) -> 2.23693629 * Mps.
mps_to_kph(Mps) -> 3.6 * Mps.
There are two key kinds of information in this module. At the top, the -module and -
export directives tell the compiler key things about the module—its name and which
functions it should make visible to other code that uses this module. The -export
directive gives a list of functions that should be made visible—not just their names,
but their arity, the number of arguments they take. Erlang considers functions with
the same name but different arity to be different functions.
All of the code in a module must be contained in functions.
Below the directives is a set of expressions defining functions, which look similar to
the fun declarations used earlier but not quite the same. The function names start
with lowercase, not uppercase, and the syntax is slightly different. fun and end don’t
appear, and the function name is immediately followed by parentheses containing a
set of arguments.
Defining Modules | 13
If you get errors like "drop.erl:2: bad function arity
drop.erl:6: syntax error before: Fall_velocity“, it’s proba‐
bly because you didn’t convert the names from your fun/s so they
start with a lowercase letter.
How do you make this actually do something?
It’s time to start compiling Erlang code. The shell will let you compile modules and
then use them immediately. The c() function lets you compile code. You need to be
in the same directory as the file, whether you started the Erlang shell from there or
navigated there with the commands shown in the previous chapter. You don’t need to
(and shouldn’t) include the .erl file extension in the name you pass to c(), though you
can specify directory paths.
1> ls().
drop.erl
ok
2> c(drop).
{ok,drop}
3> ls().
drop.beam drop.erl
ok
Line 1 checks to see if the drop.erl source file is there, and you see the directory list‐
ing. Line 2 actually compiles it, and line 3 shows that a new file, drop.beam, is now
available. Now that you have drop.beam, you can call functions from the module. You
need to prefix those calls with drop, as shown in lines 4 and 5 of the following code.
4> drop:fall_velocity(20).
19.79898987322333
5> drop:mps_to_mph(drop:fall_velocity(20)).
44.289078952755766
It works the same as its predecessors, but now you can quit the shell, return, and still
use the compiled functions.
6> q().
ok
$ erl
Erlang R15B (erts-5.9) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9 (abort with ^G)
1> drop:mps_to_mph(drop:fall_velocity(20)).
44.289078952755766
14 | Chapter 2: Functions and Modules
Most Erlang programming (beyond tinkering in the shell) is creating functions in
modules and connecting them into larger programs.
Erlang Compilation and the Runtime System
When you write Erlang in the shell, it has to interpret every command, whether or
not you’ve written it before. When you tell Erlang to compile a file, it converts your
text into something it can process without having to re-interpret all the text, tremen‐
dously improving efficiency when you run the code.
That “something it can process,” in Erlang’s case, is a BEAM file. It contains code that
the BEAM processor, a key piece of the Erlang Runtime System (ERTS) can run.
BEAM is Bogdan’s Erlang Abstract Machine, a virtual machine that interprets opti‐
mized BEAM code. This may sound slightly less efficient than the traditional compi‐
lation to machine code that runs directly on the computer, but it resembles other
virtual machines. (Oracle’s Java Virtual Machine (JVM) and the Common Language
Runtime used by Microsoft’s .NET Framework are the two most common virtual
machines.)
Having its own virtual machine and runtime system lets Erlang optimize some key
things, making it easier to build applications that scale reliably. Its process scheduler
simplifies distributing work across multiple processors in a single computer. You
don’t have to think about how many processors your application might get to use—
you just write independent processes, and Erlang spreads them out. Erlang also man‐
ages input and output in its own way, avoiding connection styles that block other pro‐
cessing. The virtual machine also uses a garbage collection strategy that fits its style of
processing, allowing for briefer pauses in program execution. (Garbage collection
releases memory that processes needed at one point but are no longer using.)
When you create and deliver Erlang programs, you will be distributing them as a set
of compiled BEAM files. You don’t need to compile each one from the shell as we’re
doing here, though. erlc will let you compile Erlang files directly and combine that
compilation into make tasks and similar things, whereas escript can compile or
interpret and run Erlang code from outside of the Erlang shell.
From Module to Fun
If you like the style of code that fun allowed but also want your code stored more
reliably in modules where it’s easier to debug, you can get the best of both worlds by
using the fun keyword to refer to a function you’ve already defined. To do that, you
don’t use parentheses after fun, and give the module name, function name, and arity.
1> F_v = fun drop:fall_velocity/1.
#Fun<drop.fall_velocity.1>
Defining Modules | 15
2> F_v(20).
19.79898987322333
You can also do this within code in a module, and if you’re referring to code in the
same module, you can leave off the module name preface. (In this case, that would
mean leaving off drop: and just using fall_velocity/1.)
Functions and Variable Scope
Erlang lets you bind a variable only once, but you might call a function many times
over the course of a program. Doesn’t that mean the same variable will be bound
many times?
Yes, it will be bound many times but always in separate contexts. Erlang doesn’t con‐
sider multiple calls to the same function to be the same thing. It starts with a fresh set
of unassigned variables every time you call that function.
Similarly, Erlang doesn’t worry if you use the same variable name in different func‐
tions or function clauses. They aren’t going to be called in the same context at the
same time, so there isn’t a collision.
The place you need to avoid re-assigning values to an already bound variable is
within a given path through a given function. As long as you don’t try to reuse a vari‐
able in a given context, you shouldn’t have to worry.
Module Directives
By default, modules have very thick walls, and everything inside of them is consid‐
ered private. Everything going in or out of the module needs a pass to do so, and you
grant those passes through module directives (sometimes called module attributes).
The example above showed two module directives—-module and -export. The
-module directive sets the name for the module, which outside code will need to
know in order to call the functions. The -export directive specifies which functions
that outside code can reach.
The drop module currently mixes two different kinds of functions. The fall_veloc
ity/1 function fits the name of the module, drop, very well, providing a calculation
based on the height from which an object falls. The mps_to_mph/1 and mps_to_kph/1
functions, however, aren’t about dropping. They are generic measurement conversion
functions that are useful in other contexts and really belong in their own module.
Example 2-2 and Example 2-3, both in ch02/ex2-combined, show how this might be
improved.
16 | Chapter 2: Functions and Modules
Example 2-2. Module for calculating fall velocities
-module(drop).
-export([fall_velocity/1]).
fall_velocity(Distance) -> math:sqrt(2 * 9.8 * Distance).
Example 2-3. Module for converting fall velocities
-module(convert).
-export([mps_to_mph/1, mps_to_kph/1]).
mps_to_mph(Mps) -> 2.23693629 * Mps.
mps_to_kph(Mps) -> 3.6 * Mps.
Next, you can compile them, and then the separated functions are available for use:
Eshell V5.9 (abort with ^G)
1> c(drop).
{ok,drop}
2> c(convert).
{ok,convert}
3> ls().
convert.beam convert.erl drop.beam drop.erl
ok
4> convert:mps_to_mph(drop:fall_velocity(20)).
44.289078952755766
That reads more neatly, but how might this code work if a third module needed to
call those functions? Modules that call code from other modules need to specify that
explicitly. Example 2-4, in ch02/ex3-combined, shows a module that uses functions
from both the drop and convert modules.
Example 2-4. Module for combining drop and convert logic
-module(combined).
-export([height_to_mph/1]).
height_to_mph(Meters) -> convert:mps_to_mph(drop:fall_velocity(Meters)).
That looks much like the way you called it from the Erlang shell, but if you have a lot
of calls to external modules, that can get verbose quickly. The -import directive,
shown in Example 2-5, lets you simplify your code, though it comes with a possible
risk of confusing other people who think the imported functions must be defined
within this module. (You can find this in ch02/ex4-combined.)
Defining Modules | 17
Example 2-5. Module for combining drop and convert logic using import
-module(combined).
-export([height_to_mph/1]).
-import(drop, [fall_velocity/1]).
-import(convert, [mps_to_mph/1]).
height_to_mph(Meters) -> mps_to_mph(fall_velocity(Meters)).
For now, it’s probably best to know about the -import directive so you can read other
people’s code, but not to use it unless you just can’t resist. It can make it harder to
figure where bugs are coming from, which may cost you more time than the extra
typing.
Erlang includes one other directive that’s similarly convenient but not best practice to
use: -compile(export_all). That directive tears down the module wall, making all
functions available for external calls. In a module where everything is supposed to be
public, that might save you typing out all the functions and all the arities of your
module. However, it also means anyone can call anything in your code, exposing a lot
more surface area for misunderstandings and complex debugging. If you just can’t
resist, it’s available, but try to resist.
You can also make up your own user directives. -author(Name)
and -date(Date) are commonly used. If you make up your own
directives, they can have only one argument. If you spend enough
time in Erlang, you’ll also encounter the following: -
behaviour(Behaviour), -record(Name, Fields), and -
vsn(Version).
Documenting Code
Your programs can run perfectly well without documentation. Your projects, how‐
ever, will have a much harder time.
While programmers like to think they write code that anyone can look at and sort
out, the painful reality is that code even a little more complicated than that shown in
the previous examples can prove mystifying to other developers. If you step away
from code for a while, the understanding you developed while programming it may
have faded, and even your own code can seem incomprehensible.
The simplest way to add more explicit explanations to your code is to insert com‐
ments. You can start a comment with %, and it runs to the end of the line. Some com‐
ments take up an entire line, while others are short snippets at the end of a line.
Example 2-6 shows both varieties of comments.
18 | Chapter 2: Functions and Modules
Example 2-6. Comments in action
-module(combined).
-export([height_to_mph/1]). % there will be more soon!
%%% combines logic from other modules into a convenience function.
height_to_mph(Meters) -> convert:mps_to_mph(drop:fall_velocity(Meters)).
The Erlang compiler will ignore all text between the % sign and the end of the line, but
humans exploring the code will be able to read them.
Why are there multiple percent signs at the start of the line? The Erlang Emacs mode
and many other Erlang tools expect the number of percent signs to indicate levels of
indentation. Three percent signs (%%%) means that the comment will be formatted
flush left, two percent signs (%%) means the comment is indented with surrounding
code, and a single percent sign (%) is used for comments on the end of a line.
Informal comments are useful, but developers have a habit of including comments
that help them keep track of what they’re doing while they’re writing the code. Those
comments may or may not be what other developers need to understand the code, or
even what you need when you return to the code after a long time away. More formal
comment structures may be more work than you want to take on in the heat of a pro‐
gramming session, but they also force you to ask who might be looking at your code
in the future and what they might want to know.
Erlang includes a documentation system called EDoc, which converts comments
placed in the code into navigable HTML documentation. It relies on specially format‐
ted comments, a directive, and occasionally an extra file to provide structured infor‐
mation about your modules and application.
Documenting Modules
The modules in this chapter are very simple so far, but there is enough there to start
documenting, as shown in the files at ch02/ex5-docs. Example 2-7 presents the drop
module with more information about who created it and why.
Example 2-7. Documented module for calculating fall velocities
%% @author Simon St.Laurent <simonstl@simonstl.com> [http://simonstl.com]
%% @doc Functions calculating velocities achieved by objects
%% dropped in a vacuum.
%% @reference from <a href= "http://shop.oreilly.com/product/0636920025818.do" >Introducing Erlang</a>
%% O'Reilly Media, Inc., 2012.
%% @copyright 2012 by Simon St.Laurent
%% @version 0.1
-module(drop).
-export([fall_velocity/1]).
Documenting Code | 19
fall_velocity(Distance) -> math:sqrt(2 * 9.8 * Distance).
Erlang can build the files for you using the EDoc file function:
Eshell V5.9 (abort with ^G)
1> edoc:files(["drop.erl"], [{dir, "doc"}]).
ok
You’ll now have a collection of files in the doc subdirectory. If you open drop.html in a
browser, you’ll see something like Figure 2-1.
Figure 2-1. Module documentation generated from the drop.erl file
All of that metadata is great, and it can be gratifying to see your name “in lights.”
However, unless you have a complex story to tell about your module as a whole, it’s
likely that the core of the documentation will appear at the function level.
Documenting Functions
The drop module contains one function: fall_velocity/1. You probably know that
it takes a distance in meters and returns a velocity in meters per second for an object
dropped in a vacuum on Earth, but the code doesn’t actually say that. Example 2-8
shows how to fix that with EDoc comments and the @doc tag.
20 | Chapter 2: Functions and Modules
Example 2-8. Documented function for calculating fall velocities
%% @doc Calculates the velocity of an object falling on Earth
%% as if it were in a vacuum (no air resistance). The distance is
%% the height from which the object falls, specified in meters,
%% and the function returns a velocity in meters per second.
fall_velocity(Distance) -> math:sqrt(2 * 9.8 * Distance).
Figure 2-2 shows the result, which is considerably more helpful than the previous
blank space around the function. It neatly takes the first sentence of the information
following @doc and put it in the index, using the whole description for the Function
Details section. You can also use XHTML markup in the @doc section.
Figure 2-2. Function documentation generated from the drop.erl file
That’s a major improvement, but what if a user specifies “twenty” meters instead of 20
meters? Because Erlang doesn’t worry much about types, the Erlang code doesn’t say
that the value for Distance has to be a number or the function will return an error.
You can add a directive, -spec, to add that information. It’s a little strange, as in some
ways it feels like a duplicate of the method declaration. In this case, it’s simple, as
shown in Example 2-9.
Documenting Code | 21
Example 2-9. Documented function for calculating fall velocities
%% @doc Calculates the velocity of an object falling on Earth
%% as if it was in a vacuum (no air resistance). The distance is
%% the height from which the object falls, specified in meters,
%% and the function returns a velocity in meters per second.
-spec(fall_velocity(number()) -> number()).
fall_velocity(Distance) -> math:sqrt(2 * 9.8 * Distance).
EDoc will combine the types specified in the -spec directive with the parameter
names in the actual function declaration to produce the documentation shown in
Figure 2-3.
Figure 2-3. EDoc documentation with type information
This chapter has really demonstrated only the number() type, which combines
integer() and float(). Appendix A includes a full list of types.
Documenting Your Application
Sometimes you want information like the author and copyright data to appear in
every module, often when it varies from module to module. Other times that
becomes clutter, and it’s easier to put it into one place where it applies to all of your
modules.
You can create an overview.edoc file in your project’s doc directory. Its content looks
much like the markup used in the modules, but because it isn’t mixed with code, you
don’t need to preface every line with %%. The overview.edoc file for this project might
look like Example 2-10.
22 | Chapter 2: Functions and Modules
Example 2-10. Documented module for calculating fall velocities
@author Simon St.Laurent <simonstl@simonstl.com> [http://simonstl.com]
@doc Functions for calculating and converting velocities.
@reference from <a href= "http://shop.oreilly.com/product/0636920025818.do"
>Introducing Erlang</a>, O'Reilly Media, Inc., 2012.
@copyright 2012 by Simon St.Laurent
@version 0.1
Now, if you re-generate documentation and click on the Overview link, you’ll see
something like Figure 2-4.
Figure 2-4. Application overview created with EDoc.
If you create similar documentation in each of the Erlang files and run
edoc:files(["drop.erl", "convert.erl", "combined.erl"]). in the Erlang
shell, EDoc will build a neat if somewhat plain set of frame-based documentation for
your application, as shown in Figure 2-5.
Documenting Code | 23
Figure 2-5. The opening to the complete set of module documentation
This is just an introduction to EDoc. For more, see Chapter 18 of Erlang Program‐
ming, where you can learn about fun things like the @todo tag.
You can learn more about working with functions and modules in
Chapters 2, 3, and 9 of Erlang Programming (O’Reilly); Chapter 3 of
Programming Erlang (Pragmatic); Sections 2.3, 2.5, and 2.7 of
Erlang and OTP in Action (Manning); and Chapters 2 and 3 of
Learn You Some Erlang For Great Good! (No Starch Press). There’s
more on documentation in Chapter 18 of Erlang Programming and
types in Chapter 30 of Learn You Some Erlang For Great Good!.
24 | Chapter 2: Functions and Modules
CHAPTER 3
Atoms, Tuples, and Pattern Matching
Erlang programs are at heart a set of message requests and tools for processing them.
Erlang provides tools that simplify the efficient handling of those messages, letting
you create code that is readable (to programmers at least) while still running effi‐
ciently when you need speed.
Atoms
Atoms are a key structure in Erlang. Technically they’re just another type of data, but
it’s hard to overstate their impact on Erlang programming style.
Usually, atoms are bits of text that start with a lowercase letter, like ok or earth. They
can also contain (though not start with) underscores (_) and at symbols (@), like
this_is_a_short_sentence or me@home. If you want more freedom to start with
uppercase letters or use spaces, you can put them in single quotes, like 'Today is a
good day’. Generally, the one word lowercase form is easier to read.
Atoms have a value—it’s the same as their text. (Remember, the period after hello
isn’t part of the atom—it ends the expression.)
1> hello.
hello
That’s not very exciting in itself. What makes atoms exciting is the way that they can
combine with other types and Erlang’s pattern matching techniques to build simple
but powerful logical structures.
Pattern Matching with Atoms
Erlang used pattern matching to make the examples in Chapter 2 work, but it was
very simple. The name of the function was the one key piece that varied, and as long
25
as you provided a numeric argument Erlang knew what you meant. Erlang’s pattern
matching offers much more sophisticated possibilities, however, allowing you to
match on arguments as well as on function names.
For example, suppose you want to calculate the velocity of falling objects not just on
Earth, where the gravitational constant is 9.8 meters per second squared, but on
Earth’s moon, where it is 1.6 meters per second squared, and on Mars, where it is 3.71
meters per second squared. Example 3-1, which you can find in ch03/ex1-atoms,
shows one way to build code that supports this.
Example 3-1. Pattern matching on atoms as well as function names
-module(drop).
-export([fall_velocity/2]).
fall_velocity(earth, Distance) -> math:sqrt(2 * 9.8 * Distance);
fall_velocity(moon, Distance) -> math:sqrt(2 * 1.6 * Distance);
fall_velocity(mars, Distance) -> math:sqrt(2 * 3.71 * Distance).
It looks like the fall_velocity function gets defined three times here, and it cer‐
tainly provides three processing paths for the same function. However, because those
definitions are separated with semicolons, they are treated as choices—selected by
pattern-matching—rather than duplicate definitions. As in English, these pieces are
called clauses.
If you use periods instead of semicolons, you’ll get errors like
drop.erl:5: function fall_velocity/2 already defined.
Once you have this, you can calculate velocities for objects falling a given distance on
Earth, the Earth’s moon, and Mars:
1> c(drop).
{ok,drop}
2> drop:fall_velocity(earth,20).
19.79898987322333
3> drop:fall_velocity(moon,20).
8.0
4> drop:fall_velocity(mars,20).
12.181953866272849
You’ll quickly find that atoms are a critical component for writing readable Erlang
code.
26 | Chapter 3: Atoms, Tuples, and Pattern Matching
Atomic Booleans
Two of Erlang’s atoms have special properties: true and false, representing the
boolean logic values of the same names. Erlang will return these atoms if you ask it to
compare something:
1> 3<2.
false
2> 3>2.
true
3> 10 == 10.
true
Erlang also has special operators that work on these atoms (and on comparisons that
resolve to these atoms):
1> true and true.
true
2> true and false.
false
3> true or false.
true
4> false or false.
false
5> true xor false.
true
6> true xor true.
false
7> not true.
false
The and, or, and xor operators both take two arguments. For and, the result is true if
and only if the two arguments are true. For or, the result is true if at least one of the
arguments is true. For xor, exclusive or, the result is true if one but not both argu‐
ments is true. In all other cases they return false. If you’re comparing expressions
more complicated than true and false, it’s wise to put them in parentheses.
There are two additional operators for situations where you don’t
want or need to evaluate all of the arguments. The andalso opera‐
tor behaves like and but evaluates the second argument only if the
first one is true. The orelse operator evaluates the second argu‐
ment only if the first one is false.
The not operator is simpler, taking just one argument. It turns true into false and
false into true. Unlike the other boolean operators, which go between their argu‐
ments, not goes before its single argument.
Atomic Booleans | 27
If you try to use these operators with any other atoms, you’ll get a bad argument
exception.
There are other atoms that often have an accepted meaning, like ok
and error, but those are more conventions than a formal part of
the language.
Guards
The fall_velocity calculations work fairly well, but there’s still one glitch: if the
function gets a negative value for distance, the square root (sqrt) function in the cal‐
culation will be unhappy:
5> drop:fall_velocity(earth,-20).
** exception error: bad argument in an arithmetic expression
in function math:sqrt/1
called as math:sqrt(-392.0)
in call from drop:fall_velocity/2 (drop.erl, line 4)
Since you can’t dig a hole 20 meters down, release an object, and marvel as it acceler‐
ates to the surface, this isn’t a terrible result. However, it might be more elegant to at
least produce a different kind of error.
In Erlang, you can specify which data a given function will accept with guards.
Guards, indicated by the when keyword, let you fine-tune the pattern matching based
on the content of arguments, not just their shape. Guards have to stay simple, can use
only a very few built-in functions, and are limited by a requirement that they evaluate
only data without any side effects, but they can still transform your code.
You can find a list of functions that can safely be used in guards in
Appendix A.
Guards evaluate their expressions to true or false, as previously described, and the
first one with a true result wins. That means that you can write when true for a
guard that always gets called if it is reached, or block out some code you don’t want to
call (for now) with when false.
In this simple case, you can keep negative numbers away from the square root func‐
tion by adding guards to the fall_velocity clauses, as shown in Example 3-2, which
you can find at ch03/ex2-guards.
28 | Chapter 3: Atoms, Tuples, and Pattern Matching
Example 3-2. Adding guards to the function clauses
-module(drop).
-export([fall_velocity/2]).
fall_velocity(earth, Distance) when Distance >= 0 -> math:sqrt(2 * 9.8 * Distance);
fall_velocity(moon, Distance) when Distance >= 0 -> math:sqrt(2 * 1.6 * Distance);
fall_velocity(mars, Distance) when Distance >= 0 -> math:sqrt(2 * 3.71 * Distance).
In Erlang, greater-than-or-equal-to is written >=, and less-than-or-
equal-to is written =<. Don’t make them look like arrows.
The when expression describes a condition or set of conditions in the function head.
In this case, the condition is simple: the Distance must be greater than or equal to
zero. If you compile that code and ask for the result of a negative distance, the result
is different:
5> drop:fall_velocity(earth,-20).
** exception error: no function clause matching
drop:fall_velocity(earth,-20) (drop.erl, line 12)
Because of the guard, Erlang doesn’t find a function clause that works with a negative
argument. The error message may not seem like a major improvement, but as you
add layers of code, “not handled” may be a more appealing response than “broke my
formula.”
A clearer, though still simple, use of guards might be code that returns an absolute
value. Yes, Erlang has a built-in function, abs/1, for this, but Example 3-3 makes clear
how this works.
Example 3-3. Calculating absolute value with guards
-module(mathdemo).
-export([absolute_value/1]).
absolute_value(Number) when Number < 0 -> -Number;
absolute_value(Number) when Number == 0 -> 0;
absolute_value(Number) when Number > 0 -> Number.
When mathdemo:absolute_value is called with a negative (less than zero) argument,
Erlang calls the first clause, which returns the negation of that negative argument,
making it positive. When the argument equals (==) zero, Erlang calls the second
Guards | 29
clause, returning 0. Finally, when the argument is positive, Erlang calls the third
clause, just returning the number. (The first two clauses have processed everything
that isn’t positive, so the guard on the last clause is unnecessary and will go away in
Example 3-4.)
1> c(mathdemo).
{ok,mathdemo}
2> mathdemo:absolute_value(-20).
20
3> mathdemo:absolute_value(0).
0
4> mathdemo:absolute_value(20).
20
This may seem like an unwieldy way to calculate. Don’t worry—Erlang has simpler
logic switches you can use inside of functions. However, guards are critically impor‐
tant to choosing among function clauses, which will be especially useful as you start
to work with recursion in Chapter 4.
Erlang runs through the function clauses in the order you list them, and stops at the
first one that matches. If you find your information is heading to the wrong clause,
you may want to re-order your clauses or fine-tune your guard conditions.
Also, when your guard clause is testing for just one value, you can easily switch to
using pattern-matching instead of a guard. This absolute_value function in
Example 3-4 does the same thing as the one in Example 3-3.
Example 3-4. Calculating absolute value with guards and pattern matching
absolute_value(Number) when Number < 0 -> -Number;
absolute_value(0) -> 0;
absolute_value(Number) -> Number.
In this case, it’s up to you whether you prefer the simpler form or preserving a parallel
approach.
You can also have multiple comparisons in a single guard. If you
separate them with semicolons it works like an OR statement, suc‐
ceeding if any of the comparisons succeeds. If you separate them
with commas, it works like an AND statement, and they all have to
succeed for the guard to succeed.
Underscoring That You Don’t Care
Guards let you specify more precise handling of incoming arguments. Sometimes you
may actually want handling that is less precise, though. Not every argument is essen‐
tial to every operation, especially when you start passing around complex data struc‐
30 | Chapter 3: Atoms, Tuples, and Pattern Matching
tures. You could create variables for arguments and then never use them, but you’ll
get warnings from the compiler (which suspects you must have made a mistake) and
you may confuse other people using your code who are surprised to find your code
cares about only half of the arguments they sent.
You might, for example, decide that you’re not concerned with what planemo (for
planetary mass object, including planets, dwarf planets, and moons) a user of your
velocity function specifies and you’re just going to use Earth’s value for gravity. Then,
you might write something like Example 3-5, from ch03/ex3-underscore.
Example 3-5. Declaring a variable and then ignoring it
-module(drop).
-export([fall_velocity/2]).
fall_velocity(Planemo, Distance) -> math:sqrt(2 * 9.8 * Distance).
This will compile, but you’ll get a warning, and if you try to use it for, say, Mars, you’ll
get the wrong answer for Mars.
1> c(drop).
drop.erl:5: Warning: variable 'Planemo' is unused
{ok,drop}
2> drop:fall_velocity(mars, 20).
19.79898987322333
On Mars, that should be more like 12 than 19, so the compiler was right to scold you.
Other times, though, you really only care about some of the arguments. In these
cases, you can use a simple underscore (_). The underscore accomplishes two things:
it tells the compiler not to bother you, and it tells anyone reading your code that
you’re not going to be using that argument. In fact, Erlang won’t let you. You can try
to assign values to the underscore, but Erlang won’t give them back to you. It consid‐
ers the underscore permanently unbound:
3> _ = 20.
20
4> _.
* 1: variable '_' is unbound
If you really wanted your code to be earth-centric and ignore any suggestions of other
planemos, you could instead write something like Example 3-6.
Example 3-6. Deliberately ignoring an argument with an underscore
-module(drop2).
-export([fall_velocity/2]).
fall_velocity(_, Distance) -> math:sqrt(2 * 9.8 * Distance).
Underscoring That You Don’t Care | 31
This time there will be no compiler warning, and anyone who looks at the code will
know that first argument is useless.
5> c(drop2).
{ok,drop2}
6> drop2:fall_velocity(you_dont_care, 20).
19.79898987322333
You can use underscore multiple times to ignore multiple arguments. It matches any‐
thing for the pattern match, and never binds, so there’s never a conflict.
You can also start variables with underscores—like _Planemo—and the compiler
won’t warn if you never use those variables. Those variables do get bound, and you
can reference them later in your code if you change your mind. However, if you use
the same variable name more than once in a set of arguments, even if the variable
name starts with an underscore, you’ll get an error from the compiler for trying to
bind twice to the same name.
Adding Structure: Tuples
Erlang’s tuples let you combine multiple items into a single composite data type. This
makes it easier to pass messages between components, letting you create your own
complex data types as you need. Tuples can contain any kind of Erlang data, includ‐
ing numbers, atoms, other tuples, and the lists and strings you’ll encounter in later
chapters.
Tuples themselves are simple, a group of items surrounded by curly braces:
1> {earth, 20}.
{earth, 20}
Tuples might contain 1 item, or they might contain 100. Two to five seem typical (and
useful, and readable). Often (but not always) an atom at the beginning of the tuple
indicates what it’s really for, providing an informal identifier of the complex informa‐
tion structure stored in the tuple.
Erlang includes rarely used built-in functions that give you access to the contents of a
tuple on an item by item basis. You can retrieve the values of items with the element
function, set values in a new tuple with the setelement function, and find out how
many items are in a tuple with the tuple_size function.
2> Tuple = {earth, 20}.
{earth,20}
3> element(2, Tuple).
20
4> NewTuple = setelement(2, Tuple, 40).
{earth,40}
5> tuple_size(NewTuple).
2
32 | Chapter 3: Atoms, Tuples, and Pattern Matching
Random documents with unrelated
content Scribd suggests to you:
before. Bad's the best, they say, but better bad than worse; and so it
was in my case, for now I was left in the dark without anything to
eat or drink at all for a great many hours, till the sunshine came in
at a hole up above, and I began to whistle to pass the time. Soon
after I was taken out, and was carried to a room where there were
five or six people, and a large curtain across one end of the room.
There was a table, too, with several things upon it, some little and
some big, made of iron, and of very odd unpleasant shapes. One
was like a barbecuing spit, only not so big; and I heard them call it
the boot. A stout man was standing by the table, twice as big as I
am, with his jerkin off and his sleeves turned up. I did not like his
look at all. When I was brought in, those who were at the table
began to cross-question me in all manner of ways as to what I did in
Scotland, and how I came to be at Trochrie; and I beat about the
bush a long time, especially when they asked me about my lady----"
"Then they knew already she was there?" said the earl.
"I'm not quite sure, my lord, now," said Austin Jute, frankly. "They
seemed to know at the time; but I believe they took me in. I would
not tell you a lie, my lord, for the world; but I've a strong notion
they made me betray myself, by pretending to know more than they
did. I'm very sorry for it; but what's done can't be undone. A bolt
that's shot must go its own way. However, when I found that, either
by what I said or by what they themselves knew, they were quite
sure of the matter, I refused to answer any more questions as to
how she was brought there, and all the rest. Then they threatened
to put the boot on me, as they called it. I did not like that at all. I
should have fancied my leg a pig being roasted alive; but instead of
that they put a thing upon my thumb, and told me to answer truly,
or it should be screwed up."
Gowrie rose from his seat, and walked up and down the room
with his cheek flushed and his brow contracted; but he said nothing;
and, after gazing at his lord for a moment, Austin Jute continued.
"They changed their course now, however, and began asking if I had
been with you in Italy; so I said I had. Then they inquired where you
had hired me; on which I said, in Padua, five years ago. After that,
this question arose, whether I had known the lady Julia there, and
her grandfather, and how long. It was an unpleasant sort of
catechism with that thing dangling at my thumb; but having heard
the king talk at Falkland about the lady's money, and how much he
expected to make by having her in ward, I saw what they were
seeking, and I said to myself, they'll come to the money in a few
minutes. A nod is as good as a wink to a blind horse, and so I
answered, boldly, that I had known her and the old gentleman ten
or twelve years, long before your lordship came to Padua."
"But that was false," exclaimed the earl.
"I can't help that, my lord," replied Austin Jute; "it answered its
purpose. As I had got into a scrape by letting out the truth, there
was only one way of mending it--by letting out some falsehood. Put
them into two scales, and the one will balance the other. If people
ask me questions they have no business to ask, they may get
answers that I have no business to give. However, they asked me
how the old gentleman and the young lady lived in Padua, and
knowing I could do no mischief now, I said, 'Heaven knows. They
were poor enough, in all conscience; but where they got what little
they had, I can't tell.' Then a club-footed man, that sat at the end of
the table, said quietly, 'Then they did not keep up much state;' at
which I laughed, and made him no answer, as if the very thought of
such a thing was too ridiculous; upon which that accursed fellow,
with the sleeves turned up, gave a turn to the thing upon my thumb,
and sent a pain running all the way down to the soles of my feet. I
never felt anything like that. I had well nigh roared with it; but I set
my teeth hard and held my breath; and the man at the end of the
table checked the tormentor for what he had done, and bade him
keep his hands off till he was bid. So the thing was unscrewed; and
then they asked me how many servants the old signor kept, and I
humbly inquired whether they meant men or maids. The answer
was, 'Both,' to which I replied, 'One, and she was an old woman. So
it answered both purposes.' The man with the club-foot called me a
saucy knave, and tried to look very angry; but he laughed
notwithstanding, and inquired if I were sure there had been no more
kept; and I answered, 'Not one as long as I had known the family.'
The other questions were all of the same sort, and they tried to
puzzle me very hard; but they could not manage it, though they
talked about a man servant whom they pretended the signor had
kept. To that I had my answer pat, however--that I was ready to
swear upon the Evangelists that there had never been any but one
and the same servant there for ten years. 'Whether it was a man or
a woman,' I said, 'it was impossible for me to say. Their honours
knew best; but one thing I would take my oath of, that it wore
petticoats and was called Tita.' Thereupon there was a great burst of
laughter; and the room had a strange echo in it, for the same
sounds came back from behind the curtain."
"The party seems to have been a merry one," said the earl,
"considering the circumstances."
"Nevertheless, they took me back, and plunged me into the same
dark hole, and left me there till this morning, when I was taken out,
in an oddish kind of way, not by a jailor or a guard, but by two
gentlemen. There was a little boy, about as high as my knee,
standing by a garden-gate to which they brought me, and he had
my horse in his hand. So they told me to get up and ride away, as if
Satan were behind me, back to Trochrie, and not to say a word to a
living soul, but more especially to you, my lord, of anything that had
happened; and they threatened me sore, moreover. I did ride away,
for I was glad to be out of their hands; but I remained at the south
ferry house till dusk, and then came back to seek your lordship and
tell you all."
"You have done well, Austin," replied Gowrie, "and are an honest
faithful fellow. I was nearer to you and them, when they mounted
you this morning, than either knew; and I heard something said
about starving your horse."
"Oh, that was but a snap, my lord, where I had no teeth to bite
hard," replied Austin. "I know that a bitter word is often worse than
a sharp sword. So, having nothing else to say, I told them they had
starved my horse to make him like themselves. I took care to be in
the saddle first, however; but, instead of trying to stop me, one of
them gave the poor beast a cut with his whip, and sent us both
about our business."
How the king had obtained information that Julia was concealed
at Trochrie was now in part revealed; but only in part, for it was
evident, from Austin's capture and examination, that some hint had
been gained before--how, Gowrie could not divine. The honest
servant was sent back before dawn on the following day, on his way
to the highland castle, and he did not depart without a liberal
reward, which he accepted without ceremony, for there were no
affectations about good Austin Jute. He served faithfully, devotedly,
where he attached himself; he would at any time have perilled life or
limb, or sacrificed every comfort and convenience for a lord he
loved; and, to say nought but truth, I do not think that, in so doing,
he ever in his inmost heart thought of a recompence, but he took it
willingly enough when it was given, and, sad to say, spent it with as
little consideration as he won it.
Several more days elapsed ere the paper Gowrie required was
drawn up by the men of law, and he twice presented himself at the
palace. All there seemed still fair and smooth; the king's good
humour lasted undisturbed; the queen was ever kind and gracious;
Sir Hugh Herries did not appear at court, and John Ramsay, though
distant to Alexander Ruthven, was warmer in his manner to the earl.
"Beatrice's doubts are unfounded, I do believe," thought Gowrie,
as he rode away after the second visit; and when he returned to his
own dwelling, he found the act of renunciation waiting for him.
Somewhat less than an hour of daylight still remained, and that time
was spent in reading and considering the document.
The sun had just set, leaving a bright glow in the April sky, and
Gowrie had risen to gaze at it from a window which looked out
towards the west, when suddenly he heard a hasty foot in the ante-
room, and the next instant Sir John Hume entered in haste.
"Here, Gowrie," he said, advancing with a small paper folded and
sealed in his hand. "Here is something for you. What it contains I
know not; but Beatrice slipped it into my hand in haste and
agitation, saying, in a whisper, 'To Gowrie, with all speed.'"
Gowrie took it, tore it open, and found the words, "Away, with all
speed, to Perth!--to-night!"
"My lord, here is Sir George Ramsay without, desiring to see you,"
said a servant, looking in.
"Admit him," replied the earl, crushing the paper in the palm of
his hand.
The next moment Ramsay entered, with as much apparent haste
as Hume; but on seeing the latter he paused, assumed a calmer air,
and advancing to the earl, shook hands with him, saying, "It is a fair
and warm afternoon, my lord, what say you to a twilight ride?"
"Not to-night, Dalhousie," replied Gowrie, gazing at him
attentively; "have you any particular object in your proposal?"
"Only to have a few minutes' conversation with you, my dear
lord," replied the other, returning his glance with one of equal
significance; "but a moment here in private will do as well;" and he
moved towards a distant window.
Gowrie followed him, bending down his head; and Ramsay
approaching close, whispered in his ear, "You are in danger, my lord.
It were well you departed at once. Lose no time--I dare not say
more."
Gowrie pressed his hand kindly and gratefully, saying, "Thanks,
Dalhousie, thanks! I had heard the tidings before; but the obligation
to you is no less."
He spoke openly and aloud; and his friend, laying his finger on his
lip, as if to counsel discretion, retired almost as hastily as he had
come.
Ere half an hour had passed, the earl was on horseback, and
riding towards Queensferry.
CHAPTER XXXV.
It was a bright, hot summer day, the sky without a cloud, the air
without a breeze. The sports of the morning were over, the hounds
had returned to their kennel, the slaughtered stag was brought in,
the horses were in the stable, the hunters seeking repose. The old
palace of Falkland, where James V. drew the last breath of a life
which had become burdensome, rose stately amidst its gardens and
woods; and the old trees, but few of which now remain in the
neighbourhood, then spread their wide branches over the velvet
turf; in some places approaching so near to the building, as, when
the wind waved them, to brush with their long fingers the palace
walls. James himself had gone in about an hour before, rejoiced with
the success, but fatigued with the exertions, of the chase; and all
the ladies of the court were screening their beauty in the shady
halls, from the glare of the full sun.
It has often struck me, in looking at the finer paintings of Claude
de Lorraine--and they are not all really fine--and in contemplating
the calm, quiet, sunny scenes they represent, that the painter must
have chosen, by preference, that hour when, under the summer
skies of Italy, all nature seems to be taking a mid-day slumber. Such
was the aspect of the scene about the palace of Falkland on the day
of which I speak. Looking towards the wood, and with one's back
towards the palace, so as to shut out its memorial of active life, one
might have fancied that one was in the midst of some primeval
solitude, or else that the whole world, oppressed with the heat, was
sound asleep. No moving object was to be seen; not a forester or
keeper was within sight; the deer were hidden in the coverts of the
wood; the very birds seemed to avoid the glare; and the court
servants themselves--those busy toilers--were all enjoying the
repose afforded by the weariness of their lords.
At length, however, after the scene had remained thus quiet for
about half an hour, a very young but very handsome man sauntered
forth from one of the smaller doors of the building, crossed the
warm green in front, turned to one of the old trees, stood for a
moment under the shade, and then walked languidly to another,
near an opposite angle of the palace. He seemed seeking a place for
repose, but difficult to please, for he again left that tree and strolled
to its green neighbour, where, stretching himself on the grass, he
laid a book, which he carried with him, open on the ground, and
supporting his head with his arm, gave himself up to thought. Oh,
the thoughts of youth--the gay, the whirling, dream-like thoughts of
youth! How pleasant is the visionary trance which boys and girls call
meditation! True, youth has its pains as well as pleasures, both
eager, intense, and thrilling; but it wants the fears and doubts of
experience, that bitterest fruit of long life. The cloud may hang over
it for an hour, but the breath of hope soon wafts it away, and it is
not till the storm comes down in its full fury that youth will believe
there are tempests in the sky.
There he lay and thought, with the branches waving gently over
him, and the chequered light and shade playing on his face and on
the open pages of the unread book beside him. The air was very
sultry, even beneath the shadow of the trees, and he untied the cord
which confined his silken vest at the neck, displaying a skin almost
as fair as a woman's, although exercise, it would seem, was not
wanting to give a browner hue; for even then he looked fatigued as
well as heated, and there was dust upon his hair and upon his dress,
as if he had ridden far and long that day. Weariness, and the hot
summer air, with the playing of the shadows over his face, seemed
to render him sleepy. His eyes looked heavy for a moment or two,
the eyelids closed, opened again, closed once more, and there he
lay, sound, sound asleep, not unlike what we may fancy was the
shepherd boy of Latmus, when under the influence of the fair queen
of night.
Some quarter of an hour had passed, and he still lay sleeping
there, when round that angle of the building near which the tree
grew, came walking, with a slow pace, a man of middle age, with an
ungraceful gait, and of an ungainly appearance. He was habited in a
suit of green, with a large ruff round his neck, and a tall crowned
gray hat and feather; but he wore neither cloak nor sword, and
instead of the latter, bore a small knife or dagger, stuck into his
girdle on the left side. He, like the youth, seemed to have come out
of the palace for fresher air than could be found within; and he, too,
appeared in a meditative mood, for he walked with his eyes bent
down, and his hand, in no very courtly fashion, scratching his breast.
Nevertheless, from time to time, he gave a glance around; and the
second time he did so, his eye fell upon the sleeping youth beneath
the tree. With a quiet step he approached his side, but was instantly
attracted by the open book, and took it up.
"Ay," murmured he, in a low tone, "love songs! That's just it; fit
food for such a wild, empty-pated callant's brain."
Thus saying, he laid down the book again, and gazed upon the
young man's face.
Suddenly he saw something which seemed to displease him
mightily. His cheek flushed, his brow contracted, and he set his teeth
hard. Then, bending down his head, he peered into the open bosom
of the lad, and even partly drew back the collar of his shirt. It was
done quietly and gently, but still it in some degree roused the
sleeper, for he lifted his hand and brushed his throat, as if a fly had
settled on him. The other started back instantly, but the young man
did not wake; and the one who watched him continued to gaze at
him sternly, with many a bitter feeling, it would appear, in his heart.
His lip quivered; and for a moment he held his hand upon the hilt of
his dagger, with a somewhat ominous look, and a cheek which had
become pale. Then, however, he seemed to have made up his mind
as to what he should do; and, stepping quietly back over the soft
green turf, he approached one of the doors of the palace, which was
close at hand, and tried to open it. It was locked, however, and
turning on his heel again, with a low muttered blasphemy, he went
round the angle of the building by the way which he had followed
when he came.
Neither the sleeper, nor he who had lately stood beside him, was
aware that there was another eye upon them both; but the instant
the latter had departed, the door which he had tried in vain opened
suddenly, and the light beautiful form of Beatrice Ruthven darted
forth, crossed the green sward with the quick spring of a roe deer,
and stooping over the sleeping youth, without care or ceremony, she
tore from his neck a thick blue silk ribbon worked with gold.
The young man raised himself suddenly on his arm, looking
surprised and bewildered; but Beatrice laid her finger on her lips,
merely saying, in a low but emphatic tone, "Into the palace like
lightning, mad boy!" and away she sprang towards the building
again, passed the door, ran through the first passage, and up a
narrow staircase to the entrance of a room on the first floor. There
she paused and listened for a single instant, then threw the door
open without ceremony and ran in.
Anne of Denmark was seated at a table, writing; but the sudden
opening of the door made her lift her fair face with a look of some
surprise and displeasure; and she said, in a reproving tone,
"Beatrice! What now?"
Without reply, the fair girl darted forward in breathless haste, and
laid the ribbon on the table before the queen.
"Quick, madam! put it in the drawer," she said, in a low, hurried
tone. "Your majesty will see why in an instant;" and without waiting
for any answer, she hurried from the room by the same way she had
come, and closed the door.
There were several drawers in the writing table at which the
queen was seated; and opening one with a hand which trembled
slightly, while her cheek glowed a good deal, she placed the ribbon
in it, closed it again, and tried to resume her writing; but not more
than one minute had passed ere the step of the king was heard
upon a staircase at the opposite side of the apartments from that by
which Beatrice had entered, and a moment after James himself
appeared, with a heavy scowl upon his brow.
Anne of Denmark looked up, not without some timidity, though
she was by nature very intrepid. There was no expression, however,
upon her countenance which could betray the agitation within; and
seeing the look of anger and malice on James's face, she boldly took
the initiative, saying, "What is the matter, sir? You seem disordered."
"No, no, my bonny bairn," said James, "there's nothing the
matter; but I was just thinking what clever chiels those Italians are;
and I want to see that ribbon which I bought for you of the
merchant man."
"Certainly, sir," replied the queen, rising, with an unconcerned
look, for she wished to test how far James's suspicions went; "you
shall see it in a moment."
"No," cried the king, hastily, thinking that the queen was going to
quit the chamber. "You had it in this room, madam, not so long ago
that you need go to seek it. It's here you keep all your gauds and
ornaments."
"Well, sir," answered Anne of Denmark, "I have no doubt that it is
here still; but I cannot even open the drawers of this table, to look
for it, without rising. I know not what is the matter with your
majesty, but your conduct is very strange."
"I just want to see the ribbon, madam, that is all; and I think it
must be in this chamber--if anywhere," was James's reply.
"Doubtless," answered Anne of Denmark, so far agitated as to
open the wrong drawer by mistake.
"It's no there," said the king, looking into the drawer. "There's
naething there but gloves, and bracelets, and such like clamjamfry."
"I see it is not, sir," replied the queen, turning over the things
with her hand; "but it may be somewhere else. Do you think any
one has stolen it?" And she opened the drawer in which it really was.
James did not reply to her question; but not a little astonishment
was painted on his rude coarse countenance, when Anne of
Denmark drew forth the ribbon and laid it in his hand. He continued
to gaze at it for a considerable time, and then put it closer to his
eyes, to examine it more carefully all over, as if he doubted that it
was really that which he had bestowed upon the queen. There it
was, however, precisely the same in every respect; and at length he
gave it her back again, and turning sharply on his heel, quitted the
room, muttering, loud enough for her to hear, "De'il tak me, if like be
not an ill mark."
A minute or two after, he was seen walking past the tree under
which Alexander Ruthven had been sleeping; but by that time the
young gentleman was gone.[4] One of the ordinary servants of the
court passed his majesty, bowing low, a moment after; and the king
called him up, saying, as he approached, "Go your ways, and rout
me out Doctor Herries and the man retiring," James continued to
walk up and down till he was joined by the person whom he had
sent for. They then turned to the farther part of the gardens, much
to the disappointment of Beatrice Ruthven, who saw all that passed
from the window of a room immediately below that of the queen,
and who had hoped to gather, at least from their demeanour, some
indications of what was passing in regard to her brother. I will not
say that she would not have listened eagerly to their conversation if
the opportunity had presented itself; and perhaps the circumstances
in which she was placed might be some justification of an act
otherwise mean and pitiful; for, as the reader will see in the
subsequent chapter, she had accidentally obtained information of
designs the most treacherous against one dear brother, of whose
high principles and noble conduct she could not entertain a doubt.
The king and his companion, however, walked away to the other
side of the garden, as I have said, and stayed there for nearly half
an hour, while Beatrice remained in anxious and painful thought. Her
head rested on her hand, as she sat near the open window; and she
had taken no note of how the time passed, when at length the
sounds of people speaking as they walked by below, caught her ear.
She would not move in the slightest degree; she even held her
breath, lest she should lose one sound, and the next instant she
distinguished the king's peculiar tone. The words as yet she could
not hear, and still less those of Herries in his reply, though she
recognised his voice at once.
The next instant, however, the sounds rose louder, and James was
heard to say, "No, no, that will never do. We should lose our grip of
the old bird, while wringing the neck of the young one; and there
would be such a dust about it, that we should never see our way
clear after."
"There, I think, your majesty is right," said Herries; "but if you will
be advised by me there is a way to----"
Beatrice lost the conclusion of the sentence, for they moved on
towards the other end of the terrace. She knew, however, that none
of the royal apartments lay in that direction, and that the only door
by which the king could enter led through the great hall, where he
must necessarily encounter a number of the servants and followers
of the court, a thing which James rarely desired. She approached
somewhat nearer the window then, calculating that the two who had
passed would return by the same way; nor was she disappointed,
for, in a very few minutes, she heard the voices again, and the
words of the king soon became audible. They were of no great
importance, indeed, and conveyed no information but that which she
already possessed--namely, that both her elder brothers were the
principal objects, for the time, of James's hatred and suspicion.
"The de'il helps they Ruthvens, I think," said the monarch. "The
one brother conveys himself away just at the minute when we have
got all ready for him; and the other sends a token I would swear to,
fleeing through the walls of Falkland like a conjuror."
This was all that Beatrice heard, but after they had passed the
window, Doctor Herries replied, "The devil always helps his own,
sire."
"And that's well said," answered the king, "for we have
information to be relied upon, that this Earl of Gowrie, when in the
city of Padua, had long and familiar dealings with a reputed sorcerer
and magician, some of whose infernal arts he has doubtless acquired
or contracted. Such matters are difficult of proof, for deeds of
darkness hide themselves from the light. But time discovers many
things, and Sathanus deals with his pets as we do with the birds and
beasts which we keep for our food. He pats them on the back till his
time comes, and then he cuts their weasands."
Doctor Herries smiled, for he was not so credulous in matters of
demonology as his master; but by this time they had reached one of
the smaller doors of the palace, which stood open, and they went in.
CHAPTER XXXVI.
I must now go back for a period of more than a month. Gowrie on
quitting Edinburgh rode on at a quick pace, hoping to save the tide
at Queensferry; but he did not succeed. The water had sunk low,
and the boat was on the shore. There was no resource but either to
ride farther up in the direction of Stirling, or to wait till the next
morning. Gowrie chose the latter course, though at the chance of
being pursued and overtaken. He did not like the feeling of flight;
and though it might be necessary, and he had already adopted the
expedient as the only means of security, his repugnance was
sufficient to turn the scale, when, on the banks of the Firth of Forth,
he had to consider what was the next step to be taken. All passed
quietly at the little inn, however. No signs or sounds of pursuit
disturbed the night; and by grey of the dawn on the following
morning, the earl and his followers were upon the shores of Fife. A
short ride brought them into Perthshire; and then feeling in safety,
the young earl paused at the first village, to consider what course he
had better follow. If he went on to Perth, he saw that he might be
detained there for some time. It was long since he had seen her
whom he loved; and he felt that yearning of the heart to hold her in
his arms again, which those who have loved truly can well
comprehend. He was also somewhat anxious for her safety after all
that had occurred to Austin Jute; but then, on the other hand, the
few brief words which his sister had written, had indicated Perth as
the place where he ought to take refuge; and it was not improbable
that she might either know of some ambush on the way to Trochrie,
or intend to send him further information before he went. The
importance of receiving the speediest intelligence of what was
passing at the court, decided him at length to act contrary to his
own wishes, and he resolved to sleep that night at least in Perth.
Hardly had he risen on the following morning, when, at one and
the same time, it was announced to him that one of the magistrates
of the town desired to see him, and that a messenger from Dirleton
had just dismounted in the courtyard. The latter was instantly
admitted, and presented the earl with a packet addressed in his
mother's hand. On opening it, however, he found a sealed letter
from his sister, and also a few lines from the countess, informing him
that the enclosed had come that morning from Beatrice, with the
request that it might be forwarded instantly, and by a trusty
messenger, to Perth. The letter from his sister contained the
following words:--
"My dear and noble Lord and Brother,
"I had but time and opportunity to write you a very few words
yesterday evening, which Hume must have delivered safely, as I find
this morning that you have followed counsel, and are gone. I now
send you farther information, not direct to Perth, but by the hands of
our dear lady mother, lest what I write should be stopped by the
way. All is quiet here at this present, but some people are much
disappointed, I believe, in their hearts. The cause of my warning
was as follows.--My maid, Margaret Brown, who is very faithful to
me, but of a very prying and inquisitive disposition, and not without
shrewdness, informed me that danger awaited you, my dear brother.
She had seen that something was going on, it seems, in the abbey,
which excited in her some suspicion; and her cousin, Robert Brown,
a menial servant of the palace, after having been called to the
presence of the king, said to her, unadvisedly, as she was coming to
my room to aid me in changing my dress for the court in the
evening, 'Your lady will have a sore heart before long.' Thereupon
the girl, after having dressed me, employed all her art and ingine to
draw forth from the man what it was he meant, and succeeded so
far as to learn that you were to be arrested the next morning; but in
such a sort, without due warrant or form of law, and with insults and
injuries belike, as might bring you to resistance, when, a fray being
created, you might perchance be killed without there seeming blame
to any one. This was the girl's story. She having got some one of the
court to call me out of the presence, and having always found her
faithful and true of tongue, I wrote hastily the words I sent, and
gave them to our friend Hume, to be delivered to your hand.
"Thus far is the girl's story confirmed since your departure, that I
have it from a certain source, several people well armed went down
to your house this morning, and others followed them not far
behind, even so much that the street was crowded. On arriving they
asked for you of the porter, but learning that you had gone for Perth
on the night before, and being confirmed of the fact by one who saw
you ride away, they separated and retired, not having told the
reason of their coming. This makes me well satisfied that I warned
you as I did, and assures me that you have not been driven away
needlessly by your loving sister,
"Beatrice Ruthven."
"I must have forgotten Scotland," murmured Gowrie to himself.
"Heaven! what a dream I have been living in!"
Perhaps what he said was true. We are all apt to forget the evils
and discomforts of a place we have left behind. Memory is fond of
pleasant objects, and plants thick ivy shrubs to rise up and decorate
the ruins of the past. He had forgotten the turbulence and dangers
which had surrounded his early days. He had almost brought himself
to fancy that, as compared with Italy, Scotland was a place of peace,
and security, and freedom, where the assassin's knife, the
oppressor's wrong, the tyrant's sway were comparatively unknown.
But the bitter reality was now before him; and he saw that to be an
enemy of the court was to be but a hunted beast, whom every dog
of favour might pull down and tear at liberty.
After a few minutes' thought, however, he cast off the impression,
and sent for the bailie, who was waiting to speak with him. This
magistrate was the reverse in everything of his junior, Bailie Roy--
tall, thin, and raw-boned in person, somewhat bluff, and very laconic
of speech; a man to be moved neither by fear or favour, but strong
in his attachments and steady in his sense of right. He made an
ungainly bow in answer to the earl's salutation, and at once dropped
into the seat which he was invited to take.
"I have come, my lord," he said, "about the prisoner, David
Drummond."
And there he stopped, as if all his say was said.
"Well, Mr. Bailie, what of him?" rejoined the earl. "I hear he has
not been tried yet. If you will name the day most convenient to the
magistrates, I will come down for the purpose, and hold a court."
"They were thinking of the twenty-second of the month,"
answered Bailie Graham; "aiblins that might not suit your lordship?"
"Quite well," answered Gowrie. "I will be down, undoubtedly."
Still Mr. Graham continued to sit and twirl his beaver, as if
labouring with some other question or announcement; and at length
he said, "Your lordship would not see the prisoner?"
"Certainly not," answered Gowrie. "He has been my own servant;
and even that might be supposed to have some effect upon my
judgment; but I can have no private communication with him while
awaiting trial. If he have anything to request, either to make
imprisonment more tolerable or to provide for his defence, let him
demand it publicly."
"He said he would write to the king, my lord, when he was told of
your answer," replied the bailie; "and he did it."
"Can he write?" asked the earl, in some surprise.
"No, not just with his own hand," said Mr. Graham; "but he got a
scrivener to do it for him; and Bailie Roy, one way or another, got
goodman Jobson to tell him what it was he said."
"I do not wish to hear, Mr. Bailie," said the earl. "It was probably
intended for the king's ear alone."
"Ay, that it was," said the bailie, drily; "and no doubt his majesty
will think no more of it than it deserves. It's not like to do the Earl of
Gowrie much harm, I should think."
"I cannot tell," replied Gowrie, coolly; "but the unfortunate man
must have his own way. If the king thinks there is anything
important in his memorial, he will probably have the prisoner
examined before the council."
"Na, na, my lord, he'll no do that," answered Bailie Graham. "He's
gotten a' that the man can gie; and so he may lie where he is for the
king."
A few words more explained to Gowrie that James had already
sent some one from Edinburgh to confer with the prisoner in his cell;
but that since then, "sin syne," as the bailie expressed it, no farther
notice had been taken of the unfortunate David Drummond.
I must not say that Gowrie had no curiosity to know what the
prisoner had said in his letter to the king; but he would not suffer it
to master him, although he had little doubt that the first intimation
of Julia's concealment at Trochrie had been thus communicated to
James, and he did not feel at all sure that many parts of his conduct
might not have been misrepresented by the sullen spirit of revenge
which he had often remarked in the prisoner.
"It is very possible, Mr. Bailie," he said, "that this man may have
attempted to injure me in his majesty's opinion by false or perverted
statements; but that shall not prevent me from doing all that justice
requires, without the slightest consideration of consequences. We
will proceed, then, to the trial on the day you have named, and I
shall not think it necessary even to let his majesty know the time
appointed, for although it would not become either you or me to
stop a letter addressed to our sovereign, yet the transaction is one
with which we have nothing to do; and we must fulfil our duties as if
it had not taken place."
"I knew your lordship was right," said Bailie Graham, in broader
Scotch than I shall attempt to transcribe. "Bailie Roy, poor body,
thought it would have been better for you to have seen the man,
and spoke civilly to him till he was hanged; but I said that was not
the way a provost of Perth should act; and so good morning to your
lordship. Let them say what they will of you, this is the way to win
through all."
Alas! that it should not always be as the worthy merchant said,
and that this history should afford a pregnant example of the
reverse.
Within an hour after the good man had departed from the earl's
great house at Perth, Gowrie himself took his way towards Trochrie,
riding with the spirit of love to hurry him forward. Gay and bright
were the dreams that he dreamed by the way; and a feeling of
rejoicing seemed to fill his heart as he thought that he had cast off
the trammels of a court, and resumed that private station in which
he now felt sure that happiness was only to be obtained. It would
seem that fate or chance takes a delight in throwing obstacles in the
way of impatience, perhaps as a check to its vehemence, and a
warning to go more quietly. Though he set out early from Perth, and
might have ridden the distance to Strathbraan in a few hours, a
thousand petty accidents beset the earl by the way. A ford, which
used to be practicable at almost all seasons, was now found
impassable, for there had been rain in the hills. The earl's own horse
cast a shoe, and it had to be replaced before he could proceed; and
lastly, turned by the necessity of crossing the river higher up, into a
more difficult and dangerous path, one of the horses slipped over a
rocky bank, was severely injured, and the rider taken up insensible.
The care of the poor man occupied some time; and so much was
lost in this and other manners, that the sun had set nearly half an
hour when the earl came to the spot whence the first view of
Trochrie Castle was to be obtained. He looked eagerly forward
through the thickening shadows of the night: the castle itself was
lost in the darkness; but a light streamed forth from two spots, side
by side, and Gowrie gladly recognised the position of the room in
which Julia sat. Oh, how cheering, how gladdening are the lights as
we approach after a long absence; what a tale does that faint
distant spot of brightness tell to the heart, of peace, and love, and
calm domestic joy, and all the hopes that gather round the hearth of
home!
Onward he went then, with renewed impatience, and in ten
minutes more he held Julia gladly to his heart. It was a moment that
well repaid all the cares and anxieties and griefs he had suffered.
And there they sat side by side, and gazed at each other in
silence, with her dear hand locked in his, and the heart looking out
through the window of the eye; and each had much to say to the
other, but still it was long unsaid, for emotions would have way
before words.
"You look pale and sad, Gowrie," said Julia, at length. "I fear you
have met with disappointment."
"No, indeed, dear girl," he answered, "I am not sad, nor have I
reason to feel disappointment. My sensations have been very mixed,
as all the feelings produced by the great world are; but now joy
certainly predominates, for I am with you, and bear you some happy
tidings. Then, as to disappointment, dearest Julia, I may experience
some at finding that my fancy had drawn pictures of men and things
in this, my native land, in colours far too bright; but that was my
own fault or my own folly; and in the most essential point of my
hopes, I have succeeded as far as I could expect."
"Thank Heaven for that!" replied Julia, with no light words;
"whatever be that point, I am sure that it is a noble and a good
one."
"Nay," said Gowrie, "do not praise too much, my Julia. It is a very
selfish one; but, to keep you in no suspense, let me tell you that the
king has given his consent, in writing, to our union in the month of
September next. All difficulties are thus removed, and I must say
that in this he has acted, to all appearance, generously; for he had
learned that you are here, and might not unreasonably, perhaps,
have expressed some anger at my having concealed the fact."
"I heard from good Austin that he had gained intelligence of my
abode," replied Julia, "and I felt some alarm, especially during your
faithful follower's long and unexplained absence; but I tried to
comfort myself by thinking of all the precautions you had taken
when last you were here; for I can hardly fancy that anything which
Gowrie undertakes can go wrong."
"Would it were so, truly, my beloved," replied Gowrie, somewhat
gloomily.
"See this very instance!" exclaimed Julia. "Have you not
succeeded where we had so little hope?"
"Not succeeded as well as I could wish," answered her lover. "The
king has made it a condition, Julia, that you shall formally renounce
all claim whatsoever upon the estates and property of your father--
even Whiteburn, though settled by deed upon your mother."
He paused a moment, watching her thoughtful face, and then
added, "Nevertheless, I have promised the renunciation in your
name; first, because I knew it was the only means of winning the
king's consent; and secondly, because I found that it was more than
doubtful whether you could establish your claim by law."
"I have but one regret in this case, Gowrie," replied the beautiful
girl--"that I come to you poor and dowerless. Oh, if I had all the
wealth which they say my poor father amassed, how gladly would I
pour it out before you!"
"If that be all, have no regret, my love," replied the young earl--
"right glad am I that you do not possess it. I have wealth enough for
both, my Julia--too much, indeed, it seems; for in this land wealth
and influence do not excite envy alone, but doubt and suspicion
likewise. It is dangerous, I am sure, to be too powerful a subject
under a weak king. However, I have enough, and to spare. If then,
dear one, you will sign the act of renunciation, I will despatch it to
the king to-morrow, and then no objection can be ever raised or
opposition offered."
"Then I must not go to the court to sign it?" asked Julia, eagerly.
"Not unless you wish it," replied Gowrie.
"Thank Heaven for that, too!" she exclaimed. "Wish it! Oh no,
Gowrie. I suppose the time will come when I must go there; but had
I my will, that time would never be. I always dreaded the thought of
courts, and what your dear sister told me of that in which she
dwells, made me more timid and fearful than ever. Oh, promise me,
Gowrie, that we shall spend the greater part of life afar from those
nests of envy, malice, and greediness."
"That promise I will make with all my heart," replied her lover;
"but tell me, Julia, are you not weary of this desert solitude?
Beatrice, who almost always counsels well, has half persuaded me to
keep you immured here till you are altogether my own; for she sees
danger in your residing anywhere not provided so well for defence
as this. She thinks the king might seize upon you, and use the
expectation of your hand as a means of leading me to a course
which my heart and conscience disapprove, or rather, employ the
fear of losing you, to drive me to acts which I am bound to oppose
and to denounce."
"I have never felt weary one day," answered Julia: "fears I may
have had--anxiety to see you again, I may have felt; but weariness,
never; nor shall I, Gowrie. A few short months will soon pass: you
will let me see you at times; I have beautiful nature before my eyes,
books, music, painting, thought, to fill up the time; and what need I
more? Yes, follow dear Beatrice's counsel. Let me rest here, dear
Gowrie, till all places become alike to me, for thou wilt be with me in
all."
Gowrie pressed her gently to his heart, and then withdrew his
arms again; for he felt that, lonely, protected only by his honour, he
must not let even the warmth of the purest love call up a doubt or a
fear in her young heart. His thoughts and words naturally followed
the course in which his feelings led; and he replied, "I will be with
you often, my Julia, though now I must leave you soon, I fear; but
when I return I will try to bring one of my sisters with me to cheer
you."
But Julia had tasted less of the tree of the knowledge of good and
evil, and she answered, innocently, "I want no cheering when you
are with me, Gowrie. Glad shall I be to see them; and if they be like
Beatrice, my heart will open to them like a humble flower to the
bright sun; but Gowrie's presence is life enough for me. But I have
many things to tell you, too; and yet, I know not why, but I think
you have not told me all."
"Oh, there are many minor things to mention," answered the
young earl, doubtful whether it were wisest to inform her of the
dangers which had menaced, or to conceal them, now that he was
safe, at least for the time. "What need," he asked himself, "to
disturb her mind, and keep her in constant agitation, whenever I am
absent, by fears for me, whose life has been already menaced?
Better let her remain in ignorance of the perils that beset my path,
when she can do nought to avert them. Could she act, could she
counsel, could she direct, I would conceal nothing from her; but she
is here helpless and alone, unable to do aught but sit and weep over
the dangers or the griefs of others. Shall I make the hours, lonely
and dull as they must be here, sad and apprehensive also? No, no; I
will not be insincere; and whatsoever she asks, will answer her truly;
but I will say no more upon such subjects than needs must be said."
Perhaps Gowrie went a little further than this, for he purposely led
the conversation away from the subject of his own fate; and all that
Julia learned was, that the king had shown no great love in his
demeanour either for the earl or for his brother. Even this made her
somewhat thoughtful; and to change the subject, Austin Jute was
sent for. He came as fresh, as gay, as ugly as ever; but on this
occasion he had little to tell, for his journey back to Trochrie had
passed without impediment from any other source but his ignorance
of the way. The difficulties he met with from that cause, he
described with considerable humour, telling the answers which had
been given to his inquiries at the different places which he had
passed, and imitating the various dialects of the counties through
which he had gone, which were in those days very strongly marked.
He did very well till he came to the Gaelic, and even then, though he
was utterly unacquainted with the words of the language, he
contrived to give some of the sounds so exactly, that Gowrie could
not refrain from laughter.
Julia rejoiced to see him so gay; and if she had entertained any
suspicion that he was withholding the painful portion of the truth
from her, it was dissipated by the cheerfulness he displayed.
An hour or two thus went by; but Gowrie would not keep her long
from repose, for he longed to go forth with her on the following
morning, and roam through the valleys, and over the hills, now
covered with the yellow broom and the young shoots of the heath.
The weather had become bright and warm. The fair season was
coming on with rapid strides, when the mountains are softened and
decorated by the hand of nature, and their solemn gloom cheered by
the smiles of the sky; and Gowrie thought of many a plan to make
the hours pass pleasantly. "While here," he said to himself, "the
feeling of security will spread a calm and tranquil atmosphere
around us, which we could not obtain in a less wild and solitary spot.
To-morrow, I will take my dear prisoner forth, and show her some of
the beauties of the land to which she is yet a stranger."
At an early hour, therefore, he bade Julia adieu for the night, and
retired to the room which he had ordered to be prepared for himself
in the gate tower. There he held a somewhat long conversation with
Donald Macduff, his baron bailie in Strathbraan; and having
ascertained from him that all strangers had withdrawn from the
neighbourhood, and that a keen watch had been kept up ever since
Austin Jute's capture, lest any of the king's people should be lurking
about in the valleys around, he lay down to rest, and slept more
soundly than he had done for many a night before.
CHAPTER XXXVII.
In a room of no very great dimensions in the fair town of Perth,
were collected a number of persons upon a solemn and serious
occasion. A number of the officers and magistrates of the town were
present, seated on a little sort of platform raised above the rest of
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.
More than just a book-buying platform, we strive to be a bridge
connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.
Join us on a journey of knowledge exploration, passion nurturing, and
personal growth every day!
ebookbell.com
Ad

Recommended

Introducing Elixir Getting Started In Functional Programming 2nd Edition Simo...
Introducing Elixir Getting Started In Functional Programming 2nd Edition Simo...
alejelmigse
 
Getting started erlang
Getting started erlang
Kwanzoo Dev
 
Python Cookbook Third Edition 3rd Edition David Beazley Brian Jones
Python Cookbook Third Edition 3rd Edition David Beazley Brian Jones
vanesacireza
 
Erlang session1
Erlang session1
mohamedsamyali
 
Erlang, an overview
Erlang, an overview
Patrick Huesler
 
Software Design By Example A Toolbased Introduction With Python Greg Wilson
Software Design By Example A Toolbased Introduction With Python Greg Wilson
balisprotzfg
 
Architecting Scalable Platforms in Erlang/OTP | Hamidreza Soleimani | Diginex...
Architecting Scalable Platforms in Erlang/OTP | Hamidreza Soleimani | Diginex...
Hamidreza Soleimani
 
learn you some erlang - chap0 to chap2
learn you some erlang - chap0 to chap2
경미 김
 
Dsa
Dsa
Saswanthram Nagabhyrava
 
Data struture and aligorism
Data struture and aligorism
mbadhi barnabas
 
Dsa book
Dsa book
invertis university
 
PythonIntro
PythonIntro
webuploader
 
python learn basic tutorial learn easy..
python learn basic tutorial learn easy..
MURTHYVENKAT2
 
data structures
data structures
Sai Lakshmi Cheedella
 
Tutor Py
Tutor Py
AkramWaseem
 
Best Python tutorial (release 3.7.0)
Best Python tutorial (release 3.7.0)
youssef bouferdou
 
Tutorial edit
Tutorial edit
Boris Popov
 
0802 python-tutorial
0802 python-tutorial
urvishathummar1
 
0802 python-tutorial
0802 python-tutorial
Zahid Hasan
 
Python everthing
Python everthing
AbdullahAbdullahabdu1
 
Nguyễn Nho Vĩnh - Problem solvingwithalgorithmsanddatastructures
Nguyễn Nho Vĩnh - Problem solvingwithalgorithmsanddatastructures
Nguyễn Nho Vĩnh
 
Python for DevOps Learn Ruthlessly Effective Automation 1st Edition Noah Gift
Python for DevOps Learn Ruthlessly Effective Automation 1st Edition Noah Gift
shanitlicai
 
Erlang is not a city in Germany
Erlang is not a city in Germany
momo-13
 
Python for Everybody
Python for Everybody
vishalpanday2
 
Introduction to Erlang
Introduction to Erlang
Raymond Tay
 
Python for everybody
Python for everybody
Nageswararao Kuchipudi
 
Elements of Programming Interviews.pdf
Elements of Programming Interviews.pdf
Sudhir Biswal
 
Dsa
Dsa
kassimics
 
Peer Teaching Observations During School Internship
Peer Teaching Observations During School Internship
AjayaMohanty7
 
Photo chemistry Power Point Presentation
Photo chemistry Power Point Presentation
mprpgcwa2024
 

More Related Content

Similar to Introducing Erlang Getting Started In Functional Programming 2nd Edition St Laurent (20)

Dsa
Dsa
Saswanthram Nagabhyrava
 
Data struture and aligorism
Data struture and aligorism
mbadhi barnabas
 
Dsa book
Dsa book
invertis university
 
PythonIntro
PythonIntro
webuploader
 
python learn basic tutorial learn easy..
python learn basic tutorial learn easy..
MURTHYVENKAT2
 
data structures
data structures
Sai Lakshmi Cheedella
 
Tutor Py
Tutor Py
AkramWaseem
 
Best Python tutorial (release 3.7.0)
Best Python tutorial (release 3.7.0)
youssef bouferdou
 
Tutorial edit
Tutorial edit
Boris Popov
 
0802 python-tutorial
0802 python-tutorial
urvishathummar1
 
0802 python-tutorial
0802 python-tutorial
Zahid Hasan
 
Python everthing
Python everthing
AbdullahAbdullahabdu1
 
Nguyễn Nho Vĩnh - Problem solvingwithalgorithmsanddatastructures
Nguyễn Nho Vĩnh - Problem solvingwithalgorithmsanddatastructures
Nguyễn Nho Vĩnh
 
Python for DevOps Learn Ruthlessly Effective Automation 1st Edition Noah Gift
Python for DevOps Learn Ruthlessly Effective Automation 1st Edition Noah Gift
shanitlicai
 
Erlang is not a city in Germany
Erlang is not a city in Germany
momo-13
 
Python for Everybody
Python for Everybody
vishalpanday2
 
Introduction to Erlang
Introduction to Erlang
Raymond Tay
 
Python for everybody
Python for everybody
Nageswararao Kuchipudi
 
Elements of Programming Interviews.pdf
Elements of Programming Interviews.pdf
Sudhir Biswal
 
Dsa
Dsa
kassimics
 
Data struture and aligorism
Data struture and aligorism
mbadhi barnabas
 
python learn basic tutorial learn easy..
python learn basic tutorial learn easy..
MURTHYVENKAT2
 
Best Python tutorial (release 3.7.0)
Best Python tutorial (release 3.7.0)
youssef bouferdou
 
0802 python-tutorial
0802 python-tutorial
Zahid Hasan
 
Nguyễn Nho Vĩnh - Problem solvingwithalgorithmsanddatastructures
Nguyễn Nho Vĩnh - Problem solvingwithalgorithmsanddatastructures
Nguyễn Nho Vĩnh
 
Python for DevOps Learn Ruthlessly Effective Automation 1st Edition Noah Gift
Python for DevOps Learn Ruthlessly Effective Automation 1st Edition Noah Gift
shanitlicai
 
Erlang is not a city in Germany
Erlang is not a city in Germany
momo-13
 
Python for Everybody
Python for Everybody
vishalpanday2
 
Introduction to Erlang
Introduction to Erlang
Raymond Tay
 
Elements of Programming Interviews.pdf
Elements of Programming Interviews.pdf
Sudhir Biswal
 

Recently uploaded (20)

Peer Teaching Observations During School Internship
Peer Teaching Observations During School Internship
AjayaMohanty7
 
Photo chemistry Power Point Presentation
Photo chemistry Power Point Presentation
mprpgcwa2024
 
University of Ghana Cracks Down on Misconduct: Over 100 Students Sanctioned
University of Ghana Cracks Down on Misconduct: Over 100 Students Sanctioned
Kweku Zurek
 
IIT KGP Quiz Week 2024 Sports Quiz (Prelims + Finals)
IIT KGP Quiz Week 2024 Sports Quiz (Prelims + Finals)
IIT Kharagpur Quiz Club
 
A Visual Introduction to the Prophet Jeremiah
A Visual Introduction to the Prophet Jeremiah
Steve Thomason
 
Romanticism in Love and Sacrifice An Analysis of Oscar Wilde’s The Nightingal...
Romanticism in Love and Sacrifice An Analysis of Oscar Wilde’s The Nightingal...
KaryanaTantri21
 
English 3 Quarter 1_LEwithLAS_Week 1.pdf
English 3 Quarter 1_LEwithLAS_Week 1.pdf
DeAsisAlyanajaneH
 
Plate Tectonic Boundaries and Continental Drift Theory
Plate Tectonic Boundaries and Continental Drift Theory
Marie
 
LAZY SUNDAY QUIZ "A GENERAL QUIZ" JUNE 2025 SMC QUIZ CLUB, SILCHAR MEDICAL CO...
LAZY SUNDAY QUIZ "A GENERAL QUIZ" JUNE 2025 SMC QUIZ CLUB, SILCHAR MEDICAL CO...
Ultimatewinner0342
 
LDMMIA Shop & Student News Summer Solstice 25
LDMMIA Shop & Student News Summer Solstice 25
LDM & Mia eStudios
 
2025 June Year 9 Presentation: Subject selection.pptx
2025 June Year 9 Presentation: Subject selection.pptx
mansk2
 
ENGLISH-5 Q1 Lesson 1.pptx - Story Elements
ENGLISH-5 Q1 Lesson 1.pptx - Story Elements
Mayvel Nadal
 
June 2025 Progress Update With Board Call_In process.pptx
June 2025 Progress Update With Board Call_In process.pptx
International Society of Service Innovation Professionals
 
THE PSYCHOANALYTIC OF THE BLACK CAT BY EDGAR ALLAN POE (1).pdf
THE PSYCHOANALYTIC OF THE BLACK CAT BY EDGAR ALLAN POE (1).pdf
nabilahk908
 
How payment terms are configured in Odoo 18
How payment terms are configured in Odoo 18
Celine George
 
This is why students from these 44 institutions have not received National Se...
This is why students from these 44 institutions have not received National Se...
Kweku Zurek
 
List View Components in Odoo 18 - Odoo Slides
List View Components in Odoo 18 - Odoo Slides
Celine George
 
YSPH VMOC Special Report - Measles Outbreak Southwest US 6-14-2025.pptx
YSPH VMOC Special Report - Measles Outbreak Southwest US 6-14-2025.pptx
Yale School of Public Health - The Virtual Medical Operations Center (VMOC)
 
GREAT QUIZ EXCHANGE 2025 - GENERAL QUIZ.pptx
GREAT QUIZ EXCHANGE 2025 - GENERAL QUIZ.pptx
Ronisha Das
 
K12 Tableau User Group virtual event June 18, 2025
K12 Tableau User Group virtual event June 18, 2025
dogden2
 
Peer Teaching Observations During School Internship
Peer Teaching Observations During School Internship
AjayaMohanty7
 
Photo chemistry Power Point Presentation
Photo chemistry Power Point Presentation
mprpgcwa2024
 
University of Ghana Cracks Down on Misconduct: Over 100 Students Sanctioned
University of Ghana Cracks Down on Misconduct: Over 100 Students Sanctioned
Kweku Zurek
 
IIT KGP Quiz Week 2024 Sports Quiz (Prelims + Finals)
IIT KGP Quiz Week 2024 Sports Quiz (Prelims + Finals)
IIT Kharagpur Quiz Club
 
A Visual Introduction to the Prophet Jeremiah
A Visual Introduction to the Prophet Jeremiah
Steve Thomason
 
Romanticism in Love and Sacrifice An Analysis of Oscar Wilde’s The Nightingal...
Romanticism in Love and Sacrifice An Analysis of Oscar Wilde’s The Nightingal...
KaryanaTantri21
 
English 3 Quarter 1_LEwithLAS_Week 1.pdf
English 3 Quarter 1_LEwithLAS_Week 1.pdf
DeAsisAlyanajaneH
 
Plate Tectonic Boundaries and Continental Drift Theory
Plate Tectonic Boundaries and Continental Drift Theory
Marie
 
LAZY SUNDAY QUIZ "A GENERAL QUIZ" JUNE 2025 SMC QUIZ CLUB, SILCHAR MEDICAL CO...
LAZY SUNDAY QUIZ "A GENERAL QUIZ" JUNE 2025 SMC QUIZ CLUB, SILCHAR MEDICAL CO...
Ultimatewinner0342
 
LDMMIA Shop & Student News Summer Solstice 25
LDMMIA Shop & Student News Summer Solstice 25
LDM & Mia eStudios
 
2025 June Year 9 Presentation: Subject selection.pptx
2025 June Year 9 Presentation: Subject selection.pptx
mansk2
 
ENGLISH-5 Q1 Lesson 1.pptx - Story Elements
ENGLISH-5 Q1 Lesson 1.pptx - Story Elements
Mayvel Nadal
 
THE PSYCHOANALYTIC OF THE BLACK CAT BY EDGAR ALLAN POE (1).pdf
THE PSYCHOANALYTIC OF THE BLACK CAT BY EDGAR ALLAN POE (1).pdf
nabilahk908
 
How payment terms are configured in Odoo 18
How payment terms are configured in Odoo 18
Celine George
 
This is why students from these 44 institutions have not received National Se...
This is why students from these 44 institutions have not received National Se...
Kweku Zurek
 
List View Components in Odoo 18 - Odoo Slides
List View Components in Odoo 18 - Odoo Slides
Celine George
 
GREAT QUIZ EXCHANGE 2025 - GENERAL QUIZ.pptx
GREAT QUIZ EXCHANGE 2025 - GENERAL QUIZ.pptx
Ronisha Das
 
K12 Tableau User Group virtual event June 18, 2025
K12 Tableau User Group virtual event June 18, 2025
dogden2
 
Ad

Introducing Erlang Getting Started In Functional Programming 2nd Edition St Laurent

  • 1. Introducing Erlang Getting Started In Functional Programming 2nd Edition St Laurent download https://ebookbell.com/product/introducing-erlang-getting-started- in-functional-programming-2nd-edition-st-laurent-55381340 Explore and download more ebooks at ebookbell.com
  • 2. Here are some recommended products that we believe you will be interested in. You can click the link to download. Introducing Erlang Getting Started In Functional Programming 2 Early Release Simon St Laurent https://ebookbell.com/product/introducing-erlang-getting-started-in- functional-programming-2-early-release-simon-st-laurent-5713014 Introducing Erlang Simon St Laurent https://ebookbell.com/product/introducing-erlang-simon-st- laurent-4081446 Introducing Erlang Simon St Laurent https://ebookbell.com/product/introducing-erlang-simon-st- laurent-170540754 Introducing Islam A Graphic Guide Graphic Guides 2nd Revised Edition 2nd Ziauddin Sardar https://ebookbell.com/product/introducing-islam-a-graphic-guide- graphic-guides-2nd-revised-edition-2nd-ziauddin-sardar-48359932
  • 3. Introducing Comparative Politics 5th Edition Stephen Walter Orvis https://ebookbell.com/product/introducing-comparative-politics-5th- edition-stephen-walter-orvis-44864186 Introducing Financial Mathematics Theory Binomial Models And Applications Chapman And Hallcrc Financial Mathematics Series 1st Edition Mladen Victor Wickerhauser https://ebookbell.com/product/introducing-financial-mathematics- theory-binomial-models-and-applications-chapman-and-hallcrc-financial- mathematics-series-1st-edition-mladen-victor-wickerhauser-44875460 Introducing Anthropology Laura Pountney Tomislav Maric https://ebookbell.com/product/introducing-anthropology-laura-pountney- tomislav-maric-46096168 Introducing Philosophy For Canadians A Text With Integrative Readings 1st Edition Robert C Solomon https://ebookbell.com/product/introducing-philosophy-for-canadians-a- text-with-integrative-readings-1st-edition-robert-c-solomon-46248138 Introducing Bronfenbrenner A Guide For Practitioners And Students In Early Years Education 2nd Edition Nirn Hayes https://ebookbell.com/product/introducing-bronfenbrenner-a-guide-for- practitioners-and-students-in-early-years-education-2nd-edition-nirn- hayes-46496164
  • 7. Simon St. Laurent Introducing Erlang Boston Farnham Sebastopol Tokyo Beijing Boston Farnham Sebastopol Tokyo Beijing
  • 8. 978-1-491-97330-1 [FILL IN] Introducing Erlang by Simon St. Laurent Copyright © 2017 O’Reilly Media. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc. , 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles ( http://oreilly.com/safari ). For more information, contact our corporate/ institutional sales department: 800-998-9938 or [email protected] . Editor: Dawn Schanafelt Production Editor: FILL IN PRODUCTION EDI‐ TOR Copyeditor: FILL IN COPYEDITOR Proofreader: FILL IN PROOFREADER Indexer: FILL IN INDEXER Interior Designer: David Futato Cover Designer: Karen Montgomery Illustrator: Rebecca Demarest January -4712: Second Edition Revision History for the Second Edition 2017-01-09: First Early Release See http://oreilly.com/catalog/errata.csp?isbn=9781491973301 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Introducing Erlang, the cover image, and related trade dress are trademarks of O’Reilly Media, Inc. While the publisher and the author(s) have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the author(s) disclaim all responsibil‐ ity for errors or omissions, including without limitation responsibility for damages resulting from the use of or reliance on this work. Use of the information and instructions contained in this work is at your own risk. If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights.
  • 9. Table of Contents Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii 1. Getting Comfortable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Installation 1 Firing It Up 2 First Steps: The Shell 2 Moving through Text 3 Moving through History 3 Moving through Files 3 Doing Something 4 Calling Functions 5 Numbers in Erlang 6 Working with Variables in the Shell 8 Seeing Your Bound Variables 9 Clearing Bound Variables in the Shell 9 2. Functions and Modules. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Fun with fun 11 Defining Modules 13 From Module to Fun 15 Functions and Variable Scope 16 Module Directives 16 Documenting Code 18 Documenting Modules 19 Documenting Functions 20 Documenting Your Application 22 iii
  • 10. 3. Atoms, Tuples, and Pattern Matching. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Atoms 25 Pattern Matching with Atoms 25 Atomic Booleans 27 Guards 28 Underscoring That You Don’t Care 30 Adding Structure: Tuples 32 Pattern Matching with Tuples 33 Processing Tuples 33 4. Logic and Recursion. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Logic Inside of Functions 37 Evaluating Cases 37 If This, Then That 40 Variable Assignment in case and if Constructs 42 The Gentlest Side Effect: io:format 43 Simple Recursion 44 Counting Down 45 Counting Up 46 Recursing with Return Values 47 5. Communicating with Humans. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 Strings 53 Asking Users for Information 55 Gathering Terms 56 Gathering Characters 59 Reading Lines of Text 60 6. Lists. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 List Basics 65 Splitting Lists into Heads and Tails 67 Processing List Content 68 Creating Lists with Heads and Tails 70 Mixing Lists and Tuples 72 Building a List of Lists 73 7. Higher-Order Functions and List Comprehensions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 Simple Higher-Order Functions 77 Creating New Lists with Higher-Order Functions 79 Reporting on a List 79 Running List Values Through a Function 80 Filtering List Values 81 iv | Table of Contents
  • 11. Beyond List Comprehensions 81 Testing Lists 82 Splitting Lists 82 Folding Lists 83 8. Playing with Processes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 The Shell Is a Process 87 Spawning Processes from Modules 89 Lightweight Processes 92 Registering a Process 92 When Processes Break 94 Processes Talking Amongst Themselves 95 Watching Your Processes 97 Breaking Things and Linking Processes 101 9. Exceptions, Errors, and Debugging. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Flavors of Errors 109 Catching Runtime Errors as They Happen 110 Raising Exceptions with throw 112 Logging Progress and Failure 113 Debugging through a GUI 114 Tracing Messages 123 Watching Function Calls 126 10. Storing Structured Data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 Mapping Your Data 129 From Tuples to Records 130 Setting Up Records 131 Creating and Reading Records 132 Using Records in Functions and Modules 134 Storing Records in Erlang Term Storage 136 Creating and Populating a Table 137 Simple Queries 143 A Key Feature: Overwriting Values 143 ETS Tables and Processes 144 Next Steps 146 Storing Records in Mnesia 146 Starting up Mnesia 147 Creating Tables 148 Reading Data 150 Query List Comprehensions 152 Table of Contents | v
  • 12. 11. Getting Started with OTP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 Creating Services with gen_server 158 A Simple Supervisor 163 Packaging an Application 168 12. Next Steps Through Erlang. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 Moving Beyond the Erlang Shell 173 Distributed Computing 174 Processing Binary Data 174 Input and Output 174 Testing, Analyzing, and Refactoring 174 Networking and the Web 175 Data Storage 175 Extending Erlang 176 Languages Built on Erlang 176 Community 176 Sharing the Gospel of Erlang 177 A. An Erlang Parts Catalog. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 B. OTP Templates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193 vi | Table of Contents
  • 13. Preface Erlang has long been a mysterious dark corner of the programming universe, visited mostly by developers who need extreme reliability or scalability and people who want to stretch their brains. Developed at Ericsson to serve on telephone switching equipment, it seemed like a strangely special-purpose language until recently, when our computer and network architectures came to look a lot more like massively parallel telephone-switching equipment. Thanks to the rise of NoSQL data stores CouchDB and Riak, you may already be using Erlang without realizing it, and Erlang is moving out into many more fields. Erlang provides a short path from discipline to resilience. The decisions made by the creators of the language let the Erlang environment seamlessly scale and handle fail‐ ure in ways that other environments have to manage by adding ever more infrastruc‐ ture. In my utterly biased opinion, any application that needs to run for a long time and scale to many interactions should be built in Erlang (or its more recent cousin Elixir). Exploring Erlang, if you come from pretty much any background other than func‐ tional programming, will require you to clear your mind of many techniques used in other programming languages. Forget classes, forget variables that change values— even forget the conventions of variable assignment. Instead, you’re going to have to think about pattern matching, message passing, and establishing pathways for data rather than telling it where to go. Erlang programming can feel like making a key whose teeth set the tumblers on a lock just right for the key to pass, or playing pachinko and watching the balls fall through a maze. Sound strange? It is—but also enjoyable, powerful, and fun. My first explorations of Erlang confused me and excited me at the same time. I’d had some experience with what I’d called “invariant variables,” variables that can be bound vii
  • 14. to a value only once, in XSLT. That created a lot of headaches for me until I realized I was coming at the problems all wrong, and then it suddenly made sense. Who This Book Is For This book is mostly for people who’ve been programming in other languages but want to look around. Maybe you’re being very practical, and Erlang’s distributed model and the resulting scale and resilience advantages appeal to you. Maybe you want to see what this “functional programming” stuff is all about. Or maybe you’re just going for a hike, taking your mind to a new place. I suspect that functional programming is more approachable as a first language, before you’ve learned to program in other paradigms. However, getting started in Erlang—sometimes even just installing it—requires a fair amount of computing skill. If you’re a complete newcomer to programming, welcome, but there will be a few challenges along the way. Who This Book Is Not For This book is not for people in a hurry to get things done. If you already know Erlang, you don’t likely need this book unless you’re looking for a slow brush-up. If you’re already familiar with functional languages, you may find the pacing of this “Gentle Introduction” hopelessly slow. Definitely feel welcome to jump to another book that moves faster if you get bored. Come back if you find the others go too fast, and feel welcome to use this as a companion guide or reference with the other books. What This Book Will Do For You In Seven Languages in Seven Weeks, Bruce Tate suggests that “Erlang makes hard things easy and easy things hard.” This book will get you through the “easy things hard” part, and show you a bit of the promised land of “hard things easy.” In practical terms, you’ll learn to write simple Erlang programs. You’ll understand why Erlang makes it easier to build resilient programs that can scale up and down with ease. Perhaps most importantly, you’ll be able to read other Erlang resources that assume a fair amount of experience and make sense of them. In more theoretical terms, you’ll get to know functional programming. You’ll learn how to design programs around message-passing and recursion, creating process- oriented programs focused more on data flow. You’ll also be better prepared to read other books and conversations about Erlang. viii | Preface
  • 15. How This Book Works This book tries to tell a story with Erlang. You’ll probably get the most out of it if you read it in order at least the first time, though you’re always welcome to come back to find whatever bits and pieces you need. You’ll start by getting Erlang installed and running, and looking around its shell. You’ll spend a lot of time in the shell, so get cozy. Next, you’ll start loading code into the shell to make it easier to write programs, and you’ll learn how to call that code and mix it up. You’ll take a close look at numbers because they’re an easy place to get familiar with Erlang’s basic structures. Then you’ll learn about atoms, pattern-matching, and guards—the likely foundations of your program structure. After that you’ll learn about strings, lists, and the recursion at the heart of much Erlang processing. Once you’ve gone a few million recursions down and back, it’ll be time to look at processes, a key part of Erlang that relies on the message-passing model to support concurrency and resilience. Once you have the foundation set, you can take a closer look at debugging and data storage, and then get a quick look at a toolset that is likely at the heart of your long- term development with Erlang: the Open Telecom Platform (OTP), which is about much much more than telephones. Some people want to learn programming languages through a dictionary. Here’s a list of operators, here’s a list of control structures, these are the datatypes—and then smash them together. Those lists are here, but they’re in Appendix A, not the main flow of the book. Many of the examples are built on the same foundation. While you will probably be tired of falling objects by the end of the book, staying with a small set of examples makes it easier to introduce new features rather than explaining endless projects. The main point you should get from this book is that you can program in Erlang. If you don’t get that, let me know! Etudes for Erlang While I was writing this book, J. David Eisenberg was developing a broad set of exer‐ cises to accompany it. They proved comprehensive enough to become a separate project, which you can find (for free on the Web) at Chimera. The etudes are structured to match this book, but hopefully will grow over time to cover a larger scope than this book does. You’ll probably get the most out of them if you explore them each time you finish a chapter, but they’re also great for general review and to test your understanding. Preface | ix
  • 16. Why I Wrote This Book I’m not an Erlang expert hoping to create more Erlang experts to get a lot of work done. I’m a writer and developer who encountered Erlang, thought it was the programming language I’d been seeking for a long time, and felt compelled to share some of that. I’m hoping that the path I followed will work for other people, probably with varia‐ tions, and that a book written from a beginner’s perspective (and vetted by experts) would help more people find and enjoy Erlang. Other Resources This book may not be the best way for you to learn Erlang. It all depends on what you want to learn and why. If your primary interest in learning Erlang is to break out of a programming rut, you should explore Bruce Tate’s wild tour of Seven Languages in Seven Weeks (Pragmatic Publishers), which explores Ruby, Io, Prolog, Scala, Erlang, Clojure, and Haskell. Erlang gets only (an excellent) 37 pages, but that might be what you want. For an online experience (now also in print from No Starch Books) with more snark and funnier illustrations, you should explore Fred Hebert’s Learn You Some Erlang for Great Good!, at http://learnyousomeerlang.com/. While much longer than Tate’s telling, it certainly moves faster and may feel more like an experienced programmer’s guide to Erlang. The two classic general books on Erlang are the similarly-titled Programming Erlang (Pragmatic Publishers) by Erlang creator Joe Armstrong, and Erlang Programming (O’Reilly) by Francesco Cesarini and Simon Thompson. They cover a lot of similar and overlapping terrain, and both may be good places to start if this book moves too slowly or you need more reference material. Erlang Programming goes further into what you can do with Erlang, whereas Programming Erlang provides a lot of detail on setting up an Erlang programming environment. On the more advanced side, Erlang and OTP in Action (Manning) by Martin Logan, Eric Merritt, and Richard Carlsson, opens with a high-speed 72-page introduction to Erlang and then spends most of its time applying the Open Telecom Platform, Erlang’s framework for building upgradeable and maintainable concurrent applica‐ tions. More recently, Designing for Scalability with Erlang/OTP (O’Reilly), by Fran‐ cesco Cesarini and Steve Vinoski, focuses squarely on building large and resilient applications with Erlang’s OTP libraries. At the end of each chapter of this book, you’ll find a note pointing to relevant infor‐ mation on the chapter’s content in other Erlang-focused books. Hopefully they’ll help x | Preface
  • 17. you move quickly among them if you use this book as a companion to the rest of the growing Erlang library. If you want to focus on connecting Erlang to the Web, you should definitely also explore Building Erlang Web Applications (O’Reilly) by Zachary Kessin. You’ll also want to visit the main Erlang website, http://www.erlang.org/, for updates, downloads, documentation, and more. Are You Sure You Want Erlang? Though they’ve been obscure for a long time, there’s a crowd of functional languages rising into greater popularity. Five of them in particular—Clojure, Scala, F#, Haskell, and Elixir—may be more appealing than Erlang if you have specific needs. • Clojure and Scala run on the Java Virtual Machine (JVM), making them insanely portable, and they have access to Java libraries as a result. ClojureScript does the same with JavaScript, too. (Erjang makes it possible to run Erlang on the JVM, but it’s not a core part of the language.) • F# runs on the .NET Common Language Runtime (CLR), making it very portable in the Microsoft ecosystem, and again, has access to .NET libraries. • Haskell doesn’t run on a virtual machine, but also offers a stronger type system and a different kind of discipline (and laziness). • Elixir is built on the same foundations as Erlang, and works well with Erlang, but has a Ruby-like syntax with strong support for metaprogramming. Personally, I got my start with these concepts in XSLT. It’s a very different kind of lan‐ guage meant for a specific domain of document transformation, but many of the same ideas flow through it. You don’t, of course, have to decide if Erlang is your life’s dream now. You can learn concepts in Erlang and apply them elsewhere if it turns out to be a better idea for your work. Erlang Will Change You Before you go deeper, you should know that working in Erlang may irrevocably change the way you look at programs. Its combination of functional code, process- orientation, and distributed development may seem alien at first. However, once it sinks in, Erlang can transform the way you solve problems, and potentially make it difficult to return to other languages, environments, and programming cultures. Preface | xi
  • 18. Conventions Used in This Book The following typographical conventions are used in this book: Italic Indicates new terms, URLs, email addresses, filenames, and file extensions. Constant width Used for program listings, as well as within paragraphs to refer to program ele‐ ments such as variable or function names, statements, and keywords. Constant width bold Shows commands or other text that should be typed literally by the user. Constant width italic Shows text that should be replaced with user-supplied values or by values deter‐ mined by context. This icon signifies a tip, suggestion, or general note. This icon indicates a warning or caution. A Note on Erlang Syntax Erlang’s syntax seems to be a sticking point for a lot of people. It doesn’t look like the C family of languages. Punctuation is different and capitalization matters. Periods even get used as conclusions rather than connectors! To me, Erlang syntax mostly feels natural, and I’m especially happy that it’s different from the other languages I typically use. I make a lot fewer mix-ups that way. Rather than dwell on syntax, I’ve chosen just to present it as it is. Comparing it to other languages doesn’t seem likely to be helpful, especially when different readers may come from different programming backgrounds. Hopefully you will find Erlang syntax as pleasant as I do. If you just can’t get past it, you may want to try Elixir instead. xii | Preface
  • 19. Using Code Examples The examples in this book are meant to teach basic concepts in small bites. While you may certainly borrow code and reuse it as you see fit, you won’t be able to take the code of this book and build a stupendous application instantly (unless perhaps you have an unusual fondness for calculating the speeds of falling objects). The examples in this book are deliberately simple and perhaps even stupid. They aren’t designed to dazzle or to show off, but to let you figure out how pieces fit together in the simplest possible way. You should, however, be able to figure out the steps you need to take to build a great application. You can download the code from the Examples link on the book’s page at http:// oreil.ly/introducing_erlang. This book is here to help you get your job done. In general, you may use the code in this book in your programs and documentation. You do not need to contact us for permission unless you are reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing a CD-ROM of examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product’s documentation does require permission. We appreciate, but do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: "Introducing Erlang, by Simon St.Lau‐ rent (O’Reilly). Copyright 2013 Simon St.Laurent, 9781449331764.” If you feel your use of code examples falls outside fair use or the permission given above, feel free to contact us at [email protected]. Help This Book Grow While I hope that you will enjoy reading this book and learn from it, I also hope that you can contribute to helping other readers learn Erlang here. You can help your fel‐ low readers in a number of ways: • If you find specific technical problems, bad explanations, or things that can be improved, please report them through the errata system. • If you like (or don’t like) the book, please leave reviews. The most visible places to do so are on Amazon.com (or its international sites) and at the O’Reilly page for the book at http://oreil.ly/introducing_erlang. Detailed explanations of what worked and what didn’t work for you (and the broader target audience of pro‐ grammers new to Erlang) are helpful to other readers and to me. Preface | xiii
  • 20. • If you find you have much more you want to say about Erlang, please consider sharing it, whether on the Web, in a book of your own, in training classes, or in whatever form you find easiest. I’ll update the book for errata, and try to address issues raised in reviews. Even once the book is “complete,” I may still add some extra pieces to it. If you purchased it as an ebook, you’ll receive these updates for free at least up to the point where it’s time for a whole new edition. I don’t expect that new edition declaration to come quickly, however, unless the Erlang world changes substantially. Hopefully this book will engage you enough to make you consider sharing. Please Use It For Good I’ll let you determine what “good” means, but think about it. Please try to use Erlang’s power for projects that make the world a better place, or at least not a worse place. Safari® Books Online Safari Books Online is an on-demand digital library that deliv‐ ers expert content in both book and video form from the world’s leading authors in technology and business. Technology professionals, software developers, web designers, and business and crea‐ tive professionals use Safari Books Online as their primary resource for research, problem solving, learning, and certification training. Safari Books Online offers a range of plans and pricing for enterprise, government, education, and individuals. Members have access to thousands of books, training videos, and prepublication manuscripts in one fully searchable database from publishers like O’Reilly Media, Prentice Hall Professional, Addison-Wesley Professional, Microsoft Press, Sams, Que, Peachpit Press, Focal Press, Cisco Press, John Wiley & Sons, Syngress, Morgan Kauf‐ mann, IBM Redbooks, Packt, Adobe Press, FT Press, Apress, Manning, New Riders, McGraw-Hill, Jones & Bartlett, Course Technology, and hundreds more. For more information about Safari Books Online, please visit us online. How to Contact Us Please address comments and questions concerning this book to the publisher: O’Reilly Media, Inc. 1005 Gravenstein Highway North xiv | Preface
  • 21. Sebastopol, CA 95472 800-998-9938 (in the United States or Canada) 707-829-0515 (international or local) 707-829-0104 (fax) We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at http://oreil.ly/introducing_erlang. To comment or ask technical questions about this book, send email to bookques‐ [email protected]. For more information about our books, courses, conferences, and news, see our web‐ site at http://www.oreilly.com. Find us on Facebook: http://facebook.com/oreilly Follow us on Twitter: http://twitter.com/oreillymedia Watch us on YouTube: http://www.youtube.com/oreillymedia Acknowledgments Many thanks to Zachary Kessin for interesting me in Erlang in the first place, and to him and Francesco Cesarini for encouraging me to write this. Detailed feedback from Steve Vinoski and Fred Hebert has made it possible, I hope, for this book to get read‐ ers started on the right track. J. David Eisenberg and Chuck Ha helped make it espe‐ cially possible for beginners to get started right, pointing out gaps and issues in my prose. In particular, thanks to my wife Angelika for encouraging me to finish this, to my son Konrad for not throwing the printouts around too much, and to my daughter Sun‐ giva for understanding that after I told her the story about Ned and Ernie, adventur‐ ing snakes, I needed to go back downstairs and work on this. Preface | xv
  • 23. CHAPTER 1 Getting Comfortable Erlang has a funny learning curve for many people. It starts gently for a little while, then gets much much steeper as you realize the discipline involved, and then goes nearly vertical for a little while as you try to figure out how that discipline affects get‐ ting work done—and then it’s suddenly calm and peaceful with a gentle grade for a long time as you reapply what you’ve learned in different contexts. Before that climb, it’s best to get comfortable in the sunny meadows at the bottom of the learning curve. Erlang’s shell, its command-line interface, is a cozy place to get started and a good place to start figuring out what works and what doesn’t work in Erlang. Its features will spare you headaches later, so settle in! Installation Erlang is officially available from http://www.erlang.org/download.html. For this edi‐ tion, I used Erlang/OTP 19, but any version of Erlang more recent than 17 should work. If you’re on Windows, it’s easy. Download the Windows binary file, run the installer, and you’re set. If you are a brave beginner tackling your first programming language, this is easily your best bet. On Linux or Mac OS X, you may be able to download the source file and compile it. If the compilation approach doesn’t work or isn’t for you, Erlang Solutions offers a number of installs at http://www.erlang-solutions.com/section/132/download-erlang- otp. Also, many different package managers (Debian, Ubuntu, MacPorts, brew, and so on) include Erlang. It may not be the very latest version, but having Erlang running is much better than not having Erlang running. 1
  • 24. Erlang is increasingly part of the default installation on many sys‐ tems, including Ubuntu, largely thanks to the spread of CouchDB. Firing It Up On Mac OS X or Linux, go to the command line and type erl. On Windows, go to the command line and type werl. You’ll see something like the following code sample, likely with a cursor next to the 1> prompt. Erlang R15B (erts-5.9) [source] [smp:2:2] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.9 (abort with ^G) 1> You’re in Erlang! First Steps: The Shell Before moving on to the excitement of programming Erlang, it’s always worth noting how to quit. The shell suggests ^G, Ctrl-G, which will bring you to a mysterious (for now) user switch command. (Ctrl-C will bring you to a menu.) The simplest way to quit, allowing everything that might be running in the shell to exit normally, is q(). 1> q(). ok 2> SimonMacBook:~ simonstl$ So what have you done here? You’ve issued a shell command, calling a function q that itself calls the init:stop() function built into Erlang. The period after the command tells Erlang you’re done with the line. It reports back with ok, prints a new line num‐ ber (it always does that after a period), and drops you back out to the regular com‐ mand line, in this case a bash shell on your laptop. If you had left off the period after q(), the results would look a little different. You’d have started a new line but the command count wouldn’t update, so the line would still start with 1>. When this happens, you can just type . and press Enter to finish your command. 1> q() 1> . ok 2> SimonMacBook:~ simonstl$ Including the period at the end of the line will soon become second nature, but leav‐ ing it off can create a lot of confusion at the start. 2 | Chapter 1: Getting Comfortable
  • 25. Quitting Erlang with q(). turns off everything Erlang is doing, period. That’s fine when you’re working locally, but will become a bad idea when you’re connecting to a remote shell. To quit the shell without the risk of shutting down the Erlang runtime on another system, try Ctrl-G and then entering q, followed by the Enter key. Moving through Text If you explore the shell, you’ll find that many things work the way they do in other shells. The left and right arrow keys move you backward and forward through the line you’re editing. Some of the key bindings echo the emacs text editor. Ctrl-A will take you to the beginning of a line, while Ctrl-E will take you back to the end of the line. If you get two characters in the wrong sequence, pressing Ctrl-T will transpose them. Like most Unix shells, pressing the Tab key will make the shell try to autocomplete what you’ve written, though in this case it’s looking for module or function names (you’ll see them soon), not filenames. Also, as you type closing parentheses or square brackets, the cursor will highlight the corresponding opening parenthesis or square bracket. Moving through History The up and down arrow keys run through the history, making it easy to reissue commands. When you use the up and down arrows, the history will be broken down by newlines, not by periods, so if you left a period off in a prior command you’ll need to add it again. If you want to see what’s in the history, try h(). You can also specify how much history to keep around with history(N) and results(N). You can tell Erlang to exe‐ cute a given line again with e(N), and reference a given result value with v(N). Those line numbers can be useful! Moving through Files The Erlang shell does understand filesystems to some extent because you may need to move through them to reach the files that will become part of your program. The commands have the same names as Unix commands but are expressed as functions. The Erlang shell starts wherever you opened the shell, and you can figure out where that is with pwd(): 4> pwd(). /Users/simonstl ok 5> First Steps: The Shell | 3
  • 26. To change directories, use the cd() command, but you’ll need to wrap the argument not only in parentheses but in quotes, preferably double quotes. 5> cd(..). * 1: syntax error before: '..' 5> cd(".."). /Users ok 6> cd("simonstl"). /Users/simonstl ok 7> You can look around with the ls() command, which will list files in the current directory if you give it no arguments, and list files in a specified directory if you give it one argument. Doing Something One of the easiest ways to get started playing with Erlang is to use the shell as a calcu‐ lator. You can enter mathematical expressions and get useful results: Eshell V5.9 (abort with ^G) 1> 2+2. 4 2> 27-14. 13 3> 35*42023943. 1470838005 4> 200/15. 13.333333333333334 5> 200 div 15. 13 6> 200 rem 15. 5 7> 3*(4+15). 57 The first three operators are addition(+), subtraction(-), and multiplication(*), which work the same way whether you’re working with integer values or floating points. The fourth, /, supports division where you expect a floating point (a number with a deci‐ mal part) result. If you want an integer result (and have integer arguments), use the div operator instead, with rem to get the remainder, as shown on lines 5 and 6. Paren‐ theses let you modify the order in which operators are processed, as shown on line 7. (The normal order of operations is listed in Appendix A.) Erlang will accept integers in place of floats, but floats are not always welcome where integers are used. If you need to convert a floating point number to an integer, you can use the round() built-in function: 4 | Chapter 1: Getting Comfortable
  • 27. 8> round(200/15). 13 The round() function drops the decimal part of the number. If the decimal part was greater than or equal to .5, it increases the integer part by 1, rounding up. If you’d rather just drop the decimal part completely, use the trunc() function, which effec‐ tively always rounds down. You can also refer to a previous result by its line number using v(). For example: 9> 4*v(8). 52 The result on line 8 was 13, and 4*13 is 52. If you’re feeling adventurous, you can use negative numbers to reference prior results. v(-1) is the previous result, v(-2) is the result before that, and so on. Calling Functions If you want to do more powerful calculations, Erlang’s math module offers pretty much the classic set of functions supported by a scientific calculator. They return floating point values. The constant pi is available as a function, math:pi(). Trigono‐ metric, logarithmic, exponential, square root, and (except on Windows) even the Gauss error functions are readily available. (The trigonometric functions take their arguments in radians, not degrees, so be ready to convert if necessary.) Using these functions is a little verbose because of the need to prefix them with math:, but it’s still reasonably sane. For example, to get the sine of zero radians, you’d write: 1> math:sin(0). 0.0 Note that it’s 0.0, not just 0, indicating that the number is floating point. To calculate the cosine of pi and 2pi radians, you’d write: 2> math:cos(math:pi()). -1.0 3> math:cos(2*math:pi()). 1.0 To calculate 2 taken to the 16th power, you’d use: 4> math:pow(2,16). 65536.0 The full set of mathematical functions supported by Erlang’s math module is listed in Appendix A. Calling Functions | 5
  • 28. Numbers in Erlang Erlang recognizes two kinds of numbers: integers and floating-point numbers (often called floats). It’s easy to think of integers as “whole numbers,” with no decimal part, and floats as “decimal numbers,” with a decimal point and some value (even if it’s 0) to the right of the decimal. 1 is an integer, 1.0 is a floating-point number. However, it’s a little trickier than that. Erlang stores integers and floats in a very dif‐ ferent way. Erlang lets you store massive numbers as integers, but whether they’re big or small, they are always precise. You don’t need to worry about their values being off by just a little. Floats, on the other hand, cover a wide range of numbers but with limited precision. Erlang uses the 64-bit IEEE 754-1985 “double precision” representation. This means that it keeps track of about 15 decimal digits plus an exponent. It can also represent some large numbers—powers up to positive or negative 308 are available—but because it tracks only a limited number of digits, results will vary a little more than may seem convenient, especially when you want to do comparisons. 1> 3487598347598347598437583475893475843749245.0. 3.4875983475983474e42 2> 2343243.345435893850234543339545. 2343243.3454358936 3> 0.0000000000000000000000000000023432432432432234232324. 2.3432432432432235e-30 As you can see, some digits get left behind, and the overall magnitude of the number represented with an exponent. When you enter floating point numbers, you must always also have at least one num‐ ber to the left of the decimal point, even if it’s zero. Otherwise Erlang reports a syntax error—it doesn’t understand what you’re doing. 4> .0000000000000000000000000000023432432432432234232324. * 1: syntax error before: 23432432432432234232324 You can also write floats using the digits plus exponent notation: 7> 2.923e127. 2.923e127 8> 7.6345435e-231. 7.6345435e-231 Floats’ lack of precision can cause anomalous results. For example, the sine of zero is zero, and the sine of pi is also zero. However, if you calculate this in Erlang, you won’t quite get to zero with the float approximation Erlang provides for pi: 1> math:sin(0). 0.0 2> math:sin(math:pi()). 1.2246467991473532e-16 6 | Chapter 1: Getting Comfortable
  • 29. If Erlang’s representation of pi went further, and its calculations went further, the result for line 2 would be closer to zero. If you need to keep track of money, integers are going to be a better bet. Use the smallest available unit—cents for US dollars, for instance—and remember that those cents are 1/100 of a dollar. (Financial transactions can go to much smaller fractions, but you’ll still want to represent them as integers with a known multiplier.) For more complex calculations, though, you’ll want to use floats, and just be aware that results will be imprecise. If you need to do calculations on integers using a base other than 10, you can use Base#Value notation. For example, if you wanted to specify the binary value of 1010111, you could write: 3> 2#1010111. 87 Erlang reports back with the base 10 value of the number. Similarly, you can specify hexadecimal numbers by using 16 instead of 2: 4> 16#cafe. 51966 Erlang lets you use either upper- or lower-case for hexdecimal numbers - 16#CAFE and 16#CaFe also produce 51966. You aren’t limited to the traditional binary (base 2), octal (base 8), and hexadecimal (base 16) choices. If you want to work in base 18, or any base up to 36, you can: 5> 18#gaffe. 1743080 Why might you use base 36? It’s an extremely easy way to create keys that look like a combination of letters and numbers, but resolve neatly to numbers. The 6-digit codes airlines use to identify tickets, like G6ZV1N, are easily treated as base 36. (However, they usually leave out some digits and letters that are easily confused, such as -0 and O, and 1 and l.) To make any of these numbers negative just put a minus sign (-) in front of them. This works with normal integers, Base#Value notation, and floats: 6> -1234. -1234 7> -16#cafe. -51966 8> -2.045234324e6. -2045234.324 Numbers in Erlang | 7
  • 30. Working with Variables in the Shell The v() function lets you refer to the results of previous expressions, but it’s not exactly convenient to keep track of result numbers, and the v() function works only in the shell. It isn’t a general-purpose mechanism. A more reasonable solution stores values with textual names, creating variables. Erlang variable names begin with a capital letter or an underscore. Normal variables start with a capital letter, whereas underscores start “don’t care” variables. For now, stick with normal variables. You assign a value to a variable using a syntax that should be familiar from algebra or other programming languages, here with N as the vari‐ able: 1> N=1. 1 To see the value of a variable, just type its name. 2> N. 1 To see Erlang protest at your rude behavior, try assigning the variable a new value: 3> N=2. ** exception error: no match of right hand side value 2 4> N=N+1. ** exception error: no match of right hand side value 2 What’s happening here? Erlang expects the righthand side of an expression, after the =, to match the lefthand side. It’s willing to make that happen if a variable on the left side isn’t bound yet, as was the case with N=1 in the first line. However, once the vari‐ able N is set to 1, Erlang interprets N=2 as 1=2, which it won’t accept. N=N+1 also evalu‐ ates to 1=2, and doesn’t work. Erlang’s single assignment model, where each variable can be assigned a value only once in a given context, imposes discipline whose value you will see in later chapters. Erlang expressions work like algebra, where N never equals N+1. It just can’t happen that way. However, once you’ve set N to 1, it’s fine to try expressions that also come to one: 5> N=2-1. 1 6> N=15 div (3*5). 1 This will get much more important when you start to take advantage of Erlang’s pat‐ tern matching capabilities. You can also write the following: 7> 1=N. 1 8 | Chapter 1: Getting Comfortable
  • 31. Erlang won’t attempt to bind any variables when they appear on the right side of the equals sign, and this just effectively asks Erlang to compare 1 to 1. Try it with 2, how‐ ever, and Erlang complains that there isn’t a match; 2 does not equal 1: 8> 2=N. ** exception error: no match of right hand side value 1 You can also use bound variables in calculations, for example to create new bound variables. Here’s one called Number: 9> Number=N*4+N. 5 10> 6*Number. 30 When you assign a value to a variable, you should make sure that all the calculations are on the right side of the equals sign. Even though I know that M should be 6 when 2*M = 3*4, Erlang doesn’t: 11> 2*M=3*4. * 1: illegal pattern The shell will remember your variables until you quit or tell it to forget them. Code in Erlang functions doesn’t forget, until the functions stop running. Seeing Your Bound Variables After a while poking around the shell using it as a calculator (try it!), you may find you’ve forgotten what variables you’ve already bound. If you need a reminder, the b() shell command can help: 11> b(). N = 1 Number = 5 ok Clearing Bound Variables in the Shell In the shell, and only in the shell, you can clear all variable bindings and you can clear specific variable bindings. This may prove useful after an egregious typo or to reset your console for new calculations, but it isn’t an option you’ll have in regular code. To clear a specific variable, removing its binding and letting you set a new value, use the f() function, giving the variable name as an argument: 12> f(N). ok 13> b(). Number = 5 ok Working with Variables in the Shell | 9
  • 32. 14> N=2. 2 To clear all the bound variables in the shell, just call f() with no arguments. 15> b(). N = 2 Number = 5 ok 16> f(). ok 17> b(). ok They all disappeared. Before moving on to the next chapter, which will introduce modules and functions, spend some time playing in the Erlang shell. The experience, even at this simple level, will help you move forward. Use variables, and see what happens with large integers. Erlang supports large numbers very well. Try mixing numbers with decimal values (floats) and integers in calculations, and see what happens. Nothing should be diffi‐ cult yet, though I suspect the idea of variables that don’t change values gives you a hint of what’s to come. You can learn more about installation and working with the shell in Chapter 2 of Erlang Programming (O’Reilly); Chapters 2 and 6 of Programming Erlang (Pragmatic); Section 2.1 of Erlang and OTP in Action (Manning); and Chapter 1 of Learn You Some Erlang For Great Good! (No Starch Press). 10 | Chapter 1: Getting Comfortable
  • 33. CHAPTER 2 Functions and Modules Like most programming languages, Erlang lets you define functions to help you rep‐ resent repeated calculations. While Erlang functions can become complicated, they start out reasonably simple. Fun with fun You can create functions in the Erlang shell using the appropriately named fun. For example, to create a function that calculates the velocity of a falling object based on the distance it drops in meters, you could create the following: 1> FallVelocity = fun(Distance) -> math:sqrt(2 * 9.8 * Distance) end. #Fun<erl_eval.6.111823515> You can read that as a pattern match that binds the variable FallVelocity to a func‐ tion that takes an argument of Distance. The function returns (I like to read the -> as yields) the square root of 2 times a gravitational constant for Earth of 9.8 m/s, times Distance (in meters). Then the function comes to an end, and a period closes the statement. If you want to include multiple statements in a fun, separate them with commas, like FallVelocity = fun(Distance) -> X = (2 * 9.8 * Distance), math:sqrt(X) end. The return value in the shell, #Fun<erl_eval.6.111823515>, isn’t especially mean‐ ingful by itself, but it tells you that you’ve created a function and didn’t just get an error. If you want a slightly more detailed sign that Erlang understood you, you can use the b() shell command to see what it thinks: 11
  • 34. 2> b(). FallVelocity = fun(Distance) -> math:sqrt(2 * 9.8 * Distance) end ok Conveniently, binding the function to the variable FallVelocity lets you use that variable to calculate the velocity of objects falling to Earth: 3> FallVelocity(20). 19.79898987322333 4> FallVelocity(200). 62.609903369994115 5> FallVelocity(2000). 197.9898987322333 If you want those meters per second in miles per hour, just create another function. You can copy and paste the earlier results into it (as I did here), or pick shorter num‐ bers: 6> Mps_to_mph = fun(Mps) -> 2.23693629 * Mps end. #Fun<erl_eval.6.111823515> 7> Mps_to_mph(19.79898987322333). 44.289078952755766 8> Mps_to_mph(62.609903369994115). 140.05436496173314 9> Mps_to_mph(197.9898987322333). 442.89078952755773 I think I’ll stay away from 2000 meter drops. Prefer the fall speed in kilometers per hour? 10> Mps_to_kph = fun(Mps) -> 3.6 * Mps end. #Fun<erl_eval.6.111823515> 11> Mps_to_kph(19.79898987322333). 71.27636354360399 12> Mps_to_kph(62.609903369994115). 225.3956521319788 13> Mps_to_kph(197.9898987322333). 712.76363543604 You can also go straight to your preferred measurement by nesting the following calls: 14> Mps_to_kph(FallVelocity(2000)). 712.76363543604 However you represent it, that’s really fast, though air resistance will slow those down a lot in reality. This is handy for repeated calculations, but you probably don’t want to push this kind of function use too far in the shell, as flushing your variables or quitting the shell ses‐ sion makes your functions vanish. 12 | Chapter 2: Functions and Modules
  • 35. If you get an error that looks like ** exception error: no func tion clause matching erl_eval:'-inside-an-interpreted-fun-'(value), check your capitalization. It may take a while to get used to capital‐ izing all your variables, including arguments in functions. Defining Modules Most Erlang programs define their functions in compiled modules rather than in the shell. Modules are a more formal place to put programs, and they give you the ability to store, encapsulate, share, and manage your code more effectively. Each module should go in its own file, with an extension of .erl. You should use name_of_module.erl, where name_of_module is the name you specify inside of the module file. Example 2-1, which you can find in the examples archive at ch02/ex1- drop, shows what a module, drop.erl, containing the functions previously defined might look like. Example 2-1. Module for calculating and converting fall velocities -module(drop). -export([fall_velocity/1, mps_to_mph/1, mps_to_kph/1]). fall_velocity(Distance) -> math:sqrt(2 * 9.8 * Distance). mps_to_mph(Mps) -> 2.23693629 * Mps. mps_to_kph(Mps) -> 3.6 * Mps. There are two key kinds of information in this module. At the top, the -module and - export directives tell the compiler key things about the module—its name and which functions it should make visible to other code that uses this module. The -export directive gives a list of functions that should be made visible—not just their names, but their arity, the number of arguments they take. Erlang considers functions with the same name but different arity to be different functions. All of the code in a module must be contained in functions. Below the directives is a set of expressions defining functions, which look similar to the fun declarations used earlier but not quite the same. The function names start with lowercase, not uppercase, and the syntax is slightly different. fun and end don’t appear, and the function name is immediately followed by parentheses containing a set of arguments. Defining Modules | 13
  • 36. If you get errors like "drop.erl:2: bad function arity drop.erl:6: syntax error before: Fall_velocity“, it’s proba‐ bly because you didn’t convert the names from your fun/s so they start with a lowercase letter. How do you make this actually do something? It’s time to start compiling Erlang code. The shell will let you compile modules and then use them immediately. The c() function lets you compile code. You need to be in the same directory as the file, whether you started the Erlang shell from there or navigated there with the commands shown in the previous chapter. You don’t need to (and shouldn’t) include the .erl file extension in the name you pass to c(), though you can specify directory paths. 1> ls(). drop.erl ok 2> c(drop). {ok,drop} 3> ls(). drop.beam drop.erl ok Line 1 checks to see if the drop.erl source file is there, and you see the directory list‐ ing. Line 2 actually compiles it, and line 3 shows that a new file, drop.beam, is now available. Now that you have drop.beam, you can call functions from the module. You need to prefix those calls with drop, as shown in lines 4 and 5 of the following code. 4> drop:fall_velocity(20). 19.79898987322333 5> drop:mps_to_mph(drop:fall_velocity(20)). 44.289078952755766 It works the same as its predecessors, but now you can quit the shell, return, and still use the compiled functions. 6> q(). ok $ erl Erlang R15B (erts-5.9) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.9 (abort with ^G) 1> drop:mps_to_mph(drop:fall_velocity(20)). 44.289078952755766 14 | Chapter 2: Functions and Modules
  • 37. Most Erlang programming (beyond tinkering in the shell) is creating functions in modules and connecting them into larger programs. Erlang Compilation and the Runtime System When you write Erlang in the shell, it has to interpret every command, whether or not you’ve written it before. When you tell Erlang to compile a file, it converts your text into something it can process without having to re-interpret all the text, tremen‐ dously improving efficiency when you run the code. That “something it can process,” in Erlang’s case, is a BEAM file. It contains code that the BEAM processor, a key piece of the Erlang Runtime System (ERTS) can run. BEAM is Bogdan’s Erlang Abstract Machine, a virtual machine that interprets opti‐ mized BEAM code. This may sound slightly less efficient than the traditional compi‐ lation to machine code that runs directly on the computer, but it resembles other virtual machines. (Oracle’s Java Virtual Machine (JVM) and the Common Language Runtime used by Microsoft’s .NET Framework are the two most common virtual machines.) Having its own virtual machine and runtime system lets Erlang optimize some key things, making it easier to build applications that scale reliably. Its process scheduler simplifies distributing work across multiple processors in a single computer. You don’t have to think about how many processors your application might get to use— you just write independent processes, and Erlang spreads them out. Erlang also man‐ ages input and output in its own way, avoiding connection styles that block other pro‐ cessing. The virtual machine also uses a garbage collection strategy that fits its style of processing, allowing for briefer pauses in program execution. (Garbage collection releases memory that processes needed at one point but are no longer using.) When you create and deliver Erlang programs, you will be distributing them as a set of compiled BEAM files. You don’t need to compile each one from the shell as we’re doing here, though. erlc will let you compile Erlang files directly and combine that compilation into make tasks and similar things, whereas escript can compile or interpret and run Erlang code from outside of the Erlang shell. From Module to Fun If you like the style of code that fun allowed but also want your code stored more reliably in modules where it’s easier to debug, you can get the best of both worlds by using the fun keyword to refer to a function you’ve already defined. To do that, you don’t use parentheses after fun, and give the module name, function name, and arity. 1> F_v = fun drop:fall_velocity/1. #Fun<drop.fall_velocity.1> Defining Modules | 15
  • 38. 2> F_v(20). 19.79898987322333 You can also do this within code in a module, and if you’re referring to code in the same module, you can leave off the module name preface. (In this case, that would mean leaving off drop: and just using fall_velocity/1.) Functions and Variable Scope Erlang lets you bind a variable only once, but you might call a function many times over the course of a program. Doesn’t that mean the same variable will be bound many times? Yes, it will be bound many times but always in separate contexts. Erlang doesn’t con‐ sider multiple calls to the same function to be the same thing. It starts with a fresh set of unassigned variables every time you call that function. Similarly, Erlang doesn’t worry if you use the same variable name in different func‐ tions or function clauses. They aren’t going to be called in the same context at the same time, so there isn’t a collision. The place you need to avoid re-assigning values to an already bound variable is within a given path through a given function. As long as you don’t try to reuse a vari‐ able in a given context, you shouldn’t have to worry. Module Directives By default, modules have very thick walls, and everything inside of them is consid‐ ered private. Everything going in or out of the module needs a pass to do so, and you grant those passes through module directives (sometimes called module attributes). The example above showed two module directives—-module and -export. The -module directive sets the name for the module, which outside code will need to know in order to call the functions. The -export directive specifies which functions that outside code can reach. The drop module currently mixes two different kinds of functions. The fall_veloc ity/1 function fits the name of the module, drop, very well, providing a calculation based on the height from which an object falls. The mps_to_mph/1 and mps_to_kph/1 functions, however, aren’t about dropping. They are generic measurement conversion functions that are useful in other contexts and really belong in their own module. Example 2-2 and Example 2-3, both in ch02/ex2-combined, show how this might be improved. 16 | Chapter 2: Functions and Modules
  • 39. Example 2-2. Module for calculating fall velocities -module(drop). -export([fall_velocity/1]). fall_velocity(Distance) -> math:sqrt(2 * 9.8 * Distance). Example 2-3. Module for converting fall velocities -module(convert). -export([mps_to_mph/1, mps_to_kph/1]). mps_to_mph(Mps) -> 2.23693629 * Mps. mps_to_kph(Mps) -> 3.6 * Mps. Next, you can compile them, and then the separated functions are available for use: Eshell V5.9 (abort with ^G) 1> c(drop). {ok,drop} 2> c(convert). {ok,convert} 3> ls(). convert.beam convert.erl drop.beam drop.erl ok 4> convert:mps_to_mph(drop:fall_velocity(20)). 44.289078952755766 That reads more neatly, but how might this code work if a third module needed to call those functions? Modules that call code from other modules need to specify that explicitly. Example 2-4, in ch02/ex3-combined, shows a module that uses functions from both the drop and convert modules. Example 2-4. Module for combining drop and convert logic -module(combined). -export([height_to_mph/1]). height_to_mph(Meters) -> convert:mps_to_mph(drop:fall_velocity(Meters)). That looks much like the way you called it from the Erlang shell, but if you have a lot of calls to external modules, that can get verbose quickly. The -import directive, shown in Example 2-5, lets you simplify your code, though it comes with a possible risk of confusing other people who think the imported functions must be defined within this module. (You can find this in ch02/ex4-combined.) Defining Modules | 17
  • 40. Example 2-5. Module for combining drop and convert logic using import -module(combined). -export([height_to_mph/1]). -import(drop, [fall_velocity/1]). -import(convert, [mps_to_mph/1]). height_to_mph(Meters) -> mps_to_mph(fall_velocity(Meters)). For now, it’s probably best to know about the -import directive so you can read other people’s code, but not to use it unless you just can’t resist. It can make it harder to figure where bugs are coming from, which may cost you more time than the extra typing. Erlang includes one other directive that’s similarly convenient but not best practice to use: -compile(export_all). That directive tears down the module wall, making all functions available for external calls. In a module where everything is supposed to be public, that might save you typing out all the functions and all the arities of your module. However, it also means anyone can call anything in your code, exposing a lot more surface area for misunderstandings and complex debugging. If you just can’t resist, it’s available, but try to resist. You can also make up your own user directives. -author(Name) and -date(Date) are commonly used. If you make up your own directives, they can have only one argument. If you spend enough time in Erlang, you’ll also encounter the following: - behaviour(Behaviour), -record(Name, Fields), and - vsn(Version). Documenting Code Your programs can run perfectly well without documentation. Your projects, how‐ ever, will have a much harder time. While programmers like to think they write code that anyone can look at and sort out, the painful reality is that code even a little more complicated than that shown in the previous examples can prove mystifying to other developers. If you step away from code for a while, the understanding you developed while programming it may have faded, and even your own code can seem incomprehensible. The simplest way to add more explicit explanations to your code is to insert com‐ ments. You can start a comment with %, and it runs to the end of the line. Some com‐ ments take up an entire line, while others are short snippets at the end of a line. Example 2-6 shows both varieties of comments. 18 | Chapter 2: Functions and Modules
  • 41. Example 2-6. Comments in action -module(combined). -export([height_to_mph/1]). % there will be more soon! %%% combines logic from other modules into a convenience function. height_to_mph(Meters) -> convert:mps_to_mph(drop:fall_velocity(Meters)). The Erlang compiler will ignore all text between the % sign and the end of the line, but humans exploring the code will be able to read them. Why are there multiple percent signs at the start of the line? The Erlang Emacs mode and many other Erlang tools expect the number of percent signs to indicate levels of indentation. Three percent signs (%%%) means that the comment will be formatted flush left, two percent signs (%%) means the comment is indented with surrounding code, and a single percent sign (%) is used for comments on the end of a line. Informal comments are useful, but developers have a habit of including comments that help them keep track of what they’re doing while they’re writing the code. Those comments may or may not be what other developers need to understand the code, or even what you need when you return to the code after a long time away. More formal comment structures may be more work than you want to take on in the heat of a pro‐ gramming session, but they also force you to ask who might be looking at your code in the future and what they might want to know. Erlang includes a documentation system called EDoc, which converts comments placed in the code into navigable HTML documentation. It relies on specially format‐ ted comments, a directive, and occasionally an extra file to provide structured infor‐ mation about your modules and application. Documenting Modules The modules in this chapter are very simple so far, but there is enough there to start documenting, as shown in the files at ch02/ex5-docs. Example 2-7 presents the drop module with more information about who created it and why. Example 2-7. Documented module for calculating fall velocities %% @author Simon St.Laurent <[email protected]> [http://simonstl.com] %% @doc Functions calculating velocities achieved by objects %% dropped in a vacuum. %% @reference from <a href= "http://shop.oreilly.com/product/0636920025818.do" >Introducing Erlang</a> %% O'Reilly Media, Inc., 2012. %% @copyright 2012 by Simon St.Laurent %% @version 0.1 -module(drop). -export([fall_velocity/1]). Documenting Code | 19
  • 42. fall_velocity(Distance) -> math:sqrt(2 * 9.8 * Distance). Erlang can build the files for you using the EDoc file function: Eshell V5.9 (abort with ^G) 1> edoc:files(["drop.erl"], [{dir, "doc"}]). ok You’ll now have a collection of files in the doc subdirectory. If you open drop.html in a browser, you’ll see something like Figure 2-1. Figure 2-1. Module documentation generated from the drop.erl file All of that metadata is great, and it can be gratifying to see your name “in lights.” However, unless you have a complex story to tell about your module as a whole, it’s likely that the core of the documentation will appear at the function level. Documenting Functions The drop module contains one function: fall_velocity/1. You probably know that it takes a distance in meters and returns a velocity in meters per second for an object dropped in a vacuum on Earth, but the code doesn’t actually say that. Example 2-8 shows how to fix that with EDoc comments and the @doc tag. 20 | Chapter 2: Functions and Modules
  • 43. Example 2-8. Documented function for calculating fall velocities %% @doc Calculates the velocity of an object falling on Earth %% as if it were in a vacuum (no air resistance). The distance is %% the height from which the object falls, specified in meters, %% and the function returns a velocity in meters per second. fall_velocity(Distance) -> math:sqrt(2 * 9.8 * Distance). Figure 2-2 shows the result, which is considerably more helpful than the previous blank space around the function. It neatly takes the first sentence of the information following @doc and put it in the index, using the whole description for the Function Details section. You can also use XHTML markup in the @doc section. Figure 2-2. Function documentation generated from the drop.erl file That’s a major improvement, but what if a user specifies “twenty” meters instead of 20 meters? Because Erlang doesn’t worry much about types, the Erlang code doesn’t say that the value for Distance has to be a number or the function will return an error. You can add a directive, -spec, to add that information. It’s a little strange, as in some ways it feels like a duplicate of the method declaration. In this case, it’s simple, as shown in Example 2-9. Documenting Code | 21
  • 44. Example 2-9. Documented function for calculating fall velocities %% @doc Calculates the velocity of an object falling on Earth %% as if it was in a vacuum (no air resistance). The distance is %% the height from which the object falls, specified in meters, %% and the function returns a velocity in meters per second. -spec(fall_velocity(number()) -> number()). fall_velocity(Distance) -> math:sqrt(2 * 9.8 * Distance). EDoc will combine the types specified in the -spec directive with the parameter names in the actual function declaration to produce the documentation shown in Figure 2-3. Figure 2-3. EDoc documentation with type information This chapter has really demonstrated only the number() type, which combines integer() and float(). Appendix A includes a full list of types. Documenting Your Application Sometimes you want information like the author and copyright data to appear in every module, often when it varies from module to module. Other times that becomes clutter, and it’s easier to put it into one place where it applies to all of your modules. You can create an overview.edoc file in your project’s doc directory. Its content looks much like the markup used in the modules, but because it isn’t mixed with code, you don’t need to preface every line with %%. The overview.edoc file for this project might look like Example 2-10. 22 | Chapter 2: Functions and Modules
  • 45. Example 2-10. Documented module for calculating fall velocities @author Simon St.Laurent <[email protected]> [http://simonstl.com] @doc Functions for calculating and converting velocities. @reference from <a href= "http://shop.oreilly.com/product/0636920025818.do" >Introducing Erlang</a>, O'Reilly Media, Inc., 2012. @copyright 2012 by Simon St.Laurent @version 0.1 Now, if you re-generate documentation and click on the Overview link, you’ll see something like Figure 2-4. Figure 2-4. Application overview created with EDoc. If you create similar documentation in each of the Erlang files and run edoc:files(["drop.erl", "convert.erl", "combined.erl"]). in the Erlang shell, EDoc will build a neat if somewhat plain set of frame-based documentation for your application, as shown in Figure 2-5. Documenting Code | 23
  • 46. Figure 2-5. The opening to the complete set of module documentation This is just an introduction to EDoc. For more, see Chapter 18 of Erlang Program‐ ming, where you can learn about fun things like the @todo tag. You can learn more about working with functions and modules in Chapters 2, 3, and 9 of Erlang Programming (O’Reilly); Chapter 3 of Programming Erlang (Pragmatic); Sections 2.3, 2.5, and 2.7 of Erlang and OTP in Action (Manning); and Chapters 2 and 3 of Learn You Some Erlang For Great Good! (No Starch Press). There’s more on documentation in Chapter 18 of Erlang Programming and types in Chapter 30 of Learn You Some Erlang For Great Good!. 24 | Chapter 2: Functions and Modules
  • 47. CHAPTER 3 Atoms, Tuples, and Pattern Matching Erlang programs are at heart a set of message requests and tools for processing them. Erlang provides tools that simplify the efficient handling of those messages, letting you create code that is readable (to programmers at least) while still running effi‐ ciently when you need speed. Atoms Atoms are a key structure in Erlang. Technically they’re just another type of data, but it’s hard to overstate their impact on Erlang programming style. Usually, atoms are bits of text that start with a lowercase letter, like ok or earth. They can also contain (though not start with) underscores (_) and at symbols (@), like this_is_a_short_sentence or me@home. If you want more freedom to start with uppercase letters or use spaces, you can put them in single quotes, like 'Today is a good day’. Generally, the one word lowercase form is easier to read. Atoms have a value—it’s the same as their text. (Remember, the period after hello isn’t part of the atom—it ends the expression.) 1> hello. hello That’s not very exciting in itself. What makes atoms exciting is the way that they can combine with other types and Erlang’s pattern matching techniques to build simple but powerful logical structures. Pattern Matching with Atoms Erlang used pattern matching to make the examples in Chapter 2 work, but it was very simple. The name of the function was the one key piece that varied, and as long 25
  • 48. as you provided a numeric argument Erlang knew what you meant. Erlang’s pattern matching offers much more sophisticated possibilities, however, allowing you to match on arguments as well as on function names. For example, suppose you want to calculate the velocity of falling objects not just on Earth, where the gravitational constant is 9.8 meters per second squared, but on Earth’s moon, where it is 1.6 meters per second squared, and on Mars, where it is 3.71 meters per second squared. Example 3-1, which you can find in ch03/ex1-atoms, shows one way to build code that supports this. Example 3-1. Pattern matching on atoms as well as function names -module(drop). -export([fall_velocity/2]). fall_velocity(earth, Distance) -> math:sqrt(2 * 9.8 * Distance); fall_velocity(moon, Distance) -> math:sqrt(2 * 1.6 * Distance); fall_velocity(mars, Distance) -> math:sqrt(2 * 3.71 * Distance). It looks like the fall_velocity function gets defined three times here, and it cer‐ tainly provides three processing paths for the same function. However, because those definitions are separated with semicolons, they are treated as choices—selected by pattern-matching—rather than duplicate definitions. As in English, these pieces are called clauses. If you use periods instead of semicolons, you’ll get errors like drop.erl:5: function fall_velocity/2 already defined. Once you have this, you can calculate velocities for objects falling a given distance on Earth, the Earth’s moon, and Mars: 1> c(drop). {ok,drop} 2> drop:fall_velocity(earth,20). 19.79898987322333 3> drop:fall_velocity(moon,20). 8.0 4> drop:fall_velocity(mars,20). 12.181953866272849 You’ll quickly find that atoms are a critical component for writing readable Erlang code. 26 | Chapter 3: Atoms, Tuples, and Pattern Matching
  • 49. Atomic Booleans Two of Erlang’s atoms have special properties: true and false, representing the boolean logic values of the same names. Erlang will return these atoms if you ask it to compare something: 1> 3<2. false 2> 3>2. true 3> 10 == 10. true Erlang also has special operators that work on these atoms (and on comparisons that resolve to these atoms): 1> true and true. true 2> true and false. false 3> true or false. true 4> false or false. false 5> true xor false. true 6> true xor true. false 7> not true. false The and, or, and xor operators both take two arguments. For and, the result is true if and only if the two arguments are true. For or, the result is true if at least one of the arguments is true. For xor, exclusive or, the result is true if one but not both argu‐ ments is true. In all other cases they return false. If you’re comparing expressions more complicated than true and false, it’s wise to put them in parentheses. There are two additional operators for situations where you don’t want or need to evaluate all of the arguments. The andalso opera‐ tor behaves like and but evaluates the second argument only if the first one is true. The orelse operator evaluates the second argu‐ ment only if the first one is false. The not operator is simpler, taking just one argument. It turns true into false and false into true. Unlike the other boolean operators, which go between their argu‐ ments, not goes before its single argument. Atomic Booleans | 27
  • 50. If you try to use these operators with any other atoms, you’ll get a bad argument exception. There are other atoms that often have an accepted meaning, like ok and error, but those are more conventions than a formal part of the language. Guards The fall_velocity calculations work fairly well, but there’s still one glitch: if the function gets a negative value for distance, the square root (sqrt) function in the cal‐ culation will be unhappy: 5> drop:fall_velocity(earth,-20). ** exception error: bad argument in an arithmetic expression in function math:sqrt/1 called as math:sqrt(-392.0) in call from drop:fall_velocity/2 (drop.erl, line 4) Since you can’t dig a hole 20 meters down, release an object, and marvel as it acceler‐ ates to the surface, this isn’t a terrible result. However, it might be more elegant to at least produce a different kind of error. In Erlang, you can specify which data a given function will accept with guards. Guards, indicated by the when keyword, let you fine-tune the pattern matching based on the content of arguments, not just their shape. Guards have to stay simple, can use only a very few built-in functions, and are limited by a requirement that they evaluate only data without any side effects, but they can still transform your code. You can find a list of functions that can safely be used in guards in Appendix A. Guards evaluate their expressions to true or false, as previously described, and the first one with a true result wins. That means that you can write when true for a guard that always gets called if it is reached, or block out some code you don’t want to call (for now) with when false. In this simple case, you can keep negative numbers away from the square root func‐ tion by adding guards to the fall_velocity clauses, as shown in Example 3-2, which you can find at ch03/ex2-guards. 28 | Chapter 3: Atoms, Tuples, and Pattern Matching
  • 51. Example 3-2. Adding guards to the function clauses -module(drop). -export([fall_velocity/2]). fall_velocity(earth, Distance) when Distance >= 0 -> math:sqrt(2 * 9.8 * Distance); fall_velocity(moon, Distance) when Distance >= 0 -> math:sqrt(2 * 1.6 * Distance); fall_velocity(mars, Distance) when Distance >= 0 -> math:sqrt(2 * 3.71 * Distance). In Erlang, greater-than-or-equal-to is written >=, and less-than-or- equal-to is written =<. Don’t make them look like arrows. The when expression describes a condition or set of conditions in the function head. In this case, the condition is simple: the Distance must be greater than or equal to zero. If you compile that code and ask for the result of a negative distance, the result is different: 5> drop:fall_velocity(earth,-20). ** exception error: no function clause matching drop:fall_velocity(earth,-20) (drop.erl, line 12) Because of the guard, Erlang doesn’t find a function clause that works with a negative argument. The error message may not seem like a major improvement, but as you add layers of code, “not handled” may be a more appealing response than “broke my formula.” A clearer, though still simple, use of guards might be code that returns an absolute value. Yes, Erlang has a built-in function, abs/1, for this, but Example 3-3 makes clear how this works. Example 3-3. Calculating absolute value with guards -module(mathdemo). -export([absolute_value/1]). absolute_value(Number) when Number < 0 -> -Number; absolute_value(Number) when Number == 0 -> 0; absolute_value(Number) when Number > 0 -> Number. When mathdemo:absolute_value is called with a negative (less than zero) argument, Erlang calls the first clause, which returns the negation of that negative argument, making it positive. When the argument equals (==) zero, Erlang calls the second Guards | 29
  • 52. clause, returning 0. Finally, when the argument is positive, Erlang calls the third clause, just returning the number. (The first two clauses have processed everything that isn’t positive, so the guard on the last clause is unnecessary and will go away in Example 3-4.) 1> c(mathdemo). {ok,mathdemo} 2> mathdemo:absolute_value(-20). 20 3> mathdemo:absolute_value(0). 0 4> mathdemo:absolute_value(20). 20 This may seem like an unwieldy way to calculate. Don’t worry—Erlang has simpler logic switches you can use inside of functions. However, guards are critically impor‐ tant to choosing among function clauses, which will be especially useful as you start to work with recursion in Chapter 4. Erlang runs through the function clauses in the order you list them, and stops at the first one that matches. If you find your information is heading to the wrong clause, you may want to re-order your clauses or fine-tune your guard conditions. Also, when your guard clause is testing for just one value, you can easily switch to using pattern-matching instead of a guard. This absolute_value function in Example 3-4 does the same thing as the one in Example 3-3. Example 3-4. Calculating absolute value with guards and pattern matching absolute_value(Number) when Number < 0 -> -Number; absolute_value(0) -> 0; absolute_value(Number) -> Number. In this case, it’s up to you whether you prefer the simpler form or preserving a parallel approach. You can also have multiple comparisons in a single guard. If you separate them with semicolons it works like an OR statement, suc‐ ceeding if any of the comparisons succeeds. If you separate them with commas, it works like an AND statement, and they all have to succeed for the guard to succeed. Underscoring That You Don’t Care Guards let you specify more precise handling of incoming arguments. Sometimes you may actually want handling that is less precise, though. Not every argument is essen‐ tial to every operation, especially when you start passing around complex data struc‐ 30 | Chapter 3: Atoms, Tuples, and Pattern Matching
  • 53. tures. You could create variables for arguments and then never use them, but you’ll get warnings from the compiler (which suspects you must have made a mistake) and you may confuse other people using your code who are surprised to find your code cares about only half of the arguments they sent. You might, for example, decide that you’re not concerned with what planemo (for planetary mass object, including planets, dwarf planets, and moons) a user of your velocity function specifies and you’re just going to use Earth’s value for gravity. Then, you might write something like Example 3-5, from ch03/ex3-underscore. Example 3-5. Declaring a variable and then ignoring it -module(drop). -export([fall_velocity/2]). fall_velocity(Planemo, Distance) -> math:sqrt(2 * 9.8 * Distance). This will compile, but you’ll get a warning, and if you try to use it for, say, Mars, you’ll get the wrong answer for Mars. 1> c(drop). drop.erl:5: Warning: variable 'Planemo' is unused {ok,drop} 2> drop:fall_velocity(mars, 20). 19.79898987322333 On Mars, that should be more like 12 than 19, so the compiler was right to scold you. Other times, though, you really only care about some of the arguments. In these cases, you can use a simple underscore (_). The underscore accomplishes two things: it tells the compiler not to bother you, and it tells anyone reading your code that you’re not going to be using that argument. In fact, Erlang won’t let you. You can try to assign values to the underscore, but Erlang won’t give them back to you. It consid‐ ers the underscore permanently unbound: 3> _ = 20. 20 4> _. * 1: variable '_' is unbound If you really wanted your code to be earth-centric and ignore any suggestions of other planemos, you could instead write something like Example 3-6. Example 3-6. Deliberately ignoring an argument with an underscore -module(drop2). -export([fall_velocity/2]). fall_velocity(_, Distance) -> math:sqrt(2 * 9.8 * Distance). Underscoring That You Don’t Care | 31
  • 54. This time there will be no compiler warning, and anyone who looks at the code will know that first argument is useless. 5> c(drop2). {ok,drop2} 6> drop2:fall_velocity(you_dont_care, 20). 19.79898987322333 You can use underscore multiple times to ignore multiple arguments. It matches any‐ thing for the pattern match, and never binds, so there’s never a conflict. You can also start variables with underscores—like _Planemo—and the compiler won’t warn if you never use those variables. Those variables do get bound, and you can reference them later in your code if you change your mind. However, if you use the same variable name more than once in a set of arguments, even if the variable name starts with an underscore, you’ll get an error from the compiler for trying to bind twice to the same name. Adding Structure: Tuples Erlang’s tuples let you combine multiple items into a single composite data type. This makes it easier to pass messages between components, letting you create your own complex data types as you need. Tuples can contain any kind of Erlang data, includ‐ ing numbers, atoms, other tuples, and the lists and strings you’ll encounter in later chapters. Tuples themselves are simple, a group of items surrounded by curly braces: 1> {earth, 20}. {earth, 20} Tuples might contain 1 item, or they might contain 100. Two to five seem typical (and useful, and readable). Often (but not always) an atom at the beginning of the tuple indicates what it’s really for, providing an informal identifier of the complex informa‐ tion structure stored in the tuple. Erlang includes rarely used built-in functions that give you access to the contents of a tuple on an item by item basis. You can retrieve the values of items with the element function, set values in a new tuple with the setelement function, and find out how many items are in a tuple with the tuple_size function. 2> Tuple = {earth, 20}. {earth,20} 3> element(2, Tuple). 20 4> NewTuple = setelement(2, Tuple, 40). {earth,40} 5> tuple_size(NewTuple). 2 32 | Chapter 3: Atoms, Tuples, and Pattern Matching
  • 55. Random documents with unrelated content Scribd suggests to you:
  • 56. before. Bad's the best, they say, but better bad than worse; and so it was in my case, for now I was left in the dark without anything to eat or drink at all for a great many hours, till the sunshine came in at a hole up above, and I began to whistle to pass the time. Soon after I was taken out, and was carried to a room where there were five or six people, and a large curtain across one end of the room. There was a table, too, with several things upon it, some little and some big, made of iron, and of very odd unpleasant shapes. One was like a barbecuing spit, only not so big; and I heard them call it the boot. A stout man was standing by the table, twice as big as I am, with his jerkin off and his sleeves turned up. I did not like his look at all. When I was brought in, those who were at the table began to cross-question me in all manner of ways as to what I did in Scotland, and how I came to be at Trochrie; and I beat about the bush a long time, especially when they asked me about my lady----" "Then they knew already she was there?" said the earl. "I'm not quite sure, my lord, now," said Austin Jute, frankly. "They seemed to know at the time; but I believe they took me in. I would not tell you a lie, my lord, for the world; but I've a strong notion they made me betray myself, by pretending to know more than they did. I'm very sorry for it; but what's done can't be undone. A bolt that's shot must go its own way. However, when I found that, either by what I said or by what they themselves knew, they were quite sure of the matter, I refused to answer any more questions as to how she was brought there, and all the rest. Then they threatened to put the boot on me, as they called it. I did not like that at all. I should have fancied my leg a pig being roasted alive; but instead of that they put a thing upon my thumb, and told me to answer truly, or it should be screwed up." Gowrie rose from his seat, and walked up and down the room with his cheek flushed and his brow contracted; but he said nothing; and, after gazing at his lord for a moment, Austin Jute continued. "They changed their course now, however, and began asking if I had
  • 57. been with you in Italy; so I said I had. Then they inquired where you had hired me; on which I said, in Padua, five years ago. After that, this question arose, whether I had known the lady Julia there, and her grandfather, and how long. It was an unpleasant sort of catechism with that thing dangling at my thumb; but having heard the king talk at Falkland about the lady's money, and how much he expected to make by having her in ward, I saw what they were seeking, and I said to myself, they'll come to the money in a few minutes. A nod is as good as a wink to a blind horse, and so I answered, boldly, that I had known her and the old gentleman ten or twelve years, long before your lordship came to Padua." "But that was false," exclaimed the earl. "I can't help that, my lord," replied Austin Jute; "it answered its purpose. As I had got into a scrape by letting out the truth, there was only one way of mending it--by letting out some falsehood. Put them into two scales, and the one will balance the other. If people ask me questions they have no business to ask, they may get answers that I have no business to give. However, they asked me how the old gentleman and the young lady lived in Padua, and knowing I could do no mischief now, I said, 'Heaven knows. They were poor enough, in all conscience; but where they got what little they had, I can't tell.' Then a club-footed man, that sat at the end of the table, said quietly, 'Then they did not keep up much state;' at which I laughed, and made him no answer, as if the very thought of such a thing was too ridiculous; upon which that accursed fellow, with the sleeves turned up, gave a turn to the thing upon my thumb, and sent a pain running all the way down to the soles of my feet. I never felt anything like that. I had well nigh roared with it; but I set my teeth hard and held my breath; and the man at the end of the table checked the tormentor for what he had done, and bade him keep his hands off till he was bid. So the thing was unscrewed; and then they asked me how many servants the old signor kept, and I humbly inquired whether they meant men or maids. The answer was, 'Both,' to which I replied, 'One, and she was an old woman. So
  • 58. it answered both purposes.' The man with the club-foot called me a saucy knave, and tried to look very angry; but he laughed notwithstanding, and inquired if I were sure there had been no more kept; and I answered, 'Not one as long as I had known the family.' The other questions were all of the same sort, and they tried to puzzle me very hard; but they could not manage it, though they talked about a man servant whom they pretended the signor had kept. To that I had my answer pat, however--that I was ready to swear upon the Evangelists that there had never been any but one and the same servant there for ten years. 'Whether it was a man or a woman,' I said, 'it was impossible for me to say. Their honours knew best; but one thing I would take my oath of, that it wore petticoats and was called Tita.' Thereupon there was a great burst of laughter; and the room had a strange echo in it, for the same sounds came back from behind the curtain." "The party seems to have been a merry one," said the earl, "considering the circumstances." "Nevertheless, they took me back, and plunged me into the same dark hole, and left me there till this morning, when I was taken out, in an oddish kind of way, not by a jailor or a guard, but by two gentlemen. There was a little boy, about as high as my knee, standing by a garden-gate to which they brought me, and he had my horse in his hand. So they told me to get up and ride away, as if Satan were behind me, back to Trochrie, and not to say a word to a living soul, but more especially to you, my lord, of anything that had happened; and they threatened me sore, moreover. I did ride away, for I was glad to be out of their hands; but I remained at the south ferry house till dusk, and then came back to seek your lordship and tell you all." "You have done well, Austin," replied Gowrie, "and are an honest faithful fellow. I was nearer to you and them, when they mounted you this morning, than either knew; and I heard something said about starving your horse."
  • 59. "Oh, that was but a snap, my lord, where I had no teeth to bite hard," replied Austin. "I know that a bitter word is often worse than a sharp sword. So, having nothing else to say, I told them they had starved my horse to make him like themselves. I took care to be in the saddle first, however; but, instead of trying to stop me, one of them gave the poor beast a cut with his whip, and sent us both about our business." How the king had obtained information that Julia was concealed at Trochrie was now in part revealed; but only in part, for it was evident, from Austin's capture and examination, that some hint had been gained before--how, Gowrie could not divine. The honest servant was sent back before dawn on the following day, on his way to the highland castle, and he did not depart without a liberal reward, which he accepted without ceremony, for there were no affectations about good Austin Jute. He served faithfully, devotedly, where he attached himself; he would at any time have perilled life or limb, or sacrificed every comfort and convenience for a lord he loved; and, to say nought but truth, I do not think that, in so doing, he ever in his inmost heart thought of a recompence, but he took it willingly enough when it was given, and, sad to say, spent it with as little consideration as he won it. Several more days elapsed ere the paper Gowrie required was drawn up by the men of law, and he twice presented himself at the palace. All there seemed still fair and smooth; the king's good humour lasted undisturbed; the queen was ever kind and gracious; Sir Hugh Herries did not appear at court, and John Ramsay, though distant to Alexander Ruthven, was warmer in his manner to the earl. "Beatrice's doubts are unfounded, I do believe," thought Gowrie, as he rode away after the second visit; and when he returned to his own dwelling, he found the act of renunciation waiting for him. Somewhat less than an hour of daylight still remained, and that time was spent in reading and considering the document.
  • 60. The sun had just set, leaving a bright glow in the April sky, and Gowrie had risen to gaze at it from a window which looked out towards the west, when suddenly he heard a hasty foot in the ante- room, and the next instant Sir John Hume entered in haste. "Here, Gowrie," he said, advancing with a small paper folded and sealed in his hand. "Here is something for you. What it contains I know not; but Beatrice slipped it into my hand in haste and agitation, saying, in a whisper, 'To Gowrie, with all speed.'" Gowrie took it, tore it open, and found the words, "Away, with all speed, to Perth!--to-night!" "My lord, here is Sir George Ramsay without, desiring to see you," said a servant, looking in. "Admit him," replied the earl, crushing the paper in the palm of his hand. The next moment Ramsay entered, with as much apparent haste as Hume; but on seeing the latter he paused, assumed a calmer air, and advancing to the earl, shook hands with him, saying, "It is a fair and warm afternoon, my lord, what say you to a twilight ride?" "Not to-night, Dalhousie," replied Gowrie, gazing at him attentively; "have you any particular object in your proposal?" "Only to have a few minutes' conversation with you, my dear lord," replied the other, returning his glance with one of equal significance; "but a moment here in private will do as well;" and he moved towards a distant window. Gowrie followed him, bending down his head; and Ramsay approaching close, whispered in his ear, "You are in danger, my lord. It were well you departed at once. Lose no time--I dare not say more."
  • 61. Gowrie pressed his hand kindly and gratefully, saying, "Thanks, Dalhousie, thanks! I had heard the tidings before; but the obligation to you is no less." He spoke openly and aloud; and his friend, laying his finger on his lip, as if to counsel discretion, retired almost as hastily as he had come. Ere half an hour had passed, the earl was on horseback, and riding towards Queensferry. CHAPTER XXXV. It was a bright, hot summer day, the sky without a cloud, the air without a breeze. The sports of the morning were over, the hounds had returned to their kennel, the slaughtered stag was brought in, the horses were in the stable, the hunters seeking repose. The old palace of Falkland, where James V. drew the last breath of a life which had become burdensome, rose stately amidst its gardens and woods; and the old trees, but few of which now remain in the neighbourhood, then spread their wide branches over the velvet turf; in some places approaching so near to the building, as, when the wind waved them, to brush with their long fingers the palace walls. James himself had gone in about an hour before, rejoiced with the success, but fatigued with the exertions, of the chase; and all the ladies of the court were screening their beauty in the shady halls, from the glare of the full sun. It has often struck me, in looking at the finer paintings of Claude de Lorraine--and they are not all really fine--and in contemplating
  • 62. the calm, quiet, sunny scenes they represent, that the painter must have chosen, by preference, that hour when, under the summer skies of Italy, all nature seems to be taking a mid-day slumber. Such was the aspect of the scene about the palace of Falkland on the day of which I speak. Looking towards the wood, and with one's back towards the palace, so as to shut out its memorial of active life, one might have fancied that one was in the midst of some primeval solitude, or else that the whole world, oppressed with the heat, was sound asleep. No moving object was to be seen; not a forester or keeper was within sight; the deer were hidden in the coverts of the wood; the very birds seemed to avoid the glare; and the court servants themselves--those busy toilers--were all enjoying the repose afforded by the weariness of their lords. At length, however, after the scene had remained thus quiet for about half an hour, a very young but very handsome man sauntered forth from one of the smaller doors of the building, crossed the warm green in front, turned to one of the old trees, stood for a moment under the shade, and then walked languidly to another, near an opposite angle of the palace. He seemed seeking a place for repose, but difficult to please, for he again left that tree and strolled to its green neighbour, where, stretching himself on the grass, he laid a book, which he carried with him, open on the ground, and supporting his head with his arm, gave himself up to thought. Oh, the thoughts of youth--the gay, the whirling, dream-like thoughts of youth! How pleasant is the visionary trance which boys and girls call meditation! True, youth has its pains as well as pleasures, both eager, intense, and thrilling; but it wants the fears and doubts of experience, that bitterest fruit of long life. The cloud may hang over it for an hour, but the breath of hope soon wafts it away, and it is not till the storm comes down in its full fury that youth will believe there are tempests in the sky. There he lay and thought, with the branches waving gently over him, and the chequered light and shade playing on his face and on the open pages of the unread book beside him. The air was very
  • 63. sultry, even beneath the shadow of the trees, and he untied the cord which confined his silken vest at the neck, displaying a skin almost as fair as a woman's, although exercise, it would seem, was not wanting to give a browner hue; for even then he looked fatigued as well as heated, and there was dust upon his hair and upon his dress, as if he had ridden far and long that day. Weariness, and the hot summer air, with the playing of the shadows over his face, seemed to render him sleepy. His eyes looked heavy for a moment or two, the eyelids closed, opened again, closed once more, and there he lay, sound, sound asleep, not unlike what we may fancy was the shepherd boy of Latmus, when under the influence of the fair queen of night. Some quarter of an hour had passed, and he still lay sleeping there, when round that angle of the building near which the tree grew, came walking, with a slow pace, a man of middle age, with an ungraceful gait, and of an ungainly appearance. He was habited in a suit of green, with a large ruff round his neck, and a tall crowned gray hat and feather; but he wore neither cloak nor sword, and instead of the latter, bore a small knife or dagger, stuck into his girdle on the left side. He, like the youth, seemed to have come out of the palace for fresher air than could be found within; and he, too, appeared in a meditative mood, for he walked with his eyes bent down, and his hand, in no very courtly fashion, scratching his breast. Nevertheless, from time to time, he gave a glance around; and the second time he did so, his eye fell upon the sleeping youth beneath the tree. With a quiet step he approached his side, but was instantly attracted by the open book, and took it up. "Ay," murmured he, in a low tone, "love songs! That's just it; fit food for such a wild, empty-pated callant's brain." Thus saying, he laid down the book again, and gazed upon the young man's face.
  • 64. Suddenly he saw something which seemed to displease him mightily. His cheek flushed, his brow contracted, and he set his teeth hard. Then, bending down his head, he peered into the open bosom of the lad, and even partly drew back the collar of his shirt. It was done quietly and gently, but still it in some degree roused the sleeper, for he lifted his hand and brushed his throat, as if a fly had settled on him. The other started back instantly, but the young man did not wake; and the one who watched him continued to gaze at him sternly, with many a bitter feeling, it would appear, in his heart. His lip quivered; and for a moment he held his hand upon the hilt of his dagger, with a somewhat ominous look, and a cheek which had become pale. Then, however, he seemed to have made up his mind as to what he should do; and, stepping quietly back over the soft green turf, he approached one of the doors of the palace, which was close at hand, and tried to open it. It was locked, however, and turning on his heel again, with a low muttered blasphemy, he went round the angle of the building by the way which he had followed when he came. Neither the sleeper, nor he who had lately stood beside him, was aware that there was another eye upon them both; but the instant the latter had departed, the door which he had tried in vain opened suddenly, and the light beautiful form of Beatrice Ruthven darted forth, crossed the green sward with the quick spring of a roe deer, and stooping over the sleeping youth, without care or ceremony, she tore from his neck a thick blue silk ribbon worked with gold. The young man raised himself suddenly on his arm, looking surprised and bewildered; but Beatrice laid her finger on her lips, merely saying, in a low but emphatic tone, "Into the palace like lightning, mad boy!" and away she sprang towards the building again, passed the door, ran through the first passage, and up a narrow staircase to the entrance of a room on the first floor. There she paused and listened for a single instant, then threw the door open without ceremony and ran in.
  • 65. Anne of Denmark was seated at a table, writing; but the sudden opening of the door made her lift her fair face with a look of some surprise and displeasure; and she said, in a reproving tone, "Beatrice! What now?" Without reply, the fair girl darted forward in breathless haste, and laid the ribbon on the table before the queen. "Quick, madam! put it in the drawer," she said, in a low, hurried tone. "Your majesty will see why in an instant;" and without waiting for any answer, she hurried from the room by the same way she had come, and closed the door. There were several drawers in the writing table at which the queen was seated; and opening one with a hand which trembled slightly, while her cheek glowed a good deal, she placed the ribbon in it, closed it again, and tried to resume her writing; but not more than one minute had passed ere the step of the king was heard upon a staircase at the opposite side of the apartments from that by which Beatrice had entered, and a moment after James himself appeared, with a heavy scowl upon his brow. Anne of Denmark looked up, not without some timidity, though she was by nature very intrepid. There was no expression, however, upon her countenance which could betray the agitation within; and seeing the look of anger and malice on James's face, she boldly took the initiative, saying, "What is the matter, sir? You seem disordered." "No, no, my bonny bairn," said James, "there's nothing the matter; but I was just thinking what clever chiels those Italians are; and I want to see that ribbon which I bought for you of the merchant man." "Certainly, sir," replied the queen, rising, with an unconcerned look, for she wished to test how far James's suspicions went; "you shall see it in a moment."
  • 66. "No," cried the king, hastily, thinking that the queen was going to quit the chamber. "You had it in this room, madam, not so long ago that you need go to seek it. It's here you keep all your gauds and ornaments." "Well, sir," answered Anne of Denmark, "I have no doubt that it is here still; but I cannot even open the drawers of this table, to look for it, without rising. I know not what is the matter with your majesty, but your conduct is very strange." "I just want to see the ribbon, madam, that is all; and I think it must be in this chamber--if anywhere," was James's reply. "Doubtless," answered Anne of Denmark, so far agitated as to open the wrong drawer by mistake. "It's no there," said the king, looking into the drawer. "There's naething there but gloves, and bracelets, and such like clamjamfry." "I see it is not, sir," replied the queen, turning over the things with her hand; "but it may be somewhere else. Do you think any one has stolen it?" And she opened the drawer in which it really was. James did not reply to her question; but not a little astonishment was painted on his rude coarse countenance, when Anne of Denmark drew forth the ribbon and laid it in his hand. He continued to gaze at it for a considerable time, and then put it closer to his eyes, to examine it more carefully all over, as if he doubted that it was really that which he had bestowed upon the queen. There it was, however, precisely the same in every respect; and at length he gave it her back again, and turning sharply on his heel, quitted the room, muttering, loud enough for her to hear, "De'il tak me, if like be not an ill mark." A minute or two after, he was seen walking past the tree under which Alexander Ruthven had been sleeping; but by that time the young gentleman was gone.[4] One of the ordinary servants of the
  • 67. court passed his majesty, bowing low, a moment after; and the king called him up, saying, as he approached, "Go your ways, and rout me out Doctor Herries and the man retiring," James continued to walk up and down till he was joined by the person whom he had sent for. They then turned to the farther part of the gardens, much to the disappointment of Beatrice Ruthven, who saw all that passed from the window of a room immediately below that of the queen, and who had hoped to gather, at least from their demeanour, some indications of what was passing in regard to her brother. I will not say that she would not have listened eagerly to their conversation if the opportunity had presented itself; and perhaps the circumstances in which she was placed might be some justification of an act otherwise mean and pitiful; for, as the reader will see in the subsequent chapter, she had accidentally obtained information of designs the most treacherous against one dear brother, of whose high principles and noble conduct she could not entertain a doubt. The king and his companion, however, walked away to the other side of the garden, as I have said, and stayed there for nearly half an hour, while Beatrice remained in anxious and painful thought. Her head rested on her hand, as she sat near the open window; and she had taken no note of how the time passed, when at length the sounds of people speaking as they walked by below, caught her ear. She would not move in the slightest degree; she even held her breath, lest she should lose one sound, and the next instant she distinguished the king's peculiar tone. The words as yet she could not hear, and still less those of Herries in his reply, though she recognised his voice at once. The next instant, however, the sounds rose louder, and James was heard to say, "No, no, that will never do. We should lose our grip of the old bird, while wringing the neck of the young one; and there would be such a dust about it, that we should never see our way clear after."
  • 68. "There, I think, your majesty is right," said Herries; "but if you will be advised by me there is a way to----" Beatrice lost the conclusion of the sentence, for they moved on towards the other end of the terrace. She knew, however, that none of the royal apartments lay in that direction, and that the only door by which the king could enter led through the great hall, where he must necessarily encounter a number of the servants and followers of the court, a thing which James rarely desired. She approached somewhat nearer the window then, calculating that the two who had passed would return by the same way; nor was she disappointed, for, in a very few minutes, she heard the voices again, and the words of the king soon became audible. They were of no great importance, indeed, and conveyed no information but that which she already possessed--namely, that both her elder brothers were the principal objects, for the time, of James's hatred and suspicion. "The de'il helps they Ruthvens, I think," said the monarch. "The one brother conveys himself away just at the minute when we have got all ready for him; and the other sends a token I would swear to, fleeing through the walls of Falkland like a conjuror." This was all that Beatrice heard, but after they had passed the window, Doctor Herries replied, "The devil always helps his own, sire." "And that's well said," answered the king, "for we have information to be relied upon, that this Earl of Gowrie, when in the city of Padua, had long and familiar dealings with a reputed sorcerer and magician, some of whose infernal arts he has doubtless acquired or contracted. Such matters are difficult of proof, for deeds of darkness hide themselves from the light. But time discovers many things, and Sathanus deals with his pets as we do with the birds and beasts which we keep for our food. He pats them on the back till his time comes, and then he cuts their weasands."
  • 69. Doctor Herries smiled, for he was not so credulous in matters of demonology as his master; but by this time they had reached one of the smaller doors of the palace, which stood open, and they went in. CHAPTER XXXVI. I must now go back for a period of more than a month. Gowrie on quitting Edinburgh rode on at a quick pace, hoping to save the tide at Queensferry; but he did not succeed. The water had sunk low, and the boat was on the shore. There was no resource but either to ride farther up in the direction of Stirling, or to wait till the next morning. Gowrie chose the latter course, though at the chance of being pursued and overtaken. He did not like the feeling of flight; and though it might be necessary, and he had already adopted the expedient as the only means of security, his repugnance was sufficient to turn the scale, when, on the banks of the Firth of Forth, he had to consider what was the next step to be taken. All passed quietly at the little inn, however. No signs or sounds of pursuit disturbed the night; and by grey of the dawn on the following morning, the earl and his followers were upon the shores of Fife. A short ride brought them into Perthshire; and then feeling in safety, the young earl paused at the first village, to consider what course he had better follow. If he went on to Perth, he saw that he might be detained there for some time. It was long since he had seen her whom he loved; and he felt that yearning of the heart to hold her in his arms again, which those who have loved truly can well comprehend. He was also somewhat anxious for her safety after all that had occurred to Austin Jute; but then, on the other hand, the few brief words which his sister had written, had indicated Perth as the place where he ought to take refuge; and it was not improbable
  • 70. that she might either know of some ambush on the way to Trochrie, or intend to send him further information before he went. The importance of receiving the speediest intelligence of what was passing at the court, decided him at length to act contrary to his own wishes, and he resolved to sleep that night at least in Perth. Hardly had he risen on the following morning, when, at one and the same time, it was announced to him that one of the magistrates of the town desired to see him, and that a messenger from Dirleton had just dismounted in the courtyard. The latter was instantly admitted, and presented the earl with a packet addressed in his mother's hand. On opening it, however, he found a sealed letter from his sister, and also a few lines from the countess, informing him that the enclosed had come that morning from Beatrice, with the request that it might be forwarded instantly, and by a trusty messenger, to Perth. The letter from his sister contained the following words:-- "My dear and noble Lord and Brother, "I had but time and opportunity to write you a very few words yesterday evening, which Hume must have delivered safely, as I find this morning that you have followed counsel, and are gone. I now send you farther information, not direct to Perth, but by the hands of our dear lady mother, lest what I write should be stopped by the way. All is quiet here at this present, but some people are much disappointed, I believe, in their hearts. The cause of my warning was as follows.--My maid, Margaret Brown, who is very faithful to me, but of a very prying and inquisitive disposition, and not without shrewdness, informed me that danger awaited you, my dear brother. She had seen that something was going on, it seems, in the abbey, which excited in her some suspicion; and her cousin, Robert Brown, a menial servant of the palace, after having been called to the presence of the king, said to her, unadvisedly, as she was coming to
  • 71. my room to aid me in changing my dress for the court in the evening, 'Your lady will have a sore heart before long.' Thereupon the girl, after having dressed me, employed all her art and ingine to draw forth from the man what it was he meant, and succeeded so far as to learn that you were to be arrested the next morning; but in such a sort, without due warrant or form of law, and with insults and injuries belike, as might bring you to resistance, when, a fray being created, you might perchance be killed without there seeming blame to any one. This was the girl's story. She having got some one of the court to call me out of the presence, and having always found her faithful and true of tongue, I wrote hastily the words I sent, and gave them to our friend Hume, to be delivered to your hand. "Thus far is the girl's story confirmed since your departure, that I have it from a certain source, several people well armed went down to your house this morning, and others followed them not far behind, even so much that the street was crowded. On arriving they asked for you of the porter, but learning that you had gone for Perth on the night before, and being confirmed of the fact by one who saw you ride away, they separated and retired, not having told the reason of their coming. This makes me well satisfied that I warned you as I did, and assures me that you have not been driven away needlessly by your loving sister, "Beatrice Ruthven." "I must have forgotten Scotland," murmured Gowrie to himself. "Heaven! what a dream I have been living in!" Perhaps what he said was true. We are all apt to forget the evils and discomforts of a place we have left behind. Memory is fond of pleasant objects, and plants thick ivy shrubs to rise up and decorate the ruins of the past. He had forgotten the turbulence and dangers which had surrounded his early days. He had almost brought himself
  • 72. to fancy that, as compared with Italy, Scotland was a place of peace, and security, and freedom, where the assassin's knife, the oppressor's wrong, the tyrant's sway were comparatively unknown. But the bitter reality was now before him; and he saw that to be an enemy of the court was to be but a hunted beast, whom every dog of favour might pull down and tear at liberty. After a few minutes' thought, however, he cast off the impression, and sent for the bailie, who was waiting to speak with him. This magistrate was the reverse in everything of his junior, Bailie Roy-- tall, thin, and raw-boned in person, somewhat bluff, and very laconic of speech; a man to be moved neither by fear or favour, but strong in his attachments and steady in his sense of right. He made an ungainly bow in answer to the earl's salutation, and at once dropped into the seat which he was invited to take. "I have come, my lord," he said, "about the prisoner, David Drummond." And there he stopped, as if all his say was said. "Well, Mr. Bailie, what of him?" rejoined the earl. "I hear he has not been tried yet. If you will name the day most convenient to the magistrates, I will come down for the purpose, and hold a court." "They were thinking of the twenty-second of the month," answered Bailie Graham; "aiblins that might not suit your lordship?" "Quite well," answered Gowrie. "I will be down, undoubtedly." Still Mr. Graham continued to sit and twirl his beaver, as if labouring with some other question or announcement; and at length he said, "Your lordship would not see the prisoner?" "Certainly not," answered Gowrie. "He has been my own servant; and even that might be supposed to have some effect upon my judgment; but I can have no private communication with him while
  • 73. awaiting trial. If he have anything to request, either to make imprisonment more tolerable or to provide for his defence, let him demand it publicly." "He said he would write to the king, my lord, when he was told of your answer," replied the bailie; "and he did it." "Can he write?" asked the earl, in some surprise. "No, not just with his own hand," said Mr. Graham; "but he got a scrivener to do it for him; and Bailie Roy, one way or another, got goodman Jobson to tell him what it was he said." "I do not wish to hear, Mr. Bailie," said the earl. "It was probably intended for the king's ear alone." "Ay, that it was," said the bailie, drily; "and no doubt his majesty will think no more of it than it deserves. It's not like to do the Earl of Gowrie much harm, I should think." "I cannot tell," replied Gowrie, coolly; "but the unfortunate man must have his own way. If the king thinks there is anything important in his memorial, he will probably have the prisoner examined before the council." "Na, na, my lord, he'll no do that," answered Bailie Graham. "He's gotten a' that the man can gie; and so he may lie where he is for the king." A few words more explained to Gowrie that James had already sent some one from Edinburgh to confer with the prisoner in his cell; but that since then, "sin syne," as the bailie expressed it, no farther notice had been taken of the unfortunate David Drummond. I must not say that Gowrie had no curiosity to know what the prisoner had said in his letter to the king; but he would not suffer it to master him, although he had little doubt that the first intimation
  • 74. of Julia's concealment at Trochrie had been thus communicated to James, and he did not feel at all sure that many parts of his conduct might not have been misrepresented by the sullen spirit of revenge which he had often remarked in the prisoner. "It is very possible, Mr. Bailie," he said, "that this man may have attempted to injure me in his majesty's opinion by false or perverted statements; but that shall not prevent me from doing all that justice requires, without the slightest consideration of consequences. We will proceed, then, to the trial on the day you have named, and I shall not think it necessary even to let his majesty know the time appointed, for although it would not become either you or me to stop a letter addressed to our sovereign, yet the transaction is one with which we have nothing to do; and we must fulfil our duties as if it had not taken place." "I knew your lordship was right," said Bailie Graham, in broader Scotch than I shall attempt to transcribe. "Bailie Roy, poor body, thought it would have been better for you to have seen the man, and spoke civilly to him till he was hanged; but I said that was not the way a provost of Perth should act; and so good morning to your lordship. Let them say what they will of you, this is the way to win through all." Alas! that it should not always be as the worthy merchant said, and that this history should afford a pregnant example of the reverse. Within an hour after the good man had departed from the earl's great house at Perth, Gowrie himself took his way towards Trochrie, riding with the spirit of love to hurry him forward. Gay and bright were the dreams that he dreamed by the way; and a feeling of rejoicing seemed to fill his heart as he thought that he had cast off the trammels of a court, and resumed that private station in which he now felt sure that happiness was only to be obtained. It would seem that fate or chance takes a delight in throwing obstacles in the
  • 75. way of impatience, perhaps as a check to its vehemence, and a warning to go more quietly. Though he set out early from Perth, and might have ridden the distance to Strathbraan in a few hours, a thousand petty accidents beset the earl by the way. A ford, which used to be practicable at almost all seasons, was now found impassable, for there had been rain in the hills. The earl's own horse cast a shoe, and it had to be replaced before he could proceed; and lastly, turned by the necessity of crossing the river higher up, into a more difficult and dangerous path, one of the horses slipped over a rocky bank, was severely injured, and the rider taken up insensible. The care of the poor man occupied some time; and so much was lost in this and other manners, that the sun had set nearly half an hour when the earl came to the spot whence the first view of Trochrie Castle was to be obtained. He looked eagerly forward through the thickening shadows of the night: the castle itself was lost in the darkness; but a light streamed forth from two spots, side by side, and Gowrie gladly recognised the position of the room in which Julia sat. Oh, how cheering, how gladdening are the lights as we approach after a long absence; what a tale does that faint distant spot of brightness tell to the heart, of peace, and love, and calm domestic joy, and all the hopes that gather round the hearth of home! Onward he went then, with renewed impatience, and in ten minutes more he held Julia gladly to his heart. It was a moment that well repaid all the cares and anxieties and griefs he had suffered. And there they sat side by side, and gazed at each other in silence, with her dear hand locked in his, and the heart looking out through the window of the eye; and each had much to say to the other, but still it was long unsaid, for emotions would have way before words. "You look pale and sad, Gowrie," said Julia, at length. "I fear you have met with disappointment."
  • 76. "No, indeed, dear girl," he answered, "I am not sad, nor have I reason to feel disappointment. My sensations have been very mixed, as all the feelings produced by the great world are; but now joy certainly predominates, for I am with you, and bear you some happy tidings. Then, as to disappointment, dearest Julia, I may experience some at finding that my fancy had drawn pictures of men and things in this, my native land, in colours far too bright; but that was my own fault or my own folly; and in the most essential point of my hopes, I have succeeded as far as I could expect." "Thank Heaven for that!" replied Julia, with no light words; "whatever be that point, I am sure that it is a noble and a good one." "Nay," said Gowrie, "do not praise too much, my Julia. It is a very selfish one; but, to keep you in no suspense, let me tell you that the king has given his consent, in writing, to our union in the month of September next. All difficulties are thus removed, and I must say that in this he has acted, to all appearance, generously; for he had learned that you are here, and might not unreasonably, perhaps, have expressed some anger at my having concealed the fact." "I heard from good Austin that he had gained intelligence of my abode," replied Julia, "and I felt some alarm, especially during your faithful follower's long and unexplained absence; but I tried to comfort myself by thinking of all the precautions you had taken when last you were here; for I can hardly fancy that anything which Gowrie undertakes can go wrong." "Would it were so, truly, my beloved," replied Gowrie, somewhat gloomily. "See this very instance!" exclaimed Julia. "Have you not succeeded where we had so little hope?" "Not succeeded as well as I could wish," answered her lover. "The king has made it a condition, Julia, that you shall formally renounce
  • 77. all claim whatsoever upon the estates and property of your father-- even Whiteburn, though settled by deed upon your mother." He paused a moment, watching her thoughtful face, and then added, "Nevertheless, I have promised the renunciation in your name; first, because I knew it was the only means of winning the king's consent; and secondly, because I found that it was more than doubtful whether you could establish your claim by law." "I have but one regret in this case, Gowrie," replied the beautiful girl--"that I come to you poor and dowerless. Oh, if I had all the wealth which they say my poor father amassed, how gladly would I pour it out before you!" "If that be all, have no regret, my love," replied the young earl-- "right glad am I that you do not possess it. I have wealth enough for both, my Julia--too much, indeed, it seems; for in this land wealth and influence do not excite envy alone, but doubt and suspicion likewise. It is dangerous, I am sure, to be too powerful a subject under a weak king. However, I have enough, and to spare. If then, dear one, you will sign the act of renunciation, I will despatch it to the king to-morrow, and then no objection can be ever raised or opposition offered." "Then I must not go to the court to sign it?" asked Julia, eagerly. "Not unless you wish it," replied Gowrie. "Thank Heaven for that, too!" she exclaimed. "Wish it! Oh no, Gowrie. I suppose the time will come when I must go there; but had I my will, that time would never be. I always dreaded the thought of courts, and what your dear sister told me of that in which she dwells, made me more timid and fearful than ever. Oh, promise me, Gowrie, that we shall spend the greater part of life afar from those nests of envy, malice, and greediness."
  • 78. "That promise I will make with all my heart," replied her lover; "but tell me, Julia, are you not weary of this desert solitude? Beatrice, who almost always counsels well, has half persuaded me to keep you immured here till you are altogether my own; for she sees danger in your residing anywhere not provided so well for defence as this. She thinks the king might seize upon you, and use the expectation of your hand as a means of leading me to a course which my heart and conscience disapprove, or rather, employ the fear of losing you, to drive me to acts which I am bound to oppose and to denounce." "I have never felt weary one day," answered Julia: "fears I may have had--anxiety to see you again, I may have felt; but weariness, never; nor shall I, Gowrie. A few short months will soon pass: you will let me see you at times; I have beautiful nature before my eyes, books, music, painting, thought, to fill up the time; and what need I more? Yes, follow dear Beatrice's counsel. Let me rest here, dear Gowrie, till all places become alike to me, for thou wilt be with me in all." Gowrie pressed her gently to his heart, and then withdrew his arms again; for he felt that, lonely, protected only by his honour, he must not let even the warmth of the purest love call up a doubt or a fear in her young heart. His thoughts and words naturally followed the course in which his feelings led; and he replied, "I will be with you often, my Julia, though now I must leave you soon, I fear; but when I return I will try to bring one of my sisters with me to cheer you." But Julia had tasted less of the tree of the knowledge of good and evil, and she answered, innocently, "I want no cheering when you are with me, Gowrie. Glad shall I be to see them; and if they be like Beatrice, my heart will open to them like a humble flower to the bright sun; but Gowrie's presence is life enough for me. But I have many things to tell you, too; and yet, I know not why, but I think you have not told me all."
  • 79. "Oh, there are many minor things to mention," answered the young earl, doubtful whether it were wisest to inform her of the dangers which had menaced, or to conceal them, now that he was safe, at least for the time. "What need," he asked himself, "to disturb her mind, and keep her in constant agitation, whenever I am absent, by fears for me, whose life has been already menaced? Better let her remain in ignorance of the perils that beset my path, when she can do nought to avert them. Could she act, could she counsel, could she direct, I would conceal nothing from her; but she is here helpless and alone, unable to do aught but sit and weep over the dangers or the griefs of others. Shall I make the hours, lonely and dull as they must be here, sad and apprehensive also? No, no; I will not be insincere; and whatsoever she asks, will answer her truly; but I will say no more upon such subjects than needs must be said." Perhaps Gowrie went a little further than this, for he purposely led the conversation away from the subject of his own fate; and all that Julia learned was, that the king had shown no great love in his demeanour either for the earl or for his brother. Even this made her somewhat thoughtful; and to change the subject, Austin Jute was sent for. He came as fresh, as gay, as ugly as ever; but on this occasion he had little to tell, for his journey back to Trochrie had passed without impediment from any other source but his ignorance of the way. The difficulties he met with from that cause, he described with considerable humour, telling the answers which had been given to his inquiries at the different places which he had passed, and imitating the various dialects of the counties through which he had gone, which were in those days very strongly marked. He did very well till he came to the Gaelic, and even then, though he was utterly unacquainted with the words of the language, he contrived to give some of the sounds so exactly, that Gowrie could not refrain from laughter. Julia rejoiced to see him so gay; and if she had entertained any suspicion that he was withholding the painful portion of the truth from her, it was dissipated by the cheerfulness he displayed.
  • 80. An hour or two thus went by; but Gowrie would not keep her long from repose, for he longed to go forth with her on the following morning, and roam through the valleys, and over the hills, now covered with the yellow broom and the young shoots of the heath. The weather had become bright and warm. The fair season was coming on with rapid strides, when the mountains are softened and decorated by the hand of nature, and their solemn gloom cheered by the smiles of the sky; and Gowrie thought of many a plan to make the hours pass pleasantly. "While here," he said to himself, "the feeling of security will spread a calm and tranquil atmosphere around us, which we could not obtain in a less wild and solitary spot. To-morrow, I will take my dear prisoner forth, and show her some of the beauties of the land to which she is yet a stranger." At an early hour, therefore, he bade Julia adieu for the night, and retired to the room which he had ordered to be prepared for himself in the gate tower. There he held a somewhat long conversation with Donald Macduff, his baron bailie in Strathbraan; and having ascertained from him that all strangers had withdrawn from the neighbourhood, and that a keen watch had been kept up ever since Austin Jute's capture, lest any of the king's people should be lurking about in the valleys around, he lay down to rest, and slept more soundly than he had done for many a night before. CHAPTER XXXVII. In a room of no very great dimensions in the fair town of Perth, were collected a number of persons upon a solemn and serious occasion. A number of the officers and magistrates of the town were present, seated on a little sort of platform raised above the rest of
  • 81. Welcome to our website – the perfect destination for book lovers and knowledge seekers. We believe that every book holds a new world, offering opportunities for learning, discovery, and personal growth. That’s why we are dedicated to bringing you a diverse collection of books, ranging from classic literature and specialized publications to self-development guides and children's books. More than just a book-buying platform, we strive to be a bridge connecting you with timeless cultural and intellectual values. With an elegant, user-friendly interface and a smart search system, you can quickly find the books that best suit your interests. Additionally, our special promotions and home delivery services help you save time and fully enjoy the joy of reading. Join us on a journey of knowledge exploration, passion nurturing, and personal growth every day! ebookbell.com