47
“Insulin” for Scala’s Syntactic Diabetes Tzach Zohar // Kenshoo // Scalapeño 2016

“Insulin” for Scala’s Syntactic Diabetes

Embed Size (px)

Citation preview

Page 1: “Insulin” for Scala’s Syntactic Diabetes

“Insulin” for Scala’s Syntactic DiabetesTzach Zohar // Kenshoo // Scalapeño 2016

Tzach Zohar
give examples for each one
Page 2: “Insulin” for Scala’s Syntactic Diabetes

OR: How to adopt Scala and survive source

Page 3: “Insulin” for Scala’s Syntactic Diabetes
Page 5: “Insulin” for Scala’s Syntactic Diabetes

Who am INOT Chuck Norris!

Scala “Advanced Beginner” / “Competent”

System Architect @ Kenshoo

Page 6: “Insulin” for Scala’s Syntactic Diabetes

Who’s Kenshoo10-year Tel-Aviv based startup

Industry Leader in Digital Marketing

Java + JavaScript shop

http://kenshoo.com/

Page 7: “Insulin” for Scala’s Syntactic Diabetes

Scala @ Kenshoo5 services written in Scala

More to come...

Internal Scala course on the go

Page 8: “Insulin” for Scala’s Syntactic Diabetes

What’s so scary?

Page 9: “Insulin” for Scala’s Syntactic Diabetes

trait GeneralizedCategory { type U <: Hom type =>:[A >: U#L <: U#H, B >: U#L <: U#H] = U#C[A, B]

def id[A >: U#L <: U#H]: A =>: A

def compose[A >: U#L <: U#H, B >: U#L <: U#H, C >: U#L <: U#H]( f: B =>: C, g: A =>: B): A =>: C

def *[UY<:Hom](that : GeneralizedCategory {type U=UY}) = Category.ProductCategory[U,UY](this,that)}

source

Page 11: “Insulin” for Scala’s Syntactic Diabetes

source

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That

Page 13: “Insulin” for Scala’s Syntactic Diabetes

val tuples = List((1, 374), (3, 42), (5, 693))

val ids = tuples.map(_._1)val ids = tuples.map(tuple => tuple._1)val ids = tuples.map { tuple => tuple._1 }

Page 14: “Insulin” for Scala’s Syntactic Diabetes

val tuples = List((1, 374), (3, 42), (5, 693))

val ids = tuples.map(_._1)val ids = tuples.map(tuple => tuple._1)val ids = tuples.map { tuple => tuple._1 }

val ids = tuples.map(t => t match { case (id, value)=> id })val ids = tuples.map(_ match { case (id, value) => id })val ids = tuples.map({ case (id, value) => id })val ids = tuples.map { case (id, value) => id }val ids = tuples.map { case (id, _) => id }

Page 15: “Insulin” for Scala’s Syntactic Diabetes

case class Profile() { … }case class ProfileId(id: Int)

def loadProfile(profileId: ProfileId): Profile = ???

Page 16: “Insulin” for Scala’s Syntactic Diabetes

case class Profile() { … }case class ProfileId(id: Int)

def loadProfile(profileId: ProfileId): Profile = ???loadProfile(ProfileId(3))loadProfile(new ProfileId(3))loadProfile(profileId = ProfileId(3))loadProfile(profileId = new ProfileId(3))

Page 17: “Insulin” for Scala’s Syntactic Diabetes

case class Profile() { … }case class ProfileId(id: Int)implicit def toId(i :Int): ProfileId = ProfileId(i)

def loadProfile(profileId: ProfileId): Profile = ???loadProfile(ProfileId(3))loadProfile(new ProfileId(3))loadProfile(profileId = ProfileId(3))loadProfile(profileId = new ProfileId(3))loadProfile(3)loadProfile(profileId = 3)

Page 18: “Insulin” for Scala’s Syntactic Diabetes

def loadInt(): Int = { … }

def f(value: () => Int) = { … }f(() => 2 + loadInt())

Page 19: “Insulin” for Scala’s Syntactic Diabetes

def loadInt(): Int = { … }

def f(value: () => Int) = { … }f(() => 2 + loadInt())

def f(value: => Int) = { … } f(2 + loadInt())

Page 21: “Insulin” for Scala’s Syntactic Diabetes

Issues so far

Too many ways to write the same thingTradeoff between short and readable

Advanced features getting in the way

Page 22: “Insulin” for Scala’s Syntactic Diabetes

Insulin to the rescue

Page 24: “Insulin” for Scala’s Syntactic Diabetes

Style Guides1. The basic: Official Scala-Lang Style Guide2. The conservative: Databricks' Scala Style Guide3. The exhaustive: Twitter's Effective Scala4. Your own!

Page 25: “Insulin” for Scala’s Syntactic Diabetes

Style Guidesimplicit def toId(i :Int): ProfileId = ProfileId(i)loadProfile(ProfileId(3))loadProfile(3)

“Do not use implicits to do automatic conversions between similar datatypes”

Page 26: “Insulin” for Scala’s Syntactic Diabetes

Style Guides

“Avoid infix notation for methods that aren't symbolic methods”

list map funcstring contains "foo"list.map(func)string.contains("foo")val x = y + 2

Page 27: “Insulin” for Scala’s Syntactic Diabetes

Style Guidesval ids = tuples.map(t => t match { case (id, value)=> id })val ids = tuples.map(_ match { case (id, value) => id })val ids = tuples.map { case (id, value) => id }val ids = tuples.map { case (id, _) => id }

“Use pattern matching directly in function definitions whenever applicable”

Page 28: “Insulin” for Scala’s Syntactic Diabetes

Style Guidesdef f(value: => Int) = ???f(2 + 3)def f(value: () => Int) = ???f(() => 2 + 3)

“Avoid using call by name. Use () => T explicitly”

Page 29: “Insulin” for Scala’s Syntactic Diabetes

@throws[IOException]def mightThrowException(): Int

def neverThrowsException(): Option[Int]def neverThrowsException(): Try[Int]def neverThrowsException(): Either[Int, String]def neverThrowsException(): MyResult

Style Guides

“Scala provides an exception facility, but do not use it for commonplace errors”

Page 30: “Insulin” for Scala’s Syntactic Diabetes

val ids = tuples.map(_._1)val ids = tuples.map(tuple => tuple._1)

val ids = tuples.map { case (id, value) => id }val ids = tuples.map { case (id, _) => id }

Style Guides

“Avoid using tuple field names like _1, prefer pattern matching or a dedicated case class”

Page 32: “Insulin” for Scala’s Syntactic Diabetes

Code ReviewsRefer author to Style GuidesMix “Scala Levels” - juniors should review seniors’ code

Page 33: “Insulin” for Scala’s Syntactic Diabetes

Code Reviews

Page 34: “Insulin” for Scala’s Syntactic Diabetes

Code Reviews

Page 35: “Insulin” for Scala’s Syntactic Diabetes

Code Reviews

[Only] methods which act as accessors [...] should be declared without parentheses, except if they have side effects

Page 37: “Insulin” for Scala’s Syntactic Diabetes

Style CheckersAutomate some of the (simpler) rules1. Scalastyle (SBT/Gradle/Maven/Eclipse/IntelliJ)2. Scalafmt (SBT/Vim/CLI/IntelliJ) [NEW]

Page 38: “Insulin” for Scala’s Syntactic Diabetes

⌚ 18:45:25 ➜ sbt scalastyle [info] Loading project definition from /.../project[info] Set current project to myProject (in build file:/.../)[warn] MyJob.scala:31:6: parameter.number.message[error]MyService.scala:42:6: public.methods.have.type.message[info] Processed 42 file(s)[info] Found 1 errors[info] Found 2 warnings[info] Found 0 infos[info] Finished in 39 ms

Style Checkers

Page 40: “Insulin” for Scala’s Syntactic Diabetes

Scala Levels

Application Programmer Library Designer

A1: Beginner L1: Junior

A2: Intermediate L2: Senior

A3: Expert L3: Expert

Defined by Martin Odersky in a 2011 post

Page 41: “Insulin” for Scala’s Syntactic Diabetes

Scala LevelsApplication Includes

A1: Beginner Basic syntax; Simple Closures; Collections; For-expressions; …

A2: Intermediate Pattern matching; Trait composition; (Tail) Recursion; …

A3: Expert Folds; Streams + other lazy data structures; Actors; …

Page 42: “Insulin” for Scala’s Syntactic Diabetes

Scala LevelsLibrary Includes

L1: Junior Type parameters; Traits; Lazy vals; Currying; By-name parameters

L2: Senior Variance; Existential types; Cake Pattern; Structural types; Extractors; …

L3: Expert Early initializers; Abstract types; Implicit definitions; Higher-kinded types; …

Page 43: “Insulin” for Scala’s Syntactic Diabetes

source

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That

Page 45: “Insulin” for Scala’s Syntactic Diabetes

Conclusions

Page 46: “Insulin” for Scala’s Syntactic Diabetes

1. Intermediate Scala works

(might be better than Expert Java!) 2. Style and Feature-

set can be controlled

3. No Chuck-Norrisness Required source

Page 47: “Insulin” for Scala’s Syntactic Diabetes

Thank You