This document provides an introduction to Scala concepts and features compared to Java, including how to set up Scala, the Simple Build Tool (SBT), case classes, lazy definitions, imports, objects, pattern matching, collections, higher-order functions, partial functions, currying, implicit conversions, and implicit parameters. Useful Scala resources are also listed.
3. SBT - Simple Build Tool
SBT is a simple build tool, similar to maven.
Helps you create, build, test, package your
scala application. It includes dependency
management which is defined in regular
Scala file, allow to define simple build-
plugins - everything simple and extensible
and XML free.
4. Main concepts of Scala:
- runs on JVM
- statically typed
- compiled into bytecode
- Advanced type system with type inference
and declaration-site variance
- Function types (including anonymous)
which support closures
- Pattern-matching
- Implicit parameters and conversions
- Full interoperability with Java
5. Let's start!
Create file hello.scala
object HelloWorld extends App {
println("Hello, World!")
}
Compile it :
>scalac hello.scala
Run it :)
>scala HelloWorld
"Hello, WOrld!"
6. - file can have whatever name
- no semicolons
- simplified syntax for many common cases
More Java-like version of previous example
(with main method):
object HelloWorld2 {
def main(args:Array[String])={
println("Hello 2")
}
}
What is going on?
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
13. 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,
14. 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
15. 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
16. 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
17. 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))
18. 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
19. 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
20. 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)
21. 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
22. Usefull resources:
https://www.coursera.org/course/progfun - Lessons and Examples on Coursera
- good staring point!!!
http://twitter.github.com/scala_school/
http://docs.scala-lang.org/tutorials/tour/tour-of-scala.html
http://stackoverflow.com/tags/scala/info
http://docs.scala-lang.org/cheatsheets/ :):)
http://github.com/jamie-allen/taxonomy-of-scala (oryginal content of pres.)
http://www.playframework.com/ - Play Framework!!!