SlideShare a Scribd company logo
1 of 47
Download to read offline
Effective
Scala
SoftShake 2013, Geneva

Mirco Dotta
twitter: @mircodotta
Golden rule?

imple!
P IT S
KEE
is not because you
It
, that you should
can
What’s this talk about?
mize your use of
Opti
Scala to solve real
world problems
thout explosions,
wi
broken thumbs or
bullet wounds
Agenda
•Style matters
•Mantras
•Collection-foo
•Implicits
Style matters
Learn the Scala way
You know it when you got it
Scala ain’t Java
nor Ruby
nor Haskell
nor <INSERT known PL>

http://docs.scala-lang.org/style/
Abstract members
trait Shape {
val edges: Int
}

Why?

class Triangle extends Shape {
override def edges: Int = 3
}

Because this
doesn’t

compile!
Abstract members
Always use def for abstract
members!
trait Shape {
def edges: Int
}
You’ve to override
trait Worker {
def run(): Unit
}
abstract class MyWorker
extends Worker {
override def run(): Unit =
//...
}
Don’t leak your types!
trait Logger {
def log(m: String): Unit
}
object Logger {
class StdLogger extends Logger {
override def log(m: String): Unit =
println(m)
}
def apply = new StdLogger()
}

What’s the return type here?
Hide your secrets
object SauceFactory {
def makeSecretSauce(): Sauce = {
val ingredients = getMagicIngredients()
val formula = getSecretFormula()
SauceMaker.prepare(ingredients, formula)
}

te! getMagicIngredients():
riva
p def

Ingredients = //...
def getSecretFormula(): Formula = //...
}
Visibility modifiers
• Scala has very expressive visibility
modifiers

•

Access modifiers can be augmented with qualifiers

Did you know that...
public

(default)

package

protected

private

private

nested packages have access
to private classes

•

Companion object/classes
have access to each other
private members!

private[pkg]

protected

•

everything you have in java, and much more
Don’t blow the stack!
IF YOU THINK IT’S
tailrecursive, SAY so!

case class Node(value: Int, edges: List[Node])
def bfs(node: Node, pred: Node => Boolean): Option[Node] = {
@scala.annotation.tailrec
def search(acc: List[Node]): Option[Node] = acc match {
case Nil => None
case x :: xs =>
if (pred(x)) Some(x)
else search(xs ::: xs.edges)
}
search(List(node))
}
String interpolation
case class Complex(real: Int, im: Int) {
override def toString: String =
real + " + " + im + "i"
}

case class Complex(real: Int, im: Int) {
override def toString: String =
s"$real + ${im}i"
}

interpolator!
Mantras

Mantras
Use the REPL
Or the Worksheet ;-)
Write Expressions,
not Statements
Expressions!
• shorter
• simpler
• Composable!
def home(): HttpPage = {
var page: HttpPage = null
try page = prepareHttpPage()
catch {
case _: TimeoutEx => page = TimeoutPage
case _: Exception => page = NoPage
}
return page
}

def home(): HttpPage =
try prepareHttpPage()
catch {
case _: TimeoutEx => TimeoutPage
case _: Exception => NoPage
}
Expressions compose!
def home(): HttpPage =
try prepareHttpPage()
catch {
case _: TimeoutEx => TimeoutPage
case _: Exception => NoPage
}

Try..catch is
an expression

This is a PartialFunction[Throwable,HttpPage]

def timeoutCatch = {
case _: TimeoutEx => TimeoutPage
}
def noPageCatch = {
case _: Exception => NoPage
}

def home(): HttpPage =
try prepareHttpPage()
catch timeoutCatch orElse
noPageCatch

mp
co

e!
os
Don’t use null
null is a disease
• nullcheks will spread
• code is brittle
• NPE will still happen
• assertions won’t help
Forget null, use Option
• no more “it may be null”
• type-safe
• documentation
def authenticate(session: HttpSession,
username: Option[String],
password: Option[String]) =
for {
user <- username
pass <- password
if canAuthenticate(user,pass)
privileges <- privilegesFor(user)
} yield inject(session, privileges)
But don’t overuse Option
sometime a null-object can be
a much better fit
def home(): HttpPage =
try prepareHttpPage()
catch {
case _: TimeoutEx => TimeoutPage
case _: Exception => NoPage
}

Null Object!
Stay immutable
Immutability
3 reasons why it matters?

• Simplifies reasoning
• simplifies reasoning
• simplifies reasoning
Immutability
Allows co/contra variance
ity
bil
uta ce
m
ian --var ---+
------- bles
rou
T

Jav
a

String[] a = {""};
Object[] b = a;
b[0] = 1;
String value = a[0];
rrayStoreException
java.lang.A
Immutability
• correct equals & hashcode!
• it also simplifies reasoning
about concurrency

• thread-safe by design
Immutability
• Mutability is still ok, but
keep it in local scopes

• api methods should return
immutable objects
Do you want faster Scala compilation?

program to an interface, not
an implementation.
Collection-foo

Collection-foo
http://www.scala-lang.org/docu/files/collections-api/collections.html
Learn the API
!=, ##, ++, ++:, +:, /:, /:, :+, ::, :::, :, <init>, ==, addString, aggregate,
andThen, apply, applyOrElse, asInstanceOf, canEqual, collect, collectFirst,
combinations, companion, compose, contains, containsSlice, copyToArray,
copyToBuffer, corresponds, count, diff, distinct, drop, dropRight, dropWhile,
endsWith, eq, equals, exists, filter, filterNot, find, flatMap, flatten, fold,
foldLeft, foldRight, forall, foreach, genericBuilder, getClass, groupBy, grouped,
hasDefiniteSize, hashCode, head, headOption, indexOf, indexOfSlice, indexWhere,
indices, init, inits, intersect, isDefinedAt, isEmpty, isInstanceOf,
isTraversableAgain, iterator, last, lastIndexOf, lastIndexOfSlice, lastIndexWhere,
lastOption, length, lengthCompare, lift, map, mapConserve, max, maxBy, min, minBy,
mkString, ne, nonEmpty, notify, notifyAll, orElse, padTo, par, partition, patch,
permutations, prefixLength, product, productArity, productElement, productIterator,
productPrefix, reduce, reduceLeft, reduceLeftOption, reduceOption, reduceRight,
reduceRightOption, removeDuplicates, repr, reverse, reverseIterator, reverseMap,
reverse_:::, runWith, sameElements, scan, scanLeft, scanRight, segmentLength, seq,
size, slice, sliding, sortBy, sortWith, sorted, span, splitAt, startsWith,
stringPrefix, sum, synchronized, tail, tails, take, takeRight, takeWhile, to,
toArray, toBuffer, toIndexedSeq, toIterable, toIterator, toList, toMap, toSeq,
toSet, toStream, toString, toTraversable, toVector, transpose, union, unzip,
unzip3, updated, view, wait, withFilter, zip, zipAll, zipWithIndex
Know when to breakOut
def adultFriends(p: Person): Array[Person] = {
val adults = // <- of type List
for { friend <- p.friends // <- of type List
if friend.age >= 18 } yield friend
adults.toArray
}

can we avoid the 2nd iteration?
def adultFriends(p: Person): Array[Person] =
(for { friend <- p.friends
if friend.age >= 18
} yield friend)(collection.breakOut)
Common pitfall
def getUsers: Seq[User]

mutable or immutable?

Good question!
remedy

import scala.collection.immutable
def getUsers: immutable.Seq[User]
Implicits
Limit the scope of implicits
Implicit Resolution
• implicits in the local scope
•
•
•

Implicits defined in current scope (1)

•
•
•

companion object of the type (and inherited types)

explicit imports (2)
wildcard imports (3)

• parts of A type
companion objects of type arguments of the type
outer objects for nested types
http://www.scala-lang.org/docu/files/ScalaReference.pdf
Implicit Scope (Parts)
trait Logger {
def log(m: String): Unit
}
object Logger {
implicit object StdLogger extends Logger {
override def log(m: String): Unit = println(m)
}
def log(m: String)(implicit l: Logger) = l.log(m)
}

Logger.log("Hello")
Looking ahead
Level up!
Scala In Depth

Joshua Suereth

http://www.manning.com/suereth/
Effective
Scala
Thanks to @heathermiller for the presentation style
Mirco Dotta
twitter: @mircodotta

More Related Content

What's hot

ScalaUA - distage: Staged Dependency Injection
ScalaUA - distage: Staged Dependency InjectionScalaUA - distage: Staged Dependency Injection
ScalaUA - distage: Staged Dependency Injection7mind
 
Flink Forward San Francisco 2019: Moving from Lambda and Kappa Architectures ...
Flink Forward San Francisco 2019: Moving from Lambda and Kappa Architectures ...Flink Forward San Francisco 2019: Moving from Lambda and Kappa Architectures ...
Flink Forward San Francisco 2019: Moving from Lambda and Kappa Architectures ...Flink Forward
 
A Deep Dive into Spark SQL's Catalyst Optimizer with Yin Huai
A Deep Dive into Spark SQL's Catalyst Optimizer with Yin HuaiA Deep Dive into Spark SQL's Catalyst Optimizer with Yin Huai
A Deep Dive into Spark SQL's Catalyst Optimizer with Yin HuaiDatabricks
 
Understanding Query Plans and Spark UIs
Understanding Query Plans and Spark UIsUnderstanding Query Plans and Spark UIs
Understanding Query Plans and Spark UIsDatabricks
 
Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...
Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...
Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...Databricks
 
Vectorized Query Execution in Apache Spark at Facebook
Vectorized Query Execution in Apache Spark at FacebookVectorized Query Execution in Apache Spark at Facebook
Vectorized Query Execution in Apache Spark at FacebookDatabricks
 
Migrating Apache Hive Workload to Apache Spark: Bridge the Gap with Zhan Zhan...
Migrating Apache Hive Workload to Apache Spark: Bridge the Gap with Zhan Zhan...Migrating Apache Hive Workload to Apache Spark: Bridge the Gap with Zhan Zhan...
Migrating Apache Hive Workload to Apache Spark: Bridge the Gap with Zhan Zhan...Databricks
 
The Rise of ZStandard: Apache Spark/Parquet/ORC/Avro
The Rise of ZStandard: Apache Spark/Parquet/ORC/AvroThe Rise of ZStandard: Apache Spark/Parquet/ORC/Avro
The Rise of ZStandard: Apache Spark/Parquet/ORC/AvroDatabricks
 
A Deep Dive into Query Execution Engine of Spark SQL
A Deep Dive into Query Execution Engine of Spark SQLA Deep Dive into Query Execution Engine of Spark SQL
A Deep Dive into Query Execution Engine of Spark SQLDatabricks
 
OpenJDK Concurrent Collectors
OpenJDK Concurrent CollectorsOpenJDK Concurrent Collectors
OpenJDK Concurrent CollectorsMonica Beckwith
 
Understanding and Improving Code Generation
Understanding and Improving Code GenerationUnderstanding and Improving Code Generation
Understanding and Improving Code GenerationDatabricks
 
Apache Spark Introduction and Resilient Distributed Dataset basics and deep dive
Apache Spark Introduction and Resilient Distributed Dataset basics and deep diveApache Spark Introduction and Resilient Distributed Dataset basics and deep dive
Apache Spark Introduction and Resilient Distributed Dataset basics and deep diveSachin Aggarwal
 
Spark shuffle introduction
Spark shuffle introductionSpark shuffle introduction
Spark shuffle introductioncolorant
 
Building a unified data pipeline in Apache Spark
Building a unified data pipeline in Apache SparkBuilding a unified data pipeline in Apache Spark
Building a unified data pipeline in Apache SparkDataWorks Summit
 
Deep Dive into Spark SQL with Advanced Performance Tuning with Xiao Li & Wenc...
Deep Dive into Spark SQL with Advanced Performance Tuning with Xiao Li & Wenc...Deep Dive into Spark SQL with Advanced Performance Tuning with Xiao Li & Wenc...
Deep Dive into Spark SQL with Advanced Performance Tuning with Xiao Li & Wenc...Databricks
 
Magnet Shuffle Service: Push-based Shuffle at LinkedIn
Magnet Shuffle Service: Push-based Shuffle at LinkedInMagnet Shuffle Service: Push-based Shuffle at LinkedIn
Magnet Shuffle Service: Push-based Shuffle at LinkedInDatabricks
 
Tuning Apache Spark for Large-Scale Workloads Gaoxiang Liu and Sital Kedia
Tuning Apache Spark for Large-Scale Workloads Gaoxiang Liu and Sital KediaTuning Apache Spark for Large-Scale Workloads Gaoxiang Liu and Sital Kedia
Tuning Apache Spark for Large-Scale Workloads Gaoxiang Liu and Sital KediaDatabricks
 
Spark's Role in the Big Data Ecosystem (Spark Summit 2014)
Spark's Role in the Big Data Ecosystem (Spark Summit 2014)Spark's Role in the Big Data Ecosystem (Spark Summit 2014)
Spark's Role in the Big Data Ecosystem (Spark Summit 2014)Databricks
 

What's hot (20)

ScalaUA - distage: Staged Dependency Injection
ScalaUA - distage: Staged Dependency InjectionScalaUA - distage: Staged Dependency Injection
ScalaUA - distage: Staged Dependency Injection
 
Flink Forward San Francisco 2019: Moving from Lambda and Kappa Architectures ...
Flink Forward San Francisco 2019: Moving from Lambda and Kappa Architectures ...Flink Forward San Francisco 2019: Moving from Lambda and Kappa Architectures ...
Flink Forward San Francisco 2019: Moving from Lambda and Kappa Architectures ...
 
A Deep Dive into Spark SQL's Catalyst Optimizer with Yin Huai
A Deep Dive into Spark SQL's Catalyst Optimizer with Yin HuaiA Deep Dive into Spark SQL's Catalyst Optimizer with Yin Huai
A Deep Dive into Spark SQL's Catalyst Optimizer with Yin Huai
 
Understanding Query Plans and Spark UIs
Understanding Query Plans and Spark UIsUnderstanding Query Plans and Spark UIs
Understanding Query Plans and Spark UIs
 
MVVM & RxSwift
MVVM & RxSwiftMVVM & RxSwift
MVVM & RxSwift
 
Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...
Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...
Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San J...
 
Vectorized Query Execution in Apache Spark at Facebook
Vectorized Query Execution in Apache Spark at FacebookVectorized Query Execution in Apache Spark at Facebook
Vectorized Query Execution in Apache Spark at Facebook
 
Migrating Apache Hive Workload to Apache Spark: Bridge the Gap with Zhan Zhan...
Migrating Apache Hive Workload to Apache Spark: Bridge the Gap with Zhan Zhan...Migrating Apache Hive Workload to Apache Spark: Bridge the Gap with Zhan Zhan...
Migrating Apache Hive Workload to Apache Spark: Bridge the Gap with Zhan Zhan...
 
The Rise of ZStandard: Apache Spark/Parquet/ORC/Avro
The Rise of ZStandard: Apache Spark/Parquet/ORC/AvroThe Rise of ZStandard: Apache Spark/Parquet/ORC/Avro
The Rise of ZStandard: Apache Spark/Parquet/ORC/Avro
 
A Deep Dive into Query Execution Engine of Spark SQL
A Deep Dive into Query Execution Engine of Spark SQLA Deep Dive into Query Execution Engine of Spark SQL
A Deep Dive into Query Execution Engine of Spark SQL
 
OpenJDK Concurrent Collectors
OpenJDK Concurrent CollectorsOpenJDK Concurrent Collectors
OpenJDK Concurrent Collectors
 
Understanding and Improving Code Generation
Understanding and Improving Code GenerationUnderstanding and Improving Code Generation
Understanding and Improving Code Generation
 
Apache Spark Introduction and Resilient Distributed Dataset basics and deep dive
Apache Spark Introduction and Resilient Distributed Dataset basics and deep diveApache Spark Introduction and Resilient Distributed Dataset basics and deep dive
Apache Spark Introduction and Resilient Distributed Dataset basics and deep dive
 
Spark shuffle introduction
Spark shuffle introductionSpark shuffle introduction
Spark shuffle introduction
 
Apache Storm
Apache StormApache Storm
Apache Storm
 
Building a unified data pipeline in Apache Spark
Building a unified data pipeline in Apache SparkBuilding a unified data pipeline in Apache Spark
Building a unified data pipeline in Apache Spark
 
Deep Dive into Spark SQL with Advanced Performance Tuning with Xiao Li & Wenc...
Deep Dive into Spark SQL with Advanced Performance Tuning with Xiao Li & Wenc...Deep Dive into Spark SQL with Advanced Performance Tuning with Xiao Li & Wenc...
Deep Dive into Spark SQL with Advanced Performance Tuning with Xiao Li & Wenc...
 
Magnet Shuffle Service: Push-based Shuffle at LinkedIn
Magnet Shuffle Service: Push-based Shuffle at LinkedInMagnet Shuffle Service: Push-based Shuffle at LinkedIn
Magnet Shuffle Service: Push-based Shuffle at LinkedIn
 
Tuning Apache Spark for Large-Scale Workloads Gaoxiang Liu and Sital Kedia
Tuning Apache Spark for Large-Scale Workloads Gaoxiang Liu and Sital KediaTuning Apache Spark for Large-Scale Workloads Gaoxiang Liu and Sital Kedia
Tuning Apache Spark for Large-Scale Workloads Gaoxiang Liu and Sital Kedia
 
Spark's Role in the Big Data Ecosystem (Spark Summit 2014)
Spark's Role in the Big Data Ecosystem (Spark Summit 2014)Spark's Role in the Big Data Ecosystem (Spark Summit 2014)
Spark's Role in the Big Data Ecosystem (Spark Summit 2014)
 

Viewers also liked

Scala Implicits - Not to be feared
Scala Implicits - Not to be fearedScala Implicits - Not to be feared
Scala Implicits - Not to be fearedDerek Wyatt
 
Akka in 100 slides or less
Akka in 100 slides or lessAkka in 100 slides or less
Akka in 100 slides or lessDerek Wyatt
 
Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)mircodotta
 
Real-World Scala Design Patterns
Real-World Scala Design PatternsReal-World Scala Design Patterns
Real-World Scala Design PatternsNLJUG
 
Baking Delicious Modularity in Scala
Baking Delicious Modularity in ScalaBaking Delicious Modularity in Scala
Baking Delicious Modularity in ScalaDerek Wyatt
 
Learning from "Effective Scala"
Learning from "Effective Scala"Learning from "Effective Scala"
Learning from "Effective Scala"Kazuhiro Sera
 
Innovations in Grid Computing with Oracle Coherence
Innovations in Grid Computing with Oracle CoherenceInnovations in Grid Computing with Oracle Coherence
Innovations in Grid Computing with Oracle CoherenceBob Rhubart
 
Managing Binary Compatibility in Scala (Scala Days 2011)
Managing Binary Compatibility in Scala (Scala Days 2011)Managing Binary Compatibility in Scala (Scala Days 2011)
Managing Binary Compatibility in Scala (Scala Days 2011)mircodotta
 
Spring 3.1 and MVC Testing Support - 4Developers
Spring 3.1 and MVC Testing Support - 4DevelopersSpring 3.1 and MVC Testing Support - 4Developers
Spring 3.1 and MVC Testing Support - 4DevelopersSam Brannen
 
Chicago Hadoop Users Group: Enterprise Data Workflows
Chicago Hadoop Users Group: Enterprise Data WorkflowsChicago Hadoop Users Group: Enterprise Data Workflows
Chicago Hadoop Users Group: Enterprise Data WorkflowsPaco Nathan
 
Reactive Programming With Akka - Lessons Learned
Reactive Programming With Akka - Lessons LearnedReactive Programming With Akka - Lessons Learned
Reactive Programming With Akka - Lessons LearnedDaniel Sawano
 
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...mircodotta
 
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingA Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingGarth Gilmour
 
The no-framework Scala Dependency Injection Framework
The no-framework Scala Dependency Injection FrameworkThe no-framework Scala Dependency Injection Framework
The no-framework Scala Dependency Injection FrameworkAdam Warski
 
Effective akka scalaio
Effective akka scalaioEffective akka scalaio
Effective akka scalaioshinolajla
 
Actor Based Asyncronous IO in Akka
Actor Based Asyncronous IO in AkkaActor Based Asyncronous IO in Akka
Actor Based Asyncronous IO in Akkadrewhk
 
Efficient HTTP Apis
Efficient HTTP ApisEfficient HTTP Apis
Efficient HTTP ApisAdrian Cole
 
Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!priort
 
C*ollege Credit: Creating Your First App in Java with Cassandra
C*ollege Credit: Creating Your First App in Java with CassandraC*ollege Credit: Creating Your First App in Java with Cassandra
C*ollege Credit: Creating Your First App in Java with CassandraDataStax
 

Viewers also liked (20)

Scala Implicits - Not to be feared
Scala Implicits - Not to be fearedScala Implicits - Not to be feared
Scala Implicits - Not to be feared
 
Akka in 100 slides or less
Akka in 100 slides or lessAkka in 100 slides or less
Akka in 100 slides or less
 
Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)
 
Scala’s implicits
Scala’s implicitsScala’s implicits
Scala’s implicits
 
Real-World Scala Design Patterns
Real-World Scala Design PatternsReal-World Scala Design Patterns
Real-World Scala Design Patterns
 
Baking Delicious Modularity in Scala
Baking Delicious Modularity in ScalaBaking Delicious Modularity in Scala
Baking Delicious Modularity in Scala
 
Learning from "Effective Scala"
Learning from "Effective Scala"Learning from "Effective Scala"
Learning from "Effective Scala"
 
Innovations in Grid Computing with Oracle Coherence
Innovations in Grid Computing with Oracle CoherenceInnovations in Grid Computing with Oracle Coherence
Innovations in Grid Computing with Oracle Coherence
 
Managing Binary Compatibility in Scala (Scala Days 2011)
Managing Binary Compatibility in Scala (Scala Days 2011)Managing Binary Compatibility in Scala (Scala Days 2011)
Managing Binary Compatibility in Scala (Scala Days 2011)
 
Spring 3.1 and MVC Testing Support - 4Developers
Spring 3.1 and MVC Testing Support - 4DevelopersSpring 3.1 and MVC Testing Support - 4Developers
Spring 3.1 and MVC Testing Support - 4Developers
 
Chicago Hadoop Users Group: Enterprise Data Workflows
Chicago Hadoop Users Group: Enterprise Data WorkflowsChicago Hadoop Users Group: Enterprise Data Workflows
Chicago Hadoop Users Group: Enterprise Data Workflows
 
Reactive Programming With Akka - Lessons Learned
Reactive Programming With Akka - Lessons LearnedReactive Programming With Akka - Lessons Learned
Reactive Programming With Akka - Lessons Learned
 
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems (Soft-Sha...
 
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingA Sceptical Guide to Functional Programming
A Sceptical Guide to Functional Programming
 
The no-framework Scala Dependency Injection Framework
The no-framework Scala Dependency Injection FrameworkThe no-framework Scala Dependency Injection Framework
The no-framework Scala Dependency Injection Framework
 
Effective akka scalaio
Effective akka scalaioEffective akka scalaio
Effective akka scalaio
 
Actor Based Asyncronous IO in Akka
Actor Based Asyncronous IO in AkkaActor Based Asyncronous IO in Akka
Actor Based Asyncronous IO in Akka
 
Efficient HTTP Apis
Efficient HTTP ApisEfficient HTTP Apis
Efficient HTTP Apis
 
Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!
 
C*ollege Credit: Creating Your First App in Java with Cassandra
C*ollege Credit: Creating Your First App in Java with CassandraC*ollege Credit: Creating Your First App in Java with Cassandra
C*ollege Credit: Creating Your First App in Java with Cassandra
 

Similar to Effective Scala (SoftShake 2013)

Intro to Functional Programming in Scala
Intro to Functional Programming in ScalaIntro to Functional Programming in Scala
Intro to Functional Programming in ScalaShai Yallin
 
Gregory Shehet "Reactive state managment"
Gregory Shehet "Reactive state managment"Gregory Shehet "Reactive state managment"
Gregory Shehet "Reactive state managment"OdessaJS Conf
 
Григорий Шехет "Introduction in Reactive Programming with React"
 Григорий Шехет "Introduction in Reactive Programming with React" Григорий Шехет "Introduction in Reactive Programming with React"
Григорий Шехет "Introduction in Reactive Programming with React"Fwdays
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n2
name name2 n2name name2 n2
name name2 n2callroom
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n2.ppt
name name2 n2.pptname name2 n2.ppt
name name2 n2.pptcallroom
 
Ruby for Perl Programmers
Ruby for Perl ProgrammersRuby for Perl Programmers
Ruby for Perl Programmersamiable_indian
 
ParaSail
ParaSail  ParaSail
ParaSail AdaCore
 
Using spl tools in your code
Using spl tools in your codeUsing spl tools in your code
Using spl tools in your codeElizabeth Smith
 
Introduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanIntroduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanJimin Hsieh
 

Similar to Effective Scala (SoftShake 2013) (20)

Intro to Functional Programming in Scala
Intro to Functional Programming in ScalaIntro to Functional Programming in Scala
Intro to Functional Programming in Scala
 
Gregory Shehet "Reactive state managment"
Gregory Shehet "Reactive state managment"Gregory Shehet "Reactive state managment"
Gregory Shehet "Reactive state managment"
 
Григорий Шехет "Introduction in Reactive Programming with React"
 Григорий Шехет "Introduction in Reactive Programming with React" Григорий Шехет "Introduction in Reactive Programming with React"
Григорий Шехет "Introduction in Reactive Programming with React"
 
ppt7
ppt7ppt7
ppt7
 
ppt2
ppt2ppt2
ppt2
 
name name2 n
name name2 nname name2 n
name name2 n
 
name name2 n2
name name2 n2name name2 n2
name name2 n2
 
test ppt
test ppttest ppt
test ppt
 
name name2 n
name name2 nname name2 n
name name2 n
 
ppt21
ppt21ppt21
ppt21
 
name name2 n
name name2 nname name2 n
name name2 n
 
ppt17
ppt17ppt17
ppt17
 
ppt30
ppt30ppt30
ppt30
 
name name2 n2.ppt
name name2 n2.pptname name2 n2.ppt
name name2 n2.ppt
 
ppt18
ppt18ppt18
ppt18
 
Ruby for Perl Programmers
Ruby for Perl ProgrammersRuby for Perl Programmers
Ruby for Perl Programmers
 
ppt9
ppt9ppt9
ppt9
 
ParaSail
ParaSail  ParaSail
ParaSail
 
Using spl tools in your code
Using spl tools in your codeUsing spl tools in your code
Using spl tools in your code
 
Introduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanIntroduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf Taiwan
 

More from mircodotta

Scala Past, Present & Future
Scala Past, Present & FutureScala Past, Present & Future
Scala Past, Present & Futuremircodotta
 
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)mircodotta
 
Lightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just RightLightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just Rightmircodotta
 
Akka streams scala italy2015
Akka streams scala italy2015Akka streams scala italy2015
Akka streams scala italy2015mircodotta
 
Scala: Simplifying Development
Scala: Simplifying DevelopmentScala: Simplifying Development
Scala: Simplifying Developmentmircodotta
 
Managing Binary Compatibility in Scala (Scala Lift Off 2011)
Managing Binary Compatibility in Scala (Scala Lift Off 2011)Managing Binary Compatibility in Scala (Scala Lift Off 2011)
Managing Binary Compatibility in Scala (Scala Lift Off 2011)mircodotta
 

More from mircodotta (7)

Scala Past, Present & Future
Scala Past, Present & FutureScala Past, Present & Future
Scala Past, Present & Future
 
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
 
Lightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just RightLightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just Right
 
Akka streams scala italy2015
Akka streams scala italy2015Akka streams scala italy2015
Akka streams scala italy2015
 
Akka streams
Akka streamsAkka streams
Akka streams
 
Scala: Simplifying Development
Scala: Simplifying DevelopmentScala: Simplifying Development
Scala: Simplifying Development
 
Managing Binary Compatibility in Scala (Scala Lift Off 2011)
Managing Binary Compatibility in Scala (Scala Lift Off 2011)Managing Binary Compatibility in Scala (Scala Lift Off 2011)
Managing Binary Compatibility in Scala (Scala Lift Off 2011)
 

Recently uploaded

Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 

Recently uploaded (20)

Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 

Effective Scala (SoftShake 2013)

  • 1. Effective Scala SoftShake 2013, Geneva Mirco Dotta twitter: @mircodotta
  • 3.
  • 4. is not because you It , that you should can
  • 5.
  • 6. What’s this talk about? mize your use of Opti Scala to solve real world problems thout explosions, wi broken thumbs or bullet wounds
  • 9. Learn the Scala way You know it when you got it Scala ain’t Java nor Ruby nor Haskell nor <INSERT known PL> http://docs.scala-lang.org/style/
  • 10. Abstract members trait Shape { val edges: Int } Why? class Triangle extends Shape { override def edges: Int = 3 } Because this doesn’t compile!
  • 11. Abstract members Always use def for abstract members! trait Shape { def edges: Int }
  • 12. You’ve to override trait Worker { def run(): Unit } abstract class MyWorker extends Worker { override def run(): Unit = //... }
  • 13. Don’t leak your types! trait Logger { def log(m: String): Unit } object Logger { class StdLogger extends Logger { override def log(m: String): Unit = println(m) } def apply = new StdLogger() } What’s the return type here?
  • 14. Hide your secrets object SauceFactory { def makeSecretSauce(): Sauce = { val ingredients = getMagicIngredients() val formula = getSecretFormula() SauceMaker.prepare(ingredients, formula) } te! getMagicIngredients(): riva p def Ingredients = //... def getSecretFormula(): Formula = //... }
  • 15. Visibility modifiers • Scala has very expressive visibility modifiers • Access modifiers can be augmented with qualifiers Did you know that... public (default) package protected private private nested packages have access to private classes • Companion object/classes have access to each other private members! private[pkg] protected • everything you have in java, and much more
  • 16. Don’t blow the stack! IF YOU THINK IT’S tailrecursive, SAY so! case class Node(value: Int, edges: List[Node]) def bfs(node: Node, pred: Node => Boolean): Option[Node] = { @scala.annotation.tailrec def search(acc: List[Node]): Option[Node] = acc match { case Nil => None case x :: xs => if (pred(x)) Some(x) else search(xs ::: xs.edges) } search(List(node)) }
  • 17. String interpolation case class Complex(real: Int, im: Int) { override def toString: String = real + " + " + im + "i" } case class Complex(real: Int, im: Int) { override def toString: String = s"$real + ${im}i" } interpolator!
  • 23. def home(): HttpPage = { var page: HttpPage = null try page = prepareHttpPage() catch { case _: TimeoutEx => page = TimeoutPage case _: Exception => page = NoPage } return page } def home(): HttpPage = try prepareHttpPage() catch { case _: TimeoutEx => TimeoutPage case _: Exception => NoPage }
  • 24. Expressions compose! def home(): HttpPage = try prepareHttpPage() catch { case _: TimeoutEx => TimeoutPage case _: Exception => NoPage } Try..catch is an expression This is a PartialFunction[Throwable,HttpPage] def timeoutCatch = { case _: TimeoutEx => TimeoutPage } def noPageCatch = { case _: Exception => NoPage } def home(): HttpPage = try prepareHttpPage() catch timeoutCatch orElse noPageCatch mp co e! os
  • 26. null is a disease • nullcheks will spread • code is brittle • NPE will still happen • assertions won’t help
  • 27. Forget null, use Option • no more “it may be null” • type-safe • documentation
  • 28. def authenticate(session: HttpSession, username: Option[String], password: Option[String]) = for { user <- username pass <- password if canAuthenticate(user,pass) privileges <- privilegesFor(user) } yield inject(session, privileges)
  • 29. But don’t overuse Option sometime a null-object can be a much better fit def home(): HttpPage = try prepareHttpPage() catch { case _: TimeoutEx => TimeoutPage case _: Exception => NoPage } Null Object!
  • 31. Immutability 3 reasons why it matters? • Simplifies reasoning • simplifies reasoning • simplifies reasoning
  • 32. Immutability Allows co/contra variance ity bil uta ce m ian --var ---+ ------- bles rou T Jav a String[] a = {""}; Object[] b = a; b[0] = 1; String value = a[0]; rrayStoreException java.lang.A
  • 33. Immutability • correct equals & hashcode! • it also simplifies reasoning about concurrency • thread-safe by design
  • 34. Immutability • Mutability is still ok, but keep it in local scopes • api methods should return immutable objects
  • 35. Do you want faster Scala compilation? program to an interface, not an implementation.
  • 38. Learn the API !=, ##, ++, ++:, +:, /:, /:, :+, ::, :::, :, <init>, ==, addString, aggregate, andThen, apply, applyOrElse, asInstanceOf, canEqual, collect, collectFirst, combinations, companion, compose, contains, containsSlice, copyToArray, copyToBuffer, corresponds, count, diff, distinct, drop, dropRight, dropWhile, endsWith, eq, equals, exists, filter, filterNot, find, flatMap, flatten, fold, foldLeft, foldRight, forall, foreach, genericBuilder, getClass, groupBy, grouped, hasDefiniteSize, hashCode, head, headOption, indexOf, indexOfSlice, indexWhere, indices, init, inits, intersect, isDefinedAt, isEmpty, isInstanceOf, isTraversableAgain, iterator, last, lastIndexOf, lastIndexOfSlice, lastIndexWhere, lastOption, length, lengthCompare, lift, map, mapConserve, max, maxBy, min, minBy, mkString, ne, nonEmpty, notify, notifyAll, orElse, padTo, par, partition, patch, permutations, prefixLength, product, productArity, productElement, productIterator, productPrefix, reduce, reduceLeft, reduceLeftOption, reduceOption, reduceRight, reduceRightOption, removeDuplicates, repr, reverse, reverseIterator, reverseMap, reverse_:::, runWith, sameElements, scan, scanLeft, scanRight, segmentLength, seq, size, slice, sliding, sortBy, sortWith, sorted, span, splitAt, startsWith, stringPrefix, sum, synchronized, tail, tails, take, takeRight, takeWhile, to, toArray, toBuffer, toIndexedSeq, toIterable, toIterator, toList, toMap, toSeq, toSet, toStream, toString, toTraversable, toVector, transpose, union, unzip, unzip3, updated, view, wait, withFilter, zip, zipAll, zipWithIndex
  • 39. Know when to breakOut def adultFriends(p: Person): Array[Person] = { val adults = // <- of type List for { friend <- p.friends // <- of type List if friend.age >= 18 } yield friend adults.toArray } can we avoid the 2nd iteration? def adultFriends(p: Person): Array[Person] = (for { friend <- p.friends if friend.age >= 18 } yield friend)(collection.breakOut)
  • 40. Common pitfall def getUsers: Seq[User] mutable or immutable? Good question! remedy import scala.collection.immutable def getUsers: immutable.Seq[User]
  • 42. Limit the scope of implicits
  • 43. Implicit Resolution • implicits in the local scope • • • Implicits defined in current scope (1) • • • companion object of the type (and inherited types) explicit imports (2) wildcard imports (3) • parts of A type companion objects of type arguments of the type outer objects for nested types http://www.scala-lang.org/docu/files/ScalaReference.pdf
  • 44. Implicit Scope (Parts) trait Logger { def log(m: String): Unit } object Logger { implicit object StdLogger extends Logger { override def log(m: String): Unit = println(m) } def log(m: String)(implicit l: Logger) = l.log(m) } Logger.log("Hello")
  • 46. Level up! Scala In Depth Joshua Suereth http://www.manning.com/suereth/
  • 47. Effective Scala Thanks to @heathermiller for the presentation style Mirco Dotta twitter: @mircodotta