SlideShare a Scribd company logo
Kotlin Cookbook A Problemfocused Approach 1st
Edition Ken Kousen download
https://ebookbell.com/product/kotlin-cookbook-a-problemfocused-
approach-1st-edition-ken-kousen-34710648
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.
Kotlin Cookbook Ken Kousen
https://ebookbell.com/product/kotlin-cookbook-ken-kousen-170706088
Kotlin Programming Cookbook Explore More Than 100 Recipes That Show
How To Build Robust Mobile And Web Applications With Kotlin Spring
Boot And Android Aanand Shekhar Roy
https://ebookbell.com/product/kotlin-programming-cookbook-explore-
more-than-100-recipes-that-show-how-to-build-robust-mobile-and-web-
applications-with-kotlin-spring-boot-and-android-aanand-shekhar-
roy-11063710
Kotlin Standard Library Cookbook Master The Powerful Kotlin Standard
Library Through Practical Code Examples Samuel Urbanowicz
https://ebookbell.com/product/kotlin-standard-library-cookbook-master-
the-powerful-kotlin-standard-library-through-practical-code-examples-
samuel-urbanowicz-11750696
Modern Android 13 Development Cookbook Over 70 Recipes To Solve
Android Development Issues And Create Better Apps With Kotlin And
Jetpack Compose Wambua
https://ebookbell.com/product/modern-android-13-development-cookbook-
over-70-recipes-to-solve-android-development-issues-and-create-better-
apps-with-kotlin-and-jetpack-compose-wambua-55529754
Kotlin The Ultimate Guide 1st Edition Sufyan Bin Uzayr
https://ebookbell.com/product/kotlin-the-ultimate-guide-1st-edition-
sufyan-bin-uzayr-46887672
Kotlin In Action Second Edition Meap V09 Chapters 1 To 10 Of 16
Svetlana Isakova
https://ebookbell.com/product/kotlin-in-action-second-edition-
meap-v09-chapters-1-to-10-of-16-svetlana-isakova-50703078
Kotlin Essentials Marcin Moskaa
https://ebookbell.com/product/kotlin-essentials-marcin-moskaa-50821696
Kotlin Multiplatform By Tutorials Second Edition 2nd Edition Carlos
Mota
https://ebookbell.com/product/kotlin-multiplatform-by-tutorials-
second-edition-2nd-edition-carlos-mota-54275474
Kotlin Programming Concise Expressive And Powerful Theophilus Edet
https://ebookbell.com/product/kotlin-programming-concise-expressive-
and-powerful-theophilus-edet-55274912
Kotlin Cookbook A Problemfocused Approach 1st Edition Ken Kousen
Ken Kousen
Kotlin
Cookbook
A Problem-Focused Approach
Kotlin Cookbook A Problemfocused Approach 1st Edition Ken Kousen
Ken Kousen
Kotlin Cookbook
A Problem-Focused Approach
978-1-492-04667-7
[LSI]
Kotlin Cookbook
by Ken Kousen
Copyright © 2020 Ken Kousen. 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). For more information, contact our corporate/institutional
sales department: 800-998-9938 or corporate@oreilly.com.
Acquisitions Editors: Zan McQuade and
Tyler Ortman
Development Editor: Corbin Collins
Production Editor: Christopher Faucher
Copyeditor: Sharon Wilkey
Proofreader: Charles Roumeliotis
Indexer: Ellen Troutman-Zaig
Interior Designer: David Futato
Cover Designer: Karen Montgomery
Illustrator: Rebecca Demarest
November 2019: First Edition
Revision History for the First Edition
2019-11-14: First Release
See http://oreilly.com/catalog/errata.csp?isbn=9781492046677 for release details.
The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Kotlin Cookbook, the cover image, and
related trade dress are trademarks of O’Reilly Media, Inc.
The views expressed in this work are those of the author, and do not represent the publisher’s views.
While the publisher and the author have used good faith efforts to ensure that the information and
instructions contained in this work are accurate, the publisher and the author disclaim all responsibility
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.
For Sandra, who got me through this.
Your kindness, unflagging support, and expert skills continue to change my life.
Kotlin Cookbook A Problemfocused Approach 1st Edition Ken Kousen
Table of Contents
Foreword. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
1. Installing and Running Kotlin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 Running Kotlin Without a Local Compiler 1
1.2 Installing Kotlin Locally 3
1.3 Compiling and Running Kotlin from the Command Line 5
1.4 Using the Kotlin REPL 7
1.5 Executing a Kotlin Script 8
1.6 Building a Standalone Application Using GraalVM 9
1.7 Adding the Kotlin Plug-in for Gradle (Groovy Syntax) 12
1.8 Adding the Kotlin Plug-in for Gradle (Kotlin Syntax) 15
1.9 Using Gradle to Build Kotlin Projects 16
1.10 Using Maven with Kotlin 19
2. Basic Kotlin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.1 Using Nullable Types in Kotlin 21
2.2 Adding Nullability Indicators to Java 24
2.3 Adding Overloaded Methods for Java 26
2.4 Converting Between Types Explicitly 31
2.5 Printing to Different Bases 33
2.6 Raising a Number to a Power 35
2.7 Using Bitwise Shift Operators 38
2.8 Using Bitwise Boolean Operators 40
2.9 Creating Pair Instances with to 43
v
3. Object-Oriented Programming in Kotlin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.1 Understanding the Difference Between const and val 47
3.2 Creating Custom Getters and Setters 49
3.3 Defining Data Classes 51
3.4 The Backing Property Technique 55
3.5 Overloading Operators 58
3.6 Using lateinit for Delayed Initialization 60
3.7 Using Safe Casting, Reference Equality, and Elvis to Override equals 63
3.8 Creating a Singleton 66
3.9 Much Ado About Nothing 69
4. Functional Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.1 Using fold in Algorithms 73
4.2 Using the reduce Function for Reductions 76
4.3 Applying Tail Recursion 79
5. Collections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
5.1 Working with Arrays 83
5.2 Creating Collections 86
5.3 Creating Read-Only Views from Existing Collections 89
5.4 Building a Map from a Collection 90
5.5 Returning a Default When a Collection Is Empty 91
5.6 Restricting a Value to a Given Range 93
5.7 Processing a Window on a Collection 94
5.8 Destructuring Lists 96
5.9 Sorting by Multiple Properties 98
5.10 Defining Your Own Iterator 100
5.11 Filtering a Collection by Type 102
5.12 Making a Range into a Progression 104
6. Sequences. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
6.1 Using Lazy Sequences 109
6.2 Generating Sequences 112
6.3 Managing Infinite Sequences 114
6.4 Yielding from a Sequence 116
7. Scope Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
7.1 Initializing Objects After Construction with apply 119
7.2 Using also for Side Effects 121
7.3 Using the let Function and Elvis 123
7.4 Using let with a Temporary Variable 124
vi | Table of Contents
8. Kotlin Delegates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
8.1 Implementing Composition by Delegation 127
8.2 Using the lazy Delegate 130
8.3 Ensuring That a Value Is Not Null 132
8.4 Using the observable and vetoable Delegates 134
8.5 Supplying Maps as Delegates 138
8.6 Creating Your Own Delegates 140
9. Testing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
9.1 Setting the Test Class Life Cycle 143
9.2 Using Data Classes for Tests 148
9.3 Using Helper Functions with Default Arguments 151
9.4 Repeating JUnit 5 Tests with Different Data 152
9.5 Using Data Classes for Parameterized Tests 156
10. Input/Output. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
10.1 Managing Resources with use 159
10.2 Writing to a File 163
11. Miscellaneous. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
11.1 Working with the Kotlin Version 165
11.2 Executing a Lambda Repeatedly 167
11.3 Forcing when to Be Exhaustive 168
11.4 Using the replace Function with Regular Expressions 170
11.5 Converting to Binary String and Back 172
11.6 Making a Class Executable 174
11.7 Measuring Elapsed Time 177
11.8 Starting Threads 179
11.9 Forcing Completion with TODO 182
11.10 Understanding the Random Behavior of Random 183
11.11 Using Special Characters in Function Names 186
11.12 Telling Java About Exceptions 187
12. The Spring Framework. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
12.1 Opening Spring-Managed Bean Classes for Extension 191
12.2 Persisting Kotlin Data Classes 194
12.3 Injecting Dependencies 197
13. Coroutines and Structured Concurrency. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
13.1 Choosing Coroutine Builders 201
13.2 Replacing async/await with withContext 207
13.3 Working with Dispatchers 209
Table of Contents | vii
13.4 Running Coroutines on a Java Thread Pool 211
13.5 Cancelling Coroutines 214
13.6 Debugging Coroutines 217
Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
viii | Table of Contents
Foreword
Every few years, there is a revolutionary new language that threatens to change the
way that people write software. The reality seldom lives up to the hype. Kotlin is dif‐
ferent. Since its creation back in 2011, it has slowly, almost imperceptibly, crept its
way into codebases across the world. Developers who have used Java for so long and
found it lacking have been able to sneak in a little Kotlin here and there. In so doing,
they have shrunk the size—and increased the power—of their code.
Having gained some fame as the preferred language for Android development, Kotlin
is now at a sufficiently mature stage that a book like this is desperately needed. With a
wealth of useful tips, Kotlin Cookbook begins at the beginning. Ken shows you how to
install Kotlin and configure it for your project. He shows how to run it in a Java envi‐
ronment, in a browser, or as a standalone application. But the book quickly moves on,
solving the kind of day-to-day programming problems faced by developers and archi‐
tects everywhere.
Although there is a section set aside for Kotlin testing, you will find that the book is
itself test-driven. It uses tests as practical examples of how to use the language. The
tests will allow you to adapt the recipes to fit your needs more precisely.
This book brings you the kind of straightforward, practical help that will guide your
progress on your Kotlin journey. It’s the essential how-to Kotlin guide, and every
developer should keep it on their desktop (real or virtual) to support their daily work.
Dawn and David Griffiths
Authors, Head First Kotlin
October 6, 2019
ix
Kotlin Cookbook A Problemfocused Approach 1st Edition Ken Kousen
Preface
Welcome to Kotlin Cookbook! The overall focus of the book is not only to teach Kotlin
syntax and semantics, but also to show you when and why a particular feature should
be used. The goal isn’t necessarily to cover every detail of Kotlin’s syntax and libraries.
In the end, however, many recipes on basic principles were added to make the book
understandable even to readers with only a beginning level of Kotlin knowledge.
There is a strong movement by JetBrains to encourage the Kotlin community to
embrace multiplatform, native, and JavaScript development. In the end, the decision
was made not to include recipes involving them, since all are either in beta form or
have very low adoption rates. As a result, the book concentrates exclusively on Kotlin
for the JVM.
The GitHub repository for all the code can be found at https://github.com/kousen/
kotlin-cookbook. It includes a Gradle wrapper (with the build file written in the Kotlin
DSL, of course) and all the tests pass.
All of the code examples in the book have been compiled and tested with both avail‐
able Long Term Support versions of Java, namely Java 8 and Java 11. Even though
Java 8 is technically past its end-of-life deadline, it is still pervasive enough in the
industry to ensure the code examples work with it. At the time of this writing, the
current version of Kotlin is 1.3.50, with 1.3.60 on the way. All the code works with
both versions, and the GitHub repository will frequently be updated to use the latest
version of Kotlin.
Who Should Read This Book
This book is written for developers who already know the basics of object-oriented
programming, especially in Java or another JVM-based language. While Java knowl‐
edge would be helpful, it isn’t required.
A recipe book like this one is more focused on using the techniques and idioms of
Kotlin than on being an exhaustive resource on the language. That has the advantage
xi
of using the full power of the language in any given recipe, but the disadvantage of
spending only a limited time on the basics of those features. Each chapter includes a
summary of the basic techniques, so if you are only vaguely familiar with how to cre‐
ate collections, work with arrays, or design classes, you should still be fine. The online
reference manual provides a solid introduction to the language, and the book makes
frequent reference to examples and discussions found there.
In addition, the book frequently dives into the implementations of features from the
Kotlin libraries. That’s to show how the developers of the language work with it in
practice, as well as to discuss why things are done the way they are. No prior knowl‐
edge of the implementation is expected, however, and you are free to skip those
details if you are in a hurry.
How This Book Is Organized
This book is organized into recipes, and while each is self-contained, many reference
others in the book. The hope is that you can read them in any particular order. That
said, there is a loose ordering to the chapters, as follows:
• Chapter 1 covers the basic process of installing and running Kotlin, including
using the REPL, working with build tools like Maven and Gradle, and employing
the native image generator in Graal.
• Chapter 2 covers some fundamental features of Kotlin—such as nullable types,
overloading operators, and converting between types—before examining some
more esoteric issues including working with bitwise shift operators or the to
extension function on the Pair class.
• Chapter 3 focuses on object-oriented features of the language that developers
from other languages might find surprising or unusual. It includes how to use the
const keyword, how Kotlin handles backing properties, delayed initialization,
and the dreaded Nothing class, which is guaranteed to confuse existing Java
developers.
• Chapter 4 has only a few recipes, which involve functional features that need
their own explanations. Functional programming concepts are covered through‐
out the book, especially when talking about collections, sequences, and corou‐
tines, but there are a handful of techniques included in this chapter that you may
find unusual or particularly interesting.
• Chapter 5 covers arrays and collections, dealing mostly with nonobvious meth‐
ods like destructing collections, sorting by multiple properties, building a win‐
dow on a collection, and creating progressions.
xii | Preface
• Chapter 6 shows how Kotlin handles sequences of items lazily, similar to the way
Java uses streams. Recipes cover generating sequences, yielding from them, and
working with infinite sequences.
• Chapter 7 covers another topic unique to Kotlin: functions that execute a block
of code in the context of an object. Functions like let, apply, and also are quite
useful in Kotlin, and this chapter illustrates why and how to use them.
• Chapter 8 discusses a convenient feature of Kotlin: how it implements delegation.
Delegation lets you employ composition rather than inheritance, and Kotlin
includes several delegates in the standard library, like lazy, observable, and
vetoable.
• Chapter 9 covers the important topic of testing, with a particular focus on JUnit
5. In its current version, JUnit is designed to work well with Kotlin, and that
includes both its regular usage and employing it in Spring Framework applica‐
tions. This chapter discusses several approaches that make writing and executing
tests easier.
• Chapter 10 includes a couple of recipes specifically for managing resources. File
I/O is covered, as is the use function, which has broad applicability in several
contexts.
• Chapter 11 covers topics that do not fit easily in any other category. Topics such
as how to get the current Kotlin version, how to force the when statement to be
exhaustive even when it doesn’t return a value, and how to use the replace func‐
tion with regular expressions are covered. In addition, the TODO function and the
Random class are discussed, as well as how to integrate with Java exception
handling.
• Chapter 12 involves the Spring Framework along with Spring Boot, which is very
friendly to Kotlin. A few recipes are included to show how to use Kotlin classes as
managed beans, how to implement JPA persistence, and how to inject dependen‐
cies when needed.
• Chapter 13 covers the subject of coroutines, one of the most popular features of
Kotlin and the basis of concurrent and parallel programming in the language.
Recipes cover the basics, like builders and dispatchers, along with how to cancel
and debug coroutines, and how to run them on your own custom Java thread
pool.
The chapters, and indeed the recipes themselves, do not have to be read in any partic‐
ular order. They do complement each other, and each recipe ends with references to
others, but you can start reading anywhere. The chapter groupings are provided as a
way to put similar recipes together, but it is expected that you will jump from one to
another to solve whatever problem you may have at the moment.
Preface | xiii
Special note for Android developers: Kotlin is now the preferred language for Android
development, but it is a much broader, general-purpose programming language. You
can use it anywhere you would use Java, and more. This book does not have a dedica‐
ted section just for Android. Instead, Android uses of Kotlin are discussed through‐
out. A few specific Android-related recipes, like coroutine cancellation, take advan‐
tage of the fact that Android libraries make extensive use of Kotlin, but in general the
features of the language covered in this book can be used anywhere. It is hoped that
by covering the language in a more general way, Android developers will find techni‐
ques useful to them in any coding project.
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, databases, data types, environment
variables, 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 element signifies a tip or suggestion.
This element signifies a general note.
This element indicates a warning or caution.
xiv | Preface
Using Code Examples
Supplemental material (code examples, exercises, etc.) is available for download at
https://github.com/kousen/kotlin-cookbook.
This book is here to help you get your job done. In general, if example code is offered
with this book, you may use it in your programs and documentation. You do not
need to contact us for permission unless you’re 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 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 per‐
mission.
We appreciate, but do not generally require, attribution. An attribution usually
includes the title, author, publisher, and ISBN. For example: “Kotlin Cookbook by Ken
Kousen (O’Reilly). Copyright 2020 Ken Kousen, 978-1-492-04667-7.”
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.
O’Reilly Online Learning
For more than 40 years, O’Reilly Media has provided technol‐
ogy and business training, knowledge, and insight to help
companies succeed.
Our unique network of experts and innovators share their knowledge and expertise
through books, articles, conferences, and our online learning platform. O’Reilly’s
online learning platform gives you on-demand access to live training courses, in-
depth learning paths, interactive coding environments, and a vast collection of text
and video from O’Reilly and 200+ other publishers. For more information, please
visit http://oreilly.com.
Preface | xv
How to Contact Us
Please address comments and questions concerning this book to the publisher:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
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: https://oreil.ly/kotlin-cookbook.
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
At the Google I/O conference in 2017, the company announced that Kotlin would be
a supported language for Android development. Later that year, Gradle, Inc.—the
company behind the Gradle build tool—announced that it would support a Gradle
domain-specific language (DSL) for builds. Both of those developments convinced
me to dig into the language, and I’ve been happy to have done so.
Over the past few years, I’ve been giving regular presentations and workshops on
Kotlin. While the basics of the language are easy to learn and apply, I’ve been
impressed with its depth and how aware it is of the way modern development ideas
are implemented in other languages, like Groovy or Scala. Kotlin is a synthesis of
many of the best programming ideas throughout the industry, and I’ve learned a lot
by doing the deep dive necessary to write a book like this.
As part of my learning process, I’ve benefitted from working with many active Kotlin
developers, including Dawn and Dave Griffiths, whose books Head First Android
Development and Head First Kotlin are outstanding; they even agreed to write the
foreword for this book. Hadi Harriri, a developer advocate at JetBrains, gives presen‐
tations on Kotlin on a regular basis. Those talks always inspire me to spend time on
xvi | Preface
the language, and he was kind enough to be a technical reviewer for this book. I’m
very grateful to them.
Bill Fly also provided a technical review. I’ve interacted with him on the O’Reilly
Learning Platform more times than I can count, and he always provides interesting
insights (and hard questions). My good friend Jim Harmon helped me get up to speed
on Android many years ago, and has always been willing to answer my questions and
talk about how Kotlin is used in practice. Mark Maynard is an active developer in
industry who helped me understand how Kotlin worked with the Spring Framework,
and I’m grateful for that. Finally, the inimitable Venkat Subramaniam was kind
enough to take time from his busy schedule writing his own Kotlin book (entitled
Programming Kotlin: it’s as good as the rest of his books) to help me with mine. I’m
happy to know all my tech reviewers and am humbled by the amount of time and
effort they spent improving the book you see now.
I need to acknowledge many of my fellow speakers on the NFJS tour, including Nate
Schutta, Michael Carducci, Matt Stine, Brian Sletten, Mark Richards, Pratik Patel,
Neal Ford, Craig Walls, Raju Gandhi, Jonathan Johnson, and Dan “the Man” Hino‐
josa for their constant doses of perspective and encouragement. I’m sure I’ve left out
someone on the tour, and, if so, I assure you it was deliberate.
Okay, maybe not. Writing books and teaching training classes (my actual day job) are
solitary pursuits. It’s great having a community of friends and colleagues that I can
rely on for perspective, advice, and various forms of entertainment.
Many people at O’Reilly Media were involved in the creation of this book. Rather
than call them out individually, I specifically want to mention Zan McQuade, who
was frequently placed in awkward positions by my irregular schedule and my general
contrary nature. Thank you for your patience, understanding, and hard work to bring
the book to completion.
Finally, I need to express all my love to my wife, Ginger, and my son, Xander. Without
the support and kindness of my family, I would not be the person I am today, a fact
that grows more obvious to me with each passing year. I can never express what you
both mean to me.
Preface | xvii
CHAPTER 1
Installing and Running Kotlin
The recipes in this chapter help you get up and running with the Kotlin compiler,
both from the command line and using an integrated development environment
(IDE).
1.1 Running Kotlin Without a Local Compiler
Problem
You want to try out Kotlin without a local installation, or run it on a machine that
does not support it (for example, a Chromebook).
Solution
Use the Kotlin Playground, an online sandbox for exploring Kotlin.
Discussion
The Kotlin Playground provides an easy way to experiment with Kotlin, explore fea‐
tures you haven’t used, or simply run Kotlin on systems that don’t have an installed
compiler. It gives you access to the latest version of the compiler, along with a web-
based editor that allows you to add code without installing Kotlin locally.
1
Figure 1-1 is a snapshot of the browser page.
Figure 1-1. The Kotlin Playground home page
Just type in your own code and click the Play button to execute it. The Settings button
(the gear icon) allows you to change Kotlin versions, decide which platform to run on
(JVM, JS, Canvas, or JUnit), or add program arguments.
As of Kotlin 1.3, the Kotlin function main can be defined without
parameters.
The Examples section contains an extensive set of sample programs, organized by
topic, that can be executed using an embedded block in a browser. Figure 1-2 shows
the “Hello world” program page.
2 | Chapter 1: Installing and Running Kotlin
Figure 1-2. Examples in the Kotlin Playground
The playground also has a dedicated section for Kotlin Koans, which are a series of
exercises to help you become more familiar with the language. While these are useful
online, if you use IntelliJ IDEA or Android Studio, the Koans can be added using the
EduTools plug-in.
1.2 Installing Kotlin Locally
Problem
You want to execute Kotlin from a command prompt on your local machine.
Solution
Perform a manual install from GitHub or use one of the available package managers
for your operating system.
1.2 Installing Kotlin Locally | 3
Discussion
The page at http://kotlinlang.org/docs/tutorials/command-line.html discusses the
options for installing a command-line compiler. One option is to download a ZIP file
containing an installer for your operating system. This page contains a link to the
GitHub repository for Kotlin current releases. ZIP files are available for Linux,
macOS, Windows, and the source distribution. Simply unzip the distribution and add
its bin subdirectory to your path.
A manual install certainly works, but some developers prefer to use package manag‐
ers. A package manager automates the installation process, and some of them allow
you to maintain multiple versions of a particular compiler.
SDKMAN!, Scoop, and other package managers
One of the most popular installation programs is SDKMAN!. Originally designed for
Unix-based shells, there are plans to make it available for other platforms as well.
Installing Kotlin with SDKMAN! begins with a curl install:
> curl -s https://get.sdkman.io | bash
Then, once it’s installed, you can use the sdk command to install any one of a variety
of products, including Kotlin:
> sdk install kotlin
By default, the latest version will be installed in the ~/.sdkman/candidates/kotlin direc‐
tory, along with a link called current that points to the selected version.
You can find out what versions are available by using the list command:
> sdk list kotlin
The install command by default selects the latest version, but the use command
will let you select any version, offering to install it if necessary:
> sdk use kotlin 1.3.50
That will install version 1.3.50 of Kotlin, if necessary, and use it in the current shell.
IntelliJ IDEA or Android Studio can use the downloaded versions,
or they can maintain their own versions separately.
Other package managers that support Kotlin include Homebrew, MacPorts, and
Snapcraft.
4 | Chapter 1: Installing and Running Kotlin
On Windows, you can use Scoop. Scoop does for Windows what the other package
managers do for non-Windows systems. Scoop requires PowerShell 5 or later
and .NET Framework 4.5 or later. Simple installation instructions are found on the
Scoop website.
Once Scoop is installed, the main bucket allows you to install the current version of
Kotlin:
> scoop install kotlin
This will install the scripts kotlin.bat, kotlinc.bat, kotlin-js.bat, and kotlin-jvm.bat and
add them all to your path.
That is sufficient, but if you want to try it, there is an experimental installer called
kotlin-native, which installs a native Windows compiler as well. This installs an
LLVM backend for the Kotlin compiler, a runtime implementation, and a native code
generation facility by using the LLVM toolchain.
Regardless of how you install Kotlin, you can verify that it works and is in your path
by using the simple command kotlin -version. A typical response to that com‐
mand is shown here:
> kotlin -version
Kotlin version 1.3.50-release-112 (JRE 13+33)
See Also
Recipe 1.3 discusses how to use Kotlin from the command line after it is installed.
1.3 Compiling and Running Kotlin from the Command
Line
Problem
You want to compile and execute Kotlin from the command line.
Solution
Use the kotlinc-jvm and kotlin commands, similar to Java.
Discussion
The Kotlin SDK for the JVM includes the Kotlin compiler command, kotlinc-jvm,
and the Kotlin execution command, kotlin. They are used just like javac and java
for Java files.
1.3 Compiling and Running Kotlin from the Command Line | 5
The Kotlin installation includes a script called kotlinc-js for compil‐
ing to JavaScript. This book assumes you are planning to use the
JVM version. The basic script kotlinc is an alias for kotlinc-jvm.
For example, consider a trivial “Hello, Kotlin!” program, stored in a file called hello.kt,
with the code shown in Example 1-1.
Example 1-1. hello.kt
fun main() {
println("Hello, Kotlin!")
}
The command kotlinc compiles this file, and the command kotlin is used to exe‐
cute the resulting class file, as in Example 1-2.
Example 1-2. Compiling and executing a regular Kotlin file
> kotlinc-jvm hello.kt
> ls
hello.kt HelloKt.class
> kotlin HelloKt
Hello, Kotlin!
Compiles the source
Executes the resulting class file
The compiler produces the HelloKt.class file, which contains bytecodes that can be
executed on the Java Virtual Machine. Kotlin does not generate Java source code—it’s
not a transpiler. It generates bytecodes that can be interpreted by the JVM.
The compiled class takes the name of the file, capitalizes the first letter, and appends
Kt on the end. This can be controlled with annotations.
If you wish to produce a self-contained JAR file that can be executed by the Java com‐
mand, add the -include-runtime argument. That allows you to produce an exe‐
cutable JAR that can be run from the java command, as in Example 1-3.
Example 1-3. Including the Kotlin runtime
> kotlinc-jvm hello.kt -include-runtime -d hello.jar
6 | Chapter 1: Installing and Running Kotlin
The resulting output file is called hello.jar, which can be executed using the java
command:
> java -jar hello.jar
Hello, Kotlin!
Leaving out the -include-runtime flag would produce a JAR file that needs the Kot‐
lin runtime on the classpath in order to execute.
The kotlinc command without any arguments starts the interac‐
tive Kotlin REPL, which is discussed in Example 1-4.
See Also
Example 1-4 shows how to use the Kotlin read-eval-print loop (REPL) for interactive
coding. Recipe 1.5 discusses executing Kotlin scripts from the command line.
1.4 Using the Kotlin REPL
Problem
You want to run Kotlin in an interactive shell.
Solution
Use the Kotlin REPL by typing kotlinc by itself at the command line.
Discussion
Kotlin includes an interactive compiler session manager, known as a REPL (read-
eval-print loop) that is triggered by the kotlinc command with no arguments. Once
inside the REPL, you can evaluate arbitrary Kotlin commands and see the results
immediately.
The Kotlin REPL is also available inside Android Studio and Intel‐
liJ IDEA as the Kotlin REPL entry under the Tools → Kotlin menu.
After running the kotlinc command, you will receive an interactive prompt. An
example session is shown in Example 1-4.
1.4 Using the Kotlin REPL | 7
Example 1-4. Using the Kotlin REPL
▶ kotlinc
Welcome to Kotlin version 1.3.50 (JRE 11.0.4+11)
Type :help for help, :quit for quit
>>> println("Hello, World!")
Hello, World!
>>> var name = "Dolly"
>>> println("Hello, $name!")
Hello, Dolly!
>>> :help
Available commands:
:help show this help
:quit exit the interpreter
:dump bytecode dump classes to terminal
:load <file> load script from specified file
>>> :quit
The REPL is a quick and easy way to evaluate Kotlin expressions without starting up
a full IDE. Use it if you don’t want to create an entire project or other IDE-based col‐
lection of files, or if you want to do a quick demo in order to help another developer,
or if you don’t have your preferred IDE available.
1.5 Executing a Kotlin Script
Problem
You want to write and execute a script written in Kotlin.
Solution
Enter your code in a file ending in .kts. Then use the kotlinc command with the
-script option to execute it.
Discussion
The kotlinc command supports several command-line options, one of which allows
Kotlin to be used as a scripting language. A script is defined as a Kotlin source file
with the file extension .kts that includes executable code.
As a simple example, the file southpole.kts in Example 1-5 shows the current time at
the South Pole and prints whether it is currently on daylight saving time. The script
uses the java.time package added to Java in version 8.
8 | Chapter 1: Installing and Running Kotlin
Example 1-5. southpole.kts
import java.time.*
val instant = Instant.now()
val southPole = instant.atZone(ZoneId.of("Antarctica/South_Pole"))
val dst = southPole.zone.rules.isDaylightSavings(instant)
println("It is ${southPole.toLocalTime()} (UTC${southPole.offset})
at the South Pole")
println("The South Pole ${if (dst) "is" else "is not"} on Daylight Savings Time")
Execute this file with the kotlinc command using the -script option:
> kotlinc -script southpole.kts
It is 10:42:56.056729 (UTC+13:00) at the South Pole
The South Pole is on Daylight Savings Time
Scripts contain the code that would normally appear inside the standard main method
in a class. Kotlin can be used as a scripting language on the JVM.
1.6 Building a Standalone Application Using GraalVM
Problem
You want to generate an application that can be run from the command line without
any additional dependencies.
Solution
Use the GraalVM compiler and native-image tool.
Discussion
GraalVM is a high-performance virtual machine that provides a cross-language run‐
time for running applications written in a variety of languages. You can write in a
JVM-based language like Java or Kotlin, and integrate with JavaScript, Ruby, Python,
R, and more.
One nice feature of GraalVM is that you can use it to create a native executable from
your code. This recipe shows a simple example of how to use GraalVM’s native-
image tool to create a native binary from Kotlin source code.
You can install GraalVM from the downloads page. For the current recipe, the free
Community Edition was installed using the SDKMAN! tool:
> sdk install java 19.2.0.1-grl
> java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-20190711112007.graal.jdk8u-src...
1.6 Building a Standalone Application Using GraalVM | 9
OpenJDK 64-Bit GraalVM CE 19.2.0.1 (build 25.222-b08-jvmci-19.2-b02, mixed mode)
> gu install native-image
// installs native image component
Consider the Kotlin version of “Hello, World!” from Figure 1-1, reproduced here:
fun main() {
println("Hello, World!")
}
As stated in Recipe 1.3, you can just compile this script by using kotlinc-jvm, which
generates HelloKt.class, and then run with kotlin:
> kotlinc-jvm hello.kt // generates HelloKt.class
> kotlin HelloKt
Hello, World!
To generate a native image instead, first compile the script with the -include-
runtime option. That generates a file called hello.jar:
> kotlinc-jvm hello.kt -include-runtime -d hello.jar
The GraalVM system includes the native-image tool, which you can use to generate
the native executable, as in Example 1-6.
Example 1-6. Building a native executable using GraalVM
> native-image -jar hello.jar
From the docs: “For compilation, native-image depends on the
local toolchain, so please make sure glibc-devel, zlib-devel (header
files for the C library and zlib) and gcc are available on your
system.”
The output will resemble the following:
> native-image -jar hello.jar
Build on Server(pid: 61247, port: 49590)*
[hello:61247] classlist: 1,497.63 ms
[hello:61247] (cap): 2,225.47 ms
[hello:61247] setup: 3,451.98 ms
[hello:61247] (typeflow): 2,163.16 ms
[hello:61247] (objects): 1,793.53 ms
[hello:61247] (features): 215.90 ms
[hello:61247] analysis: 4,247.68 ms
[hello:61247] (clinit): 107.96 ms
[hello:61247] universe: 399.58 ms
[hello:61247] (parse): 329.84 ms
[hello:61247] (inline): 753.12 ms
[hello:61247] (compile): 3,426.14 ms
10 | Chapter 1: Installing and Running Kotlin
[hello:61247] compile: 4,807.54 ms
[hello:61247] image: 306.96 ms
[hello:61247] write: 180.22 ms
[hello:61247] [total]: 15,246.88 ms
The result will be a file called hello that you can invoke at the command line. On a
Mac or other Unix-based system, you’ll see the following:
> ./hello
Hello, World!
There are now three ways to run the original script:
• Compile with kotlinc-jvm and then execute with kotlin.
• Compile including the runtime and then execute the resulting JAR with java.
• Compile with kotlinc, create a native image with GraalVM, and then execute
from the command line.
The sizes of the resulting files are quite different. The compiled bytecode file Hel‐
loKt.class is only about 700 bytes. The hello.jar file with its included runtime is about
1.2 MB. The native image is still larger, at about 2.1 MB. The speed differences are
dramatic however, even on a tiny script like this. Example 1-7 shows a simple
comparison.
Example 1-7. Timing the hello script
> time kotlin HelloKt
Hello, World!
kotlin HelloKt 0.13s user 0.05s system 112% cpu 0.157 total
~/Documents/kotlin
> time java -jar hello.jar
Hello, World!
java -jar hello.jar 0.08s user 0.02s system 99% cpu 0.106 total
~/Documents/kotlin
> time ./hello
Hello, World!
./hello 0.00s user 0.00s system 59% cpu 0.008 total
The relative values are telling. While the JAR file is somewhat quicker than running
kotlin directly, the native image is literally an order of magnitude faster. In this
example, it takes only about 8 milliseconds to run.
1.6 Building a Standalone Application Using GraalVM | 11
If you are a Gradle user, you can use a GraalVM plug-in called
gradle-graal. It adds a native-image task (among others) to your
build. See the home page for the plug-in for details.
1.7 Adding the Kotlin Plug-in for Gradle (Groovy Syntax)
Problem
You want to use add the Kotlin plug-in to a Gradle build by using the Groovy
domain-specific language (DSL) syntax.
Solution
Add the Kotlin dependency and plug-in by using the Groovy DSL tags in a build file.
Discussion
This recipe uses the Groovy DSL for Gradle. The next recipe shows
how to use the Kotlin DSL for Gradle instead.
The Gradle build tool supports compiling Kotlin on the JVM by using a plug-in sup‐
plied by JetBrains. The kotlin-gradle-plugin, adding to Gradle build script
has been registered at the Gradle plug-ins repository, and can be added to a Gradle
build script as in Example 1-8. The code shown is added to a file called build.gradle in
the project root.
Example 1-8. Adding the Kotlin plug-in by using the plugins block (Groovy DSL)
plugins {
id "org.jetbrains.kotlin.jvm" version "1.3.50"
}
The version value represents both the plug-in version and the Kotlin version. Gradle
still supports the older syntax for adding plug-ins, as shown in Example 1-9.
Example 1-9. Older syntax for the Kotlin plug-in (Groovy DSL)
buildscript {
repositories {
mavenCentral()
}
12 | Chapter 1: Installing and Running Kotlin
dependencies {
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50'
}
}
plugins {
id "org.jetbrains.kotlin.jvm" version "1.3.50"
}
Both of these snippets use the Groovy DSL syntax for Gradle build files, which sup‐
ports both single- and double-quoted strings. As with Kotlin, Groovy uses double-
quoted strings when doing interpolation, but since none is required here, single-
quoted strings also work.
The plugins block does not require you to state where the plug-in is found, as in the
repositories block in the latter example. This is true for any Gradle plug-in regis‐
tered at the Gradle plug-ins repository. Using the plugins block also automatically
“applies” the plug-in, so no apply statement is required either.
The settings.gradle file is recommended but not required. It is processed during the
initialization phase of Gradle processing, which occurs when Gradle determines
which project build files need to be analyzed. In a multiproject build, the settings file
shows which subdirectories of the root are themselves Gradle projects as well. Gradle
can share settings and dependencies among subprojects, can make one subproject
depend on another, or can even process subproject builds in parallel. For details, see
the multiproject build sections of the Gradle User Manual.
Kotlin sources can be mixed with Java sources in the same folder, or you can create
separate src/main/java and src/main/kotlin folders for them individually.
Android projects
The Kotlin plug-in for Android is handled slightly differently. Android projects are
multiproject builds in Gradle, meaning they normally have two build.gradle files: one
in the root directory, and one in a subdirectory called app by default. Example 1-10
shows a typical top-level build.gradle file containing only the Kotlin plug-in
information.
Example 1-10. Using Kotlin in Android projects (Groovy DSL)
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
}
dependencies {
1.7 Adding the Kotlin Plug-in for Gradle (Groovy Syntax) | 13
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
// ... more tasks, unrelated to the plug-in ...
In Gradle parlance, the plug-in is then applied, as in the typical app directory
build.gradle file shown in Example 1-11.
Example 1-11. Applying the Kotlin plug-in
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
// ... android information ...
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
// ... other unrelated dependencies ...
}
Applies the Kotlin plug-in for Android
Applies the Android Kotlin extensions
Standard library dependency, can use JDK 8 or JDK 7
The Kotlin plug-in for Android is declared in the buildscript section and then
applied in this file. The plug-in knows how to compile Kotlin code inside your
Android application. The downloaded plug-in also includes the Android extensions,
which makes it easy to access Android widgets by their ID values.
The Kotlin plug-in can generate bytecodes for either JDK 7 or JDK 8. Change the jdk
value in the listed dependency to select whichever you prefer.
At the time of this writing, there is no option to select the Kotlin
DSL when creating Android projects. You can create your own
build files that use the Kotlin DSL, but that is unusual. The Kotlin
DSL will be available in version 4.0 of Android Studio, which will
also include full support for KTS files and Kotlin live templates.
14 | Chapter 1: Installing and Running Kotlin
See Also
The same process using the Kotlin DSL is shown in Recipe 1.8, other than for the
Android section.
1.8 Adding the Kotlin Plug-in for Gradle (Kotlin Syntax)
Problem
You want to add the Kotlin plug-in to a Gradle build, using the Kotlin DSL.
Solution
Add the Kotlin dependency and plug-in, using the Kotlin DSL tags in a build file.
Discussion
This recipe uses the Kotlin DSL for Gradle. The previous recipe
shows how to use the Groovy DSL for Gradle instead.
Gradle (version 5.0 and above) includes the new Kotlin DSL for configuring the build
file. It also makes available kotlin-gradle-plugin, registered at the Gradle plug-in
repository, which can be added to a Gradle build script shown in Example 1-12.
Alternatively, you can use the older buildscript syntax in Example 1-13. The code
shown is added to a file called build.gradle.kts in the project root.
Example 1-12. Adding the Kotlin plug-in by using the plugins block (Kotlin DSL)
plugins {
kotlin("jvm") version "1.3.50"
}
Example 1-13. Older syntax for the Kotlin plug-in (Kotlin DSL)
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath(kotlin("gradle-plugin", version = "1.3.50"))
}
}
1.8 Adding the Kotlin Plug-in for Gradle (Kotlin Syntax) | 15
plugins {
kotlin("jvm")
}
The plugins block does not require you to state where the plug-in is found, as in the
repositories block in the latter example. This is true for any Gradle plug-in regis‐
tered at the Gradle plug-ins tepository. Using the plugins block also automatically
“applies” the plug-in, so no apply statement is required either.
The default build filenames for the Kotlin DSL in Gradle are set‐
tings.gradle.kts and build.gradle.kts.
As you can see, the biggest differences from the Groovy DSL syntax are as follows:
• Double quotes are required on any strings.
• The parentheses are required in the Kotlin DSL.
• Kotlin uses an equals sign (=) to assign values, rather than a colon (:).
The settings.gradle.kts file is recommended but not required. It is processed during
the initialization phase of Gradle processing, which occurs when Gradle determines
which project build files need to be analyzed. In a multiproject build, the settings file
shows which subdirectories of the root are themselves Gradle projects as well. Gradle
can share settings and dependencies among subprojects, can make one subproject
depend on another, or can even process subproject builds in parallel. For details, see
the multiproject build sections of the Gradle User Manual.
Kotlin and Java source code can be mixed together in src/main/java or src/main/
kotlin, or you can add your own source files by using the sourceSets property of
Gradle. See the Gradle documentation for details.
See Also
The same process using the Groovy DSL in Gradle is shown in Recipe 1.7. Additional
details for Android projects can be found in that recipe as well, as the Kotlin DSL is
not currently an option when generating Android projects.
1.9 Using Gradle to Build Kotlin Projects
Problem
You want to build a project that contains Kotlin by using Gradle.
16 | Chapter 1: Installing and Running Kotlin
Solution
In addition to the Kotlin plug-in for Gradle, add the Kotlin JDK dependency at com‐
pile time.
Discussion
The examples in Recipes 1.7 and 1.8 showed how to add the Kotlin plug-in for Gra‐
dle. This recipe adds features to the build file to process any Kotlin code in your
project.
To compile the Kotlin code in Gradle, you need to add an entry to the dependencies
block in your Gradle build file, as shown in Example 1-14.
Example 1-14. Kotlin DSL for simple Kotlin project (build.gradle.kts)
plugins {
`java-library`
kotlin("jvm") version "1.3.50"
}
repositories {
jcenter()
}
dependencies {
implementation(kotlin("stdlib"))
}
Adds tasks from the Java Library plug-in
Adds the Kotlin plug-in to Gradle
Adds the Kotlin standard library to the project at compile time
The java-library plug-in defines tasks for a basic JVM-based project, like build,
compileJava, compileTestJava, javadoc, jar, and more.
The plugins section must come first, but the other top-level blocks
(repositories, dependencies, etc.) can be in any order.
The dependencies block indicates that the Kotlin standard library is added at com‐
pile time (older versions of Gradle still use the compile configuration instead of
implementation, but the effect is the same). The repositories block indicates that
1.9 Using Gradle to Build Kotlin Projects | 17
the Kotlin dependency will be downloaded from jcenter, which is the public Artifac‐
tory Bintray repository.
If you run the gradle build --dry-run task at the command line, you can see the
tasks that would be executed by Gradle without actually running them. The result is
as follows:
> gradle build -m
:compileKotlin SKIPPED
:compileJava SKIPPED
:processResources SKIPPED
:classes SKIPPED
:inspectClassesForKotlinIC SKIPPED
:jar SKIPPED
:assemble SKIPPED
:compileTestKotlin SKIPPED
:compileTestJava SKIPPED
:processTestResources SKIPPED
:testClasses SKIPPED
:test SKIPPED
:check SKIPPED
:build SKIPPED
BUILD SUCCESSFUL in 0s
The Kotlin plug-in adds the compileKotlin, inspectClassesForKotlinIC, and
compileTestKotlin tasks.
The project can be built by using the same command without the -m flag, which is the
abbreviation for --dry-run.
18 | Chapter 1: Installing and Running Kotlin
1.10 Using Maven with Kotlin
Problem
You want to compile Kotlin by using the Maven build tool.
Solution
Use the Kotlin Maven plug-in and standard library dependencies.
Discussion
The basic details for using Maven can be found on the documentation web page.
This documentation recommends that first you specify the Kotlin version you want
to use as a property in a Maven pom.xml file that looks like this:
<properties>
<kotlin.version>1.3.50</kotlin.version>
</properties>
Then, add the Kotlin standard library as a dependency, as in Example 1-15.
Example 1-15. Adding the Kotlin standard library dependency
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
As with Gradle, you can specify kotlin-stdlib-jdk7 or kotlin-
stdlib-jdk8 to use extension functions for Java 1.7 or 1.8.
Additional available artifact IDs include kotlin-reflect for reflection, and kotlin-
test and kotlin-test-junit for testing.
To compile Kotlin source code, tell Maven in which directories it is located, as in
Example 1-16.
1.10 Using Maven with Kotlin | 19
Example 1-16. Specifying Kotlin source directories
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
</build>
Then tell the Kotlin plug-in to compile the sources and tests (Example 1-17).
Example 1-17. Referencing the Kotlin plug-in
<build>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<goals><goal>compile</goal></goals>
</execution>
<execution>
<id>test-compile</id>
<goals><goal>test-compile</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
When your project contains both Kotlin code and Java code, the Kotlin compiler
should be invoked first. That means kotlin-maven-plugin should be run before
maven-compiler-plugin. The documentation page provided previously shows how
to ensure that via configuration options in your pom.xml file.
20 | Chapter 1: Installing and Running Kotlin
CHAPTER 2
Basic Kotlin
This chapter contains recipes that work with the fundamentals of Kotlin. They show
you how to use the language without relying on specific libraries.
2.1 Using Nullable Types in Kotlin
Problem
You want to ensure that a variable is never null.
Solution
Define the type of a variable without a question mark. Nullable types also combine
with the safe call operator (?.) and the Elvis operator (?:)
Discussion
The most attractive feature of Kotlin may be that it eliminates almost all possible
nulls. In Kotlin, if you define a variable without including a trailing question mark,
the compiler will require that value to be non-null, as in Example 2-1.
Example 2-1. Declaring a non-nullable variable
var name: String
// ... later ...
name = "Dolly"
// name = null
Assignment to a non-null string
21
Assignment to null does not compile
Declaring the name variable to be of type String means that it cannot be assigned the
value null or the code won’t compile.
If you do want a variable to allow null, add a question mark to the type declaration,
as in Example 2-2.
Example 2-2. Declaring a nullable variable
class Person(val first: String,
val middle: String?,
val last: String)
val jkRowling = Person("Joanne", null, "Rowling")
val northWest = Person("North", null, "West")
JK Rowling has no given middle name; she selected K for her initial to honor her
grandmother Katherine
Neither does Kim and Kanye’s baby, who will no doubt have bigger issues than
this
In the Person class shown, you still have to supply a value for the middle parameter,
even if it’s null.
Life gets interesting when you try to use a nullable variable in an expression. Kotlin
requires you to check that the value is not null, but it’s not quite as easy as that
sounds. For example, consider the null check in Example 2-3.
Example 2-3. Checking nullability of a val variable
val p = Person(first = "North", middle = null, last = "West")
if (p.middle != null) {
val middleNameLength = p.middle.length
}
Smart cast to non-null String
The if test checks whether the middle property is non-null, and if so, Kotlin per‐
forms a smart cast: it treats p.middle as though it was of type String rather than
String?. This works, but only because the variable p was declared with the val key‐
word, so it cannot change once it is set. If, on the other hand, the variable was
declared with var instead of val, the code is as shown in Example 2-4.
22 | Chapter 2: Basic Kotlin
Example 2-4. Asserting that a var variable is not null
var p = Person(first = "North", middle = null, last = "West")
if (p.middle != null) {
// val middleNameLength = p.middle.length
val middleNameLength = p.middle!!.length
}
Smart cast to String impossible, because p.middle is a complex expression
Null-asserted (please don’t do this unless absolutely necessary)
Because p uses var instead of val, Kotlin assumes that it could change between the
time it is defined and the time the middle property is accessed, and refuses to do the
smart cast. One way around this is to use the bang-bang, or not-null, assertion opera‐
tor (!!) which is a code smell if ever there was one. The !! operator forces the vari‐
able to be treated as non-null and throws an exception if that is not correct. That’s
one of the few ways it is still possible to get a NullPointerException even in Kotlin
code, so try to avoid it if possible.
A better way to handle this situation is to use the safe call operator (?.). Safe call
short-circuits and returns a null if the value is null, as in Example 2-5.
Example 2-5. Using the safe call operator
var p = Person(first = "North", middle = null, last = "West")
val middleNameLength = p.middle?.length
Safe call; the resulting type is Int?
The problem is that the resulting inferred type is also nullable, so middleNameLength
is of type Int?, which is probably not what you want. Therefore, it is helpful to com‐
bine the safe call operator with the Elvis operator (?:), as in Example 2-6.
Example 2-6. Safe call with Elvis
var p = Person(first = "North", middle = null, last = "West")
val middleNameLength = p.middle?.length ?: 0
Elvis operator, returns 0 if middle is null
The Elvis operator checks the value of the expression to the left, and if it is not null,
returns it. Otherwise, the operator returns the value of the expression on the right. In
this case, it checks the value of p.middle?.length, which is either an integer or null.
If it is an integer, the value is returned. Otherwise, the expression returns 0.
2.1 Using Nullable Types in Kotlin | 23
1 Or, rather, Groovy was designed that way. The Elvis operator is borrowed from Groovy.
The righthand side of an Elvis operator can be an expression, so
you can use return or throw when checking function arguments.
The real challenge, perhaps, is looking at ?:, turning your head to the side, and some‐
how managing to see Elvis Presley. Clearly, Kotlin was designed for developers with
an active imagination.1
Finally, Kotlin provides a safe cast operator, as?. The idea is to avoid throwing a
ClassCastException if the cast isn’t going to work. For example, if you try to cast an
instance of Person to that type, but the value may be null, you can write the code
shown in Example 2-7.
Example 2-7. The safe cast operator
val p1 = p as? Person
Variable p1 is of type Person?
The cast will either succeed, resulting in a Person, or will fail, and p1 will receive null
as a result.
2.2 Adding Nullability Indicators to Java
Problem
Your Kotlin code needs to interact with Java code, and you want it to enforce nullabil‐
ity annotations.
Solution
Enforce JSR-305 nullability annotations in your Kotlin code, using the compile-time
parameter -Xjsr305=strict.
Discussion
One of Kotlin’s primary features is that nullability is enforced in the type system at
compile time. If you declare a variable to be of type String, it can never be null,
whereas if it is declared to be of type String?, it can, as in Example 2-8.
24 | Chapter 2: Basic Kotlin
Example 2-8. Nullable versus non-nullable types
var s: String = "Hello, World!"
var t: String? = null
Cannot be null, or code won’t compile
Question mark on type indicates a nullable type
This is fine until you want to interact with Java code, which has no such mechanism
built into the language. Java does, however, have a @Nonnull annotation defined in
the javax.annotation package. While this specification is now considered dormant,
many libraries have what are referred to as JSR-305 compatible annotations, and Kot‐
lin supports them.
For example, when using the Spring Framework, you can enforce compatibility by
adding the code in Example 2-9 to your Gradle build file.
Example 2-9. Enforcing JSR-305 compatibility in Gradle (Groovy DSL)
sourceCompatibility = 1.8
compileKotlin {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs = ["-Xjsr305=strict"]
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs = ["-Xjsr305=strict"]
}
}
To do the same using Gradle’s Kotlin DSL, see Example 2-10.
Example 2-10. Enforcing JSR-305 compatibility in Gradle (Kotlin DSL)
tasks.withType<KotlinCompile> {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs = listOf("-Xjsr305=strict")
}
}
For Maven, add the snippet from Example 2-11 to the POM file, as described in the
Kotlin reference guide.
2.2 Adding Nullability Indicators to Java | 25
Example 2-11. Enforcing JSR-305 compatibility in Maven
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>...</executions>
<configuration>
<nowarn>true</nowarn> <!-- Disable warnings -->
<args>
<!-- Enable strict mode for JSR-305 annotations -->
<arg>-Xjsr305=strict</arg>
...
</args>
</configuration>
</plugin>
The @Nonnull annotation defined in JSR-305 takes a property called when. If the value
of when is When.ALWAYS, the annotated type is treated as non-null. If it is When.MAYBE
or When.NEVER, it is considered nullable. If it is When.UNKNOWN, the type is assumed to
be a platform type whose nullability is not known.
2.3 Adding Overloaded Methods for Java
Problem
You have a Kotlin function with default parameters, and you want to invoke it from
Java without having to specify explicit values for each parameter.
Solution
Add the @JvmOverloads annotation to the function.
Discussion
Say you have a Kotlin function that specifies one or more default arguments, as in
Example 2-12.
Example 2-12. A Kotlin function with default parameters
fun addProduct(name: String, price: Double = 0.0, desc: String? = null) =
"Adding product with $name, ${desc ?: "None" }, and " +
NumberFormat.getCurrencyInstance().format(price)
For the addProduct function, a String name is required, but the description and
price have default values. The description is nullable and defaults to null, while the
price defaults to 0.
26 | Chapter 2: Basic Kotlin
It is easy enough to call this function from Kotlin with one, two, or three arguments,
as the test in Example 2-13 shows.
Example 2-13. Calling the overloaded variations from Kotlin
@Test
fun `check all overloads`() {
assertAll("Overloads called from Kotlin",
{ println(addProduct("Name", 5.0, "Desc")) },
{ println(addProduct("Name", 5.0)) },
{ println(addProduct("Name")) }
)
}
Each call to addProduct uses one fewer argument than the previous one.
Optional or nullable properties should be placed at the end of a
function signature, so they can be left out when calling the function
with positional arguments.
All of the calls execute properly.
Java, however, does not support default arguments for methods, so when calling this
function from Java, you have to supply them all, as in Example 2-14.
Example 2-14. Calling the function from Java
@Test
void supplyAllArguments() {
System.out.println(OverloadsKt.addProduct("Name", 5.0, "Desc"));
}
If you add the annotation @JvmOverloads to the function, the generated class will
support all the function overloads, as in Example 2-15.
Example 2-15. Calling all the overloads from Java
@Test
void checkOverloads() {
assertAll("overloads called from Java",
() -> System.out.println(OverloadsKt.addProduct("Name", 5.0, "Desc")),
() -> System.out.println(OverloadsKt.addProduct("Name", 5.0)),
() -> System.out.println(OverloadsKt.addProduct("Name"))
);
}
2.3 Adding Overloaded Methods for Java | 27
To see why this works, you can decompile the generated bytecodes from Kotlin.
Without the @JvmOverloads annotation, the generated code resembles Example 2-16.
Example 2-16. Decompiled function from Kotlin bytecodes
@NotNull
public static final String addProduct(@NotNull String name,
double price, @Nullable String desc) {
Intrinsics.checkParameterIsNotNull(name, "name");
// ...
}
When you add the @JvmOverloads annotation, the result instead resembles
Example 2-17.
Example 2-17. Decompiled function with overloads
// public final class OverloadsKt {
@JvmOverloads
@NotNull
public static final String addProduct(@NotNull String name,
double price, @Nullable String desc) {
Intrinsics.checkParameterIsNotNull(name, "name");
// ...
}
@JvmOverloads
@NotNull
public static final String addProduct(
@NotNull String name, double price) {
return addProduct$default(name, price,
(String)null, 4, (Object)null);
}
@JvmOverloads
@NotNull
public static final String addProduct(@NotNull String name) {
return addProduct$default(name, 0.0D,
(String)null, 6, (Object)null);
}
The generated class includes additional methods that invoke the full method with
supplied, default arguments.
You can also do this with constructors. The Product class shown in Example 2-18
generates three constructors: one with all three arguments, one with only the name
and price, and one with only the name.
28 | Chapter 2: Basic Kotlin
Example 2-18. Kotlin class with overloaded constructors
data class Product @JvmOverloads constructor(
val name: String,
val price: Double = 0.0,
val desc: String? = null
)
The explicit constructor call is necessary so that you can add the @JvmOverloads
annotation to it. Now, instantiating the class can be done with multiple arguments in
Kotlin, as in Example 2-19.
Example 2-19. Instantiating the Product class from Kotlin
@Test
internal fun `check overloaded Product contructor`() {
assertAll("Overloads called from Kotlin",
{ println(Product("Name", 5.0, "Desc")) },
{ println(Product("Name", 5.0)) },
{ println(Product("Name")) }
)
}
Or you can call the constructors from Java, as in Example 2-20.
Example 2-20. Instantiating the Product class from Java
@Test
void checkOverloadedProductCtor() {
assertAll("overloads called from Java",
() -> System.out.println(new Product("Name", 5.0, "Desc")),
() -> System.out.println(new Product("Name", 5.0)),
() -> System.out.println(new Product("Name"))
);
}
This all works, but note that a subtle trap exists. If you look at the decompiled code
for the Product class, you’ll see all the necessary constructors, shown in
Example 2-21.
Example 2-21. Overloaded Product constructors in decompiled code
@JvmOverloads
public Product(@NotNull String name, double price,
@Nullable String desc) {
Intrinsics.checkParameterIsNotNull(name, "name");
super();
this.name = name;
this.price = price;
2.3 Adding Overloaded Methods for Java | 29
this.desc = desc;
}
@JvmOverloads
public Product(String var1, double var2, String var4,
int var5, DefaultConstructorMarker var6) {
// ...
this(var1, var2, var4);
}
@JvmOverloads
public Product(@NotNull String name, double price) {
this(name, price, (String)null, 4, (DefaultConstructorMarker)null);
}
@JvmOverloads
public Product(@NotNull String name) {
this(name, 0.0D, (String)null, 6, (DefaultConstructorMarker)null);
}
Calls three-argument constructor
Calls generated constructor, which then calls three-argument constructor
Each of the overloaded constructors ultimately calls the full, three-argument version
with various defaults supplied. This is probably fine, but keep in mind that when you
invoke a constructor with optional arguments, you’re not calling the analogous con‐
structor in the superclass; all calls are going through a single constructor with the
most arguments.
Calls to constructors marked @JvmOverloads do not call super
with the same number of arguments. Instead, they call the full con‐
structor with supplied defaults.
In Java, each constructor calls its parent by using super, and when you overload con‐
structors, you often invoke super with the same number of arguments. That’s not
happening in this case. The superclass constructor that gets invoked is the one with
all the parameters, with supplied defaults.
30 | Chapter 2: Basic Kotlin
2.4 Converting Between Types Explicitly
Problem
Kotlin does not automatically promote primitive types to wider variables, such as an
Int to a Long.
Solution
Use the explicit conversion functions toInt, toLong, and so on to convert the smaller
type explicitly.
Discussion
One of the surprises Kotlin brings to Java developers is that shorter types are not
automatically promoted to longer types. For example, in Java it is perfectly normal to
write the code in Example 2-22.
Example 2-22. Promoting shorter primitive types to longer ones in Java
int myInt = 3;
long myLong = myInt;
Automatic promotion of int to long
When autoboxing was introduced in Java 1.5, it became easy to convert from a primi‐
tive to a wrapper type, but converting from one wrapper type to another still requires
extra code, as in Example 2-23.
Example 2-23. Converting from an Integer to a Long
Integer myInteger = 3;
// Long myWrappedLong = myInteger;
Long myWrappedLong = myInteger.longValue();
myWrappedLong = Long.valueOf(myInteger);
Does not compile
Extracts a long, then wraps it
Unwraps int, promotes to long, then wraps it
In other words, dealing with the wrapped types directly requires you to do the unbox‐
ing yourself. You can’t simply assign an Integer instance to a Long without extracting
the wrapped value first.
2.4 Converting Between Types Explicitly | 31
Discovering Diverse Content Through
Random Scribd Documents
Vestal Virgin), and "Fernando Cortez," were brought out in Paris and
later in Berlin, where he was general music director, 1820-1841. His
operas were heavily scored, especially for brass. Much that is noisy
in "Rienzi" may be traced to Spontini, but later Wagner understood
how to utilize the brass in the most eloquent manner; for, like
Shakespeare, Wagner possessed the genius that converts the dross
of others into refined gold.
Mention may be here made of three composers of light opera, who
succeeded in evolving a refined and charming type of the art. We at
least know the delightful overture to "The Merry Wives of Windsor,"
by Otto Nicolai (1810-1849); and the whole opera, produced in
Berlin a few months before Nicolai died, is equally frolicksome and
graceful. Conradin Kreutzer (1780-1849) brought out, in 1836, "Das
Nachtlager in Granada" (A Night's Camp in Granada), a melodious
and sparkling score.
But the German light opera composer par excellence is Albert
Lortzing (1803-1851). His chief works are, "Czar und Zimmermann"
(Czar and Carpenter), 1834, with its beautiful baritone solo, "In
childhood I played with a sceptre and crown"; "Der Wildschütz" (The
Poacher); "Undine"; and "Der Waffenschmied" (The Armourer) which
last also has a deeply expressive solo for baritone, "Ich auch war
einst Jüngling mit lockigem Haar" (I too was a youth once with fair,
curly hair).
R
Richard Wagner
(1813-1883)
ICHARD WAGNER was born at Leipsic, May 22, 1813. His father
was clerk to the city police court and a man of good education.
During the French occupation of Leipsic he was, owing to his
knowledge of French, made chief of police. He was fond of poetry
and had a special love for the drama, often taking part in amateur
theatricals.
Five months after Richard's birth his father died of an epidemic fever
brought on by the carnage during the battle of Leipsic, October 16,
18, and 19, 1813. In 1815 his widow, whom he had left in most
straitened circumstances, married Ludwig Geyer, an actor, a
playwright, and a portrait painter. By inheritance from his father, by
association with his stepfather, who was very fond of him, Wagner
readily acquired the dramatic faculty so pronounced in his operas
and music-dramas of which he is both author and composer.
At the time Wagner's mother married Geyer, he was a member of
the Court Theatre at Dresden. Thither the family removed. When the
boy was eight years old, he had learned to play on the pianoforte
the chorus of bridesmaids from "Der Freischütz," then quite new.
The day before Geyer's death, September 30, 1821, Richard was
playing this piece in an adjoining room and heard Geyer say to his
mother: "Do you think he might have a gift for music?" Coming out
of the death room Wagner's mother said to him: "Of you he wanted
to make something." "From this time on," writes Wagner in his early
autobiographical sketch, "I always had an idea that I was destined to
amount to something in this world."
At school Wagner made quite a little reputation as a writer of verses.
He was such an enthusiastic admirer of Shakespeare that at the age
of fourteen he began a grand tragedy, of which he himself says that
it was a jumble of Hamlet and Lear. So many people died in the
course of it that their ghosts had to return in order to keep the fifth
act going.
In 1833, at the age of twenty, Wagner began his career as a
professional musician. His elder brother Albert was engaged as
tenor, actor, and stage manager at the Würzburg theatre. A position
as chorus master being offered to Richard, he accepted it, although
his salary was a pittance of ten florins a month. However, the
experience was valuable. He was able to profit by many useful hints
from his brother, the Musikverein performed several of his
compositions, and his duties were not so arduous but that he found
time to write the words and music of an opera in three acts entitled
"The Fairies"—first performed in June, 1888, five years after his
death, at Munich. In the autumn of 1834 he was called to the
conductorship of the opera at Magdeburg. There he wrote and
produced an opera, "Das Liebesverbot" (Love Veto), based on
Shakespeare's Measure for Measure. The theatre at Magdeburg was,
however, on the ragged edge of bankruptcy, and during the spring of
1836 matters became so bad that it was evident the theatre must
soon close. Finally only twelve days were left for the rehearsing and
the performance of his opera. The result was that the production
went completely to pieces, singers forgetting their lines and music,
and a repetition which was announced could not come off because
of a free fight behind the scenes between two of the principal
singers. Wagner describes this in the following amusing passage in
his autobiographical sketch:
"All at once the husband of my prima donna (the impersonator of
Isabella) pounced upon the second tenor, a very young and
handsome fellow (the singer of my Claudio), against whom the
injured spouse had long cherished a secret jealousy. It seemed that
the prima donna's husband, who had from behind the curtains
inspected with me the composition of the audience, considered that
the time had now arrived when, without damage to the prospects of
the theatre, he could take his revenge on his wife's lover. Claudio
was so pounded and belaboured by him that the unhappy individual
was compelled to retire to the dressing-room with his face all
bleeding. Isabella was informed of this, and, rushing desperately
toward her furious lord, received from him such a series of violent
cuffs that she forthwith went into spasms. The confusion among my
personnel was now quite boundless: everybody took sides with one
party or the other, and everything seemed on the point of a general
fight. It seemed as if this unhappy evening appeared to all of them
precisely calculated for a final settling up of all sorts of fancied
insults. This much was evident, that the couple who had suffered
under the 'love veto' (Liebesverbot) of Isabella's husband, were
certainly unable to appear on this occasion."
Wagner was next engaged as orchestral conductor at Königsberg,
where he married the actress Wilhelmina, or Minna Planer. Later he
received notice of his appointment as conductor and of the
engagement of his wife and sister at the theatre at Riga, on the
Russian side of the Baltic.
In Riga he began the composition of his first great success, "Rienzi."
He completed the libretto during the summer of 1838, and began
the music in the autumn, and when his contract terminated in the
spring of 1839 the first two acts were finished. In July, accompanied
by his wife and a huge Newfoundland dog, he boarded a sailing
vessel for London, at the port of Pilau, his intention being to go from
London to Paris. "I shall never forget the voyage," he says. "It was
full of disaster. Three times we nearly suffered shipwreck, and once
were obliged to seek safety in a Norwegian harbour.... The legend of
the 'Flying Dutchman' was confirmed by the sailors, and the
circumstances gave it a distinct and characteristic colour in my
mind." No wonder the sea is depicted so graphically in his opera
"The Flying Dutchman."
He arrived in Paris in September, 1839, and remained until April 7,
1842, from his twenty-sixth to his twenty-ninth year. This Parisian
sojourn was one of the bitter experiences of his life. At times he
actually suffered from cold and hunger, and was obliged to do a vast
amount of most uncongenial kind of hack work.
November 19, 1840, he completed the score of "Rienzi," and in
December forwarded it to the director of the Royal Theatre at
Dresden. While awaiting a reply, he contributed to the newspapers
and did all kinds of musical drudgery for Schlesinger, the music
publisher, even making arrangements for the cornet à piston. Finally
word came from Dresden. "Rienzi" had aroused the enthusiasm of
the chorus master, Fischer, and of the tenor Tichatschek, who saw
that the title rôle was exactly suited to his robust, dramatic voice.
Then there was Mme. Schröder-Devrient for the part of Adriano. The
opera was produced October 20, 1842, the performance beginning
at six and ending just before midnight, to the enthusiastic plaudits of
an immense audience. So great was the excitement that in spite of
the late hour people remained awake to talk over the success. "We
all ought to have gone to bed," relates a witness, "but we did
nothing of the kind." Early the next morning Wagner appeared at the
theatre in order to make excisions from the score, which he thought
its great length necessitated. But when he returned in the afternoon
to see if they had been executed, the copyist excused himself by
saying the singers had protested against any cuts. Tichatschek said:
"I will have no cuts; it is too heavenly." After a while, owing to its
length, the opera was divided into two evenings.
The success of "Rienzi" led the Dresden management to put "The
Flying Dutchman" in rehearsal. It was brought out after somewhat
hasty preparations, January 2, 1843. The opera was so different
from "Rienzi," its sombre beauty contrasted so darkly with the
glaring, brilliant music and scenery of the latter, that the audience
failed to grasp it. In fact, after "Rienzi," it was a disappointment.
Before the end of January, 1843, not long after the success of
"Rienzi," Wagner was appointed one of the Royal conductors at
Dresden. He was installed February 2d. One of his first duties was to
assist Berlioz at the rehearsals of the latter's concerts. Wagner's
work in his new position was somewhat varied, consisting not only
of conducting operas, but also music between the acts at theatrical
performances and at church services. The principal operas which he
rehearsed and conducted were "Euryanthe," "Freischütz," "Don
Giovanni," "The Magic Flute," Gluck's "Armide," and "Iphigenia in
Aulis." The last-named was revised both as regards words and music
by him, and his changes are now generally accepted.
Meanwhile he worked arduously on "Tannhäuser," completing it April
13, 1844. It was produced at Dresden, October 19, 1845. At first the
work proved even a greater puzzle to the public than "The Flying
Dutchman" had, and evoked comments which nowadays, when the
opera has actually become a classic, seem ridiculous. Some people
even suggested that the plot of the opera should be changed so that
Tannhäuser should marry Elizabeth.
The management of the Dresden theatre, which had witnessed the
brilliant success of "Rienzi" and had seen "The Flying Dutchman" and
"Tannhäuser" at least hold their own in spite of the most virulent
opposition, looked upon his next work, "Lohengrin," as altogether
too risky and put off its production indefinitely.
Thinking that political changes might put an end to the routine
stagnation in musical matters, Wagner joined in the revolutionary
agitation of '48 and '49. In May, 1849, the disturbances at Dresden
reached such an alarming point that the Saxon Court fled. Prussian
troops were dispatched to quell the riot and Wagner thought it
advisable to flee. He went to Weimar, where Liszt was busy
rehearsing "Tannhäuser." While attending a rehearsal of this work,
May 19, news was received that orders had been issued for his
arrest as a politically dangerous individual. Liszt at once procured a
passport and Wagner started for Paris. In June he went to Zurich,
where he found Dresden friends and where his wife joined him,
being enabled to do so through the zeal of Liszt, who raised the
money to defray her journey from Dresden.
Liszt brought out "Lohengrin" at Weimar, August 28, 1850. The
reception of "Lohengrin" did not at first differ much from that
accorded to "Tannhäuser." Yet the performance made a deep
impression. The fact that the weight of Liszt's influence had been
cast in its favour gave vast importance to the event, and it may be
said that through this performance Wagner's cause received its first
great stimulus. The so-called Wagner movement may be said to
have dated from this production of "Lohengrin."
He finished the librettos of the "Nibelung" dramas in 1853. By May,
1854, the music of "Das Rheingold" was composed. The following
month he began "Die Walküre" and finished all but the
instrumentation during the following winter and the full score in
1856. Previous to this, in fact already in the autumn of 1854, he had
sketched some of the music of "Siegfried," and in the spring of 1857
the full score of the first act and of the greater part of the second
act was finished. Then, recognizing the difficulties which he would
encounter in securing a performance of the "Ring," and appalled by
the prospect of the battle he would be obliged to wage, he was so
disheartened that he abandoned the composition of "Siegfried" at
the Waldweben scene and turned to "Tristan." His idea at that time
was that "Tristan" would be short and comparatively easy to
perform. Genius that he was, he believed that because it was easy
for him to write great music it would be easy for others to interpret
it. A very curious, not to say laughable, incident occurred at this
time. An agent of the Emperor of Brazil called and asked if Wagner
would compose an opera for an Italian troupe at Rio de Janeiro, and
would he conduct the work himself, all upon his own terms. The
composition of "Tristan" actually was begun with a view of its being
performed by Italians in Brazil!
The poem of "Tristan" was finished early in 1857, and in the winter
of the same year the full score of the first act was ready to be
forwarded to the engraver. The second act is dated Venice, March 2,
1859. The third is dated Lyons, August, 1859.
It is interesting to note in connection with "Tristan" that, while
Wagner wrote it because he thought it would be easy to secure its
performance, he subsequently found more difficulty in getting it
produced than any other of his works. In September, 1859, he again
went to Paris with the somewhat curious hope that he could there
find opportunity to produce "Tristan" with German artists. Through
the intercession of the Princess Metternich, the Emperor ordered the
production of "Tannhäuser" at the Opéra. Beginning March 13, 1861,
three performances were given, of which it is difficult to say whether
the performance was on the stage or in the auditorium, for the
uproar in the house often drowned the sounds from the stage. The
members of the Jockey Club, who objected to the absence of a
ballet, armed themselves with shrill whistles, on which they began to
blow whenever there was the slightest hint of applause, and the
result was that between the efforts of the singers to make
themselves heard and of Wagner's friends to applaud, and the shrill
whistling from his enemies, there was confusion worse confounded.
But Wagner's friendship with Princess Metternich bore good fruit.
Through her mediation, it is supposed, he received permission to
return to all parts of Germany but Saxony. It was not until March,
1862, thirteen years after his banishment, that he was again allowed
to enter the kingdom of his birth and first success.
His first thought now was to secure the production of "Tristan," but
at Vienna, after fifty-seven rehearsals, it was put upon the shelf as
impossible.
In 1863, while working upon "Die Meistersinger," at Penzing, near
Vienna, he published his "Nibelung" dramas, expressing his hope
that through the bounty of one of the German rulers the completion
and performance of his "Ring of the Nibelung" would be made
possible. But in the spring of 1864, worn out by his struggle with
poverty and almost broken in spirit by his contest with public and
critics, he actually determined to give up his public career, and
eagerly grasped the opportunity to visit a private country seat in
Switzerland. Just at this very moment, when despair had settled
upon him, the long wished-for help came. King Ludwig II., of
Bavaria, bade him come to Munich, where he settled in 1864.
"Tristan" was produced there June 10, 1865. June 21, 1868, a model
performance of "Die Meistersinger," which he had finished in 1867,
was given at Munich under the direction of von Bülow, Richter acting
as chorus master and Wagner supervising all the details. Wagner
also worked steadily at the unfinished portion of the "Ring,"
completing the instrumentation of the third act of "Siegfried" in 1869
and the introduction and first act of "The Dusk of the Gods" in June,
1870.
August 25, 1870, his first wife having died January 25, 1866, after
five years' separation from him, he married the divorced wife of von
Bülow, Cosima Liszt. In 1869 and 1870, respectively "The Rhinegold"
and "The Valkyr" were performed at the Court Theatre in Munich.
Bayreuth having been determined upon as the place where a theatre
for the special production of his "Ring" should be built, Wagner
settled there in April, 1872. By November, 1874, "Dusk of the Gods"
received its finishing touches, and rehearsals had already been held
at Bayreuth. During the summer of 1875, under Wagner's
supervision, Hans Richter held full rehearsals there, and at last,
twenty-eight years after its first conception, on August 13th, 14th,
16th, and 17th, again from August 20 to 23, and from August 27 to
30, 1876, "The Ring of the Nibelung" was performed at Bayreuth
with the following cast: Wotan, Betz; Loge, Vogel; Alberich, Hill;
Mime, Schlosser; Fricka, Frau Grün; Donner and Gunther, Gura; Erda
and Waltraute, Frau Jaide; Siegmund, Niemann; Sieglinde, Frl.
Schefsky; Brünnhilde, Frau Materna; Siegfried, Unger; Hagen, Siehr;
Gutrune, Frl. Weckerin; Rhinedaughters, Lilli and Marie Lehmann,
and Frl. Lammert. First violin, Wilhelmj; conductor, Hans Richter. The
first Rhinedaughter was the same Lilli Lehmann who, in later years,
at the Metropolitan Opera House, New York, became one of the
greatest of prima donnas and, as regards the Wagnerian repertoire,
set a standard for all time. Materna appeared at that house in the
"Valkyr" production under Dr. Damrosch, in January, 1885, and
Niemann was heard there later.
To revert to Bayreuth, "Parsifal" was produced there in July, 1882. In
the autumn of that year, Wagner's health being in an unsatisfactory
state, though no alarming symptoms had shown themselves, he took
up his residence in Venice at the Palazzo Vendramini, on the Grand
Canal. He died February 13, 1883.
In manner incidental, that is, without attention formally being called
to the subject, Wagner's reform of the lyric stage is set forth in the
descriptive accounts of his music-dramas which follow, and in which
the leading motives are quoted in musical notation. But something
directly to the point must be said here.
Once again, like Gluck a century before, Wagner opposed the
assumption of superiority on the part of the interpreter—the singer—
over the composer. He opposed it in manner so thorough-going that
he changed the whole face of opera. A far greater tribute to
Wagner's genius than the lame attempts of some German
composers at imitating him, is the frank adoption of certain phases
of his method by modern French and Italian composers, beginning
with Verdi in "Aïda." While by no means a Wagnerian work, since it
contains not a trace of the theory of the leading motive, "Aïda,"
through the richness of its instrumentation, the significant
accompaniment of its recitative, the lack of mere bravura
embellishment in its vocal score, and its sober reaching out for true
dramatic effect in the treatment of the voices, substituting this for
ostentatious brilliancy and ear-tickling fluency, plainly shows the
influence of Wagner upon the greatest of Italian composers. And
what is true of "Aïda," is equally applicable to the whole school of
Italian verismo that came after Verdi—Mascagni, Leoncavallo,
Puccini.
Wagner's works are conceived and executed upon a gigantic scale.
They are Shakespearian in their dimensions and in their tragic
power; or, as in the "Meistersinger," in their comedy element. Each
of his works is highly individual. The "Ring" dramas and "Tristan" are
unmistakably Wagner. Yet how individually characteristic the music
of each! That of the "Ring" is of elemental power. The "Tristan"
music is molten passion. Equally characteristic and individual are his
other scores.
The theory evolved by Wagner was that the lyric stage should
present not a series of melodies for voice upon a mere framework of
plot and versified story, but a serious work of dramatic art, the music
to which should, both vocally and instrumentally, express the ever
varying development of the drama. With this end in view he
invented a melodious recitative which only at certain great crises in
the progress of the action—such as the love-climax, the gathering at
the Valkyr Rock, the "Farewell," and the "Magic Fire" scenes in "The
Valkyr"; the meeting of Siegfried and Brünnhilde in "Siegfried"; the
love duet and "Love-Death" in "Tristan"—swells into prolonged
melody. Note that I say prolonged melody. For besides these
prolonged melodies, there is almost constant melody, besides
marvellous orchestral colour, in the weft and woof of the recitative.
This is produced by the artistic use of leading motives, every leading
motive being a brief, but expressive, melody—so brief that, to one
coming to Wagner without previous study or experience, the
melodious quality of his recitative is not appreciated at first. After a
while, however, the hearer begins to recognize certain brief, but
melodious and musically eloquent phrases—leading motives—as
belonging to certain characters in the drama or to certain influences
potent in its development, such as hate, love, jealousy, the desire for
revenge, etc. Often to express a combination of circumstances,
influences, passions, or personal actions, these leading motives,
these brief melodious phrases, are combined with a skill that is
unprecedented; or the voice may express one, while the orchestra
combines with it in another.
To enable the orchestra to follow these constantly changing phases
in the evolution and development of the drama, and often to give
utterance to them separately, it was necessary for Wagner to have
most intimate knowledge of the individual tone quality and
characteristics of every instrument in the orchestra, and this mastery
of what I may call instrumental personality he possessed to a
hitherto undreamed-of degree. Nor has anyone since equalled him in
it. The result is a choice and variety of instrumentation which in itself
is almost an equivalent for dramatic action and enables the orchestra
to adapt itself with unerring accuracy to the varying phases of the
drama.
Consider that, when Wagner first projected his theory of the music-
drama, singers were accustomed in opera to step into the limelight
and, standing there, deliver themselves of set melodies,
acknowledge applause and give as many encores as were called for,
in fact were "it," while the real creative thing, the opera, was but
secondary, and it is easy to comprehend the opposition which his
works aroused among the personnel of the lyric stage; for music-
drama demands a singer's absorption not only in the music but also
in the action. A Wagner music-drama requires great singers, but the
singers no longer absorb everything. They are part—a most
important part, it is true—of a performance, in which the drama
itself, the orchestra, and the stage pictures are also of great
importance. A performance of a Wagner music-drama, to be
effective, must be a well-rounded, eloquent whole. The drama must
be well acted from a purely dramatic point of view. It must be well
sung from a purely vocal point of view. It must be well interpreted
from a purely orchestral point of view. It must be well produced
from a purely stage point of view. For all these elements go hand in
hand. It is, of course, well known that Wagner was the author of his
own librettos and showed himself a dramatist of the highest order
for the lyric stage.
While his music-dramas at first aroused great opposition among
operatic artists, growing familiarity with them caused these artists to
change their view. The interpretation of a Wagner character was
discovered to be a combined intellectual and emotional task which
slowly, but surely, appealed more and more to the great singers of
the lyric stage. They derived a new dignity and satisfaction from
their work, especially as audiences also began to realize that,
instead of mere entertainment, performances of Wagner music-
dramas were experiences that both stirred the emotions to their
depths and appealed to the intellect as well. To this day Lilli
Lehmann is regarded by all, who had the good fortune to hear her at
the Metropolitan Opera House, as the greatest prima donna and the
most dignified figure in the history of the lyric stage in this country;
for on the lyric stage the interpretation of the great characters in
Wagnerian music-drama already had come to be regarded as equal
to the interpretation of the great Shakespearian characters on the
dramatic.
Wagner's genius was so supreme that, although he has been dead
thirty-four years, he is still without a successor. Through the force of
his own genius he appears destined to remain the sole exponent of
the art form of which he was the creator. But his influence is still
potent. This we discover not only in the enrichment of the orchestral
accompaniment in opera, but in the banishment of senseless vocal
embellishment, in the search for true dramatic expression and, in
general, in the greater seriousness with which opera is taken as an
art. Even the minor point of lowering the lights in the auditorium
during a performance, so as to concentrate attention upon the
stage, is due to him; and even the older Italian operas are now
given with an attention to detail, scenic setting, and an endeavour to
bring out their dramatic effects, quite unheard of before his day. He
was, indeed, a reformer of the lyric stage whose influence long will
be potent "all along the line."
RIENZI, DER LETZTE DER TRIBUNEN
RIENZI, THE LAST OF THE TRIBUNES
Opera in five acts. Words and music by Wagner.
Produced, Dresden, October 20, 1842. London, Her
Majesty's Theatre, April 16, 1869. New York, Academy
of Music, 1878, with Charles R. Adams, as Rienzi,
Pappenheim as Adriano; Metropolitan Opera House,
February 5, 1886, with Sylva as Rienzi, Lehmann as
Irene, Brandt as Adriano, Fischer as Colonna.
Characters
Cola Rienzi, Roman Tribune and
Papal Notary
Tenor
Irene, his sister Soprano
Steffano Colonna Bass
Adriano, his son
Mezzo-
Soprano
Paolo Orsino Bass
Raimondo, Papal Legate Bass
Baroncello } Roman
citizens
{ Tenor
Cecco del Vecchio } { Bass
Messenger of Peace Soprano
Ambassadors, Nobles, Priests, Monks, Soldiers,
Messengers, and Populace in General.
Time—Middle of the Fourteenth Century.
Place—Rome.
Orsino, a Roman patrician, attempts to abduct Irene, the sister of
Rienzi, a papal notary, but is opposed at the critical moment by
Colonna, another patrician. A fight ensues between the two factions,
in the midst of which Adriano, the son of Colonna, who is in love
with Irene, appears to defend her. A crowd is attracted by the
tumult, and among others Rienzi comes upon the scene. Enraged at
the insult offered his sister, and stirred on by Cardinal Raimondo, he
urges the people to resist the outrages of the nobles. Adriano is
impelled by his love for Irene to cast his lot with her brother. The
nobles are overpowered, and appear at the capitol to swear
allegiance to Rienzi, but during the festal proceedings Adriano warns
him that the nobles have plotted to kill him. An attempt which
Orsino makes upon him with a dagger is frustrated by a steel
breastplate which Rienzi wears under his robe.
The nobles are seized and condemned to death, but on Adriano's
pleading they are spared. They, however, violate their oath of
submission, and the people again under Rienzi's leadership rise and
exterminate them, Adriano having pleaded in vain. In the end the
people prove fickle. The popular tide turns against Rienzi, especially
in consequence of the report that he is in league with the German
emperor, and intends to restore the Roman pontiff to power. As a
festive procession is escorting him to church, Adriano rushes upon
him with a drawn dagger, being infuriated at the slaughter of his
family, but the blow is averted. Instead of the "Te Deum," however,
with which Rienzi expected to be greeted on his entrance to the
church, he hears the malediction and sees the ecclesiastical
dignitaries placing the ban of excommunication against him upon the
doors. Adriano hurries to Irene to warn her of her brother's danger,
and urges her to seek safety with him in flight. She, however, repels
him, and seeks her brother, determined to die with him, if need be.
She finds him at prayer in the capitol, but rejects his counsel to save
herself with Adriano. Rienzi appeals to the infuriated populace which
has gathered around the capitol, but they do not heed him. They fire
the capitol with their torches, and hurl stones at Rienzi and Irene. As
Adriano sees his beloved one and her brother doomed to death in
the flames, he throws away his sword, rushes into the capitol, and
perishes with them.
The overture of "Rienzi" gives a vivid idea of the action of the opera.
Soon after the beginning there is heard the broad and stately
melody of Rienzi's prayer, and then the Rienzi Motive, a typical
phrase, which is used with great effect later in the opera. It is
followed in the overture by the lively melody heard in the concluding
portion of the finale of the second act. These are the three most
conspicuous portions of the overture, in which there are, however,
numerous tumultuous passages reflecting the dramatic excitement
which pervades many scenes.
The opening of the first act is full of animation, the orchestra
depicting the tumult which prevails during the struggle between the
nobles. Rienzi's brief recitative is a masterpiece of declamatory
music, and his call to arms is spirited. It is followed by a trio
between Irene, Rienzi, and Adriano, and this in turn by a duet for
the two last-named which is full of fire. The finale opens with a
double chorus for the populace and the monks in the Lateran,
accompanied by the organ. Then there is a broad and energetic
appeal to the people from Rienzi, and amid the shouts of the
populace and the ringing tones of the trumpets the act closes.
The insurrection of the people against the nobles is successful, and
Rienzi, in the second act, awaits at the capitol the patricians who are
to pledge him their submission. The act opens with a broad and
stately march, to which the messengers of peace enter. They sing a
graceful chorus. This is followed by a chorus for the senators, and
the nobles then tender their submission. There is a terzetto,
between Adriano, Colonna, and Orsino, in which the nobles express
their contempt for the young patrician. The finale which then begins
is highly spectacular. There is a march for the ambassadors, and a
grand ballet, historical in character, and supposed to be symbolical of
the triumphs of ancient Rome. In the midst of this occurs the assault
upon Rienzi. Rienzi's pardon of the nobles is conveyed in a broadly
beautiful melody, and this is succeeded by the animated passage
heard in the overture. With it are mingled the chants of the monks,
the shouts of the people who are opposed to the cardinal and
nobles, and the tolling of bells.
The third act opens tumultuously. The people have been aroused by
fresh outrages on the part of the nobles. Rienzi's emissaries
disperse, after a furious chorus, to rouse the populace to vengeance.
After they have left, Adriano has his great air, a number which can
never fail of effect when sung with all the expression of which it is
capable. The rest of the act is a grand accumulation of martial music
or noise, whichever one chooses to call it, and includes the
stupendous battle hymn, which is accompanied by the clashing of
sword and shields, the ringing of bells, and all the tumult incidental
to a riot. After Adriano has pleaded in vain with Rienzi for the
nobles, and the various bands of armed citizens have dispersed,
there is a duet between Adriano and Irene, in which Adriano takes
farewell of her. The victorious populace appears and the act closes
with their triumphant shouts. The fourth act is brief, and beyond the
description given in the synopsis of the plot, requires no further
comment.
The fifth act opens with the beautiful prayer of Rienzi, already
familiar from the overture. There is a tender duet between Rienzi
and Irene, an impassioned aria for Rienzi, a duet for Irene and
Adriano, and then the finale, which is chiefly choral.
DER FLIEGENDE HOLLÄNDER
THE FLYING DUTCHMAN
Opera in three acts, words and music by Richard
Wagner. Produced, Royal Opera, Dresden, January 2,
1843. London, July 23, 1870, as "L'Olandese Dannato";
October 3, 1876, by Carl Rosa, in English. New York,
Academy of Music, January 26, 1877, in English, with
Clara Louise Kellogg; March 12, 1877, in German; in
the spring of 1883, in Italian, with Albani, Galassi, and
Ravelli.
Characters
Daland, a Norwegian sea
captain
Bass
Senta, his daughter Soprano
Eric, a huntsman Tenor
Mary, Senta's nurse Contralto
Daland's Steersman Tenor
The Dutchman Baritone
Sailors, Maidens, Hunters, etc.
Time—Eighteenth Century.
Place—A Norwegian Fishing Village.
From "Rienzi" Wagner took a great stride to "The Flying Dutchman."
This is the first milestone on the road from opera to music-drama. Of
his "Rienzi" the composer was in after years ashamed, writing to
Liszt: "I, as an artist and man, have not the heart for the
reconstruction of that, to my taste, superannuated work, which in
consequence of its immoderate dimensions, I have had to remodel
more than once. I have no longer the heart for it, and desire from all
my soul to do something new instead." He spoke of it as a youthful
error, but in "The Flying Dutchman" there is little, if anything, which
could have troubled his artistic conscience.
One can hardly imagine the legend more effective dramatically and
musically than it is in Wagner's libretto and score. It is a work of wild
and sombre beauty, relieved only occasionally by touches of light
and grace, and has all the interest attaching to a work in which for
the first time a genius feels himself conscious of his greatness. If it is
not as impressive as "Tannhäuser" or "Lohengrin," nor as
stupendous as the music-dramas, that is because the subject of the
work is lighter. As his genius developed, his choice of subjects and
his treatment of them passed through as complete an evolution as
his musical theory, so that when he finally abandoned the operatic
form and adopted his system of leading motives, he conceived, for
the dramatic bases of his scores, dramas which it would be difficult
to fancy set to any other music than that which is so characteristic in
his music-dramas.
Wagner's present libretto is based upon the weirdly picturesque
legend of "The Flying Dutchman"—the Wandering Jew of the ocean.
A Dutch sea captain, who, we are told, tried to double the Cape of
Good Hope in the teeth of a furious gale, swore that he would
accomplish his purpose even if he kept on sailing forever. The devil,
hearing the oath, condemned the captain to sail the sea until
Judgment Day, without hope of release, unless he should find a
woman who would love him faithfully unto death. Once in every
seven years he is allowed to go ashore in search of a woman who
will redeem him through her faithful love.
The opera opens just as a term of seven years has elapsed. The
Dutchman's ship comes to anchor in a bay of the coast of Norway, in
which the ship of Daland, a Norwegian sea captain, has sought
shelter from the storm. Daland's home is not far from the bay, and
the Dutchman, learning he has a daughter, asks permission to woo
her, offering him in return all his treasures. Daland readily consents.
His daughter, Senta, is a romantic maiden upon whom the legend of
"The Flying Dutchman" has made a deep impression. As Daland
ushers the Dutchman into his home Senta is gazing dreamily upon a
picture representing the unhappy hero of the legend. The
resemblance of the stranger to the face in this picture is so striking
that the emotional girl is at once attracted to him, and pledges him
her faith, deeming it her mission to save him. Later on, Eric, a young
huntsman, who is in love with her, pleads his cause with her, and the
Dutchman, overhearing them, and thinking himself again forsaken,
rushes off to his vessel. Senta cries out that she is faithful to him,
but is held back by Eric, Daland, and her friends. The Dutchman,
who really loves Senta, then proclaims who he is, thinking to terrify
her, and at once puts to sea. But she, undismayed by his words, and
truly faithful unto death, breaks away from those who are holding
her, and rushing to the edge of a cliff casts herself into the ocean,
with her arms outstretched toward him. The phantom ship sinks, the
sea rises high and falls back into a seething whirlpool. In the sunset
glow the forms of Senta and the Dutchman are seen rising in each
other's embrace from the sea and floating upward.
In "The Flying Dutchman" Wagner employs several leading motives,
not, indeed, with the skill which he displays in his music-dramas, but
with considerably greater freedom of treatment than in "Rienzi."
There we had but one leading motive, which never varied in form.
The overture, which may be said to be an eloquent and beautiful
musical narrative of the whole opera, contains all these leading
motives. It opens with a stormy passage, out of which there bursts
the strong but sombre Motive of the Flying Dutchman himself, the
dark hero of the legend. The orchestra fairly seethes and rages like
the sea roaring under the lash of a terrific storm. And through all
this furious orchestration there is heard again and again the motive
of the Dutchman, as if his figure could be seen amid all the gloom
and fury of the elements. There he stands, hoping for death, yet
indestructible. As the excited music gradually dies away, there is
heard a calm, somewhat undulating phrase which occurs in the
opera when the Dutchman's vessel puts into the quiet Norwegian
harbour. Then, also, there occurs again the motive of the Dutchman,
but this time played softly, as if the storm-driven wretch had at last
found a moment's peace.
We at once recognize to whom it is due that he has found this
moment of repose, for we hear like prophetic measures the strains
of the beautiful ballad which is sung by Senta in the second act of
the opera, in which she relates the legend of "The Flying Dutchman"
and tells of his unhappy fate. She is the one whom he is to meet
when he goes ashore. The entire ballad is not heard at this point,
only the opening of the second part, which may be taken as
indicating in this overture the simplicity and beauty of Senta's
character. In fact, it would not be too much to call this opening
phrase the Senta Motive. It is followed by the phrase which indicates
the coming to anchor of the Dutchman's vessel; then we hear the
Motive of the Dutchman himself, dying away with the faintest
possible effect. With sudden energy the orchestra dashes into the
surging ocean music, introducing this time the wild, pathetic plaint
sung by the Dutchman in the first act of the opera. Again we hear
his motive, and again the music seems to represent the surging,
swirling ocean when aroused by a furious tempest. Even when we
hear the measures of the sailors' chorus the orchestra continues its
furious pace, making it appear as if the sailors were shouting above
the storm.
Characteristic in this overture, and also throughout the opera,
especially in Senta's ballad, is what may be called the Ocean Motive,
which most graphically depicts the wild and terrible aspect of the
ocean during a storm. It is varied from time to time, but never loses
its characteristic force and weirdness. The overture ends with an
impassioned burst of melody based upon a portion of the concluding
phrases of Senta's ballad; phrases which we hear once more at the
end of the opera when she sacrifices herself in order to save her
lover.
A wild and stormy scene is disclosed when the curtain rises upon the
first act. The sea occupies the greater part of the scene, and
stretches itself out far toward the horizon. A storm is raging.
Daland's ship has sought shelter in a little cove formed by the cliffs.
Sailors are employed in furling sails and coiling ropes. Daland is
standing on a rock, looking about him to discover in what place they
are. The orchestra, chiefly with the wild ocean music heard in the
overture, depicts the raging of the storm, and above it are heard the
shouts of the sailors at work: "Ho-jo-he! Hal-lo-jo!"
Daland discovers that they have missed their port by seven miles on
account of the storm, and deplores his bad luck that when so near
his home and his beloved child, he should have been driven out of
his course. As the storm seems to be abating the sailors descend
into the hold and Daland goes down into the cabin to rest, leaving
his steersman in charge of the deck. The steersman walks the deck
once or twice and then sits down near the rudder, yawning, and then
rousing himself as if sleep were coming over him. As if to force
himself to remain awake he intones a sailor song, an exquisite little
melody, with a dash of the sea in its undulating measures. He
intones the second verse, but sleep overcomes him and the phrases
become more and more detached, until at last he falls asleep.
The storm begins to rage again and it grows darker. Suddenly the
ship of the Flying Dutchman, with blood-red sails and black mast,
looms up in the distance. She glides over the waves as if she did not
feel the storm at all, and quickly enters the harbour over against the
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

More Related Content

PDF
Kotlin Indepth A Guide To A Multipurpose Programming Language For Serverside ...
PDF
Kotlin Cookbook A Problem Focused Approach 1st Edition Ken Kousen
PDF
Java To Kotlin A Refactoring Guidebook 1st Edition Duncan Mcgregor
PDF
Download full ebook of Java Cookbook Ian F Darwin Darwin Ian F instant downlo...
PDF
kotlin.pdf
PDF
Kotlin Programming Concise Expressive And Powerful Theophilus Edet
PDF
Best kotlin Course in Jalandhar, Punjab
PDF
Kotlin Jump Start Online Free Meetup (June 4th, 2024)
Kotlin Indepth A Guide To A Multipurpose Programming Language For Serverside ...
Kotlin Cookbook A Problem Focused Approach 1st Edition Ken Kousen
Java To Kotlin A Refactoring Guidebook 1st Edition Duncan Mcgregor
Download full ebook of Java Cookbook Ian F Darwin Darwin Ian F instant downlo...
kotlin.pdf
Kotlin Programming Concise Expressive And Powerful Theophilus Edet
Best kotlin Course in Jalandhar, Punjab
Kotlin Jump Start Online Free Meetup (June 4th, 2024)

Similar to Kotlin Cookbook A Problemfocused Approach 1st Edition Ken Kousen (20)

PPTX
K is for Kotlin
PDF
Kotlin: A pragmatic language by JetBrains
PDF
C Cookbook Modern Recipes For Professional Developers 1st Edition Joe Mayo
PDF
Kotlin in Action, Second Edition (MEAP V09) Svetlana Isakova
PDF
EloquenFundamentalsof Web Developmentt_JavaScript.pdf
PDF
Eloquent JavaScript Book for Beginners to Learn Javascript
PDF
Kotlin Online Training.pdf
PDF
Kotlin Online Training.pdf
PDF
Kotlin Online Training.pdf
PDF
Kotlin Online Training.pdf
PDF
Kotlin Online Training.pdf
PDF
Kotlin Online Training.pdf
PDF
Kotlin Online Training.pdf
PDF
Kotlin Online Training.pdf
PDF
Kotlin Online Training.pdf
PDF
Kotlin Online Training.pdf
PDF
Kotlin tutorial
PDF
Kotlin Online Training.pdf
PDF
Jetpack Compose 13 Essentials Developing Android Apps With Jetpack Compose 13...
K is for Kotlin
Kotlin: A pragmatic language by JetBrains
C Cookbook Modern Recipes For Professional Developers 1st Edition Joe Mayo
Kotlin in Action, Second Edition (MEAP V09) Svetlana Isakova
EloquenFundamentalsof Web Developmentt_JavaScript.pdf
Eloquent JavaScript Book for Beginners to Learn Javascript
Kotlin Online Training.pdf
Kotlin Online Training.pdf
Kotlin Online Training.pdf
Kotlin Online Training.pdf
Kotlin Online Training.pdf
Kotlin Online Training.pdf
Kotlin Online Training.pdf
Kotlin Online Training.pdf
Kotlin Online Training.pdf
Kotlin Online Training.pdf
Kotlin tutorial
Kotlin Online Training.pdf
Jetpack Compose 13 Essentials Developing Android Apps With Jetpack Compose 13...
Ad

Recently uploaded (20)

PPTX
UV-Visible spectroscopy..pptx UV-Visible Spectroscopy – Electronic Transition...
PPTX
Lesson notes of climatology university.
PPTX
Orientation - ARALprogram of Deped to the Parents.pptx
PDF
IGGE1 Understanding the Self1234567891011
PPTX
UNIT III MENTAL HEALTH NURSING ASSESSMENT
PPTX
1st Inaugural Professorial Lecture held on 19th February 2020 (Governance and...
PPTX
Cell Types and Its function , kingdom of life
PDF
Empowerment Technology for Senior High School Guide
PPTX
History, Philosophy and sociology of education (1).pptx
PDF
A GUIDE TO GENETICS FOR UNDERGRADUATE MEDICAL STUDENTS
PPTX
Chinmaya Tiranga Azadi Quiz (Class 7-8 )
PDF
Complications of Minimal Access Surgery at WLH
PDF
LNK 2025 (2).pdf MWEHEHEHEHEHEHEHEHEHEHE
PDF
LDMMIA Reiki Yoga Finals Review Spring Summer
PPTX
Final Presentation General Medicine 03-08-2024.pptx
PDF
advance database management system book.pdf
PDF
What if we spent less time fighting change, and more time building what’s rig...
PPTX
Digestion and Absorption of Carbohydrates, Proteina and Fats
PDF
Weekly quiz Compilation Jan -July 25.pdf
PDF
Chinmaya Tiranga quiz Grand Finale.pdf
UV-Visible spectroscopy..pptx UV-Visible Spectroscopy – Electronic Transition...
Lesson notes of climatology university.
Orientation - ARALprogram of Deped to the Parents.pptx
IGGE1 Understanding the Self1234567891011
UNIT III MENTAL HEALTH NURSING ASSESSMENT
1st Inaugural Professorial Lecture held on 19th February 2020 (Governance and...
Cell Types and Its function , kingdom of life
Empowerment Technology for Senior High School Guide
History, Philosophy and sociology of education (1).pptx
A GUIDE TO GENETICS FOR UNDERGRADUATE MEDICAL STUDENTS
Chinmaya Tiranga Azadi Quiz (Class 7-8 )
Complications of Minimal Access Surgery at WLH
LNK 2025 (2).pdf MWEHEHEHEHEHEHEHEHEHEHE
LDMMIA Reiki Yoga Finals Review Spring Summer
Final Presentation General Medicine 03-08-2024.pptx
advance database management system book.pdf
What if we spent less time fighting change, and more time building what’s rig...
Digestion and Absorption of Carbohydrates, Proteina and Fats
Weekly quiz Compilation Jan -July 25.pdf
Chinmaya Tiranga quiz Grand Finale.pdf
Ad

Kotlin Cookbook A Problemfocused Approach 1st Edition Ken Kousen

  • 1. Kotlin Cookbook A Problemfocused Approach 1st Edition Ken Kousen download https://ebookbell.com/product/kotlin-cookbook-a-problemfocused- approach-1st-edition-ken-kousen-34710648 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. Kotlin Cookbook Ken Kousen https://ebookbell.com/product/kotlin-cookbook-ken-kousen-170706088 Kotlin Programming Cookbook Explore More Than 100 Recipes That Show How To Build Robust Mobile And Web Applications With Kotlin Spring Boot And Android Aanand Shekhar Roy https://ebookbell.com/product/kotlin-programming-cookbook-explore- more-than-100-recipes-that-show-how-to-build-robust-mobile-and-web- applications-with-kotlin-spring-boot-and-android-aanand-shekhar- roy-11063710 Kotlin Standard Library Cookbook Master The Powerful Kotlin Standard Library Through Practical Code Examples Samuel Urbanowicz https://ebookbell.com/product/kotlin-standard-library-cookbook-master- the-powerful-kotlin-standard-library-through-practical-code-examples- samuel-urbanowicz-11750696 Modern Android 13 Development Cookbook Over 70 Recipes To Solve Android Development Issues And Create Better Apps With Kotlin And Jetpack Compose Wambua https://ebookbell.com/product/modern-android-13-development-cookbook- over-70-recipes-to-solve-android-development-issues-and-create-better- apps-with-kotlin-and-jetpack-compose-wambua-55529754
  • 3. Kotlin The Ultimate Guide 1st Edition Sufyan Bin Uzayr https://ebookbell.com/product/kotlin-the-ultimate-guide-1st-edition- sufyan-bin-uzayr-46887672 Kotlin In Action Second Edition Meap V09 Chapters 1 To 10 Of 16 Svetlana Isakova https://ebookbell.com/product/kotlin-in-action-second-edition- meap-v09-chapters-1-to-10-of-16-svetlana-isakova-50703078 Kotlin Essentials Marcin Moskaa https://ebookbell.com/product/kotlin-essentials-marcin-moskaa-50821696 Kotlin Multiplatform By Tutorials Second Edition 2nd Edition Carlos Mota https://ebookbell.com/product/kotlin-multiplatform-by-tutorials- second-edition-2nd-edition-carlos-mota-54275474 Kotlin Programming Concise Expressive And Powerful Theophilus Edet https://ebookbell.com/product/kotlin-programming-concise-expressive- and-powerful-theophilus-edet-55274912
  • 7. Ken Kousen Kotlin Cookbook A Problem-Focused Approach
  • 8. 978-1-492-04667-7 [LSI] Kotlin Cookbook by Ken Kousen Copyright © 2020 Ken Kousen. 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). For more information, contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com. Acquisitions Editors: Zan McQuade and Tyler Ortman Development Editor: Corbin Collins Production Editor: Christopher Faucher Copyeditor: Sharon Wilkey Proofreader: Charles Roumeliotis Indexer: Ellen Troutman-Zaig Interior Designer: David Futato Cover Designer: Karen Montgomery Illustrator: Rebecca Demarest November 2019: First Edition Revision History for the First Edition 2019-11-14: First Release See http://oreilly.com/catalog/errata.csp?isbn=9781492046677 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Kotlin Cookbook, the cover image, and related trade dress are trademarks of O’Reilly Media, Inc. The views expressed in this work are those of the author, and do not represent the publisher’s views. While the publisher and the author have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the author disclaim all responsibility 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. For Sandra, who got me through this. Your kindness, unflagging support, and expert skills continue to change my life.
  • 11. Table of Contents Foreword. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi 1. Installing and Running Kotlin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1 Running Kotlin Without a Local Compiler 1 1.2 Installing Kotlin Locally 3 1.3 Compiling and Running Kotlin from the Command Line 5 1.4 Using the Kotlin REPL 7 1.5 Executing a Kotlin Script 8 1.6 Building a Standalone Application Using GraalVM 9 1.7 Adding the Kotlin Plug-in for Gradle (Groovy Syntax) 12 1.8 Adding the Kotlin Plug-in for Gradle (Kotlin Syntax) 15 1.9 Using Gradle to Build Kotlin Projects 16 1.10 Using Maven with Kotlin 19 2. Basic Kotlin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.1 Using Nullable Types in Kotlin 21 2.2 Adding Nullability Indicators to Java 24 2.3 Adding Overloaded Methods for Java 26 2.4 Converting Between Types Explicitly 31 2.5 Printing to Different Bases 33 2.6 Raising a Number to a Power 35 2.7 Using Bitwise Shift Operators 38 2.8 Using Bitwise Boolean Operators 40 2.9 Creating Pair Instances with to 43 v
  • 12. 3. Object-Oriented Programming in Kotlin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 3.1 Understanding the Difference Between const and val 47 3.2 Creating Custom Getters and Setters 49 3.3 Defining Data Classes 51 3.4 The Backing Property Technique 55 3.5 Overloading Operators 58 3.6 Using lateinit for Delayed Initialization 60 3.7 Using Safe Casting, Reference Equality, and Elvis to Override equals 63 3.8 Creating a Singleton 66 3.9 Much Ado About Nothing 69 4. Functional Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 4.1 Using fold in Algorithms 73 4.2 Using the reduce Function for Reductions 76 4.3 Applying Tail Recursion 79 5. Collections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 5.1 Working with Arrays 83 5.2 Creating Collections 86 5.3 Creating Read-Only Views from Existing Collections 89 5.4 Building a Map from a Collection 90 5.5 Returning a Default When a Collection Is Empty 91 5.6 Restricting a Value to a Given Range 93 5.7 Processing a Window on a Collection 94 5.8 Destructuring Lists 96 5.9 Sorting by Multiple Properties 98 5.10 Defining Your Own Iterator 100 5.11 Filtering a Collection by Type 102 5.12 Making a Range into a Progression 104 6. Sequences. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 6.1 Using Lazy Sequences 109 6.2 Generating Sequences 112 6.3 Managing Infinite Sequences 114 6.4 Yielding from a Sequence 116 7. Scope Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 7.1 Initializing Objects After Construction with apply 119 7.2 Using also for Side Effects 121 7.3 Using the let Function and Elvis 123 7.4 Using let with a Temporary Variable 124 vi | Table of Contents
  • 13. 8. Kotlin Delegates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 8.1 Implementing Composition by Delegation 127 8.2 Using the lazy Delegate 130 8.3 Ensuring That a Value Is Not Null 132 8.4 Using the observable and vetoable Delegates 134 8.5 Supplying Maps as Delegates 138 8.6 Creating Your Own Delegates 140 9. Testing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 9.1 Setting the Test Class Life Cycle 143 9.2 Using Data Classes for Tests 148 9.3 Using Helper Functions with Default Arguments 151 9.4 Repeating JUnit 5 Tests with Different Data 152 9.5 Using Data Classes for Parameterized Tests 156 10. Input/Output. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 10.1 Managing Resources with use 159 10.2 Writing to a File 163 11. Miscellaneous. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 11.1 Working with the Kotlin Version 165 11.2 Executing a Lambda Repeatedly 167 11.3 Forcing when to Be Exhaustive 168 11.4 Using the replace Function with Regular Expressions 170 11.5 Converting to Binary String and Back 172 11.6 Making a Class Executable 174 11.7 Measuring Elapsed Time 177 11.8 Starting Threads 179 11.9 Forcing Completion with TODO 182 11.10 Understanding the Random Behavior of Random 183 11.11 Using Special Characters in Function Names 186 11.12 Telling Java About Exceptions 187 12. The Spring Framework. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 12.1 Opening Spring-Managed Bean Classes for Extension 191 12.2 Persisting Kotlin Data Classes 194 12.3 Injecting Dependencies 197 13. Coroutines and Structured Concurrency. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 13.1 Choosing Coroutine Builders 201 13.2 Replacing async/await with withContext 207 13.3 Working with Dispatchers 209 Table of Contents | vii
  • 14. 13.4 Running Coroutines on a Java Thread Pool 211 13.5 Cancelling Coroutines 214 13.6 Debugging Coroutines 217 Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 viii | Table of Contents
  • 15. Foreword Every few years, there is a revolutionary new language that threatens to change the way that people write software. The reality seldom lives up to the hype. Kotlin is dif‐ ferent. Since its creation back in 2011, it has slowly, almost imperceptibly, crept its way into codebases across the world. Developers who have used Java for so long and found it lacking have been able to sneak in a little Kotlin here and there. In so doing, they have shrunk the size—and increased the power—of their code. Having gained some fame as the preferred language for Android development, Kotlin is now at a sufficiently mature stage that a book like this is desperately needed. With a wealth of useful tips, Kotlin Cookbook begins at the beginning. Ken shows you how to install Kotlin and configure it for your project. He shows how to run it in a Java envi‐ ronment, in a browser, or as a standalone application. But the book quickly moves on, solving the kind of day-to-day programming problems faced by developers and archi‐ tects everywhere. Although there is a section set aside for Kotlin testing, you will find that the book is itself test-driven. It uses tests as practical examples of how to use the language. The tests will allow you to adapt the recipes to fit your needs more precisely. This book brings you the kind of straightforward, practical help that will guide your progress on your Kotlin journey. It’s the essential how-to Kotlin guide, and every developer should keep it on their desktop (real or virtual) to support their daily work. Dawn and David Griffiths Authors, Head First Kotlin October 6, 2019 ix
  • 17. Preface Welcome to Kotlin Cookbook! The overall focus of the book is not only to teach Kotlin syntax and semantics, but also to show you when and why a particular feature should be used. The goal isn’t necessarily to cover every detail of Kotlin’s syntax and libraries. In the end, however, many recipes on basic principles were added to make the book understandable even to readers with only a beginning level of Kotlin knowledge. There is a strong movement by JetBrains to encourage the Kotlin community to embrace multiplatform, native, and JavaScript development. In the end, the decision was made not to include recipes involving them, since all are either in beta form or have very low adoption rates. As a result, the book concentrates exclusively on Kotlin for the JVM. The GitHub repository for all the code can be found at https://github.com/kousen/ kotlin-cookbook. It includes a Gradle wrapper (with the build file written in the Kotlin DSL, of course) and all the tests pass. All of the code examples in the book have been compiled and tested with both avail‐ able Long Term Support versions of Java, namely Java 8 and Java 11. Even though Java 8 is technically past its end-of-life deadline, it is still pervasive enough in the industry to ensure the code examples work with it. At the time of this writing, the current version of Kotlin is 1.3.50, with 1.3.60 on the way. All the code works with both versions, and the GitHub repository will frequently be updated to use the latest version of Kotlin. Who Should Read This Book This book is written for developers who already know the basics of object-oriented programming, especially in Java or another JVM-based language. While Java knowl‐ edge would be helpful, it isn’t required. A recipe book like this one is more focused on using the techniques and idioms of Kotlin than on being an exhaustive resource on the language. That has the advantage xi
  • 18. of using the full power of the language in any given recipe, but the disadvantage of spending only a limited time on the basics of those features. Each chapter includes a summary of the basic techniques, so if you are only vaguely familiar with how to cre‐ ate collections, work with arrays, or design classes, you should still be fine. The online reference manual provides a solid introduction to the language, and the book makes frequent reference to examples and discussions found there. In addition, the book frequently dives into the implementations of features from the Kotlin libraries. That’s to show how the developers of the language work with it in practice, as well as to discuss why things are done the way they are. No prior knowl‐ edge of the implementation is expected, however, and you are free to skip those details if you are in a hurry. How This Book Is Organized This book is organized into recipes, and while each is self-contained, many reference others in the book. The hope is that you can read them in any particular order. That said, there is a loose ordering to the chapters, as follows: • Chapter 1 covers the basic process of installing and running Kotlin, including using the REPL, working with build tools like Maven and Gradle, and employing the native image generator in Graal. • Chapter 2 covers some fundamental features of Kotlin—such as nullable types, overloading operators, and converting between types—before examining some more esoteric issues including working with bitwise shift operators or the to extension function on the Pair class. • Chapter 3 focuses on object-oriented features of the language that developers from other languages might find surprising or unusual. It includes how to use the const keyword, how Kotlin handles backing properties, delayed initialization, and the dreaded Nothing class, which is guaranteed to confuse existing Java developers. • Chapter 4 has only a few recipes, which involve functional features that need their own explanations. Functional programming concepts are covered through‐ out the book, especially when talking about collections, sequences, and corou‐ tines, but there are a handful of techniques included in this chapter that you may find unusual or particularly interesting. • Chapter 5 covers arrays and collections, dealing mostly with nonobvious meth‐ ods like destructing collections, sorting by multiple properties, building a win‐ dow on a collection, and creating progressions. xii | Preface
  • 19. • Chapter 6 shows how Kotlin handles sequences of items lazily, similar to the way Java uses streams. Recipes cover generating sequences, yielding from them, and working with infinite sequences. • Chapter 7 covers another topic unique to Kotlin: functions that execute a block of code in the context of an object. Functions like let, apply, and also are quite useful in Kotlin, and this chapter illustrates why and how to use them. • Chapter 8 discusses a convenient feature of Kotlin: how it implements delegation. Delegation lets you employ composition rather than inheritance, and Kotlin includes several delegates in the standard library, like lazy, observable, and vetoable. • Chapter 9 covers the important topic of testing, with a particular focus on JUnit 5. In its current version, JUnit is designed to work well with Kotlin, and that includes both its regular usage and employing it in Spring Framework applica‐ tions. This chapter discusses several approaches that make writing and executing tests easier. • Chapter 10 includes a couple of recipes specifically for managing resources. File I/O is covered, as is the use function, which has broad applicability in several contexts. • Chapter 11 covers topics that do not fit easily in any other category. Topics such as how to get the current Kotlin version, how to force the when statement to be exhaustive even when it doesn’t return a value, and how to use the replace func‐ tion with regular expressions are covered. In addition, the TODO function and the Random class are discussed, as well as how to integrate with Java exception handling. • Chapter 12 involves the Spring Framework along with Spring Boot, which is very friendly to Kotlin. A few recipes are included to show how to use Kotlin classes as managed beans, how to implement JPA persistence, and how to inject dependen‐ cies when needed. • Chapter 13 covers the subject of coroutines, one of the most popular features of Kotlin and the basis of concurrent and parallel programming in the language. Recipes cover the basics, like builders and dispatchers, along with how to cancel and debug coroutines, and how to run them on your own custom Java thread pool. The chapters, and indeed the recipes themselves, do not have to be read in any partic‐ ular order. They do complement each other, and each recipe ends with references to others, but you can start reading anywhere. The chapter groupings are provided as a way to put similar recipes together, but it is expected that you will jump from one to another to solve whatever problem you may have at the moment. Preface | xiii
  • 20. Special note for Android developers: Kotlin is now the preferred language for Android development, but it is a much broader, general-purpose programming language. You can use it anywhere you would use Java, and more. This book does not have a dedica‐ ted section just for Android. Instead, Android uses of Kotlin are discussed through‐ out. A few specific Android-related recipes, like coroutine cancellation, take advan‐ tage of the fact that Android libraries make extensive use of Kotlin, but in general the features of the language covered in this book can be used anywhere. It is hoped that by covering the language in a more general way, Android developers will find techni‐ ques useful to them in any coding project. 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, databases, data types, environment variables, 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 element signifies a tip or suggestion. This element signifies a general note. This element indicates a warning or caution. xiv | Preface
  • 21. Using Code Examples Supplemental material (code examples, exercises, etc.) is available for download at https://github.com/kousen/kotlin-cookbook. This book is here to help you get your job done. In general, if example code is offered with this book, you may use it in your programs and documentation. You do not need to contact us for permission unless you’re 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 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 per‐ mission. We appreciate, but do not generally require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: “Kotlin Cookbook by Ken Kousen (O’Reilly). Copyright 2020 Ken Kousen, 978-1-492-04667-7.” 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. O’Reilly Online Learning For more than 40 years, O’Reilly Media has provided technol‐ ogy and business training, knowledge, and insight to help companies succeed. Our unique network of experts and innovators share their knowledge and expertise through books, articles, conferences, and our online learning platform. O’Reilly’s online learning platform gives you on-demand access to live training courses, in- depth learning paths, interactive coding environments, and a vast collection of text and video from O’Reilly and 200+ other publishers. For more information, please visit http://oreilly.com. Preface | xv
  • 22. How to Contact Us Please address comments and questions concerning this book to the publisher: O’Reilly Media, Inc. 1005 Gravenstein Highway North 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: https://oreil.ly/kotlin-cookbook. 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 At the Google I/O conference in 2017, the company announced that Kotlin would be a supported language for Android development. Later that year, Gradle, Inc.—the company behind the Gradle build tool—announced that it would support a Gradle domain-specific language (DSL) for builds. Both of those developments convinced me to dig into the language, and I’ve been happy to have done so. Over the past few years, I’ve been giving regular presentations and workshops on Kotlin. While the basics of the language are easy to learn and apply, I’ve been impressed with its depth and how aware it is of the way modern development ideas are implemented in other languages, like Groovy or Scala. Kotlin is a synthesis of many of the best programming ideas throughout the industry, and I’ve learned a lot by doing the deep dive necessary to write a book like this. As part of my learning process, I’ve benefitted from working with many active Kotlin developers, including Dawn and Dave Griffiths, whose books Head First Android Development and Head First Kotlin are outstanding; they even agreed to write the foreword for this book. Hadi Harriri, a developer advocate at JetBrains, gives presen‐ tations on Kotlin on a regular basis. Those talks always inspire me to spend time on xvi | Preface
  • 23. the language, and he was kind enough to be a technical reviewer for this book. I’m very grateful to them. Bill Fly also provided a technical review. I’ve interacted with him on the O’Reilly Learning Platform more times than I can count, and he always provides interesting insights (and hard questions). My good friend Jim Harmon helped me get up to speed on Android many years ago, and has always been willing to answer my questions and talk about how Kotlin is used in practice. Mark Maynard is an active developer in industry who helped me understand how Kotlin worked with the Spring Framework, and I’m grateful for that. Finally, the inimitable Venkat Subramaniam was kind enough to take time from his busy schedule writing his own Kotlin book (entitled Programming Kotlin: it’s as good as the rest of his books) to help me with mine. I’m happy to know all my tech reviewers and am humbled by the amount of time and effort they spent improving the book you see now. I need to acknowledge many of my fellow speakers on the NFJS tour, including Nate Schutta, Michael Carducci, Matt Stine, Brian Sletten, Mark Richards, Pratik Patel, Neal Ford, Craig Walls, Raju Gandhi, Jonathan Johnson, and Dan “the Man” Hino‐ josa for their constant doses of perspective and encouragement. I’m sure I’ve left out someone on the tour, and, if so, I assure you it was deliberate. Okay, maybe not. Writing books and teaching training classes (my actual day job) are solitary pursuits. It’s great having a community of friends and colleagues that I can rely on for perspective, advice, and various forms of entertainment. Many people at O’Reilly Media were involved in the creation of this book. Rather than call them out individually, I specifically want to mention Zan McQuade, who was frequently placed in awkward positions by my irregular schedule and my general contrary nature. Thank you for your patience, understanding, and hard work to bring the book to completion. Finally, I need to express all my love to my wife, Ginger, and my son, Xander. Without the support and kindness of my family, I would not be the person I am today, a fact that grows more obvious to me with each passing year. I can never express what you both mean to me. Preface | xvii
  • 24. CHAPTER 1 Installing and Running Kotlin The recipes in this chapter help you get up and running with the Kotlin compiler, both from the command line and using an integrated development environment (IDE). 1.1 Running Kotlin Without a Local Compiler Problem You want to try out Kotlin without a local installation, or run it on a machine that does not support it (for example, a Chromebook). Solution Use the Kotlin Playground, an online sandbox for exploring Kotlin. Discussion The Kotlin Playground provides an easy way to experiment with Kotlin, explore fea‐ tures you haven’t used, or simply run Kotlin on systems that don’t have an installed compiler. It gives you access to the latest version of the compiler, along with a web- based editor that allows you to add code without installing Kotlin locally. 1
  • 25. Figure 1-1 is a snapshot of the browser page. Figure 1-1. The Kotlin Playground home page Just type in your own code and click the Play button to execute it. The Settings button (the gear icon) allows you to change Kotlin versions, decide which platform to run on (JVM, JS, Canvas, or JUnit), or add program arguments. As of Kotlin 1.3, the Kotlin function main can be defined without parameters. The Examples section contains an extensive set of sample programs, organized by topic, that can be executed using an embedded block in a browser. Figure 1-2 shows the “Hello world” program page. 2 | Chapter 1: Installing and Running Kotlin
  • 26. Figure 1-2. Examples in the Kotlin Playground The playground also has a dedicated section for Kotlin Koans, which are a series of exercises to help you become more familiar with the language. While these are useful online, if you use IntelliJ IDEA or Android Studio, the Koans can be added using the EduTools plug-in. 1.2 Installing Kotlin Locally Problem You want to execute Kotlin from a command prompt on your local machine. Solution Perform a manual install from GitHub or use one of the available package managers for your operating system. 1.2 Installing Kotlin Locally | 3
  • 27. Discussion The page at http://kotlinlang.org/docs/tutorials/command-line.html discusses the options for installing a command-line compiler. One option is to download a ZIP file containing an installer for your operating system. This page contains a link to the GitHub repository for Kotlin current releases. ZIP files are available for Linux, macOS, Windows, and the source distribution. Simply unzip the distribution and add its bin subdirectory to your path. A manual install certainly works, but some developers prefer to use package manag‐ ers. A package manager automates the installation process, and some of them allow you to maintain multiple versions of a particular compiler. SDKMAN!, Scoop, and other package managers One of the most popular installation programs is SDKMAN!. Originally designed for Unix-based shells, there are plans to make it available for other platforms as well. Installing Kotlin with SDKMAN! begins with a curl install: > curl -s https://get.sdkman.io | bash Then, once it’s installed, you can use the sdk command to install any one of a variety of products, including Kotlin: > sdk install kotlin By default, the latest version will be installed in the ~/.sdkman/candidates/kotlin direc‐ tory, along with a link called current that points to the selected version. You can find out what versions are available by using the list command: > sdk list kotlin The install command by default selects the latest version, but the use command will let you select any version, offering to install it if necessary: > sdk use kotlin 1.3.50 That will install version 1.3.50 of Kotlin, if necessary, and use it in the current shell. IntelliJ IDEA or Android Studio can use the downloaded versions, or they can maintain their own versions separately. Other package managers that support Kotlin include Homebrew, MacPorts, and Snapcraft. 4 | Chapter 1: Installing and Running Kotlin
  • 28. On Windows, you can use Scoop. Scoop does for Windows what the other package managers do for non-Windows systems. Scoop requires PowerShell 5 or later and .NET Framework 4.5 or later. Simple installation instructions are found on the Scoop website. Once Scoop is installed, the main bucket allows you to install the current version of Kotlin: > scoop install kotlin This will install the scripts kotlin.bat, kotlinc.bat, kotlin-js.bat, and kotlin-jvm.bat and add them all to your path. That is sufficient, but if you want to try it, there is an experimental installer called kotlin-native, which installs a native Windows compiler as well. This installs an LLVM backend for the Kotlin compiler, a runtime implementation, and a native code generation facility by using the LLVM toolchain. Regardless of how you install Kotlin, you can verify that it works and is in your path by using the simple command kotlin -version. A typical response to that com‐ mand is shown here: > kotlin -version Kotlin version 1.3.50-release-112 (JRE 13+33) See Also Recipe 1.3 discusses how to use Kotlin from the command line after it is installed. 1.3 Compiling and Running Kotlin from the Command Line Problem You want to compile and execute Kotlin from the command line. Solution Use the kotlinc-jvm and kotlin commands, similar to Java. Discussion The Kotlin SDK for the JVM includes the Kotlin compiler command, kotlinc-jvm, and the Kotlin execution command, kotlin. They are used just like javac and java for Java files. 1.3 Compiling and Running Kotlin from the Command Line | 5
  • 29. The Kotlin installation includes a script called kotlinc-js for compil‐ ing to JavaScript. This book assumes you are planning to use the JVM version. The basic script kotlinc is an alias for kotlinc-jvm. For example, consider a trivial “Hello, Kotlin!” program, stored in a file called hello.kt, with the code shown in Example 1-1. Example 1-1. hello.kt fun main() { println("Hello, Kotlin!") } The command kotlinc compiles this file, and the command kotlin is used to exe‐ cute the resulting class file, as in Example 1-2. Example 1-2. Compiling and executing a regular Kotlin file > kotlinc-jvm hello.kt > ls hello.kt HelloKt.class > kotlin HelloKt Hello, Kotlin! Compiles the source Executes the resulting class file The compiler produces the HelloKt.class file, which contains bytecodes that can be executed on the Java Virtual Machine. Kotlin does not generate Java source code—it’s not a transpiler. It generates bytecodes that can be interpreted by the JVM. The compiled class takes the name of the file, capitalizes the first letter, and appends Kt on the end. This can be controlled with annotations. If you wish to produce a self-contained JAR file that can be executed by the Java com‐ mand, add the -include-runtime argument. That allows you to produce an exe‐ cutable JAR that can be run from the java command, as in Example 1-3. Example 1-3. Including the Kotlin runtime > kotlinc-jvm hello.kt -include-runtime -d hello.jar 6 | Chapter 1: Installing and Running Kotlin
  • 30. The resulting output file is called hello.jar, which can be executed using the java command: > java -jar hello.jar Hello, Kotlin! Leaving out the -include-runtime flag would produce a JAR file that needs the Kot‐ lin runtime on the classpath in order to execute. The kotlinc command without any arguments starts the interac‐ tive Kotlin REPL, which is discussed in Example 1-4. See Also Example 1-4 shows how to use the Kotlin read-eval-print loop (REPL) for interactive coding. Recipe 1.5 discusses executing Kotlin scripts from the command line. 1.4 Using the Kotlin REPL Problem You want to run Kotlin in an interactive shell. Solution Use the Kotlin REPL by typing kotlinc by itself at the command line. Discussion Kotlin includes an interactive compiler session manager, known as a REPL (read- eval-print loop) that is triggered by the kotlinc command with no arguments. Once inside the REPL, you can evaluate arbitrary Kotlin commands and see the results immediately. The Kotlin REPL is also available inside Android Studio and Intel‐ liJ IDEA as the Kotlin REPL entry under the Tools → Kotlin menu. After running the kotlinc command, you will receive an interactive prompt. An example session is shown in Example 1-4. 1.4 Using the Kotlin REPL | 7
  • 31. Example 1-4. Using the Kotlin REPL ▶ kotlinc Welcome to Kotlin version 1.3.50 (JRE 11.0.4+11) Type :help for help, :quit for quit >>> println("Hello, World!") Hello, World! >>> var name = "Dolly" >>> println("Hello, $name!") Hello, Dolly! >>> :help Available commands: :help show this help :quit exit the interpreter :dump bytecode dump classes to terminal :load <file> load script from specified file >>> :quit The REPL is a quick and easy way to evaluate Kotlin expressions without starting up a full IDE. Use it if you don’t want to create an entire project or other IDE-based col‐ lection of files, or if you want to do a quick demo in order to help another developer, or if you don’t have your preferred IDE available. 1.5 Executing a Kotlin Script Problem You want to write and execute a script written in Kotlin. Solution Enter your code in a file ending in .kts. Then use the kotlinc command with the -script option to execute it. Discussion The kotlinc command supports several command-line options, one of which allows Kotlin to be used as a scripting language. A script is defined as a Kotlin source file with the file extension .kts that includes executable code. As a simple example, the file southpole.kts in Example 1-5 shows the current time at the South Pole and prints whether it is currently on daylight saving time. The script uses the java.time package added to Java in version 8. 8 | Chapter 1: Installing and Running Kotlin
  • 32. Example 1-5. southpole.kts import java.time.* val instant = Instant.now() val southPole = instant.atZone(ZoneId.of("Antarctica/South_Pole")) val dst = southPole.zone.rules.isDaylightSavings(instant) println("It is ${southPole.toLocalTime()} (UTC${southPole.offset}) at the South Pole") println("The South Pole ${if (dst) "is" else "is not"} on Daylight Savings Time") Execute this file with the kotlinc command using the -script option: > kotlinc -script southpole.kts It is 10:42:56.056729 (UTC+13:00) at the South Pole The South Pole is on Daylight Savings Time Scripts contain the code that would normally appear inside the standard main method in a class. Kotlin can be used as a scripting language on the JVM. 1.6 Building a Standalone Application Using GraalVM Problem You want to generate an application that can be run from the command line without any additional dependencies. Solution Use the GraalVM compiler and native-image tool. Discussion GraalVM is a high-performance virtual machine that provides a cross-language run‐ time for running applications written in a variety of languages. You can write in a JVM-based language like Java or Kotlin, and integrate with JavaScript, Ruby, Python, R, and more. One nice feature of GraalVM is that you can use it to create a native executable from your code. This recipe shows a simple example of how to use GraalVM’s native- image tool to create a native binary from Kotlin source code. You can install GraalVM from the downloads page. For the current recipe, the free Community Edition was installed using the SDKMAN! tool: > sdk install java 19.2.0.1-grl > java -version openjdk version "1.8.0_222" OpenJDK Runtime Environment (build 1.8.0_222-20190711112007.graal.jdk8u-src... 1.6 Building a Standalone Application Using GraalVM | 9
  • 33. OpenJDK 64-Bit GraalVM CE 19.2.0.1 (build 25.222-b08-jvmci-19.2-b02, mixed mode) > gu install native-image // installs native image component Consider the Kotlin version of “Hello, World!” from Figure 1-1, reproduced here: fun main() { println("Hello, World!") } As stated in Recipe 1.3, you can just compile this script by using kotlinc-jvm, which generates HelloKt.class, and then run with kotlin: > kotlinc-jvm hello.kt // generates HelloKt.class > kotlin HelloKt Hello, World! To generate a native image instead, first compile the script with the -include- runtime option. That generates a file called hello.jar: > kotlinc-jvm hello.kt -include-runtime -d hello.jar The GraalVM system includes the native-image tool, which you can use to generate the native executable, as in Example 1-6. Example 1-6. Building a native executable using GraalVM > native-image -jar hello.jar From the docs: “For compilation, native-image depends on the local toolchain, so please make sure glibc-devel, zlib-devel (header files for the C library and zlib) and gcc are available on your system.” The output will resemble the following: > native-image -jar hello.jar Build on Server(pid: 61247, port: 49590)* [hello:61247] classlist: 1,497.63 ms [hello:61247] (cap): 2,225.47 ms [hello:61247] setup: 3,451.98 ms [hello:61247] (typeflow): 2,163.16 ms [hello:61247] (objects): 1,793.53 ms [hello:61247] (features): 215.90 ms [hello:61247] analysis: 4,247.68 ms [hello:61247] (clinit): 107.96 ms [hello:61247] universe: 399.58 ms [hello:61247] (parse): 329.84 ms [hello:61247] (inline): 753.12 ms [hello:61247] (compile): 3,426.14 ms 10 | Chapter 1: Installing and Running Kotlin
  • 34. [hello:61247] compile: 4,807.54 ms [hello:61247] image: 306.96 ms [hello:61247] write: 180.22 ms [hello:61247] [total]: 15,246.88 ms The result will be a file called hello that you can invoke at the command line. On a Mac or other Unix-based system, you’ll see the following: > ./hello Hello, World! There are now three ways to run the original script: • Compile with kotlinc-jvm and then execute with kotlin. • Compile including the runtime and then execute the resulting JAR with java. • Compile with kotlinc, create a native image with GraalVM, and then execute from the command line. The sizes of the resulting files are quite different. The compiled bytecode file Hel‐ loKt.class is only about 700 bytes. The hello.jar file with its included runtime is about 1.2 MB. The native image is still larger, at about 2.1 MB. The speed differences are dramatic however, even on a tiny script like this. Example 1-7 shows a simple comparison. Example 1-7. Timing the hello script > time kotlin HelloKt Hello, World! kotlin HelloKt 0.13s user 0.05s system 112% cpu 0.157 total ~/Documents/kotlin > time java -jar hello.jar Hello, World! java -jar hello.jar 0.08s user 0.02s system 99% cpu 0.106 total ~/Documents/kotlin > time ./hello Hello, World! ./hello 0.00s user 0.00s system 59% cpu 0.008 total The relative values are telling. While the JAR file is somewhat quicker than running kotlin directly, the native image is literally an order of magnitude faster. In this example, it takes only about 8 milliseconds to run. 1.6 Building a Standalone Application Using GraalVM | 11
  • 35. If you are a Gradle user, you can use a GraalVM plug-in called gradle-graal. It adds a native-image task (among others) to your build. See the home page for the plug-in for details. 1.7 Adding the Kotlin Plug-in for Gradle (Groovy Syntax) Problem You want to use add the Kotlin plug-in to a Gradle build by using the Groovy domain-specific language (DSL) syntax. Solution Add the Kotlin dependency and plug-in by using the Groovy DSL tags in a build file. Discussion This recipe uses the Groovy DSL for Gradle. The next recipe shows how to use the Kotlin DSL for Gradle instead. The Gradle build tool supports compiling Kotlin on the JVM by using a plug-in sup‐ plied by JetBrains. The kotlin-gradle-plugin, adding to Gradle build script has been registered at the Gradle plug-ins repository, and can be added to a Gradle build script as in Example 1-8. The code shown is added to a file called build.gradle in the project root. Example 1-8. Adding the Kotlin plug-in by using the plugins block (Groovy DSL) plugins { id "org.jetbrains.kotlin.jvm" version "1.3.50" } The version value represents both the plug-in version and the Kotlin version. Gradle still supports the older syntax for adding plug-ins, as shown in Example 1-9. Example 1-9. Older syntax for the Kotlin plug-in (Groovy DSL) buildscript { repositories { mavenCentral() } 12 | Chapter 1: Installing and Running Kotlin
  • 36. dependencies { classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50' } } plugins { id "org.jetbrains.kotlin.jvm" version "1.3.50" } Both of these snippets use the Groovy DSL syntax for Gradle build files, which sup‐ ports both single- and double-quoted strings. As with Kotlin, Groovy uses double- quoted strings when doing interpolation, but since none is required here, single- quoted strings also work. The plugins block does not require you to state where the plug-in is found, as in the repositories block in the latter example. This is true for any Gradle plug-in regis‐ tered at the Gradle plug-ins repository. Using the plugins block also automatically “applies” the plug-in, so no apply statement is required either. The settings.gradle file is recommended but not required. It is processed during the initialization phase of Gradle processing, which occurs when Gradle determines which project build files need to be analyzed. In a multiproject build, the settings file shows which subdirectories of the root are themselves Gradle projects as well. Gradle can share settings and dependencies among subprojects, can make one subproject depend on another, or can even process subproject builds in parallel. For details, see the multiproject build sections of the Gradle User Manual. Kotlin sources can be mixed with Java sources in the same folder, or you can create separate src/main/java and src/main/kotlin folders for them individually. Android projects The Kotlin plug-in for Android is handled slightly differently. Android projects are multiproject builds in Gradle, meaning they normally have two build.gradle files: one in the root directory, and one in a subdirectory called app by default. Example 1-10 shows a typical top-level build.gradle file containing only the Kotlin plug-in information. Example 1-10. Using Kotlin in Android projects (Groovy DSL) buildscript { ext.kotlin_version = '1.3.50' repositories { google() jcenter() } dependencies { 1.7 Adding the Kotlin Plug-in for Gradle (Groovy Syntax) | 13
  • 37. classpath 'com.android.tools.build:gradle:3.5.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } // ... more tasks, unrelated to the plug-in ... In Gradle parlance, the plug-in is then applied, as in the typical app directory build.gradle file shown in Example 1-11. Example 1-11. Applying the Kotlin plug-in apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { // ... android information ... } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" // ... other unrelated dependencies ... } Applies the Kotlin plug-in for Android Applies the Android Kotlin extensions Standard library dependency, can use JDK 8 or JDK 7 The Kotlin plug-in for Android is declared in the buildscript section and then applied in this file. The plug-in knows how to compile Kotlin code inside your Android application. The downloaded plug-in also includes the Android extensions, which makes it easy to access Android widgets by their ID values. The Kotlin plug-in can generate bytecodes for either JDK 7 or JDK 8. Change the jdk value in the listed dependency to select whichever you prefer. At the time of this writing, there is no option to select the Kotlin DSL when creating Android projects. You can create your own build files that use the Kotlin DSL, but that is unusual. The Kotlin DSL will be available in version 4.0 of Android Studio, which will also include full support for KTS files and Kotlin live templates. 14 | Chapter 1: Installing and Running Kotlin
  • 38. See Also The same process using the Kotlin DSL is shown in Recipe 1.8, other than for the Android section. 1.8 Adding the Kotlin Plug-in for Gradle (Kotlin Syntax) Problem You want to add the Kotlin plug-in to a Gradle build, using the Kotlin DSL. Solution Add the Kotlin dependency and plug-in, using the Kotlin DSL tags in a build file. Discussion This recipe uses the Kotlin DSL for Gradle. The previous recipe shows how to use the Groovy DSL for Gradle instead. Gradle (version 5.0 and above) includes the new Kotlin DSL for configuring the build file. It also makes available kotlin-gradle-plugin, registered at the Gradle plug-in repository, which can be added to a Gradle build script shown in Example 1-12. Alternatively, you can use the older buildscript syntax in Example 1-13. The code shown is added to a file called build.gradle.kts in the project root. Example 1-12. Adding the Kotlin plug-in by using the plugins block (Kotlin DSL) plugins { kotlin("jvm") version "1.3.50" } Example 1-13. Older syntax for the Kotlin plug-in (Kotlin DSL) buildscript { repositories { mavenCentral() } dependencies { classpath(kotlin("gradle-plugin", version = "1.3.50")) } } 1.8 Adding the Kotlin Plug-in for Gradle (Kotlin Syntax) | 15
  • 39. plugins { kotlin("jvm") } The plugins block does not require you to state where the plug-in is found, as in the repositories block in the latter example. This is true for any Gradle plug-in regis‐ tered at the Gradle plug-ins tepository. Using the plugins block also automatically “applies” the plug-in, so no apply statement is required either. The default build filenames for the Kotlin DSL in Gradle are set‐ tings.gradle.kts and build.gradle.kts. As you can see, the biggest differences from the Groovy DSL syntax are as follows: • Double quotes are required on any strings. • The parentheses are required in the Kotlin DSL. • Kotlin uses an equals sign (=) to assign values, rather than a colon (:). The settings.gradle.kts file is recommended but not required. It is processed during the initialization phase of Gradle processing, which occurs when Gradle determines which project build files need to be analyzed. In a multiproject build, the settings file shows which subdirectories of the root are themselves Gradle projects as well. Gradle can share settings and dependencies among subprojects, can make one subproject depend on another, or can even process subproject builds in parallel. For details, see the multiproject build sections of the Gradle User Manual. Kotlin and Java source code can be mixed together in src/main/java or src/main/ kotlin, or you can add your own source files by using the sourceSets property of Gradle. See the Gradle documentation for details. See Also The same process using the Groovy DSL in Gradle is shown in Recipe 1.7. Additional details for Android projects can be found in that recipe as well, as the Kotlin DSL is not currently an option when generating Android projects. 1.9 Using Gradle to Build Kotlin Projects Problem You want to build a project that contains Kotlin by using Gradle. 16 | Chapter 1: Installing and Running Kotlin
  • 40. Solution In addition to the Kotlin plug-in for Gradle, add the Kotlin JDK dependency at com‐ pile time. Discussion The examples in Recipes 1.7 and 1.8 showed how to add the Kotlin plug-in for Gra‐ dle. This recipe adds features to the build file to process any Kotlin code in your project. To compile the Kotlin code in Gradle, you need to add an entry to the dependencies block in your Gradle build file, as shown in Example 1-14. Example 1-14. Kotlin DSL for simple Kotlin project (build.gradle.kts) plugins { `java-library` kotlin("jvm") version "1.3.50" } repositories { jcenter() } dependencies { implementation(kotlin("stdlib")) } Adds tasks from the Java Library plug-in Adds the Kotlin plug-in to Gradle Adds the Kotlin standard library to the project at compile time The java-library plug-in defines tasks for a basic JVM-based project, like build, compileJava, compileTestJava, javadoc, jar, and more. The plugins section must come first, but the other top-level blocks (repositories, dependencies, etc.) can be in any order. The dependencies block indicates that the Kotlin standard library is added at com‐ pile time (older versions of Gradle still use the compile configuration instead of implementation, but the effect is the same). The repositories block indicates that 1.9 Using Gradle to Build Kotlin Projects | 17
  • 41. the Kotlin dependency will be downloaded from jcenter, which is the public Artifac‐ tory Bintray repository. If you run the gradle build --dry-run task at the command line, you can see the tasks that would be executed by Gradle without actually running them. The result is as follows: > gradle build -m :compileKotlin SKIPPED :compileJava SKIPPED :processResources SKIPPED :classes SKIPPED :inspectClassesForKotlinIC SKIPPED :jar SKIPPED :assemble SKIPPED :compileTestKotlin SKIPPED :compileTestJava SKIPPED :processTestResources SKIPPED :testClasses SKIPPED :test SKIPPED :check SKIPPED :build SKIPPED BUILD SUCCESSFUL in 0s The Kotlin plug-in adds the compileKotlin, inspectClassesForKotlinIC, and compileTestKotlin tasks. The project can be built by using the same command without the -m flag, which is the abbreviation for --dry-run. 18 | Chapter 1: Installing and Running Kotlin
  • 42. 1.10 Using Maven with Kotlin Problem You want to compile Kotlin by using the Maven build tool. Solution Use the Kotlin Maven plug-in and standard library dependencies. Discussion The basic details for using Maven can be found on the documentation web page. This documentation recommends that first you specify the Kotlin version you want to use as a property in a Maven pom.xml file that looks like this: <properties> <kotlin.version>1.3.50</kotlin.version> </properties> Then, add the Kotlin standard library as a dependency, as in Example 1-15. Example 1-15. Adding the Kotlin standard library dependency <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> <version>${kotlin.version}</version> </dependency> </dependencies> As with Gradle, you can specify kotlin-stdlib-jdk7 or kotlin- stdlib-jdk8 to use extension functions for Java 1.7 or 1.8. Additional available artifact IDs include kotlin-reflect for reflection, and kotlin- test and kotlin-test-junit for testing. To compile Kotlin source code, tell Maven in which directories it is located, as in Example 1-16. 1.10 Using Maven with Kotlin | 19
  • 43. Example 1-16. Specifying Kotlin source directories <build> <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory> <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory> </build> Then tell the Kotlin plug-in to compile the sources and tests (Example 1-17). Example 1-17. Referencing the Kotlin plug-in <build> <plugins> <plugin> <artifactId>kotlin-maven-plugin</artifactId> <groupId>org.jetbrains.kotlin</groupId> <version>${kotlin.version}</version> <executions> <execution> <id>compile</id> <goals><goal>compile</goal></goals> </execution> <execution> <id>test-compile</id> <goals><goal>test-compile</goal></goals> </execution> </executions> </plugin> </plugins> </build> When your project contains both Kotlin code and Java code, the Kotlin compiler should be invoked first. That means kotlin-maven-plugin should be run before maven-compiler-plugin. The documentation page provided previously shows how to ensure that via configuration options in your pom.xml file. 20 | Chapter 1: Installing and Running Kotlin
  • 44. CHAPTER 2 Basic Kotlin This chapter contains recipes that work with the fundamentals of Kotlin. They show you how to use the language without relying on specific libraries. 2.1 Using Nullable Types in Kotlin Problem You want to ensure that a variable is never null. Solution Define the type of a variable without a question mark. Nullable types also combine with the safe call operator (?.) and the Elvis operator (?:) Discussion The most attractive feature of Kotlin may be that it eliminates almost all possible nulls. In Kotlin, if you define a variable without including a trailing question mark, the compiler will require that value to be non-null, as in Example 2-1. Example 2-1. Declaring a non-nullable variable var name: String // ... later ... name = "Dolly" // name = null Assignment to a non-null string 21
  • 45. Assignment to null does not compile Declaring the name variable to be of type String means that it cannot be assigned the value null or the code won’t compile. If you do want a variable to allow null, add a question mark to the type declaration, as in Example 2-2. Example 2-2. Declaring a nullable variable class Person(val first: String, val middle: String?, val last: String) val jkRowling = Person("Joanne", null, "Rowling") val northWest = Person("North", null, "West") JK Rowling has no given middle name; she selected K for her initial to honor her grandmother Katherine Neither does Kim and Kanye’s baby, who will no doubt have bigger issues than this In the Person class shown, you still have to supply a value for the middle parameter, even if it’s null. Life gets interesting when you try to use a nullable variable in an expression. Kotlin requires you to check that the value is not null, but it’s not quite as easy as that sounds. For example, consider the null check in Example 2-3. Example 2-3. Checking nullability of a val variable val p = Person(first = "North", middle = null, last = "West") if (p.middle != null) { val middleNameLength = p.middle.length } Smart cast to non-null String The if test checks whether the middle property is non-null, and if so, Kotlin per‐ forms a smart cast: it treats p.middle as though it was of type String rather than String?. This works, but only because the variable p was declared with the val key‐ word, so it cannot change once it is set. If, on the other hand, the variable was declared with var instead of val, the code is as shown in Example 2-4. 22 | Chapter 2: Basic Kotlin
  • 46. Example 2-4. Asserting that a var variable is not null var p = Person(first = "North", middle = null, last = "West") if (p.middle != null) { // val middleNameLength = p.middle.length val middleNameLength = p.middle!!.length } Smart cast to String impossible, because p.middle is a complex expression Null-asserted (please don’t do this unless absolutely necessary) Because p uses var instead of val, Kotlin assumes that it could change between the time it is defined and the time the middle property is accessed, and refuses to do the smart cast. One way around this is to use the bang-bang, or not-null, assertion opera‐ tor (!!) which is a code smell if ever there was one. The !! operator forces the vari‐ able to be treated as non-null and throws an exception if that is not correct. That’s one of the few ways it is still possible to get a NullPointerException even in Kotlin code, so try to avoid it if possible. A better way to handle this situation is to use the safe call operator (?.). Safe call short-circuits and returns a null if the value is null, as in Example 2-5. Example 2-5. Using the safe call operator var p = Person(first = "North", middle = null, last = "West") val middleNameLength = p.middle?.length Safe call; the resulting type is Int? The problem is that the resulting inferred type is also nullable, so middleNameLength is of type Int?, which is probably not what you want. Therefore, it is helpful to com‐ bine the safe call operator with the Elvis operator (?:), as in Example 2-6. Example 2-6. Safe call with Elvis var p = Person(first = "North", middle = null, last = "West") val middleNameLength = p.middle?.length ?: 0 Elvis operator, returns 0 if middle is null The Elvis operator checks the value of the expression to the left, and if it is not null, returns it. Otherwise, the operator returns the value of the expression on the right. In this case, it checks the value of p.middle?.length, which is either an integer or null. If it is an integer, the value is returned. Otherwise, the expression returns 0. 2.1 Using Nullable Types in Kotlin | 23
  • 47. 1 Or, rather, Groovy was designed that way. The Elvis operator is borrowed from Groovy. The righthand side of an Elvis operator can be an expression, so you can use return or throw when checking function arguments. The real challenge, perhaps, is looking at ?:, turning your head to the side, and some‐ how managing to see Elvis Presley. Clearly, Kotlin was designed for developers with an active imagination.1 Finally, Kotlin provides a safe cast operator, as?. The idea is to avoid throwing a ClassCastException if the cast isn’t going to work. For example, if you try to cast an instance of Person to that type, but the value may be null, you can write the code shown in Example 2-7. Example 2-7. The safe cast operator val p1 = p as? Person Variable p1 is of type Person? The cast will either succeed, resulting in a Person, or will fail, and p1 will receive null as a result. 2.2 Adding Nullability Indicators to Java Problem Your Kotlin code needs to interact with Java code, and you want it to enforce nullabil‐ ity annotations. Solution Enforce JSR-305 nullability annotations in your Kotlin code, using the compile-time parameter -Xjsr305=strict. Discussion One of Kotlin’s primary features is that nullability is enforced in the type system at compile time. If you declare a variable to be of type String, it can never be null, whereas if it is declared to be of type String?, it can, as in Example 2-8. 24 | Chapter 2: Basic Kotlin
  • 48. Example 2-8. Nullable versus non-nullable types var s: String = "Hello, World!" var t: String? = null Cannot be null, or code won’t compile Question mark on type indicates a nullable type This is fine until you want to interact with Java code, which has no such mechanism built into the language. Java does, however, have a @Nonnull annotation defined in the javax.annotation package. While this specification is now considered dormant, many libraries have what are referred to as JSR-305 compatible annotations, and Kot‐ lin supports them. For example, when using the Spring Framework, you can enforce compatibility by adding the code in Example 2-9 to your Gradle build file. Example 2-9. Enforcing JSR-305 compatibility in Gradle (Groovy DSL) sourceCompatibility = 1.8 compileKotlin { kotlinOptions { jvmTarget = "1.8" freeCompilerArgs = ["-Xjsr305=strict"] } } compileTestKotlin { kotlinOptions { jvmTarget = "1.8" freeCompilerArgs = ["-Xjsr305=strict"] } } To do the same using Gradle’s Kotlin DSL, see Example 2-10. Example 2-10. Enforcing JSR-305 compatibility in Gradle (Kotlin DSL) tasks.withType<KotlinCompile> { kotlinOptions { jvmTarget = "1.8" freeCompilerArgs = listOf("-Xjsr305=strict") } } For Maven, add the snippet from Example 2-11 to the POM file, as described in the Kotlin reference guide. 2.2 Adding Nullability Indicators to Java | 25
  • 49. Example 2-11. Enforcing JSR-305 compatibility in Maven <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> <executions>...</executions> <configuration> <nowarn>true</nowarn> <!-- Disable warnings --> <args> <!-- Enable strict mode for JSR-305 annotations --> <arg>-Xjsr305=strict</arg> ... </args> </configuration> </plugin> The @Nonnull annotation defined in JSR-305 takes a property called when. If the value of when is When.ALWAYS, the annotated type is treated as non-null. If it is When.MAYBE or When.NEVER, it is considered nullable. If it is When.UNKNOWN, the type is assumed to be a platform type whose nullability is not known. 2.3 Adding Overloaded Methods for Java Problem You have a Kotlin function with default parameters, and you want to invoke it from Java without having to specify explicit values for each parameter. Solution Add the @JvmOverloads annotation to the function. Discussion Say you have a Kotlin function that specifies one or more default arguments, as in Example 2-12. Example 2-12. A Kotlin function with default parameters fun addProduct(name: String, price: Double = 0.0, desc: String? = null) = "Adding product with $name, ${desc ?: "None" }, and " + NumberFormat.getCurrencyInstance().format(price) For the addProduct function, a String name is required, but the description and price have default values. The description is nullable and defaults to null, while the price defaults to 0. 26 | Chapter 2: Basic Kotlin
  • 50. It is easy enough to call this function from Kotlin with one, two, or three arguments, as the test in Example 2-13 shows. Example 2-13. Calling the overloaded variations from Kotlin @Test fun `check all overloads`() { assertAll("Overloads called from Kotlin", { println(addProduct("Name", 5.0, "Desc")) }, { println(addProduct("Name", 5.0)) }, { println(addProduct("Name")) } ) } Each call to addProduct uses one fewer argument than the previous one. Optional or nullable properties should be placed at the end of a function signature, so they can be left out when calling the function with positional arguments. All of the calls execute properly. Java, however, does not support default arguments for methods, so when calling this function from Java, you have to supply them all, as in Example 2-14. Example 2-14. Calling the function from Java @Test void supplyAllArguments() { System.out.println(OverloadsKt.addProduct("Name", 5.0, "Desc")); } If you add the annotation @JvmOverloads to the function, the generated class will support all the function overloads, as in Example 2-15. Example 2-15. Calling all the overloads from Java @Test void checkOverloads() { assertAll("overloads called from Java", () -> System.out.println(OverloadsKt.addProduct("Name", 5.0, "Desc")), () -> System.out.println(OverloadsKt.addProduct("Name", 5.0)), () -> System.out.println(OverloadsKt.addProduct("Name")) ); } 2.3 Adding Overloaded Methods for Java | 27
  • 51. To see why this works, you can decompile the generated bytecodes from Kotlin. Without the @JvmOverloads annotation, the generated code resembles Example 2-16. Example 2-16. Decompiled function from Kotlin bytecodes @NotNull public static final String addProduct(@NotNull String name, double price, @Nullable String desc) { Intrinsics.checkParameterIsNotNull(name, "name"); // ... } When you add the @JvmOverloads annotation, the result instead resembles Example 2-17. Example 2-17. Decompiled function with overloads // public final class OverloadsKt { @JvmOverloads @NotNull public static final String addProduct(@NotNull String name, double price, @Nullable String desc) { Intrinsics.checkParameterIsNotNull(name, "name"); // ... } @JvmOverloads @NotNull public static final String addProduct( @NotNull String name, double price) { return addProduct$default(name, price, (String)null, 4, (Object)null); } @JvmOverloads @NotNull public static final String addProduct(@NotNull String name) { return addProduct$default(name, 0.0D, (String)null, 6, (Object)null); } The generated class includes additional methods that invoke the full method with supplied, default arguments. You can also do this with constructors. The Product class shown in Example 2-18 generates three constructors: one with all three arguments, one with only the name and price, and one with only the name. 28 | Chapter 2: Basic Kotlin
  • 52. Example 2-18. Kotlin class with overloaded constructors data class Product @JvmOverloads constructor( val name: String, val price: Double = 0.0, val desc: String? = null ) The explicit constructor call is necessary so that you can add the @JvmOverloads annotation to it. Now, instantiating the class can be done with multiple arguments in Kotlin, as in Example 2-19. Example 2-19. Instantiating the Product class from Kotlin @Test internal fun `check overloaded Product contructor`() { assertAll("Overloads called from Kotlin", { println(Product("Name", 5.0, "Desc")) }, { println(Product("Name", 5.0)) }, { println(Product("Name")) } ) } Or you can call the constructors from Java, as in Example 2-20. Example 2-20. Instantiating the Product class from Java @Test void checkOverloadedProductCtor() { assertAll("overloads called from Java", () -> System.out.println(new Product("Name", 5.0, "Desc")), () -> System.out.println(new Product("Name", 5.0)), () -> System.out.println(new Product("Name")) ); } This all works, but note that a subtle trap exists. If you look at the decompiled code for the Product class, you’ll see all the necessary constructors, shown in Example 2-21. Example 2-21. Overloaded Product constructors in decompiled code @JvmOverloads public Product(@NotNull String name, double price, @Nullable String desc) { Intrinsics.checkParameterIsNotNull(name, "name"); super(); this.name = name; this.price = price; 2.3 Adding Overloaded Methods for Java | 29
  • 53. this.desc = desc; } @JvmOverloads public Product(String var1, double var2, String var4, int var5, DefaultConstructorMarker var6) { // ... this(var1, var2, var4); } @JvmOverloads public Product(@NotNull String name, double price) { this(name, price, (String)null, 4, (DefaultConstructorMarker)null); } @JvmOverloads public Product(@NotNull String name) { this(name, 0.0D, (String)null, 6, (DefaultConstructorMarker)null); } Calls three-argument constructor Calls generated constructor, which then calls three-argument constructor Each of the overloaded constructors ultimately calls the full, three-argument version with various defaults supplied. This is probably fine, but keep in mind that when you invoke a constructor with optional arguments, you’re not calling the analogous con‐ structor in the superclass; all calls are going through a single constructor with the most arguments. Calls to constructors marked @JvmOverloads do not call super with the same number of arguments. Instead, they call the full con‐ structor with supplied defaults. In Java, each constructor calls its parent by using super, and when you overload con‐ structors, you often invoke super with the same number of arguments. That’s not happening in this case. The superclass constructor that gets invoked is the one with all the parameters, with supplied defaults. 30 | Chapter 2: Basic Kotlin
  • 54. 2.4 Converting Between Types Explicitly Problem Kotlin does not automatically promote primitive types to wider variables, such as an Int to a Long. Solution Use the explicit conversion functions toInt, toLong, and so on to convert the smaller type explicitly. Discussion One of the surprises Kotlin brings to Java developers is that shorter types are not automatically promoted to longer types. For example, in Java it is perfectly normal to write the code in Example 2-22. Example 2-22. Promoting shorter primitive types to longer ones in Java int myInt = 3; long myLong = myInt; Automatic promotion of int to long When autoboxing was introduced in Java 1.5, it became easy to convert from a primi‐ tive to a wrapper type, but converting from one wrapper type to another still requires extra code, as in Example 2-23. Example 2-23. Converting from an Integer to a Long Integer myInteger = 3; // Long myWrappedLong = myInteger; Long myWrappedLong = myInteger.longValue(); myWrappedLong = Long.valueOf(myInteger); Does not compile Extracts a long, then wraps it Unwraps int, promotes to long, then wraps it In other words, dealing with the wrapped types directly requires you to do the unbox‐ ing yourself. You can’t simply assign an Integer instance to a Long without extracting the wrapped value first. 2.4 Converting Between Types Explicitly | 31
  • 55. Discovering Diverse Content Through Random Scribd Documents
  • 56. Vestal Virgin), and "Fernando Cortez," were brought out in Paris and later in Berlin, where he was general music director, 1820-1841. His operas were heavily scored, especially for brass. Much that is noisy in "Rienzi" may be traced to Spontini, but later Wagner understood how to utilize the brass in the most eloquent manner; for, like Shakespeare, Wagner possessed the genius that converts the dross of others into refined gold. Mention may be here made of three composers of light opera, who succeeded in evolving a refined and charming type of the art. We at least know the delightful overture to "The Merry Wives of Windsor," by Otto Nicolai (1810-1849); and the whole opera, produced in Berlin a few months before Nicolai died, is equally frolicksome and graceful. Conradin Kreutzer (1780-1849) brought out, in 1836, "Das Nachtlager in Granada" (A Night's Camp in Granada), a melodious and sparkling score. But the German light opera composer par excellence is Albert Lortzing (1803-1851). His chief works are, "Czar und Zimmermann" (Czar and Carpenter), 1834, with its beautiful baritone solo, "In childhood I played with a sceptre and crown"; "Der Wildschütz" (The Poacher); "Undine"; and "Der Waffenschmied" (The Armourer) which last also has a deeply expressive solo for baritone, "Ich auch war einst Jüngling mit lockigem Haar" (I too was a youth once with fair, curly hair).
  • 57. R Richard Wagner (1813-1883) ICHARD WAGNER was born at Leipsic, May 22, 1813. His father was clerk to the city police court and a man of good education. During the French occupation of Leipsic he was, owing to his knowledge of French, made chief of police. He was fond of poetry and had a special love for the drama, often taking part in amateur theatricals. Five months after Richard's birth his father died of an epidemic fever brought on by the carnage during the battle of Leipsic, October 16, 18, and 19, 1813. In 1815 his widow, whom he had left in most straitened circumstances, married Ludwig Geyer, an actor, a playwright, and a portrait painter. By inheritance from his father, by association with his stepfather, who was very fond of him, Wagner readily acquired the dramatic faculty so pronounced in his operas and music-dramas of which he is both author and composer. At the time Wagner's mother married Geyer, he was a member of the Court Theatre at Dresden. Thither the family removed. When the boy was eight years old, he had learned to play on the pianoforte the chorus of bridesmaids from "Der Freischütz," then quite new. The day before Geyer's death, September 30, 1821, Richard was playing this piece in an adjoining room and heard Geyer say to his mother: "Do you think he might have a gift for music?" Coming out of the death room Wagner's mother said to him: "Of you he wanted to make something." "From this time on," writes Wagner in his early autobiographical sketch, "I always had an idea that I was destined to amount to something in this world." At school Wagner made quite a little reputation as a writer of verses. He was such an enthusiastic admirer of Shakespeare that at the age
  • 58. of fourteen he began a grand tragedy, of which he himself says that it was a jumble of Hamlet and Lear. So many people died in the course of it that their ghosts had to return in order to keep the fifth act going. In 1833, at the age of twenty, Wagner began his career as a professional musician. His elder brother Albert was engaged as tenor, actor, and stage manager at the Würzburg theatre. A position as chorus master being offered to Richard, he accepted it, although his salary was a pittance of ten florins a month. However, the experience was valuable. He was able to profit by many useful hints from his brother, the Musikverein performed several of his compositions, and his duties were not so arduous but that he found time to write the words and music of an opera in three acts entitled "The Fairies"—first performed in June, 1888, five years after his death, at Munich. In the autumn of 1834 he was called to the conductorship of the opera at Magdeburg. There he wrote and produced an opera, "Das Liebesverbot" (Love Veto), based on Shakespeare's Measure for Measure. The theatre at Magdeburg was, however, on the ragged edge of bankruptcy, and during the spring of 1836 matters became so bad that it was evident the theatre must soon close. Finally only twelve days were left for the rehearsing and the performance of his opera. The result was that the production went completely to pieces, singers forgetting their lines and music, and a repetition which was announced could not come off because of a free fight behind the scenes between two of the principal singers. Wagner describes this in the following amusing passage in his autobiographical sketch: "All at once the husband of my prima donna (the impersonator of Isabella) pounced upon the second tenor, a very young and handsome fellow (the singer of my Claudio), against whom the injured spouse had long cherished a secret jealousy. It seemed that the prima donna's husband, who had from behind the curtains inspected with me the composition of the audience, considered that the time had now arrived when, without damage to the prospects of
  • 59. the theatre, he could take his revenge on his wife's lover. Claudio was so pounded and belaboured by him that the unhappy individual was compelled to retire to the dressing-room with his face all bleeding. Isabella was informed of this, and, rushing desperately toward her furious lord, received from him such a series of violent cuffs that she forthwith went into spasms. The confusion among my personnel was now quite boundless: everybody took sides with one party or the other, and everything seemed on the point of a general fight. It seemed as if this unhappy evening appeared to all of them precisely calculated for a final settling up of all sorts of fancied insults. This much was evident, that the couple who had suffered under the 'love veto' (Liebesverbot) of Isabella's husband, were certainly unable to appear on this occasion." Wagner was next engaged as orchestral conductor at Königsberg, where he married the actress Wilhelmina, or Minna Planer. Later he received notice of his appointment as conductor and of the engagement of his wife and sister at the theatre at Riga, on the Russian side of the Baltic. In Riga he began the composition of his first great success, "Rienzi." He completed the libretto during the summer of 1838, and began the music in the autumn, and when his contract terminated in the spring of 1839 the first two acts were finished. In July, accompanied by his wife and a huge Newfoundland dog, he boarded a sailing vessel for London, at the port of Pilau, his intention being to go from London to Paris. "I shall never forget the voyage," he says. "It was full of disaster. Three times we nearly suffered shipwreck, and once were obliged to seek safety in a Norwegian harbour.... The legend of the 'Flying Dutchman' was confirmed by the sailors, and the circumstances gave it a distinct and characteristic colour in my mind." No wonder the sea is depicted so graphically in his opera "The Flying Dutchman." He arrived in Paris in September, 1839, and remained until April 7, 1842, from his twenty-sixth to his twenty-ninth year. This Parisian sojourn was one of the bitter experiences of his life. At times he
  • 60. actually suffered from cold and hunger, and was obliged to do a vast amount of most uncongenial kind of hack work. November 19, 1840, he completed the score of "Rienzi," and in December forwarded it to the director of the Royal Theatre at Dresden. While awaiting a reply, he contributed to the newspapers and did all kinds of musical drudgery for Schlesinger, the music publisher, even making arrangements for the cornet à piston. Finally word came from Dresden. "Rienzi" had aroused the enthusiasm of the chorus master, Fischer, and of the tenor Tichatschek, who saw that the title rôle was exactly suited to his robust, dramatic voice. Then there was Mme. Schröder-Devrient for the part of Adriano. The opera was produced October 20, 1842, the performance beginning at six and ending just before midnight, to the enthusiastic plaudits of an immense audience. So great was the excitement that in spite of the late hour people remained awake to talk over the success. "We all ought to have gone to bed," relates a witness, "but we did nothing of the kind." Early the next morning Wagner appeared at the theatre in order to make excisions from the score, which he thought its great length necessitated. But when he returned in the afternoon to see if they had been executed, the copyist excused himself by saying the singers had protested against any cuts. Tichatschek said: "I will have no cuts; it is too heavenly." After a while, owing to its length, the opera was divided into two evenings. The success of "Rienzi" led the Dresden management to put "The Flying Dutchman" in rehearsal. It was brought out after somewhat hasty preparations, January 2, 1843. The opera was so different from "Rienzi," its sombre beauty contrasted so darkly with the glaring, brilliant music and scenery of the latter, that the audience failed to grasp it. In fact, after "Rienzi," it was a disappointment. Before the end of January, 1843, not long after the success of "Rienzi," Wagner was appointed one of the Royal conductors at Dresden. He was installed February 2d. One of his first duties was to assist Berlioz at the rehearsals of the latter's concerts. Wagner's work in his new position was somewhat varied, consisting not only
  • 61. of conducting operas, but also music between the acts at theatrical performances and at church services. The principal operas which he rehearsed and conducted were "Euryanthe," "Freischütz," "Don Giovanni," "The Magic Flute," Gluck's "Armide," and "Iphigenia in Aulis." The last-named was revised both as regards words and music by him, and his changes are now generally accepted. Meanwhile he worked arduously on "Tannhäuser," completing it April 13, 1844. It was produced at Dresden, October 19, 1845. At first the work proved even a greater puzzle to the public than "The Flying Dutchman" had, and evoked comments which nowadays, when the opera has actually become a classic, seem ridiculous. Some people even suggested that the plot of the opera should be changed so that Tannhäuser should marry Elizabeth. The management of the Dresden theatre, which had witnessed the brilliant success of "Rienzi" and had seen "The Flying Dutchman" and "Tannhäuser" at least hold their own in spite of the most virulent opposition, looked upon his next work, "Lohengrin," as altogether too risky and put off its production indefinitely. Thinking that political changes might put an end to the routine stagnation in musical matters, Wagner joined in the revolutionary agitation of '48 and '49. In May, 1849, the disturbances at Dresden reached such an alarming point that the Saxon Court fled. Prussian troops were dispatched to quell the riot and Wagner thought it advisable to flee. He went to Weimar, where Liszt was busy rehearsing "Tannhäuser." While attending a rehearsal of this work, May 19, news was received that orders had been issued for his arrest as a politically dangerous individual. Liszt at once procured a passport and Wagner started for Paris. In June he went to Zurich, where he found Dresden friends and where his wife joined him, being enabled to do so through the zeal of Liszt, who raised the money to defray her journey from Dresden. Liszt brought out "Lohengrin" at Weimar, August 28, 1850. The reception of "Lohengrin" did not at first differ much from that
  • 62. accorded to "Tannhäuser." Yet the performance made a deep impression. The fact that the weight of Liszt's influence had been cast in its favour gave vast importance to the event, and it may be said that through this performance Wagner's cause received its first great stimulus. The so-called Wagner movement may be said to have dated from this production of "Lohengrin." He finished the librettos of the "Nibelung" dramas in 1853. By May, 1854, the music of "Das Rheingold" was composed. The following month he began "Die Walküre" and finished all but the instrumentation during the following winter and the full score in 1856. Previous to this, in fact already in the autumn of 1854, he had sketched some of the music of "Siegfried," and in the spring of 1857 the full score of the first act and of the greater part of the second act was finished. Then, recognizing the difficulties which he would encounter in securing a performance of the "Ring," and appalled by the prospect of the battle he would be obliged to wage, he was so disheartened that he abandoned the composition of "Siegfried" at the Waldweben scene and turned to "Tristan." His idea at that time was that "Tristan" would be short and comparatively easy to perform. Genius that he was, he believed that because it was easy for him to write great music it would be easy for others to interpret it. A very curious, not to say laughable, incident occurred at this time. An agent of the Emperor of Brazil called and asked if Wagner would compose an opera for an Italian troupe at Rio de Janeiro, and would he conduct the work himself, all upon his own terms. The composition of "Tristan" actually was begun with a view of its being performed by Italians in Brazil! The poem of "Tristan" was finished early in 1857, and in the winter of the same year the full score of the first act was ready to be forwarded to the engraver. The second act is dated Venice, March 2, 1859. The third is dated Lyons, August, 1859. It is interesting to note in connection with "Tristan" that, while Wagner wrote it because he thought it would be easy to secure its performance, he subsequently found more difficulty in getting it
  • 63. produced than any other of his works. In September, 1859, he again went to Paris with the somewhat curious hope that he could there find opportunity to produce "Tristan" with German artists. Through the intercession of the Princess Metternich, the Emperor ordered the production of "Tannhäuser" at the Opéra. Beginning March 13, 1861, three performances were given, of which it is difficult to say whether the performance was on the stage or in the auditorium, for the uproar in the house often drowned the sounds from the stage. The members of the Jockey Club, who objected to the absence of a ballet, armed themselves with shrill whistles, on which they began to blow whenever there was the slightest hint of applause, and the result was that between the efforts of the singers to make themselves heard and of Wagner's friends to applaud, and the shrill whistling from his enemies, there was confusion worse confounded. But Wagner's friendship with Princess Metternich bore good fruit. Through her mediation, it is supposed, he received permission to return to all parts of Germany but Saxony. It was not until March, 1862, thirteen years after his banishment, that he was again allowed to enter the kingdom of his birth and first success. His first thought now was to secure the production of "Tristan," but at Vienna, after fifty-seven rehearsals, it was put upon the shelf as impossible. In 1863, while working upon "Die Meistersinger," at Penzing, near Vienna, he published his "Nibelung" dramas, expressing his hope that through the bounty of one of the German rulers the completion and performance of his "Ring of the Nibelung" would be made possible. But in the spring of 1864, worn out by his struggle with poverty and almost broken in spirit by his contest with public and critics, he actually determined to give up his public career, and eagerly grasped the opportunity to visit a private country seat in Switzerland. Just at this very moment, when despair had settled upon him, the long wished-for help came. King Ludwig II., of Bavaria, bade him come to Munich, where he settled in 1864. "Tristan" was produced there June 10, 1865. June 21, 1868, a model
  • 64. performance of "Die Meistersinger," which he had finished in 1867, was given at Munich under the direction of von Bülow, Richter acting as chorus master and Wagner supervising all the details. Wagner also worked steadily at the unfinished portion of the "Ring," completing the instrumentation of the third act of "Siegfried" in 1869 and the introduction and first act of "The Dusk of the Gods" in June, 1870. August 25, 1870, his first wife having died January 25, 1866, after five years' separation from him, he married the divorced wife of von Bülow, Cosima Liszt. In 1869 and 1870, respectively "The Rhinegold" and "The Valkyr" were performed at the Court Theatre in Munich. Bayreuth having been determined upon as the place where a theatre for the special production of his "Ring" should be built, Wagner settled there in April, 1872. By November, 1874, "Dusk of the Gods" received its finishing touches, and rehearsals had already been held at Bayreuth. During the summer of 1875, under Wagner's supervision, Hans Richter held full rehearsals there, and at last, twenty-eight years after its first conception, on August 13th, 14th, 16th, and 17th, again from August 20 to 23, and from August 27 to 30, 1876, "The Ring of the Nibelung" was performed at Bayreuth with the following cast: Wotan, Betz; Loge, Vogel; Alberich, Hill; Mime, Schlosser; Fricka, Frau Grün; Donner and Gunther, Gura; Erda and Waltraute, Frau Jaide; Siegmund, Niemann; Sieglinde, Frl. Schefsky; Brünnhilde, Frau Materna; Siegfried, Unger; Hagen, Siehr; Gutrune, Frl. Weckerin; Rhinedaughters, Lilli and Marie Lehmann, and Frl. Lammert. First violin, Wilhelmj; conductor, Hans Richter. The first Rhinedaughter was the same Lilli Lehmann who, in later years, at the Metropolitan Opera House, New York, became one of the greatest of prima donnas and, as regards the Wagnerian repertoire, set a standard for all time. Materna appeared at that house in the "Valkyr" production under Dr. Damrosch, in January, 1885, and Niemann was heard there later. To revert to Bayreuth, "Parsifal" was produced there in July, 1882. In the autumn of that year, Wagner's health being in an unsatisfactory
  • 65. state, though no alarming symptoms had shown themselves, he took up his residence in Venice at the Palazzo Vendramini, on the Grand Canal. He died February 13, 1883. In manner incidental, that is, without attention formally being called to the subject, Wagner's reform of the lyric stage is set forth in the descriptive accounts of his music-dramas which follow, and in which the leading motives are quoted in musical notation. But something directly to the point must be said here. Once again, like Gluck a century before, Wagner opposed the assumption of superiority on the part of the interpreter—the singer— over the composer. He opposed it in manner so thorough-going that he changed the whole face of opera. A far greater tribute to Wagner's genius than the lame attempts of some German composers at imitating him, is the frank adoption of certain phases of his method by modern French and Italian composers, beginning with Verdi in "Aïda." While by no means a Wagnerian work, since it contains not a trace of the theory of the leading motive, "Aïda," through the richness of its instrumentation, the significant accompaniment of its recitative, the lack of mere bravura embellishment in its vocal score, and its sober reaching out for true dramatic effect in the treatment of the voices, substituting this for ostentatious brilliancy and ear-tickling fluency, plainly shows the influence of Wagner upon the greatest of Italian composers. And what is true of "Aïda," is equally applicable to the whole school of Italian verismo that came after Verdi—Mascagni, Leoncavallo, Puccini. Wagner's works are conceived and executed upon a gigantic scale. They are Shakespearian in their dimensions and in their tragic power; or, as in the "Meistersinger," in their comedy element. Each of his works is highly individual. The "Ring" dramas and "Tristan" are unmistakably Wagner. Yet how individually characteristic the music of each! That of the "Ring" is of elemental power. The "Tristan" music is molten passion. Equally characteristic and individual are his other scores.
  • 66. The theory evolved by Wagner was that the lyric stage should present not a series of melodies for voice upon a mere framework of plot and versified story, but a serious work of dramatic art, the music to which should, both vocally and instrumentally, express the ever varying development of the drama. With this end in view he invented a melodious recitative which only at certain great crises in the progress of the action—such as the love-climax, the gathering at the Valkyr Rock, the "Farewell," and the "Magic Fire" scenes in "The Valkyr"; the meeting of Siegfried and Brünnhilde in "Siegfried"; the love duet and "Love-Death" in "Tristan"—swells into prolonged melody. Note that I say prolonged melody. For besides these prolonged melodies, there is almost constant melody, besides marvellous orchestral colour, in the weft and woof of the recitative. This is produced by the artistic use of leading motives, every leading motive being a brief, but expressive, melody—so brief that, to one coming to Wagner without previous study or experience, the melodious quality of his recitative is not appreciated at first. After a while, however, the hearer begins to recognize certain brief, but melodious and musically eloquent phrases—leading motives—as belonging to certain characters in the drama or to certain influences potent in its development, such as hate, love, jealousy, the desire for revenge, etc. Often to express a combination of circumstances, influences, passions, or personal actions, these leading motives, these brief melodious phrases, are combined with a skill that is unprecedented; or the voice may express one, while the orchestra combines with it in another. To enable the orchestra to follow these constantly changing phases in the evolution and development of the drama, and often to give utterance to them separately, it was necessary for Wagner to have most intimate knowledge of the individual tone quality and characteristics of every instrument in the orchestra, and this mastery of what I may call instrumental personality he possessed to a hitherto undreamed-of degree. Nor has anyone since equalled him in it. The result is a choice and variety of instrumentation which in itself is almost an equivalent for dramatic action and enables the orchestra
  • 67. to adapt itself with unerring accuracy to the varying phases of the drama. Consider that, when Wagner first projected his theory of the music- drama, singers were accustomed in opera to step into the limelight and, standing there, deliver themselves of set melodies, acknowledge applause and give as many encores as were called for, in fact were "it," while the real creative thing, the opera, was but secondary, and it is easy to comprehend the opposition which his works aroused among the personnel of the lyric stage; for music- drama demands a singer's absorption not only in the music but also in the action. A Wagner music-drama requires great singers, but the singers no longer absorb everything. They are part—a most important part, it is true—of a performance, in which the drama itself, the orchestra, and the stage pictures are also of great importance. A performance of a Wagner music-drama, to be effective, must be a well-rounded, eloquent whole. The drama must be well acted from a purely dramatic point of view. It must be well sung from a purely vocal point of view. It must be well interpreted from a purely orchestral point of view. It must be well produced from a purely stage point of view. For all these elements go hand in hand. It is, of course, well known that Wagner was the author of his own librettos and showed himself a dramatist of the highest order for the lyric stage. While his music-dramas at first aroused great opposition among operatic artists, growing familiarity with them caused these artists to change their view. The interpretation of a Wagner character was discovered to be a combined intellectual and emotional task which slowly, but surely, appealed more and more to the great singers of the lyric stage. They derived a new dignity and satisfaction from their work, especially as audiences also began to realize that, instead of mere entertainment, performances of Wagner music- dramas were experiences that both stirred the emotions to their depths and appealed to the intellect as well. To this day Lilli Lehmann is regarded by all, who had the good fortune to hear her at
  • 68. the Metropolitan Opera House, as the greatest prima donna and the most dignified figure in the history of the lyric stage in this country; for on the lyric stage the interpretation of the great characters in Wagnerian music-drama already had come to be regarded as equal to the interpretation of the great Shakespearian characters on the dramatic. Wagner's genius was so supreme that, although he has been dead thirty-four years, he is still without a successor. Through the force of his own genius he appears destined to remain the sole exponent of the art form of which he was the creator. But his influence is still potent. This we discover not only in the enrichment of the orchestral accompaniment in opera, but in the banishment of senseless vocal embellishment, in the search for true dramatic expression and, in general, in the greater seriousness with which opera is taken as an art. Even the minor point of lowering the lights in the auditorium during a performance, so as to concentrate attention upon the stage, is due to him; and even the older Italian operas are now given with an attention to detail, scenic setting, and an endeavour to bring out their dramatic effects, quite unheard of before his day. He was, indeed, a reformer of the lyric stage whose influence long will be potent "all along the line." RIENZI, DER LETZTE DER TRIBUNEN RIENZI, THE LAST OF THE TRIBUNES Opera in five acts. Words and music by Wagner. Produced, Dresden, October 20, 1842. London, Her Majesty's Theatre, April 16, 1869. New York, Academy of Music, 1878, with Charles R. Adams, as Rienzi, Pappenheim as Adriano; Metropolitan Opera House, February 5, 1886, with Sylva as Rienzi, Lehmann as Irene, Brandt as Adriano, Fischer as Colonna.
  • 69. Characters Cola Rienzi, Roman Tribune and Papal Notary Tenor Irene, his sister Soprano Steffano Colonna Bass Adriano, his son Mezzo- Soprano Paolo Orsino Bass Raimondo, Papal Legate Bass Baroncello } Roman citizens { Tenor Cecco del Vecchio } { Bass Messenger of Peace Soprano Ambassadors, Nobles, Priests, Monks, Soldiers, Messengers, and Populace in General. Time—Middle of the Fourteenth Century. Place—Rome. Orsino, a Roman patrician, attempts to abduct Irene, the sister of Rienzi, a papal notary, but is opposed at the critical moment by Colonna, another patrician. A fight ensues between the two factions, in the midst of which Adriano, the son of Colonna, who is in love with Irene, appears to defend her. A crowd is attracted by the tumult, and among others Rienzi comes upon the scene. Enraged at the insult offered his sister, and stirred on by Cardinal Raimondo, he urges the people to resist the outrages of the nobles. Adriano is impelled by his love for Irene to cast his lot with her brother. The nobles are overpowered, and appear at the capitol to swear allegiance to Rienzi, but during the festal proceedings Adriano warns him that the nobles have plotted to kill him. An attempt which Orsino makes upon him with a dagger is frustrated by a steel breastplate which Rienzi wears under his robe.
  • 70. The nobles are seized and condemned to death, but on Adriano's pleading they are spared. They, however, violate their oath of submission, and the people again under Rienzi's leadership rise and exterminate them, Adriano having pleaded in vain. In the end the people prove fickle. The popular tide turns against Rienzi, especially in consequence of the report that he is in league with the German emperor, and intends to restore the Roman pontiff to power. As a festive procession is escorting him to church, Adriano rushes upon him with a drawn dagger, being infuriated at the slaughter of his family, but the blow is averted. Instead of the "Te Deum," however, with which Rienzi expected to be greeted on his entrance to the church, he hears the malediction and sees the ecclesiastical dignitaries placing the ban of excommunication against him upon the doors. Adriano hurries to Irene to warn her of her brother's danger, and urges her to seek safety with him in flight. She, however, repels him, and seeks her brother, determined to die with him, if need be. She finds him at prayer in the capitol, but rejects his counsel to save herself with Adriano. Rienzi appeals to the infuriated populace which has gathered around the capitol, but they do not heed him. They fire the capitol with their torches, and hurl stones at Rienzi and Irene. As Adriano sees his beloved one and her brother doomed to death in the flames, he throws away his sword, rushes into the capitol, and perishes with them. The overture of "Rienzi" gives a vivid idea of the action of the opera. Soon after the beginning there is heard the broad and stately melody of Rienzi's prayer, and then the Rienzi Motive, a typical phrase, which is used with great effect later in the opera. It is followed in the overture by the lively melody heard in the concluding portion of the finale of the second act. These are the three most conspicuous portions of the overture, in which there are, however, numerous tumultuous passages reflecting the dramatic excitement which pervades many scenes. The opening of the first act is full of animation, the orchestra depicting the tumult which prevails during the struggle between the
  • 71. nobles. Rienzi's brief recitative is a masterpiece of declamatory music, and his call to arms is spirited. It is followed by a trio between Irene, Rienzi, and Adriano, and this in turn by a duet for the two last-named which is full of fire. The finale opens with a double chorus for the populace and the monks in the Lateran, accompanied by the organ. Then there is a broad and energetic appeal to the people from Rienzi, and amid the shouts of the populace and the ringing tones of the trumpets the act closes. The insurrection of the people against the nobles is successful, and Rienzi, in the second act, awaits at the capitol the patricians who are to pledge him their submission. The act opens with a broad and stately march, to which the messengers of peace enter. They sing a graceful chorus. This is followed by a chorus for the senators, and the nobles then tender their submission. There is a terzetto, between Adriano, Colonna, and Orsino, in which the nobles express their contempt for the young patrician. The finale which then begins is highly spectacular. There is a march for the ambassadors, and a grand ballet, historical in character, and supposed to be symbolical of the triumphs of ancient Rome. In the midst of this occurs the assault upon Rienzi. Rienzi's pardon of the nobles is conveyed in a broadly beautiful melody, and this is succeeded by the animated passage heard in the overture. With it are mingled the chants of the monks, the shouts of the people who are opposed to the cardinal and nobles, and the tolling of bells. The third act opens tumultuously. The people have been aroused by fresh outrages on the part of the nobles. Rienzi's emissaries disperse, after a furious chorus, to rouse the populace to vengeance. After they have left, Adriano has his great air, a number which can never fail of effect when sung with all the expression of which it is capable. The rest of the act is a grand accumulation of martial music or noise, whichever one chooses to call it, and includes the stupendous battle hymn, which is accompanied by the clashing of sword and shields, the ringing of bells, and all the tumult incidental to a riot. After Adriano has pleaded in vain with Rienzi for the
  • 72. nobles, and the various bands of armed citizens have dispersed, there is a duet between Adriano and Irene, in which Adriano takes farewell of her. The victorious populace appears and the act closes with their triumphant shouts. The fourth act is brief, and beyond the description given in the synopsis of the plot, requires no further comment. The fifth act opens with the beautiful prayer of Rienzi, already familiar from the overture. There is a tender duet between Rienzi and Irene, an impassioned aria for Rienzi, a duet for Irene and Adriano, and then the finale, which is chiefly choral. DER FLIEGENDE HOLLÄNDER THE FLYING DUTCHMAN Opera in three acts, words and music by Richard Wagner. Produced, Royal Opera, Dresden, January 2, 1843. London, July 23, 1870, as "L'Olandese Dannato"; October 3, 1876, by Carl Rosa, in English. New York, Academy of Music, January 26, 1877, in English, with Clara Louise Kellogg; March 12, 1877, in German; in the spring of 1883, in Italian, with Albani, Galassi, and Ravelli. Characters Daland, a Norwegian sea captain Bass Senta, his daughter Soprano Eric, a huntsman Tenor Mary, Senta's nurse Contralto Daland's Steersman Tenor The Dutchman Baritone Sailors, Maidens, Hunters, etc.
  • 73. Time—Eighteenth Century. Place—A Norwegian Fishing Village. From "Rienzi" Wagner took a great stride to "The Flying Dutchman." This is the first milestone on the road from opera to music-drama. Of his "Rienzi" the composer was in after years ashamed, writing to Liszt: "I, as an artist and man, have not the heart for the reconstruction of that, to my taste, superannuated work, which in consequence of its immoderate dimensions, I have had to remodel more than once. I have no longer the heart for it, and desire from all my soul to do something new instead." He spoke of it as a youthful error, but in "The Flying Dutchman" there is little, if anything, which could have troubled his artistic conscience. One can hardly imagine the legend more effective dramatically and musically than it is in Wagner's libretto and score. It is a work of wild and sombre beauty, relieved only occasionally by touches of light and grace, and has all the interest attaching to a work in which for the first time a genius feels himself conscious of his greatness. If it is not as impressive as "Tannhäuser" or "Lohengrin," nor as stupendous as the music-dramas, that is because the subject of the work is lighter. As his genius developed, his choice of subjects and his treatment of them passed through as complete an evolution as his musical theory, so that when he finally abandoned the operatic form and adopted his system of leading motives, he conceived, for the dramatic bases of his scores, dramas which it would be difficult to fancy set to any other music than that which is so characteristic in his music-dramas. Wagner's present libretto is based upon the weirdly picturesque legend of "The Flying Dutchman"—the Wandering Jew of the ocean. A Dutch sea captain, who, we are told, tried to double the Cape of Good Hope in the teeth of a furious gale, swore that he would accomplish his purpose even if he kept on sailing forever. The devil, hearing the oath, condemned the captain to sail the sea until Judgment Day, without hope of release, unless he should find a
  • 74. woman who would love him faithfully unto death. Once in every seven years he is allowed to go ashore in search of a woman who will redeem him through her faithful love. The opera opens just as a term of seven years has elapsed. The Dutchman's ship comes to anchor in a bay of the coast of Norway, in which the ship of Daland, a Norwegian sea captain, has sought shelter from the storm. Daland's home is not far from the bay, and the Dutchman, learning he has a daughter, asks permission to woo her, offering him in return all his treasures. Daland readily consents. His daughter, Senta, is a romantic maiden upon whom the legend of "The Flying Dutchman" has made a deep impression. As Daland ushers the Dutchman into his home Senta is gazing dreamily upon a picture representing the unhappy hero of the legend. The resemblance of the stranger to the face in this picture is so striking that the emotional girl is at once attracted to him, and pledges him her faith, deeming it her mission to save him. Later on, Eric, a young huntsman, who is in love with her, pleads his cause with her, and the Dutchman, overhearing them, and thinking himself again forsaken, rushes off to his vessel. Senta cries out that she is faithful to him, but is held back by Eric, Daland, and her friends. The Dutchman, who really loves Senta, then proclaims who he is, thinking to terrify her, and at once puts to sea. But she, undismayed by his words, and truly faithful unto death, breaks away from those who are holding her, and rushing to the edge of a cliff casts herself into the ocean, with her arms outstretched toward him. The phantom ship sinks, the sea rises high and falls back into a seething whirlpool. In the sunset glow the forms of Senta and the Dutchman are seen rising in each other's embrace from the sea and floating upward. In "The Flying Dutchman" Wagner employs several leading motives, not, indeed, with the skill which he displays in his music-dramas, but with considerably greater freedom of treatment than in "Rienzi." There we had but one leading motive, which never varied in form. The overture, which may be said to be an eloquent and beautiful musical narrative of the whole opera, contains all these leading
  • 75. motives. It opens with a stormy passage, out of which there bursts the strong but sombre Motive of the Flying Dutchman himself, the dark hero of the legend. The orchestra fairly seethes and rages like the sea roaring under the lash of a terrific storm. And through all this furious orchestration there is heard again and again the motive of the Dutchman, as if his figure could be seen amid all the gloom and fury of the elements. There he stands, hoping for death, yet indestructible. As the excited music gradually dies away, there is heard a calm, somewhat undulating phrase which occurs in the opera when the Dutchman's vessel puts into the quiet Norwegian harbour. Then, also, there occurs again the motive of the Dutchman, but this time played softly, as if the storm-driven wretch had at last found a moment's peace. We at once recognize to whom it is due that he has found this moment of repose, for we hear like prophetic measures the strains of the beautiful ballad which is sung by Senta in the second act of the opera, in which she relates the legend of "The Flying Dutchman" and tells of his unhappy fate. She is the one whom he is to meet when he goes ashore. The entire ballad is not heard at this point, only the opening of the second part, which may be taken as indicating in this overture the simplicity and beauty of Senta's character. In fact, it would not be too much to call this opening phrase the Senta Motive. It is followed by the phrase which indicates the coming to anchor of the Dutchman's vessel; then we hear the Motive of the Dutchman himself, dying away with the faintest possible effect. With sudden energy the orchestra dashes into the surging ocean music, introducing this time the wild, pathetic plaint sung by the Dutchman in the first act of the opera. Again we hear his motive, and again the music seems to represent the surging, swirling ocean when aroused by a furious tempest. Even when we hear the measures of the sailors' chorus the orchestra continues its furious pace, making it appear as if the sailors were shouting above the storm.
  • 76. Characteristic in this overture, and also throughout the opera, especially in Senta's ballad, is what may be called the Ocean Motive, which most graphically depicts the wild and terrible aspect of the ocean during a storm. It is varied from time to time, but never loses its characteristic force and weirdness. The overture ends with an impassioned burst of melody based upon a portion of the concluding phrases of Senta's ballad; phrases which we hear once more at the end of the opera when she sacrifices herself in order to save her lover. A wild and stormy scene is disclosed when the curtain rises upon the first act. The sea occupies the greater part of the scene, and stretches itself out far toward the horizon. A storm is raging. Daland's ship has sought shelter in a little cove formed by the cliffs. Sailors are employed in furling sails and coiling ropes. Daland is standing on a rock, looking about him to discover in what place they are. The orchestra, chiefly with the wild ocean music heard in the overture, depicts the raging of the storm, and above it are heard the shouts of the sailors at work: "Ho-jo-he! Hal-lo-jo!" Daland discovers that they have missed their port by seven miles on account of the storm, and deplores his bad luck that when so near his home and his beloved child, he should have been driven out of his course. As the storm seems to be abating the sailors descend into the hold and Daland goes down into the cabin to rest, leaving his steersman in charge of the deck. The steersman walks the deck once or twice and then sits down near the rudder, yawning, and then rousing himself as if sleep were coming over him. As if to force himself to remain awake he intones a sailor song, an exquisite little melody, with a dash of the sea in its undulating measures. He intones the second verse, but sleep overcomes him and the phrases become more and more detached, until at last he falls asleep. The storm begins to rage again and it grows darker. Suddenly the ship of the Flying Dutchman, with blood-red sails and black mast, looms up in the distance. She glides over the waves as if she did not feel the storm at all, and quickly enters the harbour over against the
  • 77. 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