Intro to Scala for Java Developers

James Ward ~ @_JamesWard

Why Scala

  • Java++
  • Reactive OOTB
  • Expressive
  • Functional + OO

My Journey

  1. The cool kids were doing it
  2. Java without semicolons
  3. Library ecosystem: Play Framework, Akka, Spark
  4. 3+ years until "I get it"
  5. I still don't get the Haskell stuff

Getting Started

  1. Download Activator: typesafe.com/platform/getstarted
  2. Extract & launch Activator:
    activator new
  3. Create a new app with the minimal-scala template
  4. Run the app once:
    activator run
  5. Run the app continuously:
    activator ~run
  6. Launch the Scala REPL:
    activator console
  7. Run the tests continuously:
    activator ~test

Dive in, Do Scala Right

  • Immutable
  • Type Inference
  • Functional
  • Expression-Oriented
  • Pattern Matching
  • No more NPEs
  • Syntactic Sugar
  • Reactive

Hello, World

App (Hello.scala):

object Hello extends App {
  println("hello, world")
}

REPL:

scala> println("hello, world")

Immutable

Mutable state is the new spaghetti code

  • Concurrency friendly
  • Flow is linear

val foo: String = "asdf"

Type Inference

Let the compiler figure out the types

val foo = "asdf"
val listOfInt = List(1,2,3)

Functional

  • Don't iterate & mutate; Transform!
  • Define functions in any scope
  • Pass functions to other functions
val f = (s: String) => s.length
def stringLength(s: String): Int = s.length
List("asdf","zxc","q").map(stringLength)
List("asdf","zxc","q").map(s => s.length)
List("asdf","zxc","q").map(_.length)

Expression-Oriented

  • Expressions: Combination of symbols that represent a value
  • Unit is a value
  • Very few "Statements" in Scala:
    class Foo
  • No need for:
    return foo;
val foo = if (true) "foo" else "bar"

Pattern Matching

  • Tons, and tons, and tons of features
  • Expressions that match on something
  • More technically: Partial Functions applied to any value
foo match {
  case foo: Foo => println("foo")
  case bar: Bar => println("bar")
}
List(1, "asdf", false).collect {
  case i: Int => "not a number"
  case s: String => s.toUpperCase
}

No More NPEs

  • Type system support for optional values
val maybeFoo = if (util.Random.nextBoolean()) Some("Foo") else None
maybeFoo.getOrElse("Bar")

Case Classes

  • Concise syntax for value objects
  • Built-in toString, equals, hash-code, extractor, creator, copy
case class Foo(name: String)
val foo = new Foo("asdf")
val foo = Foo.apply("asdf")
val foo = Foo("asdf")
val bar = foo.copy(name = "zxvc")

For Comprehensions

val m1 = Some("asdf")
val m2 = None
m1.flatMap(mm1 => m2.map(mm2 => mm1 + mm2))
for {
  mm1 <- m1
  mm2 <- m2
} yield mm1 + mm2

Reactive

  • Futures
  • Actors
  • Non-blocking IO

Things I Stumbled On

  • Multiple Parameter Sets
  • Implicits
  • Up inference to Any
  • Objects / Companion Objects
  • Operators
  • Infix / arity-1

Multiple Parameter Sets

def foo(s: String)(i: Int): String = s.substring(i)
foo("asdf")(1)
val f: (Int => String) = foo("asdf")(_)

Implicits

Fill in this value by finding something in scope that matches the type
def foo(s: String)(implicit i: Int): String = s.substring(i)
implicit val i = 1
foo("asdf")

Up inference to Any

val l = List(1, "asdf")

Objects / Companion Objects

object Foo {
  val a = "asdf"
}
class Foo {
  val a = "zcxv"
}
new Foo().a
Foo.a

Operators

def >*#(s: String): String = s.toUpperCase
>*#("asdf")

Infix / arity-1

"asdf".substring(1)
"asdf" substring 1

Learn More