Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to...

50
Effective Scala J. Suereth

Transcript of Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to...

Page 1: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Effective ScalaJ. Suereth

Page 2: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

● Software Engineer● Blogger● Author● Big Nerd

Who am I?

Page 3: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

● Software Engineer● Blogger● Author● Big Nerd● Unicorn Expert (Klout)

Who am I?

Page 4: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds.

What is Effective Scala?

Page 5: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Write expressions, not statements

The Basics

Page 6: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

def errMsg(errorCode: Int): String = { var result: String = _ errorCode match { case 1 => result = "Network Failure" case 2 => result = "I/O Failure" case _ => result = "Unknown Error" } return result;}

Statements

Page 7: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

def errMsg(errorCode: Int): String = { var result: String = _ errorCode match { case 1 => result = "Network Failure" case 2 => result = "I/O Failure" case _ => result = "Unknown Error" } return result;}

Statements

Page 8: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

def errMsg(errorCode: Int): String = errorCode match { case 1 => "Network Failure" case 2 => "I/O Failure" case _ => "Unknown Error" }

Expression!

Page 9: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Be expressivedef findPeopleIn(city: String, people: Seq[People]): Set[People] = val found = new mutable.HashSet[People] for(person <- people) { for(address <- person.addresses) { if(address.city == city) found.put(person) } } return found}

Page 10: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Be expressivedef findPeopleIn(city: String, people: Seq[People]): Set[People] = val found = new mutable.HashSet[People] for(person <- people) { for(address <- person.addresses) { if(address.city == city) found.put(person) } } return found}

Page 11: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Be Expressivedef findPeopleIn(city: String, people: Seq[People]): Set[People] = for { person <- people.toSet[People] address <- person.addresses if address.city == city } yield person

Page 12: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Use the REPL

The Basics

Page 13: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Stay Immutable

The Basics

Page 14: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

● Safe to share across threads○ No locking

● Safe to hash on attributes● Easier equality● Safe to share internal state with other

objects● Co/Contra-variance

Immutability

Page 15: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Doesn't mean lack of mutation. def foo: Seq[A] = { val a = new ArrayBuffer[Int] fillArray(a) a.toSeq}

Using Immutability

Page 16: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Use Option

The Basics

Page 17: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Optiondef authenticateSession( session: HttpSession, username: Option[String], password: Option[Array[Char]]) = for { u <- username p <- password if canAuthenticate(u, p) privileges <- privilegesFor.get(u) } injectPrivs(session, privileges)

Page 18: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Optiondef authenticateSession( session: HttpSession, username: Option[String], password: Option[Array[Char]]) = for { u <- username p <- password if canAuthenticate(u, p) privileges <- privilegesFor.get(u) } injectPrivs(session, privileges)

NPE NOT 4 ME

Page 19: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

You know it when you got it

Scala ain't JavaScala ain't Ruby

Scala ain't Haskell

Style

Page 20: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Use def for abstract members

Object Orientation

Page 21: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

abstract defstrait Foo { def bar: String} class NewFoo extends Foo { override val bar = "ZOMG"}

Page 22: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Annotate non-trivial return types for public methods.

OO

Page 23: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Annotate Return Typesobject Foo { def name: Option[String] = ...}

Page 24: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Composition can use Inheritance

OO

Page 25: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

trait Logger { ... }trait HasLogger { def logger: Logger }trait HasAwesomeLogger { lazy val logger = new AwesomeLogger}

Composition + Inheritance

Page 26: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Limit the scope of implicits

Implicits

Page 27: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

What are implicits?implicit val pool: Executor = Executors.newCachedThreadPool() def determinant(m: Matrix)(implicit ctx: Executor): Double = ...

determinant(m)vs.

determinant(m)(pool)

Page 28: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

● First look in current scope○ Implicits defined in current scope (1)○ Explicit imports (2)○ wildcard imports (3)

● Parts of the type of implicit value being looked up and their companion objects○ Companion objects of the type○ Companion objects of type arguments of types○ Outer objects for nested types○ Other dimensions

Implicit Scope

Page 29: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Implicit Scope (Parts)trait Logger { ... }object Logger { implicit object DefaultLogger extends Logger { ... } def log(msg: String)(implicit l: Logger) = l.log(msg)} Logger.log("Foo")

Page 30: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Avoid implicit views

Implicits

Page 31: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Use for type constraints and type traits

Implicits

Page 32: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

import java.nio.ByteBuffer class Buffer[T] { def toJByteBuffer( implicit ev: T <:< Byte): ByteBuffer}

Implicit type constraints

Page 33: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

trait Encodable[T] { def encode(t: T): Array[Byte] def decode(buf: ByteBuffer): T} object Encodable { def encode[T: Encodable](t: T) = implicitly[Encodable[T]].encode(t)}

Type traits

Page 34: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

object Encodable { implicit object IntEncodable extends Encodable[Int] { ... } implicit def tupleEncodable[A,B]( implicit ea: Encodable[A], eb: Encodable[B] ): Encodable[(A,B)] = ... }

Type traits, default implementation

Page 35: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

trait TehAwesome { /* ucanthandlethis */ } object TehAwesome { implicit object encoder extends Encodable[TehAwesome] { ... }}

Type Traits - external impls

Page 36: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

● External to class hierarchy○ monkey patch on existing classes you don't control

● Overridable at call site● Separate Abstractions

○ One class can have two implementations○ Similar type-traits don't fight for method names.

● Can separate method arguments into rolesdef synchronize[ F: Source, T: Sink]( from: F, to: T): (F,T) = ...

Type traits - Benefits

Page 37: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Preserve specific types

Type System

Page 38: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

def foo(s: Seq[A]): Seq[A] = ?

vs. def foo[T <: Seq[A]](s: T): T = ?

Preserve Specific Types

Page 39: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Know your collections

Collections

Page 40: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Know your collections

Page 41: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

seq, companion, seq, flatten, transpose, toString, isEmpty, map, exists, find, init, last, head, filter, slice, tail, ++, ++, headOption, drop, filterNot, flatMap, takeWhile, repr, newBuilder, forall, foreach, thisCollection, toCollection, parCombiner, view, view, copyToArray, hasDefiniteSize, ++:, ++:, collect, partition, groupBy, scan, scanLeft, scanRight, lastOption, sliceWithKnownDelta, sliceWithKnownBound, tails, inits, toTraversable, toIterator, withFilter, take, splitAt, dropWhile, span, stringPrefix, toStream, min, max, count, size, toArray, seq, sum, toList, mkString, mkString, mkString, toSet, foldLeft, foldRight, reduceLeft, reduceRight, toSeq, toIterable, copyToArray, copyToArray, reversed, nonEmpty, collectFirst, /:, :\, reduceLeftOption, reduceRightOption, reduce, reduceOption, fold, aggregate, product, maxBy, minBy, copyToBuffer, toIndexedSeq, toBuffer, toMap, addString, addString, addString, toSet, toSeq, toIterable, toTraversable, isTraversableAgain, toMap, /:\, size, groupBy, isTraversableAgain, min, max, count, toArray, seq, sum, toList, mkString, mkString, mkString, foldLeft, foldRight, reduceRight, copyToArray, copyToArray, nonEmpty, /:, :\, reduceLeftOption, reduceRightOption, reduce, reduceOption, fold, aggregate, product, maxBy, minBy, toIndexedSeq, toBuffer, seq, par, map, head, filter, slice, tail, ++, drop, filterNot, flatMap, takeWhile, repr, foreach, collect, partition, scan, scanLeft, scanRight, take, splitAt, dropWhile, span, stringPrefix, isEmpty, exists, find, forall, copyToArray, hasDefiniteSize, toIterator, toStream, parCombiner, size, foreach, isEmpty, head, flatten, newBuilder, foreach, transpose, genericBuilder, unzip, unzip3, isEmpty, exists, find, forall, foreach, copyToArray, hasDefiniteSize, toTraversable, isEmpty, iterator, zip, head, sameElements, zipAll, zipWithIndex, seq, isEmpty, first, iterator, exists, find, zip, zip, elements, head, slice, drop, takeWhile, forall, foreach, canEqual, sameElements, sameElements, foldRight, reduceRight, dropRight, thisCollection, toCollection, view, view, projection, toIterable, grouped, sliding, sliding, copyToArray, zipAll, zipAll, zipWithIndex, firstOption, take, takeRight, toStream, equals

Know your collection API

Page 42: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Use Vector

Collections

Page 43: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Write interfaces in Java

Java Integration

Page 44: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Prefer Java primitives in APIs

Java Integration

Page 45: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Using primitive APIspublic interface Main { public int run(String[] args);}

class ScalaMain extends Main { def run(args: Array[String]): Int = args.length}

Page 46: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Learn patterns from category thoery

Functional Programming

Page 47: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Applicative Functorsdef connection( url: Option[String], username: Option[String], password: Option[Array[Char]] ): Option[Connection] = (url |@| username |@| password) apply DriverManager.getConnection

Page 48: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Applicative Functorsurl: Option[String] user: Option[String] pw: Option[String]

getConnection

Option[Connection]

PARALLEL JOIN

Page 49: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Monadsfor { input <- managed(new FileInput("in")) output <- managed(new FileOutput("out"))} yield pipe(input) into output

Page 50: Effective Scala - Philly Emerging Tech · Optimising your use of the Scala programming language to solve real world problems without explosions, broken thumbs or bullet wounds. What

Questions? www.manning.com/suereth