SlideShare une entreprise Scribd logo
1  sur  66
Scala best practices
Agoda 2017
Alexander Zaidel
Functional programming
Is a programming paradigm—a style of building the structure and elements of computer
programs—that treats computation as the evaluation of mathematical functions and avoids
changing-state and mutable data.
Referential transparency and purity
An expression e is referentially transparent if for all programs p, all occurrences of e in p
can be replaced by the result of evaluating e, without affecting the observable behavior
of p. A function f is pure if the expression f(x) is referentially transparent for all
referentially transparent x.
Example of pure function:
def fun(a: Int, b: Int): Int = a / b
Example of pure function:
def wrong(a: Int, b: Int): Int = a / b
def right(a: Int, b: Int): Try[Int] = Try(a / b)
apply
def getBookingInfo(): BookingInfo = ???
val bookingInfo = getBookingInfo()
MakeABooking(bookingInfo)
MakeABooking.apply(bookingInfo)
apply
object MakeABooking {
def apply(bookingInfo: BookingInfo): Booking = {
new Booking(bookingInfo)
}
}
Enumerations
object UserType extends Enumeration {
val NewUser, RecurringUser = Value
}
Enumerations
def someAction(userType: UserType): Unit = {
userType match {
case UserType.NewUser => action1
case UserType.RecurringUser => action2
}
}
Enumerations
def someAction(userType: UserType.Value): Unit = {
userType match {
case UserType.NewUser => action1
case UserType.RecurringUser => action2
}
}
object UserType extends Enumeration {
type UserType = Value
val NewUser, RecurringUser = Value
}
class vs case class
Hashcode
Equals,
Appy
Public access modifiers
Unapply
Immutability
Serializable
copy
case classes
case class User(name: String, birthDay: java.util.Date, country: String)
val ivan = User("Ivan", new java.util.Date(), "Thailand")
val pipat = ivan.copy(name = "Pipat")
println(ivan.name)
case classes unapply
def getUser(): User = ???
getUser match {
case User("Ivan", _, _) | User(_, _, "Thailand") => action1
case _ => action2
}
case classes immutability
val ivan = User("Ivan", new java.util.Date(), "Thailand")
ivan.birthDay.setTime(1L)
real cost
case class Person(name: String, lastName: String)
https://pastebin.com/WFbbnZ0Y
https://pastebin.com/20DVQ9QS
default values
def findUser(userName: String, birthday: Date = new Date(), country: String =
"Thailand"): User = ???
findUser("name")
findUser("name", country = "USA")
unapply
class Hotel(val name: String, val address: String, val country: String)
def getHotel(): Hotel = ???
getHotel() match {
case Hotel(_, "", "UK") => action1
case _ => action2
}
unapply
object Hotel {
def unapply(hotel: Hotel): Option[(String, String, String)] = {
Option((hotel.name, hotel.address, hotel.country))
}
}
Companion object
class Booking {
import Booking._
private val id: Long = DefaultId
private val created: Long = 0L
}
Companion object
object Booking {
def doSomething(booking: Booking): Unit = {
println(booking.created)
}
private val DefaultId = 0L
}
lazy val
class Service {
private def longRunningComputation(): Int = {
Thread.sleep(1000)
42
}
private lazy val k = longRunningComputation()
}
public class Service {
private int k; private volatile boolean bitmap$0;
private int longRunningComputation(){Thread.sleep(1000L);return 42;}
private int k$lzycompute(){
synchronized (this){
if (!this.bitmap$0){
this.k = longRunningComputation();this.bitmap$0 = true;
} return this.k; } }
private int k(){ return this.bitmap$0 ? this.k : k$lzycompute(); }
}
lazy val causing a deadlock
https://issues.scala-lang.org/browse/SI-5808
Access modifiers
equals vs ==
object Foo {
def getName(): String = null
getName().equals("")
}
equals vs ==
object Foo {
def getName(): String = null
getName() == ""
}
Option
val value: String = ???
Option(value).map(someValue => {
val tmp = someValue + 1
println(tmp)
})
Option
val value: String = ???
Option(value).map { someValue =>
val tmp = someValue + 1
println(tmp)
}
Option
case class User(age: Int, name: String, gender: Option[String])
val user = User(25, "Ivan", Some("male"))
user.gender match {
case Some(gender) => println("Gender: " + gender)
case None => println("Gender: not specified")
}
Option
def foo(gender: String): Unit = ???
val user = User(25, "Ivan", Some("male"))
if(user.gender.isDefined) {
foo(user.gender.get)
}
Option
user.gender match {
case Some(gender) => Some(gender.length)
case None => None
}
Option
def findUserFromDb(userId: Int): Option[User] = ???
val currentUser = findUserFromDb(userId)
val defaultUser = findUserFromDb(defaultUserId)
currentUser orElse defaultUser
Option
def getName(): String = null
Some(getName()).map { name =>
name.length
}
Option
def getName(): String = null
Option(getName()).map { name =>
name.length
}
Collections
def predicate: Boolean = ???
def foo(): List[Int] = ???
if(predicate) foo() else List()
List.empty, Map.empty, Array.empty
def predicate: Boolean = ???
def foo(): List[Int] = ???
if(predicate) foo() else List.empty
def foo(): List[Int] = List(1, 2, 3)
foo() match {
case b: List[String] => println("String")
case a: List[Int] => println("Int")
case c: List[AnyRef] => println("AnyRef")
case c: List[AnyVal] => println("AnyVal")
}
Collections
(1 to 400).filter(_ > 200).map(_.toString)
vs
(1 to 400).collect{
case a if(a > 200) => a.toString
}
Collections
seq.find(_ == x).isDefined
vs
seq.exists(_ == x)
seq.contains(x)
Don’t compute full length for length matching
seq.length > n
seq.length < n
seq.length == n
seq.length != n
seq.lengthCompare(n) > 0
seq.lengthCompare(n) < 0
seq.lengthCompare(n) == 0
seq.lengthCompare(n) != 0
Don’t rely on == to compare array contents
array1 == array2
vs
array1.sameElements(array2)
Don’t check index bounds explicitly
if (i < seq.length) Some(seq(i)) else None
vs
seq.lift(i)
Be careful with contains argument type
Seq(1, 2, 3).contains("1") // compilable
vs
Seq(1, 2, 3).contains(1)
Merge consecutive filter calls
seq.filter(p1).filter(p2)
vs
seq.filter(x => p1(x) && p2(x))
seq.filter(p1).headOption.map
vs
seq.collectFirst {
case (x) if predicate =>
}
tuples
case class User(name: String, hobby: String)
List(User("Ivan", "football"),
User("Pipat", "scala"),
User("Eugene", "scala")
).groupBy(_.hobby).map(users => users._2.size)
tuples
List(
User("Ivan", "football"),
User("Pipat", "scala"),
User("Eugene", "scala")
).groupBy(_.hobby).map { case (hobby, users) => users.size }
Future
def apply[T](body : => T)(implicit executor :ExecutionContext) : Future[T]
Future
def longRunningJob(): Int = {Thread.sleep(1000); 42}
Future(longRunningJob()).map { result =>
result + 100
}.recover { case NonFatal(e) => 0 }
Future
val myFuture = Future(longRunningJob())
myFuture.onComplete{
case Success(value) => value + 100
case Failure(t) => 0
}
Future
case class Hotel(id: Long)
val preCachedHotels: List[Hotel] = ???
def dbCall(id: Long): Future[Hotel] = ???
def findHotel(id: Long): Future[Hotel] = preCachedHotels.find(_.id == id).
map { user => Future(user) }.getOrElse(dbCall(id))
Future: successful
case class Hotel(id: Long)
val preCachedHotels: List[Hotel] = ???
def dbCall(id: Long): Future[Hotel] = ???
def findHotel(id: Long): Future[Hotel] = preCachedHotels.find(_.id == id).
map { user => Future.successful(user) }.getOrElse(dbCall(id))
Future
def callDB(id: Long): Future[User] = ???
def findUser(id: Long): Future[User] = {
if(id < 0) Future(new Exception("User can't contain negative id"))
else callDB(id)
}
Future: failed
def callDB(id: Long): Future[User] = ???
def findUser(id: Long): Future[User] = {
if(id < 0) Future.failed(new Exception("User can't contain negative id"))
else callDB(id)
}
Future.sequence
case class User(id: Long)
def getAllUserIds(): List[Long] = ???
def findUserById(id: Long): Future[User] = ???
val usersF: List[Future[User]] = getAllUserIds().map(findUserById)
val allUsersFetchedF: Future[List[User]] = Future.sequence(usersF)
for comprehension
val aOption = Some(5); val bOption = Some(6)
aOption.flatMap(a => bOption.map(b => a + b))
for {
a <- aOption
b <- bOption
} yield a + b
for comprehension and futures
for {
cityId <- someCalculation()
countryId <- someOtherCalculation()
district <- someDifferentCalculation()
} yield doSomethingWith(cityId, countryId, district)
val cityIdF = someCalculation()
val countryIdF = someOtherCalculation()
val districtF = someDifferentCalculation()
for {
cityId <- cityIdF
countryId <- countryIdF
district <- districtF
} yield doSomethingWith(cityId, countryId, district)
Implicits conversion
case class User(name: String, age: Int)
implicit def userToString(user: User): String = s"${user.name}${user.age}"
def giveMeString(arg: String): Unit = println(arg)
val IamString = User("string", 42)
giveMeString(IamString)
Implicit Parameter
case class Minerals(typeOfMineral: String)
implicit val calcium = Minerals("calcium")
def needMoreMinerals(implicit minerals: Minerals): Unit =
println(minerals.typeOfMineral)
needMoreMinerals
PIMP my library
implicit class StringPimp(value: String) {
def allStringsAreMine(): String = "I was enslaved"
}
println("Hello".allStringsAreMine())
Abstract methods in traits
trait Foo { def foo() }
trait M extends Foo{abstract override def foo() { println("M"); super.foo() } }
class FooImpl1 extends Foo { override def foo() { println("Impl") } }
class FooImpl2 extends FooImpl1 with M
new FooImpl2().foo()
Sealed classes
def getMyOption[T](): MyOption[T] =
???
getMyOption() match {
case MyEmpty => action1
case MySome(a) => action1
}
sealed abstract class
MyOption[T]
case object MyEmpty extends
MyOption[Nothing]
case class MySome[T](t: T)
extends MyOption[T]
case class MyAnotherState[T](t: T)
extends MyOption[T]
Resources
Scala for the Impatient
https://pavelfatin.com/scala-collections-tips-and-tricks/
http://danielwestheide.com/scala/neophytes.html
Programming in Scala, 3rd Edition
Q & A

Contenu connexe

Tendances

Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverseLuka Jacobowitz
 
FP 201 - Unit4 Part 2
FP 201 - Unit4 Part 2FP 201 - Unit4 Part 2
FP 201 - Unit4 Part 2rohassanie
 
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, allCiklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, allCiklum Ukraine
 
Collection v3
Collection v3Collection v3
Collection v3Sunil OS
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to PythonUC San Diego
 
Monoids, monoids, monoids
Monoids, monoids, monoidsMonoids, monoids, monoids
Monoids, monoids, monoidsLuka Jacobowitz
 
The java language cheat sheet
The java language cheat sheetThe java language cheat sheet
The java language cheat sheetanand_study
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patternsleague
 
Monad Transformers In The Wild
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The WildStackMob Inc
 
Core c sharp and .net quick reference
Core c sharp and .net quick referenceCore c sharp and .net quick reference
Core c sharp and .net quick referenceArduino Aficionado
 
Model-Driven Software Development - Static Analysis & Error Checking
Model-Driven Software Development - Static Analysis & Error CheckingModel-Driven Software Development - Static Analysis & Error Checking
Model-Driven Software Development - Static Analysis & Error CheckingEelco Visser
 
Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge O T
 
The Ring programming language version 1.5.1 book - Part 36 of 180
The Ring programming language version 1.5.1 book - Part 36 of 180The Ring programming language version 1.5.1 book - Part 36 of 180
The Ring programming language version 1.5.1 book - Part 36 of 180Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 29 of 180
The Ring programming language version 1.5.1 book - Part 29 of 180The Ring programming language version 1.5.1 book - Part 29 of 180
The Ring programming language version 1.5.1 book - Part 29 of 180Mahmoud Samir Fayed
 
The Ring programming language version 1.9 book - Part 39 of 210
The Ring programming language version 1.9 book - Part 39 of 210The Ring programming language version 1.9 book - Part 39 of 210
The Ring programming language version 1.9 book - Part 39 of 210Mahmoud Samir Fayed
 
The Ring programming language version 1.9 book - Part 41 of 210
The Ring programming language version 1.9 book - Part 41 of 210The Ring programming language version 1.9 book - Part 41 of 210
The Ring programming language version 1.9 book - Part 41 of 210Mahmoud Samir Fayed
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meetMario Fusco
 
Let the type system be your friend
Let the type system be your friendLet the type system be your friend
Let the type system be your friendThe Software House
 

Tendances (20)

Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverse
 
Java cheatsheet
Java cheatsheetJava cheatsheet
Java cheatsheet
 
FP 201 - Unit4 Part 2
FP 201 - Unit4 Part 2FP 201 - Unit4 Part 2
FP 201 - Unit4 Part 2
 
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, allCiklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
 
Collection v3
Collection v3Collection v3
Collection v3
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 
Monoids, monoids, monoids
Monoids, monoids, monoidsMonoids, monoids, monoids
Monoids, monoids, monoids
 
The java language cheat sheet
The java language cheat sheetThe java language cheat sheet
The java language cheat sheet
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
Monad Transformers In The Wild
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The Wild
 
Core c sharp and .net quick reference
Core c sharp and .net quick referenceCore c sharp and .net quick reference
Core c sharp and .net quick reference
 
Python Cheat Sheet
Python Cheat SheetPython Cheat Sheet
Python Cheat Sheet
 
Model-Driven Software Development - Static Analysis & Error Checking
Model-Driven Software Development - Static Analysis & Error CheckingModel-Driven Software Development - Static Analysis & Error Checking
Model-Driven Software Development - Static Analysis & Error Checking
 
Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge
 
The Ring programming language version 1.5.1 book - Part 36 of 180
The Ring programming language version 1.5.1 book - Part 36 of 180The Ring programming language version 1.5.1 book - Part 36 of 180
The Ring programming language version 1.5.1 book - Part 36 of 180
 
The Ring programming language version 1.5.1 book - Part 29 of 180
The Ring programming language version 1.5.1 book - Part 29 of 180The Ring programming language version 1.5.1 book - Part 29 of 180
The Ring programming language version 1.5.1 book - Part 29 of 180
 
The Ring programming language version 1.9 book - Part 39 of 210
The Ring programming language version 1.9 book - Part 39 of 210The Ring programming language version 1.9 book - Part 39 of 210
The Ring programming language version 1.9 book - Part 39 of 210
 
The Ring programming language version 1.9 book - Part 41 of 210
The Ring programming language version 1.9 book - Part 41 of 210The Ring programming language version 1.9 book - Part 41 of 210
The Ring programming language version 1.9 book - Part 41 of 210
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 
Let the type system be your friend
Let the type system be your friendLet the type system be your friend
Let the type system be your friend
 

Similaire à Scala best practices

Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed worldDebasish Ghosh
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaDaniel Sebban
 
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...PROIDEA
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsJohn De Goes
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기진성 오
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with GroovyArturo Herrero
 
ITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingIstanbul Tech Talks
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala Knoldus Inc.
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type ClassesTapio Rautonen
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kirill Rozov
 
Un dsl pour ma base de données
Un dsl pour ma base de donnéesUn dsl pour ma base de données
Un dsl pour ma base de donnéesRomain Lecomte
 
Делаем пользовательское Api на базе Shapeless
Делаем пользовательское Api на базе ShapelessДелаем пользовательское Api на базе Shapeless
Делаем пользовательское Api на базе ShapelessВадим Челышов
 

Similaire à Scala best practices (20)

Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with Scala
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
ITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function Programming
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type Classes
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Monadologie
MonadologieMonadologie
Monadologie
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2
 
Un dsl pour ma base de données
Un dsl pour ma base de donnéesUn dsl pour ma base de données
Un dsl pour ma base de données
 
Делаем пользовательское Api на базе Shapeless
Делаем пользовательское Api на базе ShapelessДелаем пользовательское Api на базе Shapeless
Делаем пользовательское Api на базе Shapeless
 
Python : Functions
Python : FunctionsPython : Functions
Python : Functions
 

Dernier

Thermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.pptThermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.pptDineshKumar4165
 
Wadi Rum luxhotel lodge Analysis case study.pptx
Wadi Rum luxhotel lodge Analysis case study.pptxWadi Rum luxhotel lodge Analysis case study.pptx
Wadi Rum luxhotel lodge Analysis case study.pptxNadaHaitham1
 
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptxA CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptxmaisarahman1
 
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills KuwaitKuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwaitjaanualu31
 
Design For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startDesign For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startQuintin Balsdon
 
Thermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VThermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VDineshKumar4165
 
Online electricity billing project report..pdf
Online electricity billing project report..pdfOnline electricity billing project report..pdf
Online electricity billing project report..pdfKamal Acharya
 
Online food ordering system project report.pdf
Online food ordering system project report.pdfOnline food ordering system project report.pdf
Online food ordering system project report.pdfKamal Acharya
 
Double Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueDouble Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueBhangaleSonal
 
NO1 Top No1 Amil Baba In Azad Kashmir, Kashmir Black Magic Specialist Expert ...
NO1 Top No1 Amil Baba In Azad Kashmir, Kashmir Black Magic Specialist Expert ...NO1 Top No1 Amil Baba In Azad Kashmir, Kashmir Black Magic Specialist Expert ...
NO1 Top No1 Amil Baba In Azad Kashmir, Kashmir Black Magic Specialist Expert ...Amil baba
 
Introduction to Serverless with AWS Lambda
Introduction to Serverless with AWS LambdaIntroduction to Serverless with AWS Lambda
Introduction to Serverless with AWS LambdaOmar Fathy
 
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
COST-EFFETIVE  and Energy Efficient BUILDINGS ptxCOST-EFFETIVE  and Energy Efficient BUILDINGS ptx
COST-EFFETIVE and Energy Efficient BUILDINGS ptxJIT KUMAR GUPTA
 
Moment Distribution Method For Btech Civil
Moment Distribution Method For Btech CivilMoment Distribution Method For Btech Civil
Moment Distribution Method For Btech CivilVinayVitekari
 
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptxS1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptxSCMS School of Architecture
 
PE 459 LECTURE 2- natural gas basic concepts and properties
PE 459 LECTURE 2- natural gas basic concepts and propertiesPE 459 LECTURE 2- natural gas basic concepts and properties
PE 459 LECTURE 2- natural gas basic concepts and propertiessarkmank1
 
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best ServiceTamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Servicemeghakumariji156
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXssuser89054b
 
Employee leave management system project.
Employee leave management system project.Employee leave management system project.
Employee leave management system project.Kamal Acharya
 
Work-Permit-Receiver-in-Saudi-Aramco.pptx
Work-Permit-Receiver-in-Saudi-Aramco.pptxWork-Permit-Receiver-in-Saudi-Aramco.pptx
Work-Permit-Receiver-in-Saudi-Aramco.pptxJuliansyahHarahap1
 
Standard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power PlayStandard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power PlayEpec Engineered Technologies
 

Dernier (20)

Thermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.pptThermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.ppt
 
Wadi Rum luxhotel lodge Analysis case study.pptx
Wadi Rum luxhotel lodge Analysis case study.pptxWadi Rum luxhotel lodge Analysis case study.pptx
Wadi Rum luxhotel lodge Analysis case study.pptx
 
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptxA CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
 
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills KuwaitKuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
 
Design For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startDesign For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the start
 
Thermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VThermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - V
 
Online electricity billing project report..pdf
Online electricity billing project report..pdfOnline electricity billing project report..pdf
Online electricity billing project report..pdf
 
Online food ordering system project report.pdf
Online food ordering system project report.pdfOnline food ordering system project report.pdf
Online food ordering system project report.pdf
 
Double Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueDouble Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torque
 
NO1 Top No1 Amil Baba In Azad Kashmir, Kashmir Black Magic Specialist Expert ...
NO1 Top No1 Amil Baba In Azad Kashmir, Kashmir Black Magic Specialist Expert ...NO1 Top No1 Amil Baba In Azad Kashmir, Kashmir Black Magic Specialist Expert ...
NO1 Top No1 Amil Baba In Azad Kashmir, Kashmir Black Magic Specialist Expert ...
 
Introduction to Serverless with AWS Lambda
Introduction to Serverless with AWS LambdaIntroduction to Serverless with AWS Lambda
Introduction to Serverless with AWS Lambda
 
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
COST-EFFETIVE  and Energy Efficient BUILDINGS ptxCOST-EFFETIVE  and Energy Efficient BUILDINGS ptx
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
 
Moment Distribution Method For Btech Civil
Moment Distribution Method For Btech CivilMoment Distribution Method For Btech Civil
Moment Distribution Method For Btech Civil
 
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptxS1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
 
PE 459 LECTURE 2- natural gas basic concepts and properties
PE 459 LECTURE 2- natural gas basic concepts and propertiesPE 459 LECTURE 2- natural gas basic concepts and properties
PE 459 LECTURE 2- natural gas basic concepts and properties
 
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best ServiceTamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
Employee leave management system project.
Employee leave management system project.Employee leave management system project.
Employee leave management system project.
 
Work-Permit-Receiver-in-Saudi-Aramco.pptx
Work-Permit-Receiver-in-Saudi-Aramco.pptxWork-Permit-Receiver-in-Saudi-Aramco.pptx
Work-Permit-Receiver-in-Saudi-Aramco.pptx
 
Standard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power PlayStandard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power Play
 

Scala best practices

  • 1. Scala best practices Agoda 2017 Alexander Zaidel
  • 2. Functional programming Is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data.
  • 3. Referential transparency and purity An expression e is referentially transparent if for all programs p, all occurrences of e in p can be replaced by the result of evaluating e, without affecting the observable behavior of p. A function f is pure if the expression f(x) is referentially transparent for all referentially transparent x.
  • 4. Example of pure function: def fun(a: Int, b: Int): Int = a / b
  • 5. Example of pure function: def wrong(a: Int, b: Int): Int = a / b def right(a: Int, b: Int): Try[Int] = Try(a / b)
  • 6. apply def getBookingInfo(): BookingInfo = ??? val bookingInfo = getBookingInfo() MakeABooking(bookingInfo) MakeABooking.apply(bookingInfo)
  • 7. apply object MakeABooking { def apply(bookingInfo: BookingInfo): Booking = { new Booking(bookingInfo) } }
  • 8. Enumerations object UserType extends Enumeration { val NewUser, RecurringUser = Value }
  • 9. Enumerations def someAction(userType: UserType): Unit = { userType match { case UserType.NewUser => action1 case UserType.RecurringUser => action2 } }
  • 10. Enumerations def someAction(userType: UserType.Value): Unit = { userType match { case UserType.NewUser => action1 case UserType.RecurringUser => action2 } }
  • 11. object UserType extends Enumeration { type UserType = Value val NewUser, RecurringUser = Value }
  • 12. class vs case class Hashcode Equals, Appy Public access modifiers Unapply Immutability Serializable copy
  • 13. case classes case class User(name: String, birthDay: java.util.Date, country: String) val ivan = User("Ivan", new java.util.Date(), "Thailand") val pipat = ivan.copy(name = "Pipat") println(ivan.name)
  • 14. case classes unapply def getUser(): User = ??? getUser match { case User("Ivan", _, _) | User(_, _, "Thailand") => action1 case _ => action2 }
  • 15. case classes immutability val ivan = User("Ivan", new java.util.Date(), "Thailand") ivan.birthDay.setTime(1L)
  • 16. real cost case class Person(name: String, lastName: String) https://pastebin.com/WFbbnZ0Y https://pastebin.com/20DVQ9QS
  • 17. default values def findUser(userName: String, birthday: Date = new Date(), country: String = "Thailand"): User = ??? findUser("name") findUser("name", country = "USA")
  • 18. unapply class Hotel(val name: String, val address: String, val country: String) def getHotel(): Hotel = ??? getHotel() match { case Hotel(_, "", "UK") => action1 case _ => action2 }
  • 19. unapply object Hotel { def unapply(hotel: Hotel): Option[(String, String, String)] = { Option((hotel.name, hotel.address, hotel.country)) } }
  • 20. Companion object class Booking { import Booking._ private val id: Long = DefaultId private val created: Long = 0L }
  • 21. Companion object object Booking { def doSomething(booking: Booking): Unit = { println(booking.created) } private val DefaultId = 0L }
  • 22. lazy val class Service { private def longRunningComputation(): Int = { Thread.sleep(1000) 42 } private lazy val k = longRunningComputation() }
  • 23. public class Service { private int k; private volatile boolean bitmap$0; private int longRunningComputation(){Thread.sleep(1000L);return 42;} private int k$lzycompute(){ synchronized (this){ if (!this.bitmap$0){ this.k = longRunningComputation();this.bitmap$0 = true; } return this.k; } } private int k(){ return this.bitmap$0 ? this.k : k$lzycompute(); } }
  • 24. lazy val causing a deadlock https://issues.scala-lang.org/browse/SI-5808
  • 26. equals vs == object Foo { def getName(): String = null getName().equals("") }
  • 27. equals vs == object Foo { def getName(): String = null getName() == "" }
  • 28. Option val value: String = ??? Option(value).map(someValue => { val tmp = someValue + 1 println(tmp) })
  • 29. Option val value: String = ??? Option(value).map { someValue => val tmp = someValue + 1 println(tmp) }
  • 30. Option case class User(age: Int, name: String, gender: Option[String]) val user = User(25, "Ivan", Some("male")) user.gender match { case Some(gender) => println("Gender: " + gender) case None => println("Gender: not specified") }
  • 31. Option def foo(gender: String): Unit = ??? val user = User(25, "Ivan", Some("male")) if(user.gender.isDefined) { foo(user.gender.get) }
  • 32. Option user.gender match { case Some(gender) => Some(gender.length) case None => None }
  • 33. Option def findUserFromDb(userId: Int): Option[User] = ??? val currentUser = findUserFromDb(userId) val defaultUser = findUserFromDb(defaultUserId) currentUser orElse defaultUser
  • 34. Option def getName(): String = null Some(getName()).map { name => name.length }
  • 35. Option def getName(): String = null Option(getName()).map { name => name.length }
  • 36. Collections def predicate: Boolean = ??? def foo(): List[Int] = ??? if(predicate) foo() else List()
  • 37. List.empty, Map.empty, Array.empty def predicate: Boolean = ??? def foo(): List[Int] = ??? if(predicate) foo() else List.empty
  • 38. def foo(): List[Int] = List(1, 2, 3) foo() match { case b: List[String] => println("String") case a: List[Int] => println("Int") case c: List[AnyRef] => println("AnyRef") case c: List[AnyVal] => println("AnyVal") }
  • 39. Collections (1 to 400).filter(_ > 200).map(_.toString) vs (1 to 400).collect{ case a if(a > 200) => a.toString }
  • 41. Don’t compute full length for length matching seq.length > n seq.length < n seq.length == n seq.length != n seq.lengthCompare(n) > 0 seq.lengthCompare(n) < 0 seq.lengthCompare(n) == 0 seq.lengthCompare(n) != 0
  • 42. Don’t rely on == to compare array contents array1 == array2 vs array1.sameElements(array2)
  • 43. Don’t check index bounds explicitly if (i < seq.length) Some(seq(i)) else None vs seq.lift(i)
  • 44. Be careful with contains argument type Seq(1, 2, 3).contains("1") // compilable vs Seq(1, 2, 3).contains(1)
  • 45. Merge consecutive filter calls seq.filter(p1).filter(p2) vs seq.filter(x => p1(x) && p2(x))
  • 47. tuples case class User(name: String, hobby: String) List(User("Ivan", "football"), User("Pipat", "scala"), User("Eugene", "scala") ).groupBy(_.hobby).map(users => users._2.size)
  • 48. tuples List( User("Ivan", "football"), User("Pipat", "scala"), User("Eugene", "scala") ).groupBy(_.hobby).map { case (hobby, users) => users.size }
  • 49. Future def apply[T](body : => T)(implicit executor :ExecutionContext) : Future[T]
  • 50. Future def longRunningJob(): Int = {Thread.sleep(1000); 42} Future(longRunningJob()).map { result => result + 100 }.recover { case NonFatal(e) => 0 }
  • 51. Future val myFuture = Future(longRunningJob()) myFuture.onComplete{ case Success(value) => value + 100 case Failure(t) => 0 }
  • 52. Future case class Hotel(id: Long) val preCachedHotels: List[Hotel] = ??? def dbCall(id: Long): Future[Hotel] = ??? def findHotel(id: Long): Future[Hotel] = preCachedHotels.find(_.id == id). map { user => Future(user) }.getOrElse(dbCall(id))
  • 53. Future: successful case class Hotel(id: Long) val preCachedHotels: List[Hotel] = ??? def dbCall(id: Long): Future[Hotel] = ??? def findHotel(id: Long): Future[Hotel] = preCachedHotels.find(_.id == id). map { user => Future.successful(user) }.getOrElse(dbCall(id))
  • 54. Future def callDB(id: Long): Future[User] = ??? def findUser(id: Long): Future[User] = { if(id < 0) Future(new Exception("User can't contain negative id")) else callDB(id) }
  • 55. Future: failed def callDB(id: Long): Future[User] = ??? def findUser(id: Long): Future[User] = { if(id < 0) Future.failed(new Exception("User can't contain negative id")) else callDB(id) }
  • 56. Future.sequence case class User(id: Long) def getAllUserIds(): List[Long] = ??? def findUserById(id: Long): Future[User] = ??? val usersF: List[Future[User]] = getAllUserIds().map(findUserById) val allUsersFetchedF: Future[List[User]] = Future.sequence(usersF)
  • 57. for comprehension val aOption = Some(5); val bOption = Some(6) aOption.flatMap(a => bOption.map(b => a + b)) for { a <- aOption b <- bOption } yield a + b
  • 58. for comprehension and futures for { cityId <- someCalculation() countryId <- someOtherCalculation() district <- someDifferentCalculation() } yield doSomethingWith(cityId, countryId, district)
  • 59. val cityIdF = someCalculation() val countryIdF = someOtherCalculation() val districtF = someDifferentCalculation() for { cityId <- cityIdF countryId <- countryIdF district <- districtF } yield doSomethingWith(cityId, countryId, district)
  • 60. Implicits conversion case class User(name: String, age: Int) implicit def userToString(user: User): String = s"${user.name}${user.age}" def giveMeString(arg: String): Unit = println(arg) val IamString = User("string", 42) giveMeString(IamString)
  • 61. Implicit Parameter case class Minerals(typeOfMineral: String) implicit val calcium = Minerals("calcium") def needMoreMinerals(implicit minerals: Minerals): Unit = println(minerals.typeOfMineral) needMoreMinerals
  • 62. PIMP my library implicit class StringPimp(value: String) { def allStringsAreMine(): String = "I was enslaved" } println("Hello".allStringsAreMine())
  • 63. Abstract methods in traits trait Foo { def foo() } trait M extends Foo{abstract override def foo() { println("M"); super.foo() } } class FooImpl1 extends Foo { override def foo() { println("Impl") } } class FooImpl2 extends FooImpl1 with M new FooImpl2().foo()
  • 64. Sealed classes def getMyOption[T](): MyOption[T] = ??? getMyOption() match { case MyEmpty => action1 case MySome(a) => action1 } sealed abstract class MyOption[T] case object MyEmpty extends MyOption[Nothing] case class MySome[T](t: T) extends MyOption[T] case class MyAnotherState[T](t: T) extends MyOption[T]
  • 65. Resources Scala for the Impatient https://pavelfatin.com/scala-collections-tips-and-tricks/ http://danielwestheide.com/scala/neophytes.html Programming in Scala, 3rd Edition
  • 66. Q & A