professional scala · 2017-11-22 · advanced usage 52 advanced dependencies 53 testing in the...

25

Upload: others

Post on 22-May-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager
Page 2: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager
Page 3: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

ffi rs.indd 05/12/2016 Page i

PROFESSIONAL SCALA

INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv

CHAPTER 1 Language Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

CHAPTER 2 Functional Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

CHAPTER 3 Java Compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

CHAPTER 4 Simple Build Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

CHAPTER 5 Maven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

CHAPTER 6 Scala Style/Lint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

CHAPTER 7 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

CHAPTER 8 Documenting Your Code with Scaladoc . . . . . . . . . . . . . . . . . . . . . . 95

CHAPTER 9 Type System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

CHAPTER 10 Advanced Functional Programming . . . . . . . . . . . . . . . . . . . . . . . . 165

CHAPTER 11 Concurrency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179

CHAPTER 12 Scala.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205

INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

Page 4: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager
Page 5: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

ffi rs.indd 05/12/2016 Page iii

PROFESSIONAL

Scala

Aliaksandr BedrytskiJanek Bogucki

Alessandro LacavaMatthew de Detrich

Benjamin Neil

Page 6: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

ffi rs.indd 05/12/2016 Page iv

Professional Scala

Published byJohn Wiley & Sons, Inc.10475 Crosspoint BoulevardIndianapolis, IN 46256www.wiley.com

Copyright © 2016 by John Wiley & Sons, Inc., Indianapolis, Indiana

Published by John Wiley & Sons, Inc., Indianapolis, Indiana

Published simultaneously in Canada

ISBN: 978-1-119-26722-5ISBN: 978-1-119-26725-6 (ebk)ISBN: 978-1-119-26726-3 (ebk)

Manufactured in the United States of America

10 9 8 7 6 5 4 3 2 1

No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, scanning or otherwise, except as permitted under Sections 107 or 108 of the 1976 United States Copyright Act, without either the prior written permission of the Publisher, or authorization through payment of the appropriate per-copy fee to the Copyright Clearance Center, 222 Rosewood Drive, Danvers, MA 01923, (978) 750-8400, fax (978) 646-8600. Requests to the Publisher for permission should be addressed to the Permissions Department, John Wiley & Sons, Inc., 111 River Street, Hoboken, NJ 07030, (201) 748-6011, fax (201) 748-6008, or online at http://www.wiley.com/go/permissions.

Limit of Liability/Disclaimer of Warranty: The publisher and the author make no representations or warranties with respect to the accuracy or completeness of the contents of this work and specifi cally disclaim all warranties, including without limitation warranties of fi tness for a particular purpose. No warranty may be created or extended by sales or promotional materials. The advice and strategies contained herein may not be suitable for every situation. This work is sold with the understanding that the publisher is not engaged in rendering legal, accounting, or other professional ser-vices. If professional assistance is required, the services of a competent professional person should be sought. Neither the publisher nor the author shall be liable for damages arising herefrom. The fact that an organization or Web site is referred to in this work as a citation and/or a potential source of further information does not mean that the author or the pub-lisher endorses the information the organization or Web site may provide or recommendations it may make. Further, read-ers should be aware that Internet Web sites listed in this work may have changed or disappeared between when this work was written and when it is read.

For general information on our other products and services please contact our Customer Care Department within the United States at (877) 762-2974, outside the United States at (317) 572-3993 or fax (317) 572-4002.

Wiley publishes in a variety of print and electronic formats and by print-on-demand. Some material included with stan-dard print versions of this book may not be included in e-books or in print-on-demand. If this book refers to media such as a CD or DVD that is not included in the version you purchased, you may download this material at http://book-support.wiley.com. For more information about Wiley products, visit www.wiley.com.

Library of Congress Control Number: 2016937234

Trademarks: Wiley, the Wiley logo, Wrox, the Wrox logo, Programmer to Programmer, and related trade dress are trade-marks or registered trademarks of John Wiley & Sons, Inc. and/or its affi liates, in the United States and other countries, and may not be used without written permission. All other trademarks are the property of their respective owners. John Wiley & Sons, Inc., is not associated with any product or vendor mentioned in this book.

Page 7: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

ffi rs.indd 05/12/2016 Page v

ABOUT THE AUTHORS

ALIAKSANDR BEDRYTSKI is a passionate software engineer at Worldline Lyon, France. Even though it’s been more than four years since he discovered Scala, he’s still in love with the language and is trying to push its boundaries every day. In his spare time he’s learning something new about space, physics, and bleeding edge technologies. He is currently working as a lead developer on a data-analysis project featuring Hadoop, Spark-Scala, Hive, and other Big Data tools. 

JANEK BOGUCKI is a co-founder at Inferess Inc. and principal consultant (Machine Learning and Scala) at Combination One. He has a background in mathematics with an ongoing interest in com-puter science, data science, machine learning, graph theory, and development methodologies. He lives in Kent, UK with his wife Rebecca, son Theo, two cats, one dog, and a variable number of chickens.

ALESSANDRO LACAVA holds a degree in telecommunications engineering. He’s had extensive experience with OOP before becoming very passionate about functional programming. He is cur-rently working as a lead designer and developer on different types of applications using mainly, but not only, Scala. He’s also a contributor of pretty famous open source projects, such as shape-less and cats.

MATTHEW DE DETRICH is a tech lead for Monetise Pty Ltd, where he primarily works on full stack applications with backends written in Scala. Matthew has a passion for designing, building, and integrating complex multi-domain systems from the ground up. In his spare time he is exploring new developments in the Scala space, such as Scala.js.

BENJAMIN NEIL is a full stack engineer at AppThis LLC. He is a polyglot engineer who has had the privilege of working the past eight years making websites, services, and tools for amazing compa-nies. He is obsessed with Scala, Vim, DevOps, and making services scale smoothly.

Page 8: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

ffi rs.indd 05/12/2016 Page vi

ABOUT THE TECHNICAL EDITORS

JACOB PARK is a Scala and Typesafe enthusiast; he embraces Akka, Play, and Spark, all with Scala, to solve various problems regarding distributed systems with additional technologies such as Cassandra and Kafka. As a believer in open-source software, he contributes to various projects on GitHub related to Akka and Cassandra: https://github.com/jparkie. When he’s not working, Jacob can be found at various Scala and Typesafe conferences and meetups, either as an attendee or a presenter.

ARIEL SCARPINELLI is a senior Java developer at VirtualMind and is a passionate developer with more than 15 years of professional experience. He currently leads four agile teams for a U.S.-based enterprise SaaS company. He has experience in a lot of languages but is currently focused on Java and JavaScript with some PHP and Python.

RADU GANCEA is a software engineer and consultant at Eloquentix with a Java background (also C/C++). He is involved in projects in the energy and advertising sectors. His current focus is on Scala and other JVM languages and frameworks.

Page 9: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

ffi rs.indd 05/12/2016 Page vii

PROJECT EDITORCharlotte Kughen

TECHNICAL EDITORSJacob ParkAriel ScarpinelliRadu Gancea

PRODUCTION EDITORBarath Kumar Rajasekaran

COPY EDITORTroy Mott

MANAGER OF CONTENT DEVELOPMENT AND ASSEMBLYMary Beth Wakefi eld

PRODUCTION MANAGERKathleen Wisor

MARKETING MANAGERDavid Mayhew

PROFESSIONAL TECHNOLOGY & STRATEGY DIRECTORBarry Pruett

BUSINESS MANAGERAmy Knies

EXECUTIVE EDITORJim Minatel

PROJECT COORDINATOR, COVERBrent Savage

PROOFREADERNancy Bell

INDEXERNancy Guenther

COVER DESIGNERWiley

COVER IMAGE©Sergey Nivens/Shutterstock

CREDITS

Page 10: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager
Page 11: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

ftoc.indd 05/11/2016 Page ix

CONTENTS

INTRODUCTION xv

CHAPTER 1: LANGUAGE FEATURES 1

Static Types and Type Inference 2Implicit Parameters, Conversions, and Their Resolution 3Case Class, Tuples, and Case Object 5Abstract Class, Traits, and Sealed 6

Pattern Matching 8Statements Are Expressions 9String Interpolation 9Scala Collections, immutable and mutable 10For Comprehension 12

Packages, Companion Objects, Package Objects, and Scoping 13

AnyVal, AnyRef, Any, and the Type Hierarchy 16Summary 17

CHAPTER 2: FUNCTIONAL PROGRAMMING 19

Immutability 20Pure Functions 22Recursion 23Higher-Order Functions 26Core Collection Methods 27

Methods Returning a Collection 29Methods Returning a Value 31

Currying and Partially Applied Functions 32Null Handling (Option) 34Strict versus Non-Strict Initialization 35Summary 36

CHAPTER 3: JAVA COMPATIBILITY 37

Scala and Java Collections 37Interfaces and Traits 40Scala/Java Enumerations 42Summary 43

Page 12: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

x

CONTENTS

ftoc.indd 05/11/2016 Page x

CHAPTER 4: SIMPLE BUILD TOOL 45

Basic Usage 46Project Structure 47Single Project 47Scopes 49Custom Tasks 50Dependencies 50Resolvers 51

Advanced Usage 52Advanced Dependencies 53Testing in the Console 55

Release Management 56Deploying to Sonatype 56Packaging with SBT-Native-Packager 58Creating a Docker Image 59Common SBT Commands 60Useful Plugins 61

Summary 62

CHAPTER 5: MAVEN 63

Getting Started with Maven and Scala 64Introducing scala-maven-plugin 67Adding Library Dependencies 70Using the REPL 71Getting Help 72Running Tests 72Joint Compilation with Java 74Accelerating Compilation with Zinc 76Summary 77

CHAPTER 6: SCALA STYLE/LINT 79

Scala with Style 79Scaliform 81Scapegoat 82WartRemover 82Scoverage 84Summary 84

Page 13: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

xi

CONTENTS

ftoc.indd 05/11/2016 Page xi

CHAPTER 7: TESTING 85

ScalaTest 86Unit Tests 87Integration Testing 87

Data-Driven Tests 88Performance Testing 89Acceptance Testing 90Mocks 92

Load Testing 93Summary 94

CHAPTER 8: DOCUMENTING YOUR CODE WITH SCALADOC 95

Why Document Your Code? 96Revealing the Benefi ts 96Bookending the Continuum 96Choosing What to Document 96

Scaladoc Structure 97Overall Layout 97Index Pane 98Content Pane 100

Invoking the Scaladoc Tool 106Wiki Syntax 108

Formatting with Inline Wiki Syntax 108Structuring with Block Elements 110Linking 113Locating Scaladoc 117

Tagging 117Everyday Tagging 117Tagging for Groups 123Advanced Tagging 125

Invoking scaladoc: Additional Options 132Integrating Scaladoc Creation with Your Project 133

Confi guring Maven 133Confi guring SBT 134

Publishing Scaladoc 134Tables and CSS 136Summary 138

Page 14: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

xii

CONTENTS

ftoc.indd 05/11/2016 Page xii

CHAPTER 9: TYPE SYSTEM 139

What Is a Type System? 140Static versus Dynamic Typing 140What Static Type Systems Are Good For 141What Dynamic Type Systems Are Good For 141

Scala’s Unifi ed Type System 141Value Classes 143

Polymorphism 145Subtype Polymorphism 145Parametric Polymorphism 146Ad Hoc Polymorphism 146

Bounds 149Context Bounds 149Upper and Lower Bounds 150Variance 151

Other Niceties 155Self-Type Annotations 155Self-Recursive Types 158Abstract Type Members 159Dynamic Programming 161Structural Types 161Dynamic Trait 162

Summary 164

CHAPTER 10: ADVANCED FUNCTIONAL PROGRAMMING 165

Higher-Kinded Types 165Functional Design Patterns 167

Functor 167Applicative Functor 170Monad 172Semigroup 173Monoid 174

Summary 176

CHAPTER 11: CONCURRENCY 179

Synchronize/Atomic Variables 181Future Composition 184Parallel Collections 187Reactive Streams 192STM 195

Page 15: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

xiii

CONTENTS

ftoc.indd 05/11/2016 Page xiii

Actors (Akka) 198Spark 200Summary 202

CHAPTER 12: SCALA.JS 205

Scala.js and Its Design 205Getting Started: Scala.js with SBT 206Scala.js Peculiarities 210Webjars and Dealing with the Frontend Ecosytem 211Summary 213

INDEX 215

Page 16: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

fl ast.indd 05/10/2016 Page xiv

Page 17: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

fl ast.indd 05/10/2016 Page xv

INTRODUCTION

A working knowledge of Scala puts you in demand. As both the language and applications expand, so do the opportunities for experienced Scala programmers—and many positions are going unfi lled. Major enterprises across industries are using Scala every day, in a number of different applications and capacities. Professional Scala helps you update your skills quickly to start advancing your career.

Scala bridges the gap between functional and object-oriented programming, and this book details that link with a clear discussion of both Java compatibility and the read-eval-print loop used in declarative programming. You’ll learn the details of Scala testing, design patterns, concurrency, and much more as you build the in-demand skill set required to utilize Scala in a real-world production environment.

WHO THIS BOOK IS FOR

This book is for experienced programmers who already have some understanding of the Scala language and are looking for more depth. You should have a basic working knowledge of the lan-guage because this book skips over the fundamentals of programming, and the discussion launches directly into practical Scala topics.

WHAT THIS BOOK COVERS

This book explains everything professional programmers need to start using Scala quickly and effectively.

➤ Link functional and object-oriented programming.

➤ Master syntax, the SBT interactive build tool, and the REPL workfl ow.

➤ Explore functional design patterns, the type system, concurrency, and testing.

➤ Work effectively with Maven, Scala.js, and more.

HOW THIS BOOK IS STRUCTURED

This book was written in three parts. The fi rst part of the book discusses language structure includ-ing syntax, practical functional programming, and Java compatibility.

The second part of the book takes the reader through tooling, including discussions of SBT, Maven, lint tools, testing, and Scaladoc. The last portion of the book continues to examine Scala through advanced topics such as polymorphism, dynamic programming, concurrency, Scala.js, and more.

Page 18: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

xvi

INTRODUCTION

fl ast.indd 05/10/2016 Page xvi

WHAT YOU NEED TO USE THIS BOOK

For this book, we have used Scala version 2.11.7. The source code for the samples is available for download from the Wrox website at www.wrox.com/go/professionalscala or from GitHub at https://github.com/backstopmedia/scalabook.

CONVENTIONS

To help you get the most from the text and keep track of what’s happening, we’ve used a number of conventions throughout the book.

NOTE Notes indicate notes, tips, hints, tricks, and/or asides to the current discussion.

As for styles in the text:

➤ We highlight new terms and important words when we introduce them.

➤ We show code within the text like so: persistence.properties.

➤ We show all code snippets in the book using this style:

FileSystem fs = FileSystem.get(URI.create(uri), conf); InputStream in = null; try {

➤ We show URLs in text like this:

http://<Slave Hostname>:50075

SOURCE CODE

As you work through the examples in this book, you may choose either to type in all the code man-ually, or to use the source code fi les that accompany the book. All the source code used in this book is available for download at www.wrox.com. Specifi cally for this book, the code download is on the Download Code tab at:

www.wrox.com/go/professionalscala

You can also search for the book at www.wrox.com by ISBN (the ISBN for this book is 9781119267225 to fi nd the code. And a complete list of code downloads for all current Wrox books is available at www.wrox.com/dynamic/books/download.aspx.

Page 19: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

xvii

INTRODUCTION

fl ast.indd 05/10/2016 Page xvii

NOTE Because many books have similar titles, you may fi nd it easiest to search by ISBN; this book’s ISBN is 978-1-119-26722-5

Once you download the code, just decompress it with your favorite compression tool. Alternatively, you can go to the main Wrox code download page at www.wrox.com/dynamic/books/download.aspx to see the code available for this book and all other Wrox books.

ERRATA

We make every effort to ensure that there are no errors in the text or in the code. However, no one is perfect, and mistakes do occur. If you fi nd an error in one of our books, like a spelling mistake or faulty piece of code, we would be very grateful for your feedback. By sending in errata, you may save another reader hours of frustration, and at the same time, you will be helping us provide even higher quality information.

To fi nd the errata page for this book, go to

www.wrox.com/go/professionalscala

and click the Errata link. On this page you can view all errata that has been submitted for this book and posted by Wrox editors.

If you don’t spot “your” error on the Book Errata page, go to www.wrox.com/contact/techsupport.shtml and complete the form there to send us the error you have found. We’ll check the information and, if appropriate, post a message to the book’s errata page and fi x the problem in subsequent editions of the book.

P2P.WROX.COM

For author and peer discussion, join the P2P forums at http://p2p.wrox.com. The forums are a web-based system for you to post messages relating to Wrox books and related technologies and interact with other readers and technology users. The forums offer a subscription feature to e-mail you topics of interest of your choosing when new posts are made to the forums. Wrox authors, edi-tors, other industry experts, and your fellow readers are present on these forums.

At http://p2p.wrox.com, you will fi nd a number of different forums that will help you, not only as you read this book, but also as you develop your own applications. To join the forums, just follow these steps:

1. Go to http://p2p.wrox.com and click the Register link.

2. Read the terms of use and click Agree.

Page 20: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

xviii

INTRODUCTION

fl ast.indd 05/10/2016 Page xviii

3. Complete the required information to join, as well as any optional information you wish to provide, and click Submit.

4. You will receive an e-mail with information describing how to verify your account and complete the joining process.

NOTE You can read messages in the forums without joining P2P, but in order to post your own messages, you must join.

Once you join, you can post new messages and respond to messages other users post. You can read messages at any time on the web. If you would like to have new messages from a particular forum e-mailed to you, click the Subscribe to This Forum icon by the forum name in the forum listing.

For more information about how to use the Wrox P2P, be sure to read the P2P FAQs for answers to questions about how the forum software works, as well as many common questions specifi c to P2P and Wrox books. To read the FAQs, click the FAQ link on any P2P page.

Page 21: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

c01.indd 05/10/2016 Page 1

Language Features WHAT’S IN THIS CHAPTER?

➤ Outlining various control structures in Scala

➤ Using various tools in the standard library

➤ Mastering inheritance and composition in Scala

Scala borrows many of its syntax and control structures from various other languages. Methods are declared in Algol/C style with the addition of features such as optional braces, and semicolons to reduce code boilerplate.

Scala syntax also has features such as expressions for statements, local type inference, suffi x/infi x notation, and implicit return statements, which make typical idiomatic Scala code look like dynamic languages such as Lisp/Python/Ruby, but with the added benefi t of strong static typing.

The expressive nature of Scala’s syntax is useful to create custom DSL’s, with the most notable example being Scala’s own XML library. Scala also features several forms of inheritance (traits, classes, objects), which can be combined in various ways to structure composition in your code in a more natural and elegant way. This combined with a strong support for func-tional programming, syntactic sugar (for comprehension), and type inference makes it possible to create very terse domain specifi c code that is also type safe.

This chapter provides a broad overview of the various parts of Scala’s design and syntax, as well as the features that are expected in modern generic programming languages (control of scoping, string interpolation, encapsulation, and modules).

1

Page 22: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

2 ❘ CHAPTER 1 LANGUAGE FEATURES

c01.indd 05/10/2016 Page 2

STATIC TYPES AND TYPE INFERENCE

Scala is fi rst and foremost a statically typed language, which is similar to other statically typed languages you can annotate types for:

➤ Variable declarations

➤ Method/function arguments

➤ Method/function return values

➤ Various types of data structures

Below is a code sample to demonstrate these types of annotations:

val s: String // type definition on variable declarationdef doSomething(s: String) // type definition in a parameterdef doSomething: String // type definition for return type of a functionclass SomeClass(s: String) // type definition in a class constructor definitiontype MyString = String // type aliasing

A signifi cant reason why Scala requires mandatory type signatures is that it’s very diffi cult to pro-vide a practical implementation of global type inference in a statically typed language that supports subtyping. Thankfully, while Scala mandates that you provide type signatures for method param-eters and type defi nitions, for variable declarations inside function/method bodies it features local type inference. This drastically reduces the amount of boilerplate code when it comes to function/method bodies. Here is an example of local type inference in action.

def doSomething(input: String) = {val l = List(1,3,5)val summed = l.sumval asString = summed.toString + inputasString.toUpperCase}

As you can see for variable declarations, you don’t need to specify their respective types. To manually specify the types, do the following:

def doSomething(input: String): String = {val l: List[Int] = List(1,3,5)val summed: Int = l.sumval asString: String = summed.toString + inputasString.toUpperCase()}

One bonus of specifying types for function arguments is that they also act as a form of documentation, which is particularly helpful. Return types of functions are also optional; however, it is encouraged to annotate them for documentation/clarity reasons. Due to Scala’s generic code functionality, it is possible to have expressions that return different values in unexpected scenarios. One good example is Int’s versus Double:

def f = 342342.43

def f_v2 = 342342

Page 23: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

Static Types and Type Inference ❘ 3

f == 342342 // returns false

f_v2 == 342342 // return true

Since f and f_v2 don’t have their return types annotated, we aren’t aware of what types they can return (let’s assume you don’t know what the actual values of f and f_v2 are). This means that the f== 342342 expression returns something else compared to f_v2 == 342342. If, however, you know the return types of f and f_v2, you can do the following:

def f: Double = 342342.43

def f_v2: Int = 342342

As a user, you know that the return type of f is a Double, so don’t compare it with an Int when asking for equality ( since it’s a Float by extension you should provide custom equality with a delta).

Manual type signatures can also be used to force the type of a declaration. This is similar to the typecast feature in languages like Java or C; however, it’s more powerful due to type conversionsavailable in Scala. A simple example in Scala is to assign a Long type to an integer literal.

val l: Long = 45458

By default, if you use a number literal in Scala it defaults to an Int. Note that it is also possible to use the number based suffi x like so:

val l = 45458L

Arguably, the type annotation is more idiomatic, especially for custom types that may not have lit-eral operators.

Implicit Parameters, Conversions, and Their ResolutionScala has an incredibly powerful feature called implicits. When you ask for a value implicitly, such as a method parameter, or the implicit keyword you are telling the Scala compiler to look fora value that has the same type in scope. This is unlike the explicit value, where you need a type tospecify when it’s called/used. A practical use case for implicits is providing an API key for a REST web service. The API key is typically only provided once, so an implicit is a good use case in this instance, since you only need to defi ne and import it once.

case class ApiKey(id: String)

Since implicits are found by their type you need to create a new type, in this case ApiKey. Now let’s defi ne a method that makes a HTTP call.

import scala.concurrent.Future

def getUser(userId: Long)(implicit apiKey: ApiKey): Future[Option[User]] = ???

In order to call this function you must make sure that an implicit ApiKey is visible in the scope. Let’sfi rst make an instance of ApiKey and place it in an object.

Page 24: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

4 ❘ CHAPTER 1 LANGUAGE FEATURES

c01.indd 05/10/2016 Page 4

object Config { implicit val apiKey = ApiKey(System.getenv("apiKey"))}

Whenever you call getUser, ApiKey needs to be visible, and the code should look something like this:

import Config._ // This imports everything in Config, including implicits

object Main extends App {val userId = args(0).toLong getUser(userId)}

It’s also possible to supply an implicit argument explicitly.

object Main extends App { val userId = args(0).toLong val apiKey = ApiKey(args(1)) getUser(userId)(apiKey)}

Implicits can be used to make automatic conversions between types; however, such usage is consid-ered advanced and should be done sparingly, because it’s easy to abuse code that uses these features. A prominent use of implicit conversions is in DSLs. For example, if you have a trivial DSL that attempts to represent SQL queries, you might have something like this:

Users.filter(_.firstName is "Bob")

In this case, _.firstName may be a different type from a String (in this example, let’s say it has type Column[String]). And it can only work on types of Column[String]:

val columnStringImplementation = new Column[String] { def is(other: Column[String]): EqualsComparison = ???}

To compare two instances of Column[String] (to see if they are equal) you want an implicit con-version of String to Column[String], so that you don’t have to write:

Users.filter(_.firstName is ColumString("Bob"))

To do this you need to defi ne the following:

implicit def stringToColumnStringConverter(s: String): Column[String] = ???

In this case, when you import your stringToColumnStringConverter, it will automatically con-vert any instances of String to Column[String] if it’s required to do so. Since the is method only works on Column[String], the compiler will try to see if there is an implicit conversion available for the String “BoB,” so it can satisfy the method signature for is.

Implicit classes are a type safe solution that Scala provides for monkey patching (extending an exist-ing class, or in Scala’s case, a type without having to modify the existing source of the type). Let’s try this by adding a replaceSpaceWithUnderScore method to a String.

Page 25: PROFESSIONAL SCALA · 2017-11-22 · Advanced Usage 52 Advanced Dependencies 53 Testing in the Console 55 Release Management 56 Deploying to Sonatype 56 Packaging with SBT-Native-Packager

Static Types and Type Inference ❘ 5

c01.indd 05/10/2016 Page 5

object Implicits { implicit class StringExtensionMethods(string: String) { def replaceSpaceWithUnderScore = string.replaceAll(" ","_") }}

Like the previous example, you need to import this class to make it available:

import Implicits._"test this string".replaceSpaceWithUnderScore // returns test_this_string

Case Class, Tuples, and Case ObjectScala has a feature called case class, which is a fundamental structure to represent an immutable data. A case class contains various helper methods, which provide automatic accessors, and methods such as copy (return new instances of the case class with modifi ed values), as well as implementa-tions of .hashCode and equals.

case class User(id: Int, firstName: String, lastName: String)

User(1,"Bob","Elvin").copy(lastName = "Jane") // returns User(1,"Bob","Jane")

These combined features allow you to compare case classes directly. Case classes also provide a generic .toString method to pretty print the constructor values.

User(1,"Bob","Elvin").toString // returns "User(1,Bob,Elvin)"

Scala also has tuples, which work similarly to Python’s tuples. A nice way to think of tuples is a case class that has its fi elds defi ned positionally (i.e., without its fi eld name), and there is no restriction on a tuple requiring the same type for all of its elements. You can construct tuples by surrounding an expression with an extra set of parenthesis:

val userData = (5,"Maria", "Florence") //This will have type Tuple3 [Int,String,String]

You can then convert between tuples and case classes easily, as long as the types and positions match:

val userData2: Tuple3[Int,String,String] = User.unapply(User(15,"Shelly","Sherbert")).getval constructedUserData: User = User.tupled.apply(userData2) // Will beUser(15,"Shelly","Sherbert").

Tuples are a handy way to store grouped data of multiple types, and they can be destructured using the following notation:

val (id, firstName, lastName) = userData2

Note that tuples also provide an _index (where index is the position) and methods to access the ele-ments of the tuple by position (in the example above, ._2 would return “Shelly”). We recommend that you use the deconstruction mentioned above, since it’s clearer what the fi eld is meant to be.

For internal and local use, tuples can be quite convenient due to not needing to defi ne something like a case class to store data. However, if you fi nd yourself constantly structuring/destructing tuples, and/or if you have methods returning tuples, it’s usually a good idea to use a case class instead.