scala for curious

88
Scala for curious val you = new Developer[Any] with ScalaKnowledge

Upload: tim-dev-tim-zadorozhniy

Post on 15-Apr-2017

311 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Scala for curious

Scala for curiousval you = new Developer[Any] with ScalaKnowledge

Page 2: Scala for curious

What is Scala?

Is it hard to get started?

First steps

Page 3: Scala for curious

What is Scala?

- Built by Martin Odersky in 2003

- JVM programming language

- Backward compatible with Java

- FP driven with OOP features

- Has awesome community

- Great docs

Page 4: Scala for curious

Scala is Functional language

Scala is also Object-oriented language

Scala is strongly typed language

Runs on JVM, compiles to bytecode

Page 5: Scala for curious

In contrast to C++ more you learn Scala,easier it gets.

Scala community member

Page 6: Scala for curious

Scala in production

yep, it’s used. A lot.

Page 7: Scala for curious

Hello world!

object HelloWorld extends App { println(“Hello world!”)}

Page 8: Scala for curious

Basic ideas

#1 Mutability is evil

#2 Everything returns data

#3 Functions are first-class citizens

Page 9: Scala for curious

#1 Mutability is evil

- Side effects

- Need in defensive copies

- Hell in multithreading

- Need to manage changing state

Page 10: Scala for curious

#1 Mutability is evil

val count = 9000

count = 9001 // won’t compile

var count = 100

count = 101 // compile

Page 11: Scala for curious

#2 Everything returns data

- Everything is “evaluated” expressions

- Everything returns values or functions

- Functions are values

- return is not needed (last statement does the job)

Page 12: Scala for curious

#2 Everything returns data

val result = if (condition) value1 else value2

lazy val result = for (i <- 1 to 10) yield i

def sin(x: Double) = Math.sin(x)

Page 13: Scala for curious

Expressions everywhere: // evaluates to the value

val result = if (condition) value1 else value2

// evaluates to the value as it was used somewhere

lazy val result = for (i <- 1 to 10) yield i

// evaluates every time we call it

def sin(x: Double) = Math.sin(x)

Page 14: Scala for curious

#3 Functions are first-class citizens

Function is a value (object)!

val square = (x: Int) => x * x

And can be called later!

val result = square(5) // returns 25

Function here

Page 15: Scala for curious

Scala Basic Types

Page 16: Scala for curious

#1 Basic types are objects

#2 Scala defines Unified type system

#3 Types inference

Page 17: Scala for curious
Page 18: Scala for curious
Page 19: Scala for curious

Scala defines it’s own unified type system:

#1 Basic types are objects

#2 Root of the family is Any (as Object in Java)

#3 Alias for types type IntMaker = () => Int

Page 20: Scala for curious

Type inference

val sum = 2 + 2 // Infers to Int we don’t need a type!val str = “a” + “b” // Infers to String as well, compiles!

val problem = if (condition) sum else str // will give us Any !

WAT!?

Page 21: Scala for curious

Type inference

#1 Type inference reduce code and makes refactoring easier!

#2 Inference is resolved by compilerin the end we will get a defined type

Page 22: Scala for curious

Data flow and data structures

Page 23: Scala for curious

Borrowed a lot from Java: - if else

- for

- while

- try, catch

But they return some values and have

advanced syntax

Page 24: Scala for curious

Tuple (Pairs)

A way to bind 2 unrelated results:val t1 = (42, “dog”)

val t2 = (42, “cat”, List(1,2,3))

can be unwrapped: val (a,b) = t1 // a = 42, b = “dog”

Page 25: Scala for curious

Scala OOP basics

Page 26: Scala for curious

#1 Better classes

#2 Object == Built-in singleton

#3 Traits

#4 Case classes

#5 Multiple inheritance

Page 27: Scala for curious

#1 Better classesclass Chair(val color: String) {

println(“I’m chair!”);

private val id: Int = 1

def sit(): Unit = {

println(“Sitting on the chair - ”+ id)

}

}

Class method

Private field

Public field

Page 28: Scala for curious

#2 Objectsobject Singleton {

val result = “Test”

def foo(): Int = {}

def boo(): Int = {}

}

Singleton.boo()

It creates class that will have only one instance.

There are no static fields, though

Page 29: Scala for curious

#3 Traitstrait Logging {

val logger = Logger(this.getClass)

}

class Foo extends Boo with Logging {

logger.info(“WAT!!!?”) defined in Logging

}

Traits are advanced interfaces in Java.

They can have methods

implementation and non-static values.

Page 30: Scala for curious

#3 Abstract classabstract class Boo {

def config()

}

class Foo extends Boo with Logging {

def config() = {} // implemented in child class

}

Page 31: Scala for curious

#4 Case classesWhat is the difference?

case class Chair(height: Int, b:Buyer)

vs

class Chair(val height:Int, val b:Buyer)

Page 32: Scala for curious

case class is “Sugared” class:

#1 Used to store and match on it’s contents

#2 Designed to work with pattern matching

#3 Have implemented equals() hashCode()

and toString()

#4 Have “companion” object already defined

Page 33: Scala for curious

Scala pattern matching

switch => match

Page 34: Scala for curious

Pattern matching

Is used to match on:

class or (partial) value of it, or

specific condition

Page 35: Scala for curious

Pattern matchingStart with simple:

val value = 42;

val matchResult = value match {

case 42 => “matched!”

case _ => “not matched:(”

}

matchResult = ????

It also returns a value!

Page 36: Scala for curious

Pattern matchingcase class Chair(h:Int, color:String)

val myChair = Chair(42, “black”);

val matchResult = value match {

case c: Chair => “matched!”

case _ => “not matched:(”

}

matchResult = ????

Page 37: Scala for curious

Pattern matchingcase class Chair(h:Int, color:String)

val myChair = Chair(42, “black”);

val matchResult = value match {

case Chair(_, “black”) => “matched!”

case Chair(33, _) => “not matched:(”

case c => “not matched:(” // default case

}

matchResult = ????

Page 38: Scala for curious

Now imagine how many if () else

statements and logical conditions you can

save with it?

Page 39: Scala for curious

Functions, lambdas and all the

stuff

Page 40: Scala for curious

Functions are good.

Scala defines them as first-class citizen.

You can define them and assign to some

value:

val square = (x: Int) => x * x

Page 41: Scala for curious

Use of lambda or how to define a function?

(x: Int, y: String) => x * x

Define 0 .. * params Do some stuff and return results

Page 42: Scala for curious

Functions might be params as well

val foo = (n: Int, fn: (Int) => Int) => fn(n)

val square = (x: Int) => x*x

foo(5, square) // returns 25

Function as a parameter

Page 43: Scala for curious

Functions might be params as well

val foo = (n: Int, fn: (Int) => Int) => fn(n)

val square = (x: Int) => x*x

foo(5, square) // returns 25

Function as a parameter

It was Function composition!

Page 44: Scala for curious

Partial Function Applicationdef add(a:Int, b:Int) = a +b

val fn = add(2,_:Int) // returns a function

fn(2) // returns 4!

Useful when we don’t have both values

Page 45: Scala for curious

Curried functionsdef multiply(a:Int)(b:Int): Int = a +b

val fn = multiply(2)(2) // returns 4

Useful when we don’t have both values

Page 46: Scala for curious

Variable params lengthdef doubleAll(args:Int *) = args.map { arg => arg *2 }

doubleAll(1,2,3) // returns Seq(1,4,6)

This function would return Seq of results, according to the number of

params

Page 47: Scala for curious

Functions and methods

Functions assigned in context of the class -

methods

or

They can be assigned to the defs or values in context of

another function

Page 48: Scala for curious

Scala collections

Page 49: Scala for curious

Idea was taken from Java and re-

implemented properly

Page 50: Scala for curious

Idea was taken from Java and re-

implemented properly

Page 51: Scala for curious

Similar abstractions with functional

nature

Page 52: Scala for curious

Scala Collections:

Page 53: Scala for curious

Scala Collections:

Immutableimport scala.collection.mutable._

Mutableimport scala.collection.immutable._

Prefer immutable, unless you need mutability for performance

Page 54: Scala for curious

Lists, Maps, Sets, Seq, ….- defined functional methods on collections

- chain transformations

- transformations as functions

- Immutable: return new modified list

- Mutable: modify existing

Page 55: Scala for curious

Lists - Let’s define itval lists = List() // empty list

val firstList = List(List(1,2),List(1,2,4,4)) // why not? // alternative way to define list

val anotherList = “a”::”b”::”c”::Nil

Page 56: Scala for curious

Lists - Manipulate on itval list = List(1,2,3)

list.map(x => x*x) // returns List(1,4,9)

// let’s chain some stuff

list.map(x => x*x).filter(x => x > 3) // returns List(4,9)

// let’s chain some stuff

list.map(x => x*2).filter(x => x > 1).find(x => x == 4) // returns Option[Int]

Page 57: Scala for curious

Mapsval map = Map()

val map = Map(“key” -> “value”) // “key” -> “value” returns Tuple

val newMap = map += (“anotherKey” -> “value”)

val yetAnotherMap = newMap -= (“anotherKey”) // returns yet another map

val result: Option[String] = newMap.get(“key”)

Returns tuple

Page 58: Scala for curious

Again Options?

WTF?

Page 59: Scala for curious

Monads

Page 60: Scala for curious

Before we start with Options, Try and

Futures,

let’s remember childhood :)

Page 61: Scala for curious
Page 62: Scala for curious

Monads, wrap some values and add extra features,

aka “Superpower”

Value might be anything

Page 63: Scala for curious

Simplified, Monads wrap anything with

some additional context.

It allows to manipulate on that value

Page 64: Scala for curious

Similar concepts:

Promises in js, Optional in Java, etc

Page 65: Scala for curious

More formal definition:

// get some value to that context

def unit: (a: A) => M[A]

// transform that value with a function but leave it in the context

def bind[B]: (a => M[B]) => M[B]

Page 66: Scala for curious

In Scala:def map

def flatMap

def flatten

def reduce

def reduceLeft

def reduceRight

def filter

def fold

Page 67: Scala for curious
Page 68: Scala for curious

No panic, let’s just use it

Page 69: Scala for curious

Options

Page 70: Scala for curious

You have a value or not:- Option[TypeOfYourValue]- Some(yourValue)- None

Replacement of Null in Java, Js, python

Page 71: Scala for curious

You have a value or not:val maybeString: Option[String] = Some(“I’m string”)

val maybeString: Option[String] = None

val maybeString: Option[String] = someFunction()

Page 72: Scala for curious

Optionval maybeString: Option[String] = someFunction()

maybeString match {

case Some(s) => println(s)

case None => prtinln(“No values found :(”)

}

Page 73: Scala for curious

Option is a monadcase class Company(name: String)

val maybeString: Option[String] = someFunction()

val maybeCompany: Option[Company] =

maybeString.map(str => Company(name))

Options - is an exoskeleton!

Page 74: Scala for curious

Options composition val maybeHeight: Option[Int] = findChairHeight()

def findChairName(height: Int): Option[String]

def buildChair(h: Int, name: String): Chair = {....}

maybeHeight.flatMap(height => height -> findChairName(height))

.map {

case (height, name) => buildChair(height, name)

} // returns Option[Chair] in case if all vals were Some !!!

Page 75: Scala for curious

Even better composition val maybeHeight: Option[Int] = findChairHeight()

def findChairName(height: Int): Option[String]

def buildChair(h: Int, name: String): Chair = {....}

val maybeChair = for {

height <- findChairHeight() // we got a chair and it’s Some()

name <- findChairName(height) // we got Some name

chair <- buildChair(height, name) // we can use it to build chair!

} yield chair // collect chair

If any value is None - chain breaks, and we return None

Page 76: Scala for curious

Try

Page 77: Scala for curious

Try - we maybe we something done

Try[TypeOfYourValue] might be:

- Success(someValues)

- Failure(e: Exception)

Replacement of try {} catch {} in Java

Page 78: Scala for curious

Try exampleval result = Try(100/0) // Failure(ex)

result match {

case Success(res) => println(“Math is broken”)

case Failure(ex) => println(“We can’t divide by zero”)

}

Page 79: Scala for curious

Try exampleval result = Try(parseSomeStuff()) // Failure(ex)

result.map(parsedVal => toUpperCase(parsedVal))

Page 80: Scala for curious

Real world exampleimport java.io.InputStream

def inputStreamForURL(url: String): Try[Try[Try[InputStream]]] = {

parseURL(url).map { u =>

Try(u.openConnection()).map(conn => Try(conn.getInputStream))

}

}

Page 81: Scala for curious

Future

Page 82: Scala for curious

In future you maybe have a value- Future[TypeOfYourValue]- Success(yourValue)- Failure(exception)

Replacement of Future in Java

Page 83: Scala for curious

Basic use of Future

val futureVal = Future { get(url) }

futureVal on Complete {

case Success(v) => println(v)

case Failure(ex) => log.error(ex)

}

Page 84: Scala for curious

Future advanced usage

val futureVal = Future { get(url) }

futureVal.map(v => {

println(v)

v

} ).recover { case e => log.error(e) }

Page 85: Scala for curious

Options, Futures, Trys, Lists and a lot

more follow idea of Monads

Page 86: Scala for curious

So they also supports compositions!

Page 87: Scala for curious

Thanks!

Page 88: Scala for curious

Q & A