A Taxonomy of Scala
            StrangeLoop 2012

                 Jamie Allen
                @jamie_allen
http://github.com/jamie-allen/taxonomy-of-scala
Agenda
•   Goal
•   Object-Oriented Features
•   Pattern Matching
•   Functional Programming
•   Actors
•   Futures
•   Implicits
•   Type Theory
•   Macros
•   Category Theory
Goal



Provide you with a reference point for many of
  the terms you hear in the Scala community
How Programming in Scala Makes Me Feel
How I Write Programs
• Pre-Scala:
  – Make it work
  – Make it work well
  – Make it work fast
• With Scala:
  – Make it work and work well
  – Make it work fast
Object-Oriented
   Features
Case Classes
case class Person(firstName: String = "Jamie",
   lastName: String = "Allen")

val jamieDoe = Person(lastName = "Doe")
res0: Person = Person(Jamie,Doe)
• Data Transfer Objects (DTOs) done right
• By default, class arguments are immutable & public
• Should never be extended
• Provide equals(), copy(), hashCode() and toString()
  implementations
• Don’t have to use new keyword to create instances
• Named Parameters and Default arguments give us Builder pattern
  semantics
Lazy Definitions
lazy val calculatedValue = piToOneMillionDecimalPoints()


 • Excellent for deferring expensive operations
   until they are needed
 • Reducing initial footprint
 • Resolving ordering issues
 • Implemented with a guard field and
   synchronization, ensuring it is created when
   necessary
Imports
import scala.collection.immutable.Map

class Person(val fName: String, val lName: String) {
   import scala.collection.mutable.{Map => MMap}
   val cars: MMap[String, String] = MMap()
   ...
}

 • Can be anywhere in a class
 • Allow for selecting multiple classes from a package or
   using wildcards
 • Aliasing
 • Order matters!
Objects
object Bootstrapper extends App { Person.createJamieAllen }

object Person {
  def createJamieAllen = new Person("Jamie", "Allen")
  def createJamieDoe = new Person("Jamie", "Doe")
  val aConstantValue = "A constant value”
}

class Person(val firstName: String, val lastName: String)

 • Singletons within a JVM process
 • No private constructor histrionics
 • Companion Objects, used for factories and constants
The apply() method
Array(1, 2, 3)
res0: Array[Int] = Array(1, 2, 3)

res0(1)
res1: Int = 2



 • In companion objects, it defines default
   behavior if no method is called on it
 • In a class, it defines the same thing on an
   instance of the class
Tuples
def firstPerson = (1, Person(firstName = “Barbara”))
val (num: Int, person: Person) = firstPerson


 • Binds you to an implementation
 • Great way to group values without a DTO
 • How to return multiple values, but wrapped in
   a single instance that you can bind to specific
   values
Pattern Matching
Pattern Matching Examples
name match {
  case "Lisa" => println("Found Lisa”)
  case Person("Bob") => println("Found Bob”)
  case "Karen" | "Michelle" => println("Found Karen or Michelle”)
  case Seq("Dave", "John") => println("Got Dave before John”)
  case Seq("Dave", "John", _*) => println("Got Dave before John”)
  case ("Susan", "Steve") => println("Got Susan and Steve”)
  case x: Int if x > 5 => println("got value greater than 5: " + x)
  case x => println("Got something that wasn't an Int: " + x)
  case _ => println("Not found”)
}

 • A gateway drug for Scala
 • Extremely powerful and readable
 • Not compiled down to lookup/table switch unless
   you use the @switch annotation,
Functional
Programming
Immutability
• Extends beyond marking instances final
• You must not leak mutability
Referential Transparency
// Transparent
val example1 = "jamie".reverse
val example2 = example1.reverse
println(example1 + example2) // eimajjamie

// Opaque
val example1 = new StringBuffer("Jamie").reverse
val example2 = example1.reverse
println(example1 append example2) // jamiejamie

 • An expression is transparent if it can be replaced by its
   VALUE without changing the behavior of the program
 • In math, all functions are referentially transparent
Scala Collections
val   myMap = Map(1 -> "one", 2 -> "two", 3 -> "three")
val   mySet = Set(1, 4, 2, 8)
val   myList = List(1, 2, 8, 3, 3, 4)
val   myVector = Vector(1, 2, 3...)



 • You have the choice of mutable or immutable
   collection instances, immutable by default
 • Rich implementations, extremely flexible
Rich Collection Functionality
val numbers = 1 to 20 // Range(1, 2, 3, ... 20)

numbers.head //   Int = 1
numbers.tail //   Range(2, 3, 4, ... 20)
numbers.take(5)   // Range(1, 2, 3, 4, 5)
numbers.drop(5)   // Range(6, 7, 8, ... 20)




 • There are many methods available to you in
   the Scala collections library
 • Spend 5 minutes every day going over the
   ScalaDoc for one collection class
Higher Order Functions
val names = List("Barb", "May", "Jon")

names map(_.toUpperCase)
res0: List[java.lang.String] = List(BARB, MAY, JON)




 • Really methods in Scala
 • Applying closures to collections
Higher Order Functions
val names = List("Barb", "May", "Jon")

names map(_.toUpperCase)
res0: List[java.lang.String] = List(BARB, MAY, JON)

names flatMap(_.toUpperCase)
res1: List[Char] = List(B, A, R, B, M, A, Y, J, O, N)

names filter (_.contains("a"))
res2: List[java.lang.String] = List(Barb, May)

val numbers = 1 to 20 // Range(1, 2, 3, ... 20)

numbers.groupBy(_ % 3)
res3: Map[Int, IndexedSeq[Int]] = Map(1 -> Vector(1, 4, 7, 10, 13,
16, 19), 2 -> Vector(2, 5, 8, 11, 14, 17, 20), 0 -> Vector(3, 6, 9,
12, 15, 18))
For Comprehensions
val myNums = 1 to 20

for (i <- myNums) yield i + 1
myNums map(_ + 1)

for {
  i <- myNums
  j <- 1 to i
} yield i * j
myNums flatMap(i => 1 to i map (j => i * j))

 • Used for composing higher-order functions
 • As you chain higher-order functions, you may
   find it easier to reason about them this way
Parallel Collections
scala> 1 to 1000000
res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3,...

scala> res0.par
res1: s.c.parallel.immutable.ParRange = ParRange(1, 2, 3,...

scala> res1 map(_ + 1)
res2: s.c.parallel.immutable.ParSeq[Int] = ParVector(2, 3, 4,...

scala> res2.seq
res3: s.c.immutable.Range = Range(2, 3, 4,...


 • You can easily parallelize the application of a function literal to your
   collection by calling the par() method on a collection instance
 • Uses JSR166 under the covers to fork/join for you
 • Use the seq() method on the parallel collection to return to a
   non-parallel instance
Partial Functions
class MyActor extends Actor {
  def receive = {
    case s: String => println("Got a String: " + s)
    case i: Int => println("Got an Int: " + i)
    case x => println("Got something else: " + x)
  }
}


 • A simple match without the match keyword
 • The receive block in Akka actors is an excellent
   example
 • Is characterized by what "isDefinedAt" in the
   case statements
Currying
def product(i: Int)(j: Int) = i * j
val doubler = product(2)_
doubler(3) // Int = 6
doubler(4) // Int = 8

val tripler = product(3)_
tripler(4) // Int = 12
tripler(5) // Int = 15

 • Take a function that takes n parameters as separate argument lists
 • “Curry” it to create a new function that only takes one parameter
 • Fix on a value and use it to apply a specific implementation of a
   product with semantic value
 • Have to be defined explicitly as such in Scala
 • The _ is what explicitly marks this as curried
Actors
Actors
import akka.actor._

class MyActor extends Actor {
  def receive = {
     case x => println(“Got value: “ + x)
  }
}

 • Based on concepts from Erlang/OTP
 • Akka is replacing the core language actors
 • Concurrency paradigm using networks of
   independent objects that only communicate
   via messaging and mailboxes
Futures
Futures
import scala.concurrent._

val costInDollars = Future {
  webServiceProxy.getCostInDollars.mapTo[Int]
}

costInDollars map (myPurchase.setCostInDollars(_))



 • Allows you to write asynchronous code, which
   can be more performant than blocking
 • Are not typed, hence the mapTo call above
Futures in Sequence
val customerPurchases = for (
  costUSD <- Future{ proxy.getCostInDollars.mapTo[Int]}
  totalPurchase <- Future{ proxy.addToTotal(costUSD).mapTo[Int]}
} yield ((customerId -> totalPurchase))

 • Scala’s for comprehensions allow you to
   compose higher-order functions, including
   Futures
 • By sequencing the expressions on multiple
   lines, you can order dependencies
Futures in Parallel
val costUSD = Future{proxy.getCostInUSD(cost).mapTo[Int]}
val costCAD = Future{proxy.getCostInCAD(cost).mapTo[Int]}
val combinedCosts = for {
  cUSD <- costUSD
  cCAD <- costCAD
} yield (cUSD, cCAD)

val costs = for (
  (costUSD, costCAD) <-
    Future{proxy.getCostInUSD(cost).mapTo[Int]} zip
    Future{proxy.getCostInCAD(cost).mapTo[Int]}
} yield (costUSD, costCAD)

 • Define the futures separately and then compose
 • Alternatively, the zip method allows you to
   parallelize futures execution within a for
   comprehension
Implicits
Implicit Conversions
Implicit Conversions
case class Person(firstName: String, lastName: String)
implicit def PersonToInt(p: Person) = p.toString.head.toInt

val me = Person("Jamie", "Allen")

val weird = 1 + me
res0: Int = 81


 • Looks for definitions at compile time that will
   satisfy type incompatibilities
 • Modern IDEs will warn you with an underline
   when they are in use
 • Limit scope as much as possible (see Josh
   Suereth's NE Scala 2011)
Implicit Parameters
def executeFutureWithTimeout(f: Future)(implicit t: Timeout)

implicit val t: Timeout = Timeout(20, TimeUnit.MILLISECONDS)
executeFutureWithTimeout(Future {proxy.getCustomer(id)})


 • Allow you to define default parameter values
   that are only overridden if you do so explicitly
 • Handy to avoid code duplication
Implicit Classes
implicit class Person(name: String)

class Person(name: String)
implicit final def Person(name: String): Person = new Person(name)




 • New to Scala 2.10
 • Create extension methods to existing types
 • Desugars at compile time into a class
   definition with an implicit conversion
Type Theory
Type Inference
•   Declaring a variable/value
•   Return types of methods/functions
•   See Daniel Spiewak's Philly ETE 2011 talk
•   Good idea to show types on public interfaces
•   Specify types when you want to type certainty
Type Classes I
case class Customer(id: Long, firstName: String, lastName: String)

trait CustomerOrderById extends Ordering[Customer] {
  def compare(x: Customer, y: Customer): Int = { ... }
}
implicit object CustomerIdSort extends CustomerOrderById

val customers = List(Customer(1, "Jamie", "Allen"), Customer(5,
"John", "Doe"), Customer(2, "Jane", "Smith"))
val sortedCustomers = customers.sorted(CustomerIdSort)
sortedCustomers: List[Customer] = List(Customer(1,Jamie,Allen),
Customer(2,Jane,Smith), Customer(5,John,Doe))

 • Allow you to layer in varying implementations
   of behavior without changing an existing
   inheritance structure
Type Classes II
case class Dog(name: String)
case class Ferret(name: String)
case class Cat(name: String)
abstract class OkayPets[T]
object OkayPets {
  implicit object OkayDog extends OkayPets[Dog]
  implicit object OkayFerret extends OkayPets[Ferret]
}
def getPet[T](t: T)(implicit p: OkayPets[T]) = t

val myDog = getPet(Dog("Sparky")) // Works
val myCat = getPet(Cat("Sneezy")) // Fails at compile time

 • Allows you to generalize types that are
   acceptable parameters for methods
Higher Kinded Types
Map[A, B] // Type constructor, not a type!

val myMap = Map[Int, String]() // Now it’s a type!




 • Use other types to construct a new type
 • Also called type constructors
Algebraic Data Types
sealed abstract class DayOfTheWeek
case object Sunday extends DayOfTheWeek
case object Monday extends DayOfTheWeek
  ...
case object Saturday extends DayOfTheWeek

val nextDay(d: DayOfTheWeek): DayOfTheWeek = d match {
    case Sunday => Monday
    case Monday => Tuesday
    ...
    case Saturday => Sunday
  }
}
 • Allow you to model the world in finite terms, such as enumerations, but
   also define behavior around them, with all of the power of case classes
 • A finite number of possible subtypes, enforced by the "sealed" keyword
   (must be defined in the same source file)
Macros
Macros
• New to Scala 2.10
• Macros are used for generating code at
  compile time, similar to LISP macros
• Does not have compiler pragmas such as
  #ifdef
• Are implemented as "hygenic" macros at the
  point you call reify() – identifiers cannot
  be closed over in a macro definition
ScalaLogging Macro
def debug(message: String): Unit = macro LoggerMacros.debug
private object LoggerMacros {
 def debug(c: LoggerContext)(message: c.Expr[String]) = c.universe.reify(
   if (c.prefix.splice.underlying.isDebugEnabled)
     c.prefix.splice.underlying.debug(message.splice)
  )
}

import com.typesafe.scalalogging.Logging
class MyClass extends Logging {
  logger.debug("This won't occur if debug is not defined")
}




 • Existing log libraries allow us to define logging statements and then
   determine whether they result in output at runtime
 • ScalaLogging allows a user to use a logging facility but decide at compile
   time whether or not to include the logging statement based on log level.
Category Theory
Category Theory
Concepts and Arrows
val myIntToStringArrow: Int => String = _.toString

myIntToStringArrow(1100)
res0: String = 1100


 • Concepts are types
 • Arrows are functions that convert one concept
   to another
Morphism
val number = 1000
val numericString = number.toString



 • Morphisms change one value in a category to
   another in the same category, from one type
   to another where types are the category
 • Simplified, it converts a type with one
   property to a type with another property
 • Must be pure, not side-effecting
Functor
val numbers = List(1, 2, 3, 4)
val numericStrings = numbers.map(_.toString)




 • Functors are transformations from one
   category to another that preserve morphisms
 • Simplified, converts a type from one to
   another while maintaining the conversion of a
   type with one property to a type with another
   property
Monad
val customerPurchases = for (
  costUSD <- proxy.getCostInDollars
  totalPurchase <- proxy.addToTotal(costUSD)
} yield ((customerId -> totalPurchase))




 • Very ephemeral concept
 • Must meet the laws of a monad to be one
 • Combine functor applications because they can be
   bound together, sequencing operations on the
   underlying types
 • flatMap() is the method the Scala compiler uses to
   bind monads
Thank You!
Credits
• Sources
   –   Fast Track to Scala courseware by Typesafe
   –   Scala in Depth, by Josh Suereth
   –   DSLs in Action, Debasish Ghosh
   –   Wikipedia
   –   Runar Bjarnason's NE Scala 2011 talk
   –   Daniel Sobral's blog
   –   Brendan McAdams' blog

• Contributors
   – Dave Esterkin, Chariot Solutions
   – Josh Suereth, Typesafe

More Related Content

PDF
Scala for Java Programmers
PPTX
PPT
Scala collection
ODP
A Tour Of Scala
PPTX
A Brief Intro to Scala
PDF
Scala collections api expressivity and brevity upgrade from java
PPTX
Joy of scala
PPTX
Scala Back to Basics: Type Classes
Scala for Java Programmers
Scala collection
A Tour Of Scala
A Brief Intro to Scala
Scala collections api expressivity and brevity upgrade from java
Joy of scala
Scala Back to Basics: Type Classes

What's hot (20)

PPTX
Scala for curious
PDF
Getting Started With Scala
ODP
Functions In Scala
PDF
Programming in Scala: Notes
PPTX
Intro to Functional Programming in Scala
PDF
scalaliftoff2009.pdf
PDF
Scala coated JVM
PDF
Introducing Akka
PPTX
Scala fundamentals
PPT
Scala introduction
PDF
Introduction to Functional Programming with Scala
PDF
Scala @ TechMeetup Edinburgh
PDF
Stepping Up : A Brief Intro to Scala
PDF
Scala in Places API
PDF
Scala - core features
PDF
Scala at HUJI PL Seminar 2008
PPT
Scala Talk at FOSDEM 2009
PDF
Scala introduction
PDF
Starting with Scala : Frontier Developer's Meetup December 2010
PDF
Metaprogramming in Scala 2.10, Eugene Burmako,
Scala for curious
Getting Started With Scala
Functions In Scala
Programming in Scala: Notes
Intro to Functional Programming in Scala
scalaliftoff2009.pdf
Scala coated JVM
Introducing Akka
Scala fundamentals
Scala introduction
Introduction to Functional Programming with Scala
Scala @ TechMeetup Edinburgh
Stepping Up : A Brief Intro to Scala
Scala in Places API
Scala - core features
Scala at HUJI PL Seminar 2008
Scala Talk at FOSDEM 2009
Scala introduction
Starting with Scala : Frontier Developer's Meetup December 2010
Metaprogramming in Scala 2.10, Eugene Burmako,
Ad

Similar to Taxonomy of Scala (20)

ODP
Functional programming with Scala
PPTX
Scala, Play 2.0 & Cloud Foundry
PDF
Scala taxonomy
ODP
Functional Programming With Scala
ODP
PPTX
Principles of functional progrmming in scala
PDF
Scala Paradigms
PDF
The Scala Programming Language
PDF
Meet scala
PDF
Scala.pdf
PDF
Learning Functional Programming Without Growing a Neckbeard
PDF
Scala Bootcamp 1
ODP
Introducing scala
PPT
An introduction to scala
PDF
Scala for Java Developers (Silicon Valley Code Camp 13)
PDF
Scala In The Wild
PDF
Lecture 5
PDF
An Introduction to Scala (2014)
PDF
Functional programming in Scala
PPTX
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
Functional programming with Scala
Scala, Play 2.0 & Cloud Foundry
Scala taxonomy
Functional Programming With Scala
Principles of functional progrmming in scala
Scala Paradigms
The Scala Programming Language
Meet scala
Scala.pdf
Learning Functional Programming Without Growing a Neckbeard
Scala Bootcamp 1
Introducing scala
An introduction to scala
Scala for Java Developers (Silicon Valley Code Camp 13)
Scala In The Wild
Lecture 5
An Introduction to Scala (2014)
Functional programming in Scala
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
Ad

More from shinolajla (18)

PPTX
20180416 reactive is_a_product_rs
PDF
20180416 reactive is_a_product
PPTX
20161027 scala io_keynote
PPTX
20160609 nike techtalks reactive applications tools of the trade
PPTX
20160524 ibm fast data meetup
PPTX
20160520 The Future of Services
PDF
20160520 what youneedtoknowaboutlambdas
PDF
20160317 lagom sf scala
PDF
Effective Akka v2
PPTX
20150411 mutability matrix of pain scala
PPTX
Reactive applications tools of the trade huff po
PDF
20140228 fp and_performance
PDF
Effective akka scalaio
PDF
Cpu Caches
PDF
Real world akka recepies v3
PDF
Effective actors japanesesub
PDF
Effective Actors
PPTX
CPU Caches
20180416 reactive is_a_product_rs
20180416 reactive is_a_product
20161027 scala io_keynote
20160609 nike techtalks reactive applications tools of the trade
20160524 ibm fast data meetup
20160520 The Future of Services
20160520 what youneedtoknowaboutlambdas
20160317 lagom sf scala
Effective Akka v2
20150411 mutability matrix of pain scala
Reactive applications tools of the trade huff po
20140228 fp and_performance
Effective akka scalaio
Cpu Caches
Real world akka recepies v3
Effective actors japanesesub
Effective Actors
CPU Caches

Recently uploaded (20)

PDF
CXOs-Are-you-still-doing-manual-DevOps-in-the-age-of-AI.pdf
PPTX
Internet of Everything -Basic concepts details
PDF
A symptom-driven medical diagnosis support model based on machine learning te...
PDF
Rapid Prototyping: A lecture on prototyping techniques for interface design
PDF
Planning-an-Audit-A-How-To-Guide-Checklist-WP.pdf
PDF
EIS-Webinar-Regulated-Industries-2025-08.pdf
PPTX
AI-driven Assurance Across Your End-to-end Network With ThousandEyes
PDF
Introduction to MCP and A2A Protocols: Enabling Agent Communication
PDF
Electrocardiogram sequences data analytics and classification using unsupervi...
PPTX
Module 1 Introduction to Web Programming .pptx
PPTX
Presentation - Principles of Instructional Design.pptx
PDF
Aug23rd - Mulesoft Community Workshop - Hyd, India.pdf
PDF
ment.tech-Siri Delay Opens AI Startup Opportunity in 2025.pdf
PDF
Altius execution marketplace concept.pdf
PDF
Human Computer Interaction Miterm Lesson
PDF
Transform-Your-Supply-Chain-with-AI-Driven-Quality-Engineering.pdf
PDF
Auditboard EB SOX Playbook 2023 edition.
PDF
5-Ways-AI-is-Revolutionizing-Telecom-Quality-Engineering.pdf
PDF
Ensemble model-based arrhythmia classification with local interpretable model...
PPTX
SGT Report The Beast Plan and Cyberphysical Systems of Control
CXOs-Are-you-still-doing-manual-DevOps-in-the-age-of-AI.pdf
Internet of Everything -Basic concepts details
A symptom-driven medical diagnosis support model based on machine learning te...
Rapid Prototyping: A lecture on prototyping techniques for interface design
Planning-an-Audit-A-How-To-Guide-Checklist-WP.pdf
EIS-Webinar-Regulated-Industries-2025-08.pdf
AI-driven Assurance Across Your End-to-end Network With ThousandEyes
Introduction to MCP and A2A Protocols: Enabling Agent Communication
Electrocardiogram sequences data analytics and classification using unsupervi...
Module 1 Introduction to Web Programming .pptx
Presentation - Principles of Instructional Design.pptx
Aug23rd - Mulesoft Community Workshop - Hyd, India.pdf
ment.tech-Siri Delay Opens AI Startup Opportunity in 2025.pdf
Altius execution marketplace concept.pdf
Human Computer Interaction Miterm Lesson
Transform-Your-Supply-Chain-with-AI-Driven-Quality-Engineering.pdf
Auditboard EB SOX Playbook 2023 edition.
5-Ways-AI-is-Revolutionizing-Telecom-Quality-Engineering.pdf
Ensemble model-based arrhythmia classification with local interpretable model...
SGT Report The Beast Plan and Cyberphysical Systems of Control

Taxonomy of Scala

  • 1. A Taxonomy of Scala StrangeLoop 2012 Jamie Allen @jamie_allen http://github.com/jamie-allen/taxonomy-of-scala
  • 2. Agenda • Goal • Object-Oriented Features • Pattern Matching • Functional Programming • Actors • Futures • Implicits • Type Theory • Macros • Category Theory
  • 3. Goal Provide you with a reference point for many of the terms you hear in the Scala community
  • 4. How Programming in Scala Makes Me Feel
  • 5. How I Write Programs • Pre-Scala: – Make it work – Make it work well – Make it work fast • With Scala: – Make it work and work well – Make it work fast
  • 6. Object-Oriented Features
  • 7. Case Classes case class Person(firstName: String = "Jamie", lastName: String = "Allen") val jamieDoe = Person(lastName = "Doe") res0: Person = Person(Jamie,Doe) • Data Transfer Objects (DTOs) done right • By default, class arguments are immutable & public • Should never be extended • Provide equals(), copy(), hashCode() and toString() implementations • Don’t have to use new keyword to create instances • Named Parameters and Default arguments give us Builder pattern semantics
  • 8. Lazy Definitions lazy val calculatedValue = piToOneMillionDecimalPoints() • Excellent for deferring expensive operations until they are needed • Reducing initial footprint • Resolving ordering issues • Implemented with a guard field and synchronization, ensuring it is created when necessary
  • 9. Imports import scala.collection.immutable.Map class Person(val fName: String, val lName: String) { import scala.collection.mutable.{Map => MMap} val cars: MMap[String, String] = MMap() ... } • Can be anywhere in a class • Allow for selecting multiple classes from a package or using wildcards • Aliasing • Order matters!
  • 10. Objects object Bootstrapper extends App { Person.createJamieAllen } object Person { def createJamieAllen = new Person("Jamie", "Allen") def createJamieDoe = new Person("Jamie", "Doe") val aConstantValue = "A constant value” } class Person(val firstName: String, val lastName: String) • Singletons within a JVM process • No private constructor histrionics • Companion Objects, used for factories and constants
  • 11. The apply() method Array(1, 2, 3) res0: Array[Int] = Array(1, 2, 3) res0(1) res1: Int = 2 • In companion objects, it defines default behavior if no method is called on it • In a class, it defines the same thing on an instance of the class
  • 12. Tuples def firstPerson = (1, Person(firstName = “Barbara”)) val (num: Int, person: Person) = firstPerson • Binds you to an implementation • Great way to group values without a DTO • How to return multiple values, but wrapped in a single instance that you can bind to specific values
  • 14. Pattern Matching Examples name match { case "Lisa" => println("Found Lisa”) case Person("Bob") => println("Found Bob”) case "Karen" | "Michelle" => println("Found Karen or Michelle”) case Seq("Dave", "John") => println("Got Dave before John”) case Seq("Dave", "John", _*) => println("Got Dave before John”) case ("Susan", "Steve") => println("Got Susan and Steve”) case x: Int if x > 5 => println("got value greater than 5: " + x) case x => println("Got something that wasn't an Int: " + x) case _ => println("Not found”) } • A gateway drug for Scala • Extremely powerful and readable • Not compiled down to lookup/table switch unless you use the @switch annotation,
  • 16. Immutability • Extends beyond marking instances final • You must not leak mutability
  • 17. Referential Transparency // Transparent val example1 = "jamie".reverse val example2 = example1.reverse println(example1 + example2) // eimajjamie // Opaque val example1 = new StringBuffer("Jamie").reverse val example2 = example1.reverse println(example1 append example2) // jamiejamie • An expression is transparent if it can be replaced by its VALUE without changing the behavior of the program • In math, all functions are referentially transparent
  • 18. Scala Collections val myMap = Map(1 -> "one", 2 -> "two", 3 -> "three") val mySet = Set(1, 4, 2, 8) val myList = List(1, 2, 8, 3, 3, 4) val myVector = Vector(1, 2, 3...) • You have the choice of mutable or immutable collection instances, immutable by default • Rich implementations, extremely flexible
  • 19. Rich Collection Functionality val numbers = 1 to 20 // Range(1, 2, 3, ... 20) numbers.head // Int = 1 numbers.tail // Range(2, 3, 4, ... 20) numbers.take(5) // Range(1, 2, 3, 4, 5) numbers.drop(5) // Range(6, 7, 8, ... 20) • There are many methods available to you in the Scala collections library • Spend 5 minutes every day going over the ScalaDoc for one collection class
  • 20. Higher Order Functions val names = List("Barb", "May", "Jon") names map(_.toUpperCase) res0: List[java.lang.String] = List(BARB, MAY, JON) • Really methods in Scala • Applying closures to collections
  • 21. Higher Order Functions val names = List("Barb", "May", "Jon") names map(_.toUpperCase) res0: List[java.lang.String] = List(BARB, MAY, JON) names flatMap(_.toUpperCase) res1: List[Char] = List(B, A, R, B, M, A, Y, J, O, N) names filter (_.contains("a")) res2: List[java.lang.String] = List(Barb, May) val numbers = 1 to 20 // Range(1, 2, 3, ... 20) numbers.groupBy(_ % 3) res3: Map[Int, IndexedSeq[Int]] = Map(1 -> Vector(1, 4, 7, 10, 13, 16, 19), 2 -> Vector(2, 5, 8, 11, 14, 17, 20), 0 -> Vector(3, 6, 9, 12, 15, 18))
  • 22. For Comprehensions val myNums = 1 to 20 for (i <- myNums) yield i + 1 myNums map(_ + 1) for { i <- myNums j <- 1 to i } yield i * j myNums flatMap(i => 1 to i map (j => i * j)) • Used for composing higher-order functions • As you chain higher-order functions, you may find it easier to reason about them this way
  • 23. Parallel Collections scala> 1 to 1000000 res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3,... scala> res0.par res1: s.c.parallel.immutable.ParRange = ParRange(1, 2, 3,... scala> res1 map(_ + 1) res2: s.c.parallel.immutable.ParSeq[Int] = ParVector(2, 3, 4,... scala> res2.seq res3: s.c.immutable.Range = Range(2, 3, 4,... • You can easily parallelize the application of a function literal to your collection by calling the par() method on a collection instance • Uses JSR166 under the covers to fork/join for you • Use the seq() method on the parallel collection to return to a non-parallel instance
  • 24. Partial Functions class MyActor extends Actor { def receive = { case s: String => println("Got a String: " + s) case i: Int => println("Got an Int: " + i) case x => println("Got something else: " + x) } } • A simple match without the match keyword • The receive block in Akka actors is an excellent example • Is characterized by what "isDefinedAt" in the case statements
  • 25. Currying def product(i: Int)(j: Int) = i * j val doubler = product(2)_ doubler(3) // Int = 6 doubler(4) // Int = 8 val tripler = product(3)_ tripler(4) // Int = 12 tripler(5) // Int = 15 • Take a function that takes n parameters as separate argument lists • “Curry” it to create a new function that only takes one parameter • Fix on a value and use it to apply a specific implementation of a product with semantic value • Have to be defined explicitly as such in Scala • The _ is what explicitly marks this as curried
  • 27. Actors import akka.actor._ class MyActor extends Actor { def receive = { case x => println(“Got value: “ + x) } } • Based on concepts from Erlang/OTP • Akka is replacing the core language actors • Concurrency paradigm using networks of independent objects that only communicate via messaging and mailboxes
  • 29. Futures import scala.concurrent._ val costInDollars = Future { webServiceProxy.getCostInDollars.mapTo[Int] } costInDollars map (myPurchase.setCostInDollars(_)) • Allows you to write asynchronous code, which can be more performant than blocking • Are not typed, hence the mapTo call above
  • 30. Futures in Sequence val customerPurchases = for ( costUSD <- Future{ proxy.getCostInDollars.mapTo[Int]} totalPurchase <- Future{ proxy.addToTotal(costUSD).mapTo[Int]} } yield ((customerId -> totalPurchase)) • Scala’s for comprehensions allow you to compose higher-order functions, including Futures • By sequencing the expressions on multiple lines, you can order dependencies
  • 31. Futures in Parallel val costUSD = Future{proxy.getCostInUSD(cost).mapTo[Int]} val costCAD = Future{proxy.getCostInCAD(cost).mapTo[Int]} val combinedCosts = for { cUSD <- costUSD cCAD <- costCAD } yield (cUSD, cCAD) val costs = for ( (costUSD, costCAD) <- Future{proxy.getCostInUSD(cost).mapTo[Int]} zip Future{proxy.getCostInCAD(cost).mapTo[Int]} } yield (costUSD, costCAD) • Define the futures separately and then compose • Alternatively, the zip method allows you to parallelize futures execution within a for comprehension
  • 34. Implicit Conversions case class Person(firstName: String, lastName: String) implicit def PersonToInt(p: Person) = p.toString.head.toInt val me = Person("Jamie", "Allen") val weird = 1 + me res0: Int = 81 • Looks for definitions at compile time that will satisfy type incompatibilities • Modern IDEs will warn you with an underline when they are in use • Limit scope as much as possible (see Josh Suereth's NE Scala 2011)
  • 35. Implicit Parameters def executeFutureWithTimeout(f: Future)(implicit t: Timeout) implicit val t: Timeout = Timeout(20, TimeUnit.MILLISECONDS) executeFutureWithTimeout(Future {proxy.getCustomer(id)}) • Allow you to define default parameter values that are only overridden if you do so explicitly • Handy to avoid code duplication
  • 36. Implicit Classes implicit class Person(name: String) class Person(name: String) implicit final def Person(name: String): Person = new Person(name) • New to Scala 2.10 • Create extension methods to existing types • Desugars at compile time into a class definition with an implicit conversion
  • 38. Type Inference • Declaring a variable/value • Return types of methods/functions • See Daniel Spiewak's Philly ETE 2011 talk • Good idea to show types on public interfaces • Specify types when you want to type certainty
  • 39. Type Classes I case class Customer(id: Long, firstName: String, lastName: String) trait CustomerOrderById extends Ordering[Customer] { def compare(x: Customer, y: Customer): Int = { ... } } implicit object CustomerIdSort extends CustomerOrderById val customers = List(Customer(1, "Jamie", "Allen"), Customer(5, "John", "Doe"), Customer(2, "Jane", "Smith")) val sortedCustomers = customers.sorted(CustomerIdSort) sortedCustomers: List[Customer] = List(Customer(1,Jamie,Allen), Customer(2,Jane,Smith), Customer(5,John,Doe)) • Allow you to layer in varying implementations of behavior without changing an existing inheritance structure
  • 40. Type Classes II case class Dog(name: String) case class Ferret(name: String) case class Cat(name: String) abstract class OkayPets[T] object OkayPets { implicit object OkayDog extends OkayPets[Dog] implicit object OkayFerret extends OkayPets[Ferret] } def getPet[T](t: T)(implicit p: OkayPets[T]) = t val myDog = getPet(Dog("Sparky")) // Works val myCat = getPet(Cat("Sneezy")) // Fails at compile time • Allows you to generalize types that are acceptable parameters for methods
  • 41. Higher Kinded Types Map[A, B] // Type constructor, not a type! val myMap = Map[Int, String]() // Now it’s a type! • Use other types to construct a new type • Also called type constructors
  • 42. Algebraic Data Types sealed abstract class DayOfTheWeek case object Sunday extends DayOfTheWeek case object Monday extends DayOfTheWeek ... case object Saturday extends DayOfTheWeek val nextDay(d: DayOfTheWeek): DayOfTheWeek = d match { case Sunday => Monday case Monday => Tuesday ... case Saturday => Sunday } } • Allow you to model the world in finite terms, such as enumerations, but also define behavior around them, with all of the power of case classes • A finite number of possible subtypes, enforced by the "sealed" keyword (must be defined in the same source file)
  • 44. Macros • New to Scala 2.10 • Macros are used for generating code at compile time, similar to LISP macros • Does not have compiler pragmas such as #ifdef • Are implemented as "hygenic" macros at the point you call reify() – identifiers cannot be closed over in a macro definition
  • 45. ScalaLogging Macro def debug(message: String): Unit = macro LoggerMacros.debug private object LoggerMacros { def debug(c: LoggerContext)(message: c.Expr[String]) = c.universe.reify( if (c.prefix.splice.underlying.isDebugEnabled) c.prefix.splice.underlying.debug(message.splice) ) } import com.typesafe.scalalogging.Logging class MyClass extends Logging { logger.debug("This won't occur if debug is not defined") } • Existing log libraries allow us to define logging statements and then determine whether they result in output at runtime • ScalaLogging allows a user to use a logging facility but decide at compile time whether or not to include the logging statement based on log level.
  • 48. Concepts and Arrows val myIntToStringArrow: Int => String = _.toString myIntToStringArrow(1100) res0: String = 1100 • Concepts are types • Arrows are functions that convert one concept to another
  • 49. Morphism val number = 1000 val numericString = number.toString • Morphisms change one value in a category to another in the same category, from one type to another where types are the category • Simplified, it converts a type with one property to a type with another property • Must be pure, not side-effecting
  • 50. Functor val numbers = List(1, 2, 3, 4) val numericStrings = numbers.map(_.toString) • Functors are transformations from one category to another that preserve morphisms • Simplified, converts a type from one to another while maintaining the conversion of a type with one property to a type with another property
  • 51. Monad val customerPurchases = for ( costUSD <- proxy.getCostInDollars totalPurchase <- proxy.addToTotal(costUSD) } yield ((customerId -> totalPurchase)) • Very ephemeral concept • Must meet the laws of a monad to be one • Combine functor applications because they can be bound together, sequencing operations on the underlying types • flatMap() is the method the Scala compiler uses to bind monads
  • 53. Credits • Sources – Fast Track to Scala courseware by Typesafe – Scala in Depth, by Josh Suereth – DSLs in Action, Debasish Ghosh – Wikipedia – Runar Bjarnason's NE Scala 2011 talk – Daniel Sobral's blog – Brendan McAdams' blog • Contributors – Dave Esterkin, Chariot Solutions – Josh Suereth, Typesafe

Editor's Notes

  • #4: When you walk out of this room, your head should hurt. But that’s a GOOD thing – the problem is not that these concepts are difficult to grasp, but that you have to understand the vocabulary to even sit in the room with someone discussing them. I want to provide you with a reference point from which you can do your own investigation of what these concepts mean.
  • #8: Ask why we don’t need the “new” keyword with case classes
  • #13: Very fragile
  • #15: Constant, Constructor, Or, Sequence, Sequence with wildcard, tuple, typed with guard, bound variable wildcard, wildcardBy definition, a lookup/table switch on the JVM can only be an int or enumerated type. Tell the story about your implementation of a jump table using hashes of class definitions – 5000 of them, had to do some delegation due to max method size on the JVM, but was able to perform the deepest match in ~300ns
  • #16: Very powerful programming paradigmInverts imperative logic - apply your idempotent function to your dataThis is NOT monads, functors and the like, despite what you will hear in the communityAt it’s essence, functional programming is functions, referential transparency and immutability ONLY
  • #17: How many times have you been bitten by someone altering the contents of your collection?Can happen with closing over state very easily, or sending state to another method/function without considering whether or not it can be changed after it is sent.
  • #19: Map is key to valueSet does not allow dups and doesn’t care about orderSequence allows dups and maintains orderList provides Lisp-like cons semantics, but is a linked list and can be slow, must prependVector is a bitmapped vector trie, organizing data into 32-element arrays. Very performant, holds 2.15 billion elements only seven levels deep
  • #23: map, filter and flatMap in ScalaYou have the choice as to how to organize your code
  • #24: Map is key to valueSet does not allow dups and doesn’t care about orderSequence allows dups and maintains orderList provides Lisp-like cons semantics, but is a linked list and can be slow, must prependVector is a bitmapped vector trie, organizing data into 32-element arrays. Very performant, holds 2.15 billion elements only seven levels deep
  • #26: Functions are automatically curry-able in ML and Haskell, but has to be explicitly defined with multiple parameter lists in Scala
  • #28: This is ALL you need to know. There is a ton of goodness in Akka that make performing actor-based work much simpler and reasonable than it has been in the past, as well as a codifying of best practices. Please check out the documentation if you are interested.
  • #34: Don&apos;t use them until you understand them! And limit their scope when you do so nobody shoots their foot off.
  • #35: Implicits will seem like voodoo at first. Exist in other languages, like C type coercion
  • #38: Very powerful programming paradigmInverts imperative logic - apply your idempotent function to your dataThis is NOT monads, functors and the like, despite what you will hear in the communityAt it’s essence, functional programming is functions, referential transparency and immutability ONLY
  • #39: Global type inferencing is found in ML, for example
  • #40: Using Java&apos;s interfaces requires you to specify the inheritance structure in your code. What if you can&apos;t because you&apos;re using a library? What if you want to make the way your code handles situations orthogonal to it&apos;s inheritance structure
  • #41: Using Java&apos;s interfaces requires you to specify the inheritance structure in your code. What if you can&apos;t because you&apos;re using a library? What if you want to make the way your code handles situations orthogonal to it&apos;s inheritance structure
  • #48: This is the understandable reaction of most developers when they first engage the people who like CT. Or when they read their first blog post about how monads are like burritos or some other metaphor. I&apos;m convinced what we need to do is understand that there is a whole vocabulary that must be learned in order for you to know what CT is.
  • #50: Morphism is chewy brownie to a hard brownie
  • #51: Would convert a brownie to a cookie, and a chewy brownie to a chewy cookie and hard brownie into hard cookie, but also chewy cookies into hard cookies just like the brownie because the morphism is preserved
  • #52: They are not containers! They are not collections. Having a flatMap method does not mean that your type is monadic.Like a collection with flatMap. you won&apos;t know what they are by looking at code at first. Monads are ephemeral - they have to meet the laws of monads. Left and right identity as well as binding.
  • #53: Is the language trying to support too many paradigms at the expense of usability? Should a language be responsible for providing convention as well as capability? I think not. You can start by using Scala as a DSL for Java and make your code more concise, more readable and more correct. As your abilities with the language grows, try expanding what you&apos;re doing, but keep in mind your limitations.
  • #54: They are not containers! They are not collections. Having a flatMap method does not mean that your type is monadic.Like a collection with flatMap. you won&apos;t know what they are by looking at code at first. Monads are ephemeral - they have to meet the laws of monads. Left and right identity as well as binding.