SlideShare una empresa de Scribd logo
1 de 31
Scala
Refactoring
Tomer Gabel, CodeMotion Tel-Aviv 2015
for Fun and Profit
Agenda
• For the next 40
minutes, we’ll:
– Look at examples
– Discuss patterns
– … and anti-patterns
– Showcase refactoring
techniques
Our Victim
• … is ScalaChess
– Provides a full domain
model for chess
– Good test coverage
– Long-lived
– High quality code
– MIT license
– Integrated in lichess.org
* ScalaChess is an open-source project by Thibault Duplessis
STARTING OFF
Naming Things
• New features complicate matters:
– Infix notation (a.k.a dot-free syntax)
case class Geo(lat: Double, long: Double) {
def distance(other: Geo): Double = // ...
}
val (center, location): Geo = // ...
if (centre.distance(location) <= radius)
Some(loc) else None
Naming Things
• New features complicate matters:
– Infix notation (a.k.a dot-free syntax)
case class Geo(lat: Double, long: Double) {
def distance(other: Geo): Double = // ...
}
val (center, location): Geo = // ...
if (centre distance location <= radius)
Some(loc) else None What language is this?
Naming Things
• New features complicate matters:
– Infix notation (a.k.a dot-free syntax)
case class Geo(lat: Double, long: Double) {
def distanceFrom(other: Geo): Double = //…
}
val (center, location): Geo = // ...
if (location distanceFrom center <= radius)
Some(loc) else None A little clearer now
Naming Things
• Oh, the humanity: Symbolic operators
case class Geo(lat: Double, long: Double) {
def <->(other: Geo): Double = // ...
}
val Geo(center, location) = // ...
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
Questions?
tomer@tomergabel.com
@tomerg
http://il.linkedin.com/in/tomergabel
WE’RE DONE
HERE!

Más contenido relacionado

La actualidad más candente

Scala In The Wild
Scala In The WildScala In The Wild
Scala In The Wild
djspiewak
 
Live coding scala 'the java of the future'
Live coding scala 'the java of the future'Live coding scala 'the java of the future'
Live coding scala 'the java of the future'
Xebia Nederland BV
 

La actualidad más candente (20)

Scala Intro
Scala IntroScala Intro
Scala Intro
 
Scala jargon cheatsheet
Scala jargon cheatsheetScala jargon cheatsheet
Scala jargon cheatsheet
 
A Tour Of Scala
A Tour Of ScalaA Tour Of Scala
A Tour Of Scala
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
 
Demystifying Shapeless
Demystifying Shapeless Demystifying Shapeless
Demystifying Shapeless
 
Scala Refactoring for Fun and Profit (Japanese subtitles)
Scala Refactoring for Fun and Profit (Japanese subtitles)Scala Refactoring for Fun and Profit (Japanese subtitles)
Scala Refactoring for Fun and Profit (Japanese subtitles)
 
Scala : language of the future
Scala : language of the futureScala : language of the future
Scala : language of the future
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Practically Functional
Practically FunctionalPractically Functional
Practically Functional
 
Introduction to Scala for Java Developers
Introduction to Scala for Java DevelopersIntroduction to Scala for Java Developers
Introduction to Scala for Java Developers
 
Weaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
Weaving Dataflows with Silk - ScalaMatsuri 2014, TokyoWeaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
Weaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
 
10 Things I Hate About Scala
10 Things I Hate About Scala10 Things I Hate About Scala
10 Things I Hate About Scala
 
Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To Scala
 
Scala In The Wild
Scala In The WildScala In The Wild
Scala In The Wild
 
Spark workshop
Spark workshopSpark workshop
Spark workshop
 
The Evolution of Scala / Scala進化論
The Evolution of Scala / Scala進化論The Evolution of Scala / Scala進化論
The Evolution of Scala / Scala進化論
 
Brief tour of psp-std
Brief tour of psp-stdBrief tour of psp-std
Brief tour of psp-std
 
Scala - just good for Java shops?
Scala - just good for Java shops?Scala - just good for Java shops?
Scala - just good for Java shops?
 
Live coding scala 'the java of the future'
Live coding scala 'the java of the future'Live coding scala 'the java of the future'
Live coding scala 'the java of the future'
 
Scala in Practice
Scala in PracticeScala in Practice
Scala in Practice
 

Destacado

унікальні рослини і тварини (підсумковий проект)
унікальні рослини і тварини (підсумковий проект)унікальні рослини і тварини (підсумковий проект)
унікальні рослини і тварини (підсумковий проект)
Наталія Горя
 
FAWZEY CV LATEST UPDATE-3
FAWZEY CV LATEST  UPDATE-3FAWZEY CV LATEST  UPDATE-3
FAWZEY CV LATEST UPDATE-3
fawzey mukhtar
 

Destacado (10)

унікальні рослини і тварини (підсумковий проект)
унікальні рослини і тварини (підсумковий проект)унікальні рослини і тварини (підсумковий проект)
унікальні рослини і тварини (підсумковий проект)
 
Deferred Action (DACA)
Deferred Action (DACA)Deferred Action (DACA)
Deferred Action (DACA)
 
Nii情報リテラシー研修 20151120 大阪大・久保山_参考事例
Nii情報リテラシー研修 20151120 大阪大・久保山_参考事例Nii情報リテラシー研修 20151120 大阪大・久保山_参考事例
Nii情報リテラシー研修 20151120 大阪大・久保山_参考事例
 
Contentstrategie en -aanpak ABN AMRO @ Content Club 30 juni 2016
Contentstrategie en -aanpak ABN AMRO @ Content Club 30 juni 2016Contentstrategie en -aanpak ABN AMRO @ Content Club 30 juni 2016
Contentstrategie en -aanpak ABN AMRO @ Content Club 30 juni 2016
 
What would hhappen if payday loans are outlawed
What would hhappen if payday loans are outlawedWhat would hhappen if payday loans are outlawed
What would hhappen if payday loans are outlawed
 
Power tools in Java
Power tools in JavaPower tools in Java
Power tools in Java
 
ICT AS Level Software AQA
ICT AS Level Software AQA ICT AS Level Software AQA
ICT AS Level Software AQA
 
Hanz and Franz
Hanz and FranzHanz and Franz
Hanz and Franz
 
7 Mistakes Professionals Make on Social Media
7 Mistakes Professionals Make on Social Media7 Mistakes Professionals Make on Social Media
7 Mistakes Professionals Make on Social Media
 
FAWZEY CV LATEST UPDATE-3
FAWZEY CV LATEST  UPDATE-3FAWZEY CV LATEST  UPDATE-3
FAWZEY CV LATEST UPDATE-3
 

Similar a Scala Refactoring for Fun and Profit

(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
Tomasz Wrobel
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
shinolajla
 

Similar a Scala Refactoring for Fun and Profit (20)

(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
 
Scala for curious
Scala for curiousScala for curious
Scala for curious
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
 
Proposals for new function in Java SE 9 and beyond
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
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Language
 
Scala ntnu
Scala ntnuScala ntnu
Scala ntnu
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Scala: Functioneel programmeren in een object georiënteerde wereld
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
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Pune Clojure Course Outline
Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course Outline
 
Meet scala
Meet scalaMeet scala
Meet scala
 
Scala: Object-Oriented Meets Functional, by Iulian Dragos
Scala: Object-Oriented Meets Functional, by Iulian DragosScala: Object-Oriented Meets Functional, by Iulian Dragos
Scala: Object-Oriented Meets Functional, by Iulian Dragos
 
scala-101
scala-101scala-101
scala-101
 
Lecture 3
Lecture 3Lecture 3
Lecture 3
 
From Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risksFrom Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risks
 
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...
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...
 
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...
Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...
 

Más de Tomer Gabel

Más de Tomer Gabel (20)

How shit works: Time
How shit works: TimeHow shit works: Time
How shit works: Time
 
Nondeterministic Software for the Rest of Us
Nondeterministic Software for the Rest of UsNondeterministic Software for the Rest of Us
Nondeterministic Software for the Rest of Us
 
Slaying Sacred Cows: Deconstructing Dependency Injection
Slaying Sacred Cows: Deconstructing Dependency InjectionSlaying Sacred Cows: Deconstructing Dependency Injection
Slaying Sacred Cows: Deconstructing Dependency Injection
 
An Abridged Guide to Event Sourcing
An Abridged Guide to Event SourcingAn Abridged Guide to Event Sourcing
An Abridged Guide to Event Sourcing
 
How shit works: the CPU
How shit works: the CPUHow shit works: the CPU
How shit works: the CPU
 
How Shit Works: Storage
How Shit Works: StorageHow Shit Works: Storage
How Shit Works: Storage
 
Java 8 and Beyond, a Scala Story
Java 8 and Beyond, a Scala StoryJava 8 and Beyond, a Scala Story
Java 8 and Beyond, a Scala Story
 
The Wix Microservice Stack
The Wix Microservice StackThe Wix Microservice Stack
The Wix Microservice Stack
 
Onboarding at Scale
Onboarding at ScaleOnboarding at Scale
Onboarding at Scale
 
Scala in the Wild
Scala in the WildScala in the Wild
Scala in the Wild
 
Put Your Thinking CAP On
Put Your Thinking CAP OnPut Your Thinking CAP On
Put Your Thinking CAP On
 
Leveraging Scala Macros for Better Validation
Leveraging Scala Macros for Better ValidationLeveraging Scala Macros for Better Validation
Leveraging Scala Macros for Better Validation
 
A Field Guide to DSL Design in Scala
A Field Guide to DSL Design in ScalaA Field Guide to DSL Design in Scala
A Field Guide to DSL Design in Scala
 
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)
Functional Leap of Faith (Keynote at JDay Lviv 2014)
 
5 Bullets to Scala Adoption
5 Bullets to Scala Adoption5 Bullets to Scala Adoption
5 Bullets to Scala Adoption
 
Nashorn: JavaScript that doesn’t suck (ILJUG)
Nashorn: JavaScript that doesn’t suck (ILJUG)Nashorn: JavaScript that doesn’t suck (ILJUG)
Nashorn: JavaScript that doesn’t suck (ILJUG)
 
Lab: JVM Production Debugging 101
Lab: JVM Production Debugging 101Lab: JVM Production Debugging 101
Lab: JVM Production Debugging 101
 
DevCon³: Scala Best Practices
DevCon³: Scala Best PracticesDevCon³: Scala Best Practices
DevCon³: Scala Best Practices
 
Maven for Dummies
Maven for DummiesMaven for Dummies
Maven for Dummies
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 

Último

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
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 Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
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...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
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
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 

Scala Refactoring for Fun and Profit

  • 1. Scala Refactoring Tomer Gabel, CodeMotion Tel-Aviv 2015 for Fun and Profit
  • 2. Agenda • For the next 40 minutes, we’ll: – Look at examples – Discuss patterns – … and anti-patterns – Showcase refactoring techniques
  • 3. Our Victim • … is ScalaChess – Provides a full domain model for chess – Good test coverage – Long-lived – High quality code – MIT license – Integrated in lichess.org * ScalaChess is an open-source project by Thibault Duplessis
  • 5. Naming Things • New features complicate matters: – Infix notation (a.k.a dot-free syntax) case class Geo(lat: Double, long: Double) { def distance(other: Geo): Double = // ... } val (center, location): Geo = // ... if (centre.distance(location) <= radius) Some(loc) else None
  • 6. Naming Things • New features complicate matters: – Infix notation (a.k.a dot-free syntax) case class Geo(lat: Double, long: Double) { def distance(other: Geo): Double = // ... } val (center, location): Geo = // ... if (centre distance location <= radius) Some(loc) else None What language is this?
  • 7. Naming Things • New features complicate matters: – Infix notation (a.k.a dot-free syntax) case class Geo(lat: Double, long: Double) { def distanceFrom(other: Geo): Double = //… } val (center, location): Geo = // ... if (location distanceFrom center <= radius) Some(loc) else None A little clearer now
  • 8. Naming Things • Oh, the humanity: Symbolic operators case class Geo(lat: Double, long: Double) { def <->(other: Geo): Double = // ... } val Geo(center, location) = // ... if (loc <-> center <= radius) Some(loc) else None Why would you do that?!
  • 9. 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
  • 10. 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))
  • 12. THE LAY OF THE LAND
  • 13. Stringly Typed “Used to describe an implementation that needlessly relies on strings when programmer & refactor friendly options are available.” -- Coding Horror
  • 14. 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?
  • 15. 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?
  • 16. 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!
  • 17. 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 :-)
  • 19. 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
  • 20. 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?
  • 21. 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!
  • 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 What’s with all these underscores?
  • 23. 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.
  • 25. Scoping • Correct scoping is incredibly important! –Separation of concerns –Code navigation and discovery –Reduced autocompletion noise
  • 26. Scoping • Scala offers an impressive toolbox: – Nested scopes – Companion objects – Traits – Visibility modifiers – Type classes
  • 27. 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!
  • 29. Scoping • Lessons learned: –Keep logic and data separate –Case classes are your friends! –Add “aspects” via type classes
  • 30. Scoping • Rules of the road: –Keep your public API small –Make everything else private –Put helpers in companions –… or via implicit extensions

Notas del editor

  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