Speaking Scala: Refactoring for Fun and Profit (Workshop)

Tomer Gabel
Tomer GabelConsulting Engineer at Substrate Software Services
Speaking
Scala
Refactoring for Fun and Profit
Tomer Gabel, August 2015
Agenda
• Part 1, where we’ll:
– Show examples
– Identify patterns
– … and anti-patterns
– Discuss our findings
– And learn!
Agenda
• Part 2, where you
do the lifting:
– Fork (the repo)
– Bork (the code)
– Work (the tests)
Prepare Thyself
• You’ll need…
–Your favorite IDE
–Sbt
–Git
–And of course…
Our Victim
• … is ScalaChess
– Provides a full domain
model for chess
– Great test coverage
– High quality code
– MIT license
– Integrated in lichess.org
* ScalaChess is an open-source project by Thibault Duplessis
Fork that shit:
http://github.com/holograph/scalachess
STARTING OFF
Naming Things
• Scala adds certain classes of offenses:
– Infix notation (a.k.a dot-free syntax)
– Symbolic operators
case class Geo(lat: Double, long: Double) {
def distance(other: Geo): Double = // ...
}
val (center, loc): Geo = // ...
if (centre.distance(loc) <= radius)
Some(loc) else None
Naming Things
• Scala adds certain classes of offenses:
– Infix notation (a.k.a dot-free syntax)
– Symbolic operators
case class Geo(lat: Double, long: Double) {
def distanceFrom(other: Geo): Double = // ...
}
val (center, loc): Geo = // ...
if (loc distanceFrom center <= radius)
Some(loc) else None
Naming Things
• Scala adds certain classes of offenses:
– Infix notation (a.k.a dot-free syntax)
– Symbolic operators
case class Geo(lat: Double, long: Double) {
def <->(other: Geo): Double = // ...
}
val (center, loc): Geo = // ...
if (loc <-> center <= radius)
Some(loc) else None
Why would you do that?!
Naming Things
• There are worse offenders. Take Dispatch:
import dispatch.Http
import Http._
val server = url("http://example.com")
val headers = Map("Accept" -> "application/json")
Http(server >>> System.out) // GET
Http(server <:< headers >>> System.out) // GET
Http(server << yourPostData >|) // POST
Naming Things
• There are worse offenders. Take scalaz:
def s[A](a: A) = a.success[List[String]]
val add3 = (x: Int) =>
(y: Int) =>
(z: Int) => x + y + z
val res = (7) <*> (s(8) <*> (s(9) ∘ add3))
assert(res == s(24))
REAL-WORLD EXAMPLE TIME!
THE LAY OF THE
LAND
Stringly Typed
“Used to describe an implementation
that needlessly relies on strings when
programmer & refactor friendly options
are available.”
-- Coding
Horror
Stringly Typed
• Examples:
– Passing dates as strings
– Carrying unparsed data around
– Using empty strings instead of Options
case class Person(name: String, created: String)
def resolveConflict(p1: Person, p2: Person): Person = {
val c1 = dateParser.parse(p1.created)
val c2 = dateParser.parse(p2.created)
if (c1 compareTo c2 > 0) p1 else p2
}
1. Parser needs to be well-known
2. Error handling all over the place
3. What’s with all the boilerplate?
Stringly Typed
• Examples:
– Passing dates as strings
– Carrying unparsed data around
– Using empty strings instead of Options
case class Person(name: String, location: String)
def nearest(to: Person, all: List[Person]): Person = {
val geo: Point = Point.parse(to.location)
all.minBy(p => geo.distanceTo(Point.parse(p.location)))
}
1. Inefficient (space/time)
2. Error handling all over the place
3. What’s with all the boilerplate?
Stringly Typed
• Examples:
– Passing dates as strings
– Carrying unparsed data around
– Using empty strings instead of Options
case class Person(name: String, location: Point)
def nearest(to: Person, all: List[Person]): Person =
all.minBy(p => to.location distanceTo p.location)1. Efficient (only parsed once)
2. Sane error handling
3. Zero boilerplate!
Stringly Typed
• Examples:
– Passing dates as strings
– Carrying unparsed data around
– Using empty strings instead of Options
case class Person(firstName: String, lastName: String)
def render(p: Person): String =
s"""
|<div id='first-name'>${p.firstName}</div>
|<div id='last-name'>${p.lastName}</div>
""".stripMargin
1. Nothing enforces emptiness check!
2. Scala has a great type for these :-)
REAL-WORLD EXAMPLE TIME!
Collective Abuse
• Scala has a massive
collection library
• Loads of built-ins too
– Case classes
– Functions and partials
– Tuples, tuples, tuples
• Fairly easy to abuse
Collective Abuse
• Common anti-patterns:
– Too many inline steps
– Tuple overload
val actors: List[(Int, String, Double)] = // ...
def bestActor(query: String) =
actors.filter(_._2 contains query)
.sortBy(-_._3)
.map(_._1)
.headOption
1. What does this even do?!
2. How does data flow here?
Collective Abuse
• Common anti-patterns:
– Too many inline steps
– Tuple overload
val actors: List[(Int, String, Double)] = // ...
def bestActor(query: String) = {
val matching = actors.filter(_._2 contains query)
val bestByScore = matching.sortBy(-_._3).headOption
bestByScore.map(_._1)
} Name intermediate steps!
Collective Abuse
• Common anti-patterns:
– Too many inline steps
– Tuple overload
val actors: List[(Int, String, Double)] = // ...
def bestActor(query: String) =
actors.filter(_._2 contains query)
.sortBy(-_._3)
.map(_._1)
.headOption
What’s with all these
underscores?
Collective Abuse
• Common anti-patterns:
– Too many inline steps
– Tuple overload
case class Actor(id: Int, name: String, score: Double)
def bestActor(query: String, actors: List[Actor]) =
actors.filter(_.name contains query)
.sortBy(-_.score)
.map(_.id)
.headOption
Scala classes are cheap.
Use them.
REAL-WORLD EXAMPLE TIME!
Scoping
• Correct scoping is incredibly
important!
–Separation of concerns
–Code navigation and discovery
–Reduced autocompletion noise
Scoping
• Scala offers an
impressive toolbox:
– Nested scopes
– Companion objects
– Traits
– Visibility modifiers
– Type classes
Scoping
class User(var name: String,
var age: Int,
initialStatus: UserStatus = New) {
private var _status = initialStatus
def status = _status
def delete(): Unit = {
_status = Deleted
Mailer.notify(Mailer.userDeletion, this)
}
}
Mutable data ⇒ Boilerplate
SoC broken!
EXAMPLE TIME!
https://github.com/holograph/scala-refactoring
Scoping
• Lessons learned:
–Keep logic and data separate
–Case classes are your friends!
–Add “aspects” via type classes
Scoping
• Rules of the road:
–Keep your public API small
–Make everything else private
–Put helpers in companions
–… or via implicit extensions
AND NOW…
PART 2
1 of 33

Recommended

Scala Refactoring for Fun and Profit by
Scala Refactoring for Fun and ProfitScala Refactoring for Fun and Profit
Scala Refactoring for Fun and ProfitTomer Gabel
985 views31 slides
From Ruby to Scala by
From Ruby to ScalaFrom Ruby to Scala
From Ruby to Scalatod esking
7.9K views41 slides
A Scala Corrections Library by
A Scala Corrections LibraryA Scala Corrections Library
A Scala Corrections LibraryPaul Phillips
33K views47 slides
A Brief Intro to Scala by
A Brief Intro to ScalaA Brief Intro to Scala
A Brief Intro to ScalaTim Underwood
23.1K views56 slides
Ponies and Unicorns With Scala by
Ponies and Unicorns With ScalaPonies and Unicorns With Scala
Ponies and Unicorns With ScalaTomer Gabel
961 views25 slides
Introduction to Scala by
Introduction to ScalaIntroduction to Scala
Introduction to ScalaRahul Jain
4.6K views27 slides

More Related Content

What's hot

Scala Intro by
Scala IntroScala Intro
Scala IntroAlexey (Mr_Mig) Migutsky
7.6K views142 slides
Few simple-type-tricks in scala by
Few simple-type-tricks in scalaFew simple-type-tricks in scala
Few simple-type-tricks in scalaRuslan Shevchenko
1K views20 slides
10 Things I Hate About Scala by
10 Things I Hate About Scala10 Things I Hate About Scala
10 Things I Hate About ScalaMeir Maor
3K views36 slides
SE 20016 - programming languages landscape. by
SE 20016 - programming languages landscape.SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.Ruslan Shevchenko
804 views41 slides
A Tour Of Scala by
A Tour Of ScalaA Tour Of Scala
A Tour Of Scalafanf42
3.4K views40 slides
Scala Refactoring for Fun and Profit (Japanese subtitles) by
Scala Refactoring for Fun and Profit (Japanese subtitles)Scala Refactoring for Fun and Profit (Japanese subtitles)
Scala Refactoring for Fun and Profit (Japanese subtitles)Tomer Gabel
6.6K views16 slides

What's hot(20)

10 Things I Hate About Scala by Meir Maor
10 Things I Hate About Scala10 Things I Hate About Scala
10 Things I Hate About Scala
Meir Maor3K views
SE 20016 - programming languages landscape. by Ruslan Shevchenko
SE 20016 - programming languages landscape.SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.
Ruslan Shevchenko804 views
A Tour Of Scala by fanf42
A Tour Of ScalaA Tour Of Scala
A Tour Of Scala
fanf423.4K views
Scala Refactoring for Fun and Profit (Japanese subtitles) by Tomer Gabel
Scala Refactoring for Fun and Profit (Japanese subtitles)Scala Refactoring for Fun and Profit (Japanese subtitles)
Scala Refactoring for Fun and Profit (Japanese subtitles)
Tomer Gabel6.6K views
The Evolution of Scala / Scala進化論 by scalaconfjp
The Evolution of Scala / Scala進化論The Evolution of Scala / Scala進化論
The Evolution of Scala / Scala進化論
scalaconfjp5.2K views
Introduction to Scala by Saleem Ansari
Introduction to ScalaIntroduction to Scala
Introduction to Scala
Saleem Ansari2.6K views
Introduction To Scala by Peter Maas
Introduction To ScalaIntroduction To Scala
Introduction To Scala
Peter Maas1.6K views
High Wizardry in the Land of Scala by djspiewak
High Wizardry in the Land of ScalaHigh Wizardry in the Land of Scala
High Wizardry in the Land of Scala
djspiewak3.6K views
Scala - just good for Java shops? by Sarah Mount
Scala - just good for Java shops?Scala - just good for Java shops?
Scala - just good for Java shops?
Sarah Mount5.4K views
Practically Functional by djspiewak
Practically FunctionalPractically Functional
Practically Functional
djspiewak1.5K views
Introduction to Scala : Clueda by Andreas Neumann
Introduction to Scala : CluedaIntroduction to Scala : Clueda
Introduction to Scala : Clueda
Andreas Neumann1.2K views

Similar to Speaking Scala: Refactoring for Fun and Profit (Workshop)

Taxonomy of Scala by
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scalashinolajla
10.1K views53 slides
Proposals for new function in Java SE 9 and beyond by
Proposals for new function in Java SE 9 and beyondProposals for new function in Java SE 9 and beyond
Proposals for new function in Java SE 9 and beyondBarry Feigenbaum
945 views401 slides
(How) can we benefit from adopting scala? by
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?Tomasz Wrobel
1.1K views69 slides
Scala in Places API by
Scala in Places APIScala in Places API
Scala in Places APIŁukasz Bałamut
629 views22 slides
Scala for Java Programmers by
Scala for Java ProgrammersScala for Java Programmers
Scala for Java ProgrammersEric Pederson
967 views46 slides
Scala Back to Basics: Type Classes by
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesTomer Gabel
3.7K views35 slides

Similar to Speaking Scala: Refactoring for Fun and Profit (Workshop)(20)

Taxonomy of Scala by shinolajla
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
shinolajla10.1K views
Proposals for new function in Java SE 9 and beyond by Barry Feigenbaum
Proposals for new function in Java SE 9 and beyondProposals for new function in Java SE 9 and beyond
Proposals for new function in Java SE 9 and beyond
Barry Feigenbaum945 views
(How) can we benefit from adopting scala? by Tomasz Wrobel
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
Tomasz Wrobel1.1K views
Scala for Java Programmers by Eric Pederson
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
Eric Pederson967 views
Scala Back to Basics: Type Classes by Tomer Gabel
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
Tomer Gabel3.7K views
The Scala Programming Language by league
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Language
league1.4K views
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i... by Andrew Phillips
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...
Andrew Phillips463 views
Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit... by Andrew Phillips
Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...
Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...
Andrew Phillips294 views
Scala @ TechMeetup Edinburgh by Stuart Roebuck
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
Stuart Roebuck1.1K views
The Great Scala Makeover by Garth Gilmour
The Great Scala MakeoverThe Great Scala Makeover
The Great Scala Makeover
Garth Gilmour177 views
Code for Startup MVP (Ruby on Rails) Session 2 by Henry S
Code for Startup MVP (Ruby on Rails) Session 2Code for Startup MVP (Ruby on Rails) Session 2
Code for Startup MVP (Ruby on Rails) Session 2
Henry S1.7K views
Scala collections api expressivity and brevity upgrade from java by IndicThreads
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from java
IndicThreads677 views
ScalaCheck by BeScala
ScalaCheckScalaCheck
ScalaCheck
BeScala2.5K views
Scala: Functioneel programmeren in een object georiënteerde wereld by Werner Hofstra
Scala: Functioneel programmeren in een object georiënteerde wereldScala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereld
Werner Hofstra378 views
楽々Scalaプログラミング by Tomoharu ASAMI
楽々Scalaプログラミング楽々Scalaプログラミング
楽々Scalaプログラミング
Tomoharu ASAMI2.4K views

More from Tomer Gabel

How shit works: Time by
How shit works: TimeHow shit works: Time
How shit works: TimeTomer Gabel
342 views53 slides
Nondeterministic Software for the Rest of Us by
Nondeterministic Software for the Rest of UsNondeterministic Software for the Rest of Us
Nondeterministic Software for the Rest of UsTomer Gabel
329 views39 slides
Slaying Sacred Cows: Deconstructing Dependency Injection by
Slaying Sacred Cows: Deconstructing Dependency InjectionSlaying Sacred Cows: Deconstructing Dependency Injection
Slaying Sacred Cows: Deconstructing Dependency InjectionTomer Gabel
1.3K views34 slides
An Abridged Guide to Event Sourcing by
An Abridged Guide to Event SourcingAn Abridged Guide to Event Sourcing
An Abridged Guide to Event SourcingTomer Gabel
1K views32 slides
How shit works: the CPU by
How shit works: the CPUHow shit works: the CPU
How shit works: the CPUTomer Gabel
1.8K views38 slides
How Shit Works: Storage by
How Shit Works: StorageHow Shit Works: Storage
How Shit Works: StorageTomer Gabel
914 views44 slides

More from Tomer Gabel(20)

How shit works: Time by Tomer Gabel
How shit works: TimeHow shit works: Time
How shit works: Time
Tomer Gabel342 views
Nondeterministic Software for the Rest of Us by Tomer Gabel
Nondeterministic Software for the Rest of UsNondeterministic Software for the Rest of Us
Nondeterministic Software for the Rest of Us
Tomer Gabel329 views
Slaying Sacred Cows: Deconstructing Dependency Injection by Tomer Gabel
Slaying Sacred Cows: Deconstructing Dependency InjectionSlaying Sacred Cows: Deconstructing Dependency Injection
Slaying Sacred Cows: Deconstructing Dependency Injection
Tomer Gabel1.3K views
An Abridged Guide to Event Sourcing by Tomer Gabel
An Abridged Guide to Event SourcingAn Abridged Guide to Event Sourcing
An Abridged Guide to Event Sourcing
Tomer Gabel1K views
How shit works: the CPU by Tomer Gabel
How shit works: the CPUHow shit works: the CPU
How shit works: the CPU
Tomer Gabel1.8K views
How Shit Works: Storage by Tomer Gabel
How Shit Works: StorageHow Shit Works: Storage
How Shit Works: Storage
Tomer Gabel914 views
Java 8 and Beyond, a Scala Story by Tomer Gabel
Java 8 and Beyond, a Scala StoryJava 8 and Beyond, a Scala Story
Java 8 and Beyond, a Scala Story
Tomer Gabel747 views
The Wix Microservice Stack by Tomer Gabel
The Wix Microservice StackThe Wix Microservice Stack
The Wix Microservice Stack
Tomer Gabel1.7K views
Onboarding at Scale by Tomer Gabel
Onboarding at ScaleOnboarding at Scale
Onboarding at Scale
Tomer Gabel1.5K views
Scala in the Wild by Tomer Gabel
Scala in the WildScala in the Wild
Scala in the Wild
Tomer Gabel2.8K views
Put Your Thinking CAP On by Tomer Gabel
Put Your Thinking CAP OnPut Your Thinking CAP On
Put Your Thinking CAP On
Tomer Gabel3.5K views
Leveraging Scala Macros for Better Validation by Tomer Gabel
Leveraging Scala Macros for Better ValidationLeveraging Scala Macros for Better Validation
Leveraging Scala Macros for Better Validation
Tomer Gabel1.4K views
A Field Guide to DSL Design in Scala by Tomer Gabel
A Field Guide to DSL Design in ScalaA Field Guide to DSL Design in Scala
A Field Guide to DSL Design in Scala
Tomer Gabel6.5K views
Functional Leap of Faith (Keynote at JDay Lviv 2014) by Tomer Gabel
Functional Leap of Faith (Keynote at JDay Lviv 2014)Functional Leap of Faith (Keynote at JDay Lviv 2014)
Functional Leap of Faith (Keynote at JDay Lviv 2014)
Tomer Gabel1.5K views
5 Bullets to Scala Adoption by Tomer Gabel
5 Bullets to Scala Adoption5 Bullets to Scala Adoption
5 Bullets to Scala Adoption
Tomer Gabel2.7K views
Nashorn: JavaScript that doesn’t suck (ILJUG) by Tomer Gabel
Nashorn: JavaScript that doesn’t suck (ILJUG)Nashorn: JavaScript that doesn’t suck (ILJUG)
Nashorn: JavaScript that doesn’t suck (ILJUG)
Tomer Gabel5.9K views
Lab: JVM Production Debugging 101 by Tomer Gabel
Lab: JVM Production Debugging 101Lab: JVM Production Debugging 101
Lab: JVM Production Debugging 101
Tomer Gabel2.1K views
DevCon³: Scala Best Practices by Tomer Gabel
DevCon³: Scala Best PracticesDevCon³: Scala Best Practices
DevCon³: Scala Best Practices
Tomer Gabel3.7K views
Maven for Dummies by Tomer Gabel
Maven for DummiesMaven for Dummies
Maven for Dummies
Tomer Gabel6.3K views
Scala in practice by Tomer Gabel
Scala in practiceScala in practice
Scala in practice
Tomer Gabel25.5K views

Recently uploaded

The Research Portal of Catalonia: Growing more (information) & more (services) by
The Research Portal of Catalonia: Growing more (information) & more (services)The Research Portal of Catalonia: Growing more (information) & more (services)
The Research Portal of Catalonia: Growing more (information) & more (services)CSUC - Consorci de Serveis Universitaris de Catalunya
80 views25 slides
PharoJS - Zürich Smalltalk Group Meetup November 2023 by
PharoJS - Zürich Smalltalk Group Meetup November 2023PharoJS - Zürich Smalltalk Group Meetup November 2023
PharoJS - Zürich Smalltalk Group Meetup November 2023Noury Bouraqadi
132 views17 slides
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院 by
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院IttrainingIttraining
58 views8 slides
Ransomware is Knocking your Door_Final.pdf by
Ransomware is Knocking your Door_Final.pdfRansomware is Knocking your Door_Final.pdf
Ransomware is Knocking your Door_Final.pdfSecurity Bootcamp
59 views46 slides
MVP and prioritization.pdf by
MVP and prioritization.pdfMVP and prioritization.pdf
MVP and prioritization.pdfrahuldharwal141
31 views8 slides
Five Things You SHOULD Know About Postman by
Five Things You SHOULD Know About PostmanFive Things You SHOULD Know About Postman
Five Things You SHOULD Know About PostmanPostman
36 views43 slides

Recently uploaded(20)

PharoJS - Zürich Smalltalk Group Meetup November 2023 by Noury Bouraqadi
PharoJS - Zürich Smalltalk Group Meetup November 2023PharoJS - Zürich Smalltalk Group Meetup November 2023
PharoJS - Zürich Smalltalk Group Meetup November 2023
Noury Bouraqadi132 views
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院 by IttrainingIttraining
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院
Five Things You SHOULD Know About Postman by Postman
Five Things You SHOULD Know About PostmanFive Things You SHOULD Know About Postman
Five Things You SHOULD Know About Postman
Postman36 views
Unit 1_Lecture 2_Physical Design of IoT.pdf by StephenTec
Unit 1_Lecture 2_Physical Design of IoT.pdfUnit 1_Lecture 2_Physical Design of IoT.pdf
Unit 1_Lecture 2_Physical Design of IoT.pdf
StephenTec12 views
Igniting Next Level Productivity with AI-Infused Data Integration Workflows by Safe Software
Igniting Next Level Productivity with AI-Infused Data Integration Workflows Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Safe Software280 views
Special_edition_innovator_2023.pdf by WillDavies22
Special_edition_innovator_2023.pdfSpecial_edition_innovator_2023.pdf
Special_edition_innovator_2023.pdf
WillDavies2218 views
Powerful Google developer tools for immediate impact! (2023-24) by wesley chun
Powerful Google developer tools for immediate impact! (2023-24)Powerful Google developer tools for immediate impact! (2023-24)
Powerful Google developer tools for immediate impact! (2023-24)
wesley chun10 views
"Running students' code in isolation. The hard way", Yurii Holiuk by Fwdays
"Running students' code in isolation. The hard way", Yurii Holiuk "Running students' code in isolation. The hard way", Yurii Holiuk
"Running students' code in isolation. The hard way", Yurii Holiuk
Fwdays17 views
Future of AR - Facebook Presentation by ssuserb54b561
Future of AR - Facebook PresentationFuture of AR - Facebook Presentation
Future of AR - Facebook Presentation
ssuserb54b56115 views
Data Integrity for Banking and Financial Services by Precisely
Data Integrity for Banking and Financial ServicesData Integrity for Banking and Financial Services
Data Integrity for Banking and Financial Services
Precisely25 views

Speaking Scala: Refactoring for Fun and Profit (Workshop)

  • 1. Speaking Scala Refactoring for Fun and Profit Tomer Gabel, August 2015
  • 2. Agenda • Part 1, where we’ll: – Show examples – Identify patterns – … and anti-patterns – Discuss our findings – And learn!
  • 3. Agenda • Part 2, where you do the lifting: – Fork (the repo) – Bork (the code) – Work (the tests)
  • 4. Prepare Thyself • You’ll need… –Your favorite IDE –Sbt –Git –And of course…
  • 5. Our Victim • … is ScalaChess – Provides a full domain model for chess – Great test coverage – High quality code – MIT license – Integrated in lichess.org * ScalaChess is an open-source project by Thibault Duplessis
  • 8. Naming Things • Scala adds certain classes of offenses: – Infix notation (a.k.a dot-free syntax) – Symbolic operators case class Geo(lat: Double, long: Double) { def distance(other: Geo): Double = // ... } val (center, loc): Geo = // ... if (centre.distance(loc) <= radius) Some(loc) else None
  • 9. Naming Things • Scala adds certain classes of offenses: – Infix notation (a.k.a dot-free syntax) – Symbolic operators case class Geo(lat: Double, long: Double) { def distanceFrom(other: Geo): Double = // ... } val (center, loc): Geo = // ... if (loc distanceFrom center <= radius) Some(loc) else None
  • 10. Naming Things • Scala adds certain classes of offenses: – Infix notation (a.k.a dot-free syntax) – Symbolic operators case class Geo(lat: Double, long: Double) { def <->(other: Geo): Double = // ... } val (center, loc): Geo = // ... if (loc <-> center <= radius) Some(loc) else None Why would you do that?!
  • 11. Naming Things • There are worse offenders. Take Dispatch: import dispatch.Http import Http._ val server = url("http://example.com") val headers = Map("Accept" -> "application/json") Http(server >>> System.out) // GET Http(server <:< headers >>> System.out) // GET Http(server << yourPostData >|) // POST
  • 12. Naming Things • There are worse offenders. Take scalaz: def s[A](a: A) = a.success[List[String]] val add3 = (x: Int) => (y: Int) => (z: Int) => x + y + z val res = (7) <*> (s(8) <*> (s(9) ∘ add3)) assert(res == s(24))
  • 14. THE LAY OF THE LAND
  • 15. Stringly Typed “Used to describe an implementation that needlessly relies on strings when programmer & refactor friendly options are available.” -- Coding Horror
  • 16. Stringly Typed • Examples: – Passing dates as strings – Carrying unparsed data around – Using empty strings instead of Options case class Person(name: String, created: String) def resolveConflict(p1: Person, p2: Person): Person = { val c1 = dateParser.parse(p1.created) val c2 = dateParser.parse(p2.created) if (c1 compareTo c2 > 0) p1 else p2 } 1. Parser needs to be well-known 2. Error handling all over the place 3. What’s with all the boilerplate?
  • 17. Stringly Typed • Examples: – Passing dates as strings – Carrying unparsed data around – Using empty strings instead of Options case class Person(name: String, location: String) def nearest(to: Person, all: List[Person]): Person = { val geo: Point = Point.parse(to.location) all.minBy(p => geo.distanceTo(Point.parse(p.location))) } 1. Inefficient (space/time) 2. Error handling all over the place 3. What’s with all the boilerplate?
  • 18. Stringly Typed • Examples: – Passing dates as strings – Carrying unparsed data around – Using empty strings instead of Options case class Person(name: String, location: Point) def nearest(to: Person, all: List[Person]): Person = all.minBy(p => to.location distanceTo p.location)1. Efficient (only parsed once) 2. Sane error handling 3. Zero boilerplate!
  • 19. Stringly Typed • Examples: – Passing dates as strings – Carrying unparsed data around – Using empty strings instead of Options case class Person(firstName: String, lastName: String) def render(p: Person): String = s""" |<div id='first-name'>${p.firstName}</div> |<div id='last-name'>${p.lastName}</div> """.stripMargin 1. Nothing enforces emptiness check! 2. Scala has a great type for these :-)
  • 21. Collective Abuse • Scala has a massive collection library • Loads of built-ins too – Case classes – Functions and partials – Tuples, tuples, tuples • Fairly easy to abuse
  • 22. Collective Abuse • Common anti-patterns: – Too many inline steps – Tuple overload val actors: List[(Int, String, Double)] = // ... def bestActor(query: String) = actors.filter(_._2 contains query) .sortBy(-_._3) .map(_._1) .headOption 1. What does this even do?! 2. How does data flow here?
  • 23. Collective Abuse • Common anti-patterns: – Too many inline steps – Tuple overload val actors: List[(Int, String, Double)] = // ... def bestActor(query: String) = { val matching = actors.filter(_._2 contains query) val bestByScore = matching.sortBy(-_._3).headOption bestByScore.map(_._1) } Name intermediate steps!
  • 24. Collective Abuse • Common anti-patterns: – Too many inline steps – Tuple overload val actors: List[(Int, String, Double)] = // ... def bestActor(query: String) = actors.filter(_._2 contains query) .sortBy(-_._3) .map(_._1) .headOption What’s with all these underscores?
  • 25. Collective Abuse • Common anti-patterns: – Too many inline steps – Tuple overload case class Actor(id: Int, name: String, score: Double) def bestActor(query: String, actors: List[Actor]) = actors.filter(_.name contains query) .sortBy(-_.score) .map(_.id) .headOption Scala classes are cheap. Use them.
  • 27. Scoping • Correct scoping is incredibly important! –Separation of concerns –Code navigation and discovery –Reduced autocompletion noise
  • 28. Scoping • Scala offers an impressive toolbox: – Nested scopes – Companion objects – Traits – Visibility modifiers – Type classes
  • 29. Scoping class User(var name: String, var age: Int, initialStatus: UserStatus = New) { private var _status = initialStatus def status = _status def delete(): Unit = { _status = Deleted Mailer.notify(Mailer.userDeletion, this) } } Mutable data ⇒ Boilerplate SoC broken!
  • 31. Scoping • Lessons learned: –Keep logic and data separate –Case classes are your friends! –Add “aspects” via type classes
  • 32. Scoping • Rules of the road: –Keep your public API small –Make everything else private –Put helpers in companions –… or via implicit extensions

Editor's Notes

  1. Source: http://stackoverflow.com/questions/5564074/scala-http-operations
  2. Source: http://scalaz.github.io/scalaz/scalaz-2.9.1-6.0.4/doc.sxr/scalaz/example/ExampleApplicative.scala.html
  3. Photo source: https://flic.kr/p/3xcrQG
  4. Image source: http://www.flickeringmyth.com/2015/06/fallout-4-graphics-and-why-visual-demands-are-dumb.html
  5. Image source: https://thisistwitchy.files.wordpress.com/2013/04/oh-the-horror.jpg
  6. Image source: http://onlinesalesstepbystep.com/wp-content/uploads/2014/08/Toppling-books.jpg
  7. Photo source: https://flic.kr/p/3xcrQG
  8. Photo source: https://flic.kr/p/c4QJzC
  9. Photo source: https://flic.kr/p/3xcrQG
  10. Image source: http://www.penny-arcade.com/comic/2002/02/22