SlideShare a Scribd company logo
1 of 46
Analysing Scala Puzzlers:
Essential and Accidental
Complexity in Scala
Andrew Phillips & Nermin Serifovic
@ScalaPuzzlers
About us
Andrew
● Lots of enterprise software
development on high-
performance systems
● Active open source contributor
and committer
Nermin
Co-organizer of Boston Area Scala
Enthusiasts
Co-instructor of Concurrent
Programming in Scala
Maintainers of scalapuzzlers.com and
authors of Scala Puzzlers
Agenda
Introduction
Puzzler Clusters
Reflections & Conclusions
Introduction
What are we trying to do here?
● We’ve been collecting examples of “surprising”
Scala code for a couple of years now
● We thought it was time to see if we could
identify some patterns
● Looking at the results, we tried to ask
ourselves: is the “puzzler cost” of a particular
language area outweighed by the “feature
benefit”
What are we trying to do here?
The clusters, based on 46 puzzlers:
● Cluster 1: Object-orientation
● Cluster 2: Collections
● Cluster 3: Syntax sugar
● Cluster 4: The type system
●Cluster 5: Functional programming
Cluster 1: Object-
orientation
15 puzzlers
What’s the issue?
Scala aims to combine functional and object-
oriented features...and play nicely with Java on
top of that.
Gotcha: Java peeking in
def value: Int = {
def one(x: Int): Int = { return x; 1 }
val two = (x: Int) => { return x; 2 }
1 + one(2) + two(3)
}
println(value)
Gotcha: Initialization in subclasses
class A {
type X // equivalent to X <: Any
var x: X = _
}
class B extends A { type X = Int }
val b = new B
println(b.x)
val bX = b.x
println(bX)
Gotcha: Constructors
object HipNTrendyMarket extends App { // now extends App!
implicit val normalMarkup = new Markup
Console println makeLabel(3)
implicit val touristMarkup = new TouristMarkup
Console println makeLabel(5)
}
object OldSkoolMarket {
def main(args: Array[String]): Unit = {
implicit val normalMarkup = new Markup
Console println makeLabel(3)
implicit val touristMarkup = new TouristMarkup
Console println makeLabel(5)
}
}
Moral of the story
Try to prevent non-idiomatic elements from
seeping though Scala/Java boundaries in
your code
If you’re using a lot of inheritance, study the
rules for variable initialization
Class body != method body
Cluster 2: Collections
9 puzzlers
Collections are powerful...and sometimes
puzzling
What’s the issue?
Gotcha: collections are functions!
Most commonly used collections are instances
of Function1:
List: index => element
Set: element => Boolean
Map: key => value
Gotcha: collections are functions!
This comes handy in many situations, such as:
val daysOfWeek = Map("Mon" -> 1, "Tue" -> 2, "Wed" -> 3,
"Thu" -> 4, "Fri" -> 5, "Sat" -> 6, "Sun" -> 7)
def foo(day: String, daysOfWeek: String => Int) =
println(s"${day} is the ${daysOfWeek(day)}. day of the week")
scala> foo("Mon", daysOfWeek)
Mon is the 1. day of the week
Gotcha: collections are functions!
Sometimes, this produces undesired effects...
def pad2(sb: StringBuilder, width: Int) = {
1 to width - sb.length foreach { sb append '*' }
sb
}
Gotcha: collections are functions!
Sometimes, this produces undesired effects...
def pad2(sb: StringBuilder, width: Int) = {
1 to width - sb.length foreach { sb append '*' }
sb
}
// 1 to (width - sb.length) foreach (_ => sb append '*')
Gotcha: convenience (?) methods
val ints = Map(1 -> List(1, 2, 3, 4, 5))
val bits = ints map { case (k, v) => (k, v.toIterator) }
val nits = ints mapValues (_.toIterator)
scala> print(bits(1).next, bits(1).next)
(1,2)
scala> print(nits(1).next, nits(1).next)
(1,1)
// keys are mapped to key => this(key).toIterator
Gotcha: convenience (?) methods
import collection.mutable.Queue
val goodies: Map[String, Queue[String]] = Map().withDefault(_ =>
Queue("No superheros here. Keep looking."))
val baddies: Map[String, Queue[String]] =
Map().withDefaultValue(Queue("No monsters here. Lucky you."))
println(goodies("kitchen").dequeue)
println(baddies("in attic").dequeue)
println(goodies("dining room").dequeue)
println(baddies("under bed").dequeue)
Moral of the story
Scala collections are powerful
Can be passed where Function1 is expected,
which is a useful feature, but also one to be
careful about
Pay special attention when dealing with
convenience methods that appear similar -
not all of them behave intuitively
Cluster 3:
Syntax sugar
11 puzzlers
Scala promotes elegant, concise coding style.
At the same time, the spec tries to remove
complexity from the compilation process early.
This results in a lot of rewriting of expressions.
What’s the issue?
Gotcha: placeh_lders
List(1, 2).map { i => println("Hi"); i + 1 }
List(1, 2).map { println("Hi"); _ + 1 }
Gotcha: for expressions
val xs = Seq(Seq("a", "b", "c"), Seq("d", "e", "f"), Seq("g",
"h"), Seq("i", "j", "k"))
val ys = for (Seq(x, y, z) <- xs) yield x + y + z
val zs = xs map { case Seq(x, y, z) => x + y + z }
Gotcha: implicit magic
case class Card(number: Int, suit: String = "clubs") {
val value = (number % 13) + 1 // ace = 1, king = 13
def isInDeck(implicit deck: List[Card]) = deck contains this
}
implicit val deck = List(Card(1, "clubs"))
implicit def intToCard(n: Int) = Card(n)
println(1.isInDeck)
Moral of the story
Beware when the syntax sugar for similar but
different things looks almost identical
Learn the details of more complex
desugarings, e.g. how for expressions are
translated
There are too many ways to do (almost) the
same thing with implicits - stick to one style
Cluster 4:
The Type System
7 puzzlers
By design, the Scala compiler tries to be
tolerant and “make the most of” an expression
by slightly transforming it in various ways.
In lots of situations, this goes against
programmer’s intentions
What’s the issue?
Gotcha: Type widening
val zippedLists = (List(1,3,5), List(2,4,6)).zipped
val result = zippedLists.find(_._1 > 10).getOrElse(10)
result: Any = 10
def List.find(p: (A) ⇒ Boolean): Option[A]
def Option.getOrElse[B >: A](default: ⇒ B): B
Type B is inferred to be Any - the least common
supertype between Tuple2 and Int
Gotcha: Type widening
For explicitly defined type hierarchies, this works as
intended:
scala> trait Animal
scala> class Dog extends Animal
scala> class Cat extends Animal
scala> val dog = Option(new Dog())
scala> val cat = Option(new Cat())
scala> dog.orElse(cat)
res0: Option[Animal] = Some(Dog@7d8995e)
Gotcha: Auto-tupling
def foo(any: Any) = println(any)
foo(“a”, “b”, “c”)
(a, b, c)
The compiler tries to pack all arguments into a
tuple and applies foo to that. This is the last
thing which is tried (after default arguments).
Gotcha: Type adaption galore
val numbers = List("1", "2").toSet() + "3"
println(numbers)
false3
def List.toSet[B >: A]: Set[B]
List("1", "2").toSet.apply() // apply() == contains()
Compiler implicitly inserts Unit value () and infers
supertype Any:
List("1", "2").toSet[Any].apply(())
Gotcha: Type adaption galore
●Not desirable in general
●Too much “magic” involved
●Automatic () insertion deprecated in 2.11
Moral of the story
We often wish the compiler was more strict
and threw an error in such cases
We should take advantage of static analysis
tools available (WartRemover, compiler
flags, linters, etc.)
Extensive unit testing of statically typed code
is still necessary
Moral of the story
Take advantage of the compiler flags:
-deprecation,
-unchecked,
-feature,
-Xfatal-warnings,
-Xlint
Cluster 5:
Functional programming
5 puzzlers
What’s the issue?
There are lots of ways you can specify and call
functions...
Gotcha: Partial application
var x = 0
def counter = { x += 1; x }
def add(a: Int)(b: Int) = a + b
val adder1 = add(counter)(_)
val adder2 = add(counter) _
println("x = " + x)
println(adder1(10))
println("x = " + x)
println(adder2(10))
println("x = " + x)
Gotcha: Native function syntax
val isEven = PartialFunction[Int, String] {
case n if n % 2 == 0 => "Even"
}
Moral of the story
There are many flavours of partial application
that do slightly different things - try to stick to
a few
If you are going to use native function syntax,
ensure you know exactly what you’re
creating
Reflections &
Conclusions
●Java interoperability comes at a high cost
●It pays to study the rules of common
desugarings closely
●Implicits up the level of “magic” in your code
quite significantly
●Read the ScalaDoc carefully
●Don’t skimp on unit testing
TL;DR: agree on :
● Scala features you really need; use linters,
code review etc. to catch the others
●common code style in areas where the
language allows multiple options
Questions?
Thank you!
Be the one to submit the next puzzler at
scalapuzzlers.com!

More Related Content

What's hot

Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesDebasish Ghosh
 
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingA Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingGarth Gilmour
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation streamRuslan Shevchenko
 
A Brief Intro to Scala
A Brief Intro to ScalaA Brief Intro to Scala
A Brief Intro to ScalaTim Underwood
 
Scala introduction
Scala introductionScala introduction
Scala introductionvito jeng
 
A Tour Of Scala
A Tour Of ScalaA Tour Of Scala
A Tour Of Scalafanf42
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecLoïc Descotte
 
Introduction to scala
Introduction to scalaIntroduction to scala
Introduction to scalaMichel Perez
 
Scala collections api expressivity and brevity upgrade from java
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 javaIndicThreads
 
Demystifying functional programming with Scala
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with ScalaDenis
 
ScalaDays 2013 Keynote Speech by Martin Odersky
ScalaDays 2013 Keynote Speech by Martin OderskyScalaDays 2013 Keynote Speech by Martin Odersky
ScalaDays 2013 Keynote Speech by Martin OderskyTypesafe
 
scala.reflect, Eugene Burmako
scala.reflect, Eugene Burmakoscala.reflect, Eugene Burmako
scala.reflect, Eugene BurmakoVasil Remeniuk
 
Metaprogramming in Scala 2.10, Eugene Burmako,
Metaprogramming  in Scala 2.10, Eugene Burmako, Metaprogramming  in Scala 2.10, Eugene Burmako,
Metaprogramming in Scala 2.10, Eugene Burmako, Vasil Remeniuk
 

What's hot (20)

Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rules
 
Why Haskell
Why HaskellWhy Haskell
Why Haskell
 
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingA Sceptical Guide to Functional Programming
A Sceptical Guide to Functional Programming
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
 
A Brief Intro to Scala
A Brief Intro to ScalaA Brief Intro to Scala
A Brief Intro to Scala
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
 
A Tour Of Scala
A Tour Of ScalaA Tour Of Scala
A Tour Of Scala
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
 
Introduction to scala
Introduction to scalaIntroduction to scala
Introduction to scala
 
Scala for curious
Scala for curiousScala for curious
Scala for curious
 
Scala collections api expressivity and brevity upgrade from java
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
 
Demystifying functional programming with Scala
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with Scala
 
Scala vs java 8
Scala vs java 8Scala vs java 8
Scala vs java 8
 
ScalaDays 2013 Keynote Speech by Martin Odersky
ScalaDays 2013 Keynote Speech by Martin OderskyScalaDays 2013 Keynote Speech by Martin Odersky
ScalaDays 2013 Keynote Speech by Martin Odersky
 
Scala on Android
Scala on AndroidScala on Android
Scala on Android
 
scala.reflect, Eugene Burmako
scala.reflect, Eugene Burmakoscala.reflect, Eugene Burmako
scala.reflect, Eugene Burmako
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Metaprogramming in Scala 2.10, Eugene Burmako,
Metaprogramming  in Scala 2.10, Eugene Burmako, Metaprogramming  in Scala 2.10, Eugene Burmako,
Metaprogramming in Scala 2.10, Eugene Burmako,
 

Viewers also liked

Viewers also liked (17)

Valentine's Day Wine Menu
Valentine's Day Wine MenuValentine's Day Wine Menu
Valentine's Day Wine Menu
 
T.s.16 piragua 1
T.s.16 piragua  1T.s.16 piragua  1
T.s.16 piragua 1
 
Watching wrc 2015 rally poland live
Watching wrc 2015 rally poland liveWatching wrc 2015 rally poland live
Watching wrc 2015 rally poland live
 
Wrc 2015 rally poland
Wrc 2015 rally polandWrc 2015 rally poland
Wrc 2015 rally poland
 
Desarrollo sustentable
Desarrollo sustentableDesarrollo sustentable
Desarrollo sustentable
 
Deployment is the new build
Deployment is the new buildDeployment is the new build
Deployment is the new build
 
My role
My roleMy role
My role
 
mapa-conceptual-actividad1-grupo6
mapa-conceptual-actividad1-grupo6mapa-conceptual-actividad1-grupo6
mapa-conceptual-actividad1-grupo6
 
Diagrama Slideshare
Diagrama SlideshareDiagrama Slideshare
Diagrama Slideshare
 
Fenomenosydesastresnaturales final 1.0
Fenomenosydesastresnaturales final 1.0Fenomenosydesastresnaturales final 1.0
Fenomenosydesastresnaturales final 1.0
 
Kelopok kursi amer
Kelopok kursi amerKelopok kursi amer
Kelopok kursi amer
 
Las políticas alimentarias
Las políticas alimentariasLas políticas alimentarias
Las políticas alimentarias
 
Metrics-driven Continuous Delivery
Metrics-driven Continuous DeliveryMetrics-driven Continuous Delivery
Metrics-driven Continuous Delivery
 
Comunicación 1.0 y 2.0: Aplicación en el ámbito de la SST
Comunicación 1.0 y 2.0: Aplicación en el ámbito de la SSTComunicación 1.0 y 2.0: Aplicación en el ámbito de la SST
Comunicación 1.0 y 2.0: Aplicación en el ámbito de la SST
 
Know your cirrus from your cumulus (with notes)
Know your cirrus from your cumulus (with notes)Know your cirrus from your cumulus (with notes)
Know your cirrus from your cumulus (with notes)
 
Ts 16 observacio 5
Ts 16 observacio 5Ts 16 observacio 5
Ts 16 observacio 5
 
Mapa conceptual proyectos
Mapa conceptual proyectosMapa conceptual proyectos
Mapa conceptual proyectos
 

Similar to Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexity in Scala"

Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With ScalaKnoldus Inc.
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with ScalaNeelkanth Sachdeva
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scalashinolajla
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java ProgrammersEric Pederson
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Martin Odersky
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 
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 risksSeniorDevOnly
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
 
The things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaThe things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaKonrad Malawski
 
Scala final ppt vinay
Scala final ppt vinayScala final ppt vinay
Scala final ppt vinayViplav Jain
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Languageleague
 
Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)Tomer Gabel
 
Introduction to meta-programming in scala
Introduction to meta-programming in scalaIntroduction to meta-programming in scala
Introduction to meta-programming in scalaAlessandro Marrella
 

Similar to Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexity in Scala" (20)

Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with Scala
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009
 
Scala ntnu
Scala ntnuScala ntnu
Scala ntnu
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
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
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Scala coated JVM
Scala coated JVMScala coated JVM
Scala coated JVM
 
The things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaThe things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and Akka
 
Scala final ppt vinay
Scala final ppt vinayScala final ppt vinay
Scala final ppt vinay
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Language
 
Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)
 
Fancy talk
Fancy talkFancy talk
Fancy talk
 
Introduction to meta-programming in scala
Introduction to meta-programming in scalaIntroduction to meta-programming in scala
Introduction to meta-programming in scala
 
Scala - core features
Scala - core featuresScala - core features
Scala - core features
 

More from Andrew Phillips

Spinnaker Summit 2019: Where are we heading? The Future of Continuous Delivery
Spinnaker Summit 2019: Where are we heading? The Future of Continuous DeliverySpinnaker Summit 2019: Where are we heading? The Future of Continuous Delivery
Spinnaker Summit 2019: Where are we heading? The Future of Continuous DeliveryAndrew Phillips
 
Docker New York City: From GitOps to a scalable CI/CD Pattern for Kubernetes
Docker New York City: From GitOps to a scalable CI/CD Pattern for KubernetesDocker New York City: From GitOps to a scalable CI/CD Pattern for Kubernetes
Docker New York City: From GitOps to a scalable CI/CD Pattern for KubernetesAndrew Phillips
 
Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...
Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...
Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...Andrew Phillips
 
Spinnaker Summit 2018: CI/CD Patterns for Kubernetes with Spinnaker
Spinnaker Summit 2018: CI/CD Patterns for Kubernetes with SpinnakerSpinnaker Summit 2018: CI/CD Patterns for Kubernetes with Spinnaker
Spinnaker Summit 2018: CI/CD Patterns for Kubernetes with SpinnakerAndrew Phillips
 
OpenDev 2018: "Open CD for Open Infrastructure - Hybrid and Multi-Cloud Deplo...
OpenDev 2018: "Open CD for Open Infrastructure - Hybrid and Multi-Cloud Deplo...OpenDev 2018: "Open CD for Open Infrastructure - Hybrid and Multi-Cloud Deplo...
OpenDev 2018: "Open CD for Open Infrastructure - Hybrid and Multi-Cloud Deplo...Andrew Phillips
 
New York Kubernetes: CI/CD Patterns for Kubernetes
New York Kubernetes: CI/CD Patterns for KubernetesNew York Kubernetes: CI/CD Patterns for Kubernetes
New York Kubernetes: CI/CD Patterns for KubernetesAndrew Phillips
 
nycdevops: "Breaking Down the Prod/Dev Wall"
nycdevops: "Breaking Down the Prod/Dev Wall"nycdevops: "Breaking Down the Prod/Dev Wall"
nycdevops: "Breaking Down the Prod/Dev Wall"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...
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...Andrew Phillips
 
The Multiple Dimensions of Cross-Cloud Computing
The Multiple Dimensions of Cross-Cloud ComputingThe Multiple Dimensions of Cross-Cloud Computing
The Multiple Dimensions of Cross-Cloud ComputingAndrew Phillips
 
Implementing Continuous Deployment
Implementing Continuous DeploymentImplementing Continuous Deployment
Implementing Continuous DeploymentAndrew Phillips
 
Know your cirrus from your cumulus
Know your cirrus from your cumulusKnow your cirrus from your cumulus
Know your cirrus from your cumulusAndrew Phillips
 

More from Andrew Phillips (11)

Spinnaker Summit 2019: Where are we heading? The Future of Continuous Delivery
Spinnaker Summit 2019: Where are we heading? The Future of Continuous DeliverySpinnaker Summit 2019: Where are we heading? The Future of Continuous Delivery
Spinnaker Summit 2019: Where are we heading? The Future of Continuous Delivery
 
Docker New York City: From GitOps to a scalable CI/CD Pattern for Kubernetes
Docker New York City: From GitOps to a scalable CI/CD Pattern for KubernetesDocker New York City: From GitOps to a scalable CI/CD Pattern for Kubernetes
Docker New York City: From GitOps to a scalable CI/CD Pattern for Kubernetes
 
Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...
Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...
Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...
 
Spinnaker Summit 2018: CI/CD Patterns for Kubernetes with Spinnaker
Spinnaker Summit 2018: CI/CD Patterns for Kubernetes with SpinnakerSpinnaker Summit 2018: CI/CD Patterns for Kubernetes with Spinnaker
Spinnaker Summit 2018: CI/CD Patterns for Kubernetes with Spinnaker
 
OpenDev 2018: "Open CD for Open Infrastructure - Hybrid and Multi-Cloud Deplo...
OpenDev 2018: "Open CD for Open Infrastructure - Hybrid and Multi-Cloud Deplo...OpenDev 2018: "Open CD for Open Infrastructure - Hybrid and Multi-Cloud Deplo...
OpenDev 2018: "Open CD for Open Infrastructure - Hybrid and Multi-Cloud Deplo...
 
New York Kubernetes: CI/CD Patterns for Kubernetes
New York Kubernetes: CI/CD Patterns for KubernetesNew York Kubernetes: CI/CD Patterns for Kubernetes
New York Kubernetes: CI/CD Patterns for Kubernetes
 
nycdevops: "Breaking Down the Prod/Dev Wall"
nycdevops: "Breaking Down the Prod/Dev Wall"nycdevops: "Breaking Down the Prod/Dev Wall"
nycdevops: "Breaking Down the Prod/Dev Wall"
 
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...
 
The Multiple Dimensions of Cross-Cloud Computing
The Multiple Dimensions of Cross-Cloud ComputingThe Multiple Dimensions of Cross-Cloud Computing
The Multiple Dimensions of Cross-Cloud Computing
 
Implementing Continuous Deployment
Implementing Continuous DeploymentImplementing Continuous Deployment
Implementing Continuous Deployment
 
Know your cirrus from your cumulus
Know your cirrus from your cumulusKnow your cirrus from your cumulus
Know your cirrus from your cumulus
 

Recently uploaded

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 

Recently uploaded (20)

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 

Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexity in Scala"

  • 1. Analysing Scala Puzzlers: Essential and Accidental Complexity in Scala Andrew Phillips & Nermin Serifovic @ScalaPuzzlers
  • 2. About us Andrew ● Lots of enterprise software development on high- performance systems ● Active open source contributor and committer Nermin Co-organizer of Boston Area Scala Enthusiasts Co-instructor of Concurrent Programming in Scala Maintainers of scalapuzzlers.com and authors of Scala Puzzlers
  • 5. What are we trying to do here? ● We’ve been collecting examples of “surprising” Scala code for a couple of years now ● We thought it was time to see if we could identify some patterns ● Looking at the results, we tried to ask ourselves: is the “puzzler cost” of a particular language area outweighed by the “feature benefit”
  • 6. What are we trying to do here? The clusters, based on 46 puzzlers: ● Cluster 1: Object-orientation ● Cluster 2: Collections ● Cluster 3: Syntax sugar ● Cluster 4: The type system ●Cluster 5: Functional programming
  • 8. What’s the issue? Scala aims to combine functional and object- oriented features...and play nicely with Java on top of that.
  • 9. Gotcha: Java peeking in def value: Int = { def one(x: Int): Int = { return x; 1 } val two = (x: Int) => { return x; 2 } 1 + one(2) + two(3) } println(value)
  • 10. Gotcha: Initialization in subclasses class A { type X // equivalent to X <: Any var x: X = _ } class B extends A { type X = Int } val b = new B println(b.x) val bX = b.x println(bX)
  • 11. Gotcha: Constructors object HipNTrendyMarket extends App { // now extends App! implicit val normalMarkup = new Markup Console println makeLabel(3) implicit val touristMarkup = new TouristMarkup Console println makeLabel(5) } object OldSkoolMarket { def main(args: Array[String]): Unit = { implicit val normalMarkup = new Markup Console println makeLabel(3) implicit val touristMarkup = new TouristMarkup Console println makeLabel(5) } }
  • 12. Moral of the story Try to prevent non-idiomatic elements from seeping though Scala/Java boundaries in your code If you’re using a lot of inheritance, study the rules for variable initialization Class body != method body
  • 14. Collections are powerful...and sometimes puzzling What’s the issue?
  • 15. Gotcha: collections are functions! Most commonly used collections are instances of Function1: List: index => element Set: element => Boolean Map: key => value
  • 16. Gotcha: collections are functions! This comes handy in many situations, such as: val daysOfWeek = Map("Mon" -> 1, "Tue" -> 2, "Wed" -> 3, "Thu" -> 4, "Fri" -> 5, "Sat" -> 6, "Sun" -> 7) def foo(day: String, daysOfWeek: String => Int) = println(s"${day} is the ${daysOfWeek(day)}. day of the week") scala> foo("Mon", daysOfWeek) Mon is the 1. day of the week
  • 17. Gotcha: collections are functions! Sometimes, this produces undesired effects... def pad2(sb: StringBuilder, width: Int) = { 1 to width - sb.length foreach { sb append '*' } sb }
  • 18. Gotcha: collections are functions! Sometimes, this produces undesired effects... def pad2(sb: StringBuilder, width: Int) = { 1 to width - sb.length foreach { sb append '*' } sb } // 1 to (width - sb.length) foreach (_ => sb append '*')
  • 19. Gotcha: convenience (?) methods val ints = Map(1 -> List(1, 2, 3, 4, 5)) val bits = ints map { case (k, v) => (k, v.toIterator) } val nits = ints mapValues (_.toIterator) scala> print(bits(1).next, bits(1).next) (1,2) scala> print(nits(1).next, nits(1).next) (1,1) // keys are mapped to key => this(key).toIterator
  • 20. Gotcha: convenience (?) methods import collection.mutable.Queue val goodies: Map[String, Queue[String]] = Map().withDefault(_ => Queue("No superheros here. Keep looking.")) val baddies: Map[String, Queue[String]] = Map().withDefaultValue(Queue("No monsters here. Lucky you.")) println(goodies("kitchen").dequeue) println(baddies("in attic").dequeue) println(goodies("dining room").dequeue) println(baddies("under bed").dequeue)
  • 21. Moral of the story Scala collections are powerful Can be passed where Function1 is expected, which is a useful feature, but also one to be careful about Pay special attention when dealing with convenience methods that appear similar - not all of them behave intuitively
  • 23. Scala promotes elegant, concise coding style. At the same time, the spec tries to remove complexity from the compilation process early. This results in a lot of rewriting of expressions. What’s the issue?
  • 24. Gotcha: placeh_lders List(1, 2).map { i => println("Hi"); i + 1 } List(1, 2).map { println("Hi"); _ + 1 }
  • 25. Gotcha: for expressions val xs = Seq(Seq("a", "b", "c"), Seq("d", "e", "f"), Seq("g", "h"), Seq("i", "j", "k")) val ys = for (Seq(x, y, z) <- xs) yield x + y + z val zs = xs map { case Seq(x, y, z) => x + y + z }
  • 26. Gotcha: implicit magic case class Card(number: Int, suit: String = "clubs") { val value = (number % 13) + 1 // ace = 1, king = 13 def isInDeck(implicit deck: List[Card]) = deck contains this } implicit val deck = List(Card(1, "clubs")) implicit def intToCard(n: Int) = Card(n) println(1.isInDeck)
  • 27. Moral of the story Beware when the syntax sugar for similar but different things looks almost identical Learn the details of more complex desugarings, e.g. how for expressions are translated There are too many ways to do (almost) the same thing with implicits - stick to one style
  • 28. Cluster 4: The Type System 7 puzzlers
  • 29. By design, the Scala compiler tries to be tolerant and “make the most of” an expression by slightly transforming it in various ways. In lots of situations, this goes against programmer’s intentions What’s the issue?
  • 30. Gotcha: Type widening val zippedLists = (List(1,3,5), List(2,4,6)).zipped val result = zippedLists.find(_._1 > 10).getOrElse(10) result: Any = 10 def List.find(p: (A) ⇒ Boolean): Option[A] def Option.getOrElse[B >: A](default: ⇒ B): B Type B is inferred to be Any - the least common supertype between Tuple2 and Int
  • 31. Gotcha: Type widening For explicitly defined type hierarchies, this works as intended: scala> trait Animal scala> class Dog extends Animal scala> class Cat extends Animal scala> val dog = Option(new Dog()) scala> val cat = Option(new Cat()) scala> dog.orElse(cat) res0: Option[Animal] = Some(Dog@7d8995e)
  • 32. Gotcha: Auto-tupling def foo(any: Any) = println(any) foo(“a”, “b”, “c”) (a, b, c) The compiler tries to pack all arguments into a tuple and applies foo to that. This is the last thing which is tried (after default arguments).
  • 33. Gotcha: Type adaption galore val numbers = List("1", "2").toSet() + "3" println(numbers) false3 def List.toSet[B >: A]: Set[B] List("1", "2").toSet.apply() // apply() == contains() Compiler implicitly inserts Unit value () and infers supertype Any: List("1", "2").toSet[Any].apply(())
  • 34. Gotcha: Type adaption galore ●Not desirable in general ●Too much “magic” involved ●Automatic () insertion deprecated in 2.11
  • 35. Moral of the story We often wish the compiler was more strict and threw an error in such cases We should take advantage of static analysis tools available (WartRemover, compiler flags, linters, etc.) Extensive unit testing of statically typed code is still necessary
  • 36. Moral of the story Take advantage of the compiler flags: -deprecation, -unchecked, -feature, -Xfatal-warnings, -Xlint
  • 38. What’s the issue? There are lots of ways you can specify and call functions...
  • 39. Gotcha: Partial application var x = 0 def counter = { x += 1; x } def add(a: Int)(b: Int) = a + b val adder1 = add(counter)(_) val adder2 = add(counter) _ println("x = " + x) println(adder1(10)) println("x = " + x) println(adder2(10)) println("x = " + x)
  • 40. Gotcha: Native function syntax val isEven = PartialFunction[Int, String] { case n if n % 2 == 0 => "Even" }
  • 41. Moral of the story There are many flavours of partial application that do slightly different things - try to stick to a few If you are going to use native function syntax, ensure you know exactly what you’re creating
  • 43. ●Java interoperability comes at a high cost ●It pays to study the rules of common desugarings closely ●Implicits up the level of “magic” in your code quite significantly ●Read the ScalaDoc carefully ●Don’t skimp on unit testing
  • 44. TL;DR: agree on : ● Scala features you really need; use linters, code review etc. to catch the others ●common code style in areas where the language allows multiple options
  • 46. Thank you! Be the one to submit the next puzzler at scalapuzzlers.com!