getting started with scala

35
Getting Started With Scala Meetu Maltiar Cisco twitter: @meetumaltiar blog: meetumaltiar.com 1 26th April 2014 Bangalore, INDIA

Upload: meetu-maltiar

Post on 28-Jan-2015

123 views

Category:

Technology


0 download

DESCRIPTION

My talk at Bangalore Java Users Group. It was meant developers who want to get them started on Scala. This talk objectives was to get started on creating a project in Scala, write some code using collections and test it using ScalaTest.

TRANSCRIPT

Page 1: Getting Started With Scala

Getting Started With Scala

Meetu Maltiar Cisco

twitter: @meetumaltiar blog: meetumaltiar.com

1

26th April 2014 Bangalore, INDIA

Page 2: Getting Started With Scala

Agenda

Making a Scala project with SBT Scala language features Scala Collections Scala Test Wrap up

Page 3: Getting Started With Scala

SBT

Build tool for Scala projects Scala based frameworks like Akka uses it SBT build definition uses Scala based DSL Incremental compilation Works with mixed scala and java projects

Page 4: Getting Started With Scala

SBT: Create a projectSBT installation: download jar and create a script

instructions: http://www.scala-sbt.org/

Create a directory bojug-scala-bootcamp and descend to it

In terminal type sbt

Once sbt is started enter following commands: set name := “bojug-scala-bootcamp” set version := “1.0” set scalaVersion := “2.10.2” session save exit !Open build.sbt and have a look!!

Page 5: Getting Started With Scala

SBT: dependency & eclipse plugin

Current build.sbt has same information we inserted before !now add a dependency for ScalaTest by adding a following line: libraryDependencies += "org.scalatest" % "scalatest_2.10" % "2.1.0" % “test" !our full build.sbt is like this now: name := "bojug-scala-bootcamp" version := "1.0" scalaVersion := “2.10.2" libraryDependencies += "org.scalatest" % "scalatest_2.10" % "2.1.0" % “test" !Create projects/plugins.sbt and add sbteclipse plugin by adding a single line: addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % “2.1.2") !Execute sbt eclipse It will generate src folder and eclipse related configs. We are ready to import this project to eclipse!!

Page 6: Getting Started With Scala

Scala: Introduction

Scala is a JVM based language Scala is a hybrid FP and OO making it scalable Scala has a REPL Scala is interoperable with java

Page 7: Getting Started With Scala

Scala: Feels like a scripting language

It has a REPL Types can be inferred Less boilerplate

scala> var capitals = Map("US" -> "Washington", "France" -> "Paris") capitals: scala.collection.immutable.Map[String,String] = Map(US -> Washington, France -> Paris) !scala> capitals += ("Japan" -> "Tokyo") !scala> capitals("Japan") res1: String = Tokyo

Page 8: Getting Started With Scala

Scala: It’s Object Oriented

Every value is an object Every operation is a method call Exceptions like statics and primitives are removed

scala> (1).hashCode res2: Int = 1 !scala> (1).+(2) res3: Int = 3

Page 9: Getting Started With Scala

Scala: Compared With Java

Scala adds Scala removes

pure object system static members

operator overloading primitive types

closures break and continue

mixin composition with traits special treatment of interfaces

existential types wildcards

abstract types raw types

pattern matching enums

Page 10: Getting Started With Scala

Scala: cheat sheet (1) definitions

Scala method definitions !def fun(x: Int) = { result } !def fun = result !Scala variable definitions !var x: Int = expression val x: String = expression

Java method definitions !Int fun(int x) { return result } !(no parameterless methods) !java variable definitions !Int x = expression final String x = expression

Page 11: Getting Started With Scala

Scala: cheat sheet (2) definitions

Scala class and object !class Sample(x: Int, p: Int) { def instMeth(y: Int): Int = x + y } !object Sample { def staticMeth(x: Int, y: Int): Int = x * y } !!!!!!!!!

Java class !class Sample { private final int x; public final int p; ! Sample(int x, int p) { this.x = x; this.p = p; } ! int instMeth(int y) { return x + y; } ! static int staticMeth(int x, int y) { return x *y; } }

Page 12: Getting Started With Scala

Scala: cheat sheet (3) Traits

Scala Trait !trait T { var field = “!” ! def abstractMeth(x: Int) def concreteMeth(x: String) = x + field } !Scala mixin composition !class C extends Super with T !!!!!

Java Interface !Interface T { int abstractMeth(int x) } !(no concrete methods) !(no fields) !java extension plus implementation !class C extends Super implements T !!!!

Page 13: Getting Started With Scala

Scala: Higher Order Functions

Functions are first class entities in Scala !You can create them anonymously, pass them around as parameters or assign it to variable !scala> val incrementFunction = (x: Int) = x + 1 incrementFunction: Int => Int = <function1> !Higher order function takes other functions as parameters, or whose result is a function !def higherOrderFunction(f: Int => Int, x: Int): Int = { f(x) + x } !higherOrderFunction: (f: Int => Int, x: Int) !and when we call higherOrderFunction(incrementFunction, 2) ??

Page 14: Getting Started With Scala

Scala: Pattern matching

All that is required to add a case keyword to each class that is to be pattern matchable !Pattern match also returns a value !Similar to switch except that Scala compares objects as expressions. Only one matcher is executed at a time. !case class Employee(name: String) val employee = Employee(“john”) employee match { case Employee(“john”) => “Hello John!” case _ => “Hello there!” } !res0: String = Hello John

Page 15: Getting Started With Scala

Scala: Traits

They are fundamental unit of code reuse in Scala !They encapsulate method and field definitions, which can be reused by mixing them in classes !They cannot be instantiated so they refer to pure behaviours unlike classes !Unlike class inheritance a class can mix any number of traits !Unlike interfaces they can have concrete methods

We have already have a look at them in scala cheat sheet

Page 16: Getting Started With Scala

Scala Collections: Introduction

case class Person(name: String, age: Int) !val people = List(Person(“John”, 23), Person(“Jack”, 13), Person(“Mary”, 17), Person(“May”, 43)) !val (minors, adults) = people partition (_.age < 18)

There are three concepts in play here: Pattern matching infix method call a function value

Page 17: Getting Started With Scala

Scala Collections: It’s way

De-emphasise destructive updates

Focus on transformers that map collections to collections

Have a complete range of persistent collections

Page 18: Getting Started With Scala

Scala Collections: Properties

Object-oriented !Generic: List[T], Map[K, V] !Optionally persistent: scala.collections.immutable !Higher order: methods like foreach, map, filter !Uniform return type principle: operations return same type as their left operand

Page 19: Getting Started With Scala

Scala Collections: Uniform return type

scala> val ys = List(1, 2, 3) ys: List[Int] = List(1, 2, 3) !scala> val xs: Seq[Int] = ys xs: Seq[Int] = List(1, 2, 3) !scala> xs map (_ + 1) res0: Seq[Int] = List(2, 3, 4) !scala> ys map (_ + 1) res1: List[Int] = List(2, 3, 4)

Page 20: Getting Started With Scala

Scala Collections: Map and Filterscala> val xs = List(1, 2, 3) xs: List[Int] = List(1, 2, 3) !scala> val ys = xs map (x => x + 1) ys: List[Int] = List(2, 3, 4) !scala> val ys = xs map (_ + 1) ys: List[Int] = List(2, 3, 4) !scala> val zs = ys filter(_ % 2 == 0) zs: List[Int] = List(2, 4) !scala> val as = ys map (0 to _) as: List[scala.collection.immutable.Range.Inclusive] = List(Range(0, 1), Range(0, 1, 2), Range(0, 1, 2, 3))

Page 21: Getting Started With Scala

Scala Collections: flatMap and groupBy

scala> val bs = as.flatten bs: List[Int] = List(0, 1, 0, 1, 2, 0, 1, 2, 3) !scala> val bs = ys flatMap(0 to _) bs: List[Int] = List(0, 1, 0, 1, 2, 0, 1, 2, 3) !scala> val fruits = Vector(“apples, oranges”, “ananas”) fruits: scala.collection.immutable.Vector[java.lang.String] = Vector(apples, oranges, ananas) !scala> fruit groupBy(_.head) res2: scala.collection.immutable.Map[char, scala.collection.immutable.Vector[java.lang.String]] = Map(a -> Vector(apples, ananas), o -> Vector(oranges))

Page 22: Getting Started With Scala

Scala Collections: for notation

scala> for(x <- xs) yield x + 1 // map res0: Seq[Int] = List(2, 3, 4) !scala> for(x <- res0 if x % 2 == 0) yield x // filter res1: Seq[Int] = List(2, 4) !scala> for(x <- xs; y <- 0 to x) yield y // flatMap res2: Seq[Int] = List(0, 1, 0, 1, 2, 0, 1, 2, 3)

Page 23: Getting Started With Scala

Scala Collections: Using Maps

scala> val m = Map(1 -> “ABC”, 2 -> “DEF”, 3 -> “GHI”) m:scala.collection.immutable.Map[Int, java.lang.String] = Map(1 -> ABC, 2 -> DEF, 3 -> GHI) !scala> m(2) res1: java.lang.String = DEF !scala> m + (4 -> “JKL”) res2: scala.collection.immutable.Map[Int, java.lang.String] = Map(1 -> ABC, 2 -> DEF, 3 -> GHI, 4 -> JKL) !scala> m map { case (k, v) => (v, k)} res3: scala.collection.immutable.Map[java.lang.String, Int] = Map(ABC -> 1, DEF -> 2, GHI -> 3)

23

Page 24: Getting Started With Scala

Scala Collections: Hierarchy

All collection are in scala.collection or one of its sub-packages mutable, immutable and generic !Root collections are in scala.collection define same interface as immutable collections and mutable collections and adds some modification operations to make it mutable !The generic package contains building block for implementing collections

24

Page 25: Getting Started With Scala

Scala Collections: Hierarchy

25

Traversable Iterable Seq IndexedSeq LinearSeq mutable.buffer Range Set SortedSet immutable.HashSet mutable.HashSet mutable.LinkedHashSet BitSet Map SortedMap immutable.HashMap mutable.HashMap mutable.LinkedHashMap

Page 26: Getting Started With Scala

Scala Collections: Trait Traversable

26

Top of collection hierarchy. Its abstract method is foreach def foreach[U](f: Elem => U) !Traversable also provides lot of concrete methods they fall in following categories !Addition: ++, appends two traversables together Map operations: map, flatMap, collect Conversions: toArray, toList, toIterable, toSeq, toIndexedSeq, toStream, toSet, toMap Copying operations: copyToBuffer and copyToArray Size info operations: isEmpty, nonEmpty, size and hasDefiniteSize Element retrieval operations: head, last, headOption, lastOption and find Sub-collection retrieval operations: tail, init, slice, take, drop, takeWhile, dropWhile, filter, filterNot, withFilter Subdivision operations: splitAt, span, partition, groupBy Element tests: exists, forAll, count Folds: foldLeft, foldRight, /:, :\, reduceLeft, reduceRight Specific Folds: sum, product, min, max String operations: mkString, addString, stringPrefix

Page 27: Getting Started With Scala

Scala Collections: Everything is a library

27

Collections feel that they are like language constructs !Language does not contain any collection related constructs - no collection types - no collection literals - no collection operators !Everything is a library !They are extensible

Page 28: Getting Started With Scala

Scala Test: Introduction

28

ScalaTest is an open source framework for java platform !With ScalaTest we can test either Scala or Java code !Integrates with popular tools like jUnit, TestNG, Ant, Maven and SBT !Designed to do different styles of testing like Behaviour Driven Design for example

Page 29: Getting Started With Scala

Scala Test: Concepts

29

Three concepts: !Suite: A collection of tests. A test is anything which has a name and can succeed or fail !Runner: ScalaTest provides a runner application and can run a suite of tests !Reporter: As the tests are run, events are fired to the reporter, it takes care of presenting results back to user

Page 30: Getting Started With Scala

Scala Test: It is customisable

30

Suite <<trait>>

def expectedTestCount(Filter: Int) def testNames: Set[String] def tags: Map[String, Set[String]] def nestedSuites: List[Suite] def run(Option[String], Reporter, …) def runNestedSuites(Reporter, …) def runTests(Option[String], Reporter) def runTest(Reporter, …) def withFixture(NoArgTest)

Page 31: Getting Started With Scala

Scala Test: under the hood

31

When you run Test in ScalaTest you basically invoke run(Option[String], Reporter, …) on Suite object It then calls runNestedSuites(Reporter, …) And it calls runTests(Option[String], Reporter, …) !runNestedSuites(Reporter, …): Invokes nestedSuites(): List[Suite] to get all nested suites !runTests(Option[String], Reporter, …) will call def testNames: Set[String] to get set of tests to run. For each test it calls runTest(Reporter, …) It wraps the test code as a function object with a name and passes it to the withFixture(NoArgTest) which actually runs the test

Page 32: Getting Started With Scala

Scala Test: Available Traits

32

Suite FunSuite Spec FlatSpec WordSpec FeatureSpec Assertions ShouldMatchers MustMatchers

Page 33: Getting Started With Scala

Scala Test: FunSuite

33

ScalaTest provided === operator. It is defined in trait Assertions. Allows the failure report to include both left and right values !For writing Functional Tests use FunSuite trait. Test name goes in parentheses and test body goes in curly braces !The test code in curly braces is passed as a by-name parameter to “test” method which registers for later execution

Page 34: Getting Started With Scala

Scala Test: FunSuite Example

34

import org.scalatest.FunSuite!class EmployeeFunSuiteTest extends FunSuite {! test("employees with same name are same") { val emp1 = Employee("john") val emp2 = Employee("john") emp1 === emp2 }!}!case class Employee(name: String)

Page 35: Getting Started With Scala

Assignment

35

Lets map the world. We have Continents and Countries !Make a collection hierarchy to hold the above information !Write method on the collection hierarchy to get countries for a continent !Write method on the collection hierarchy to get continent for a country !Write tests using FunSuite to test methods created above