KEMBAR78
Scala for curious | PPTX
Scala for curious
val you = new Developer[Any] with ScalaKnowledge
What is Scala?
Is it hard to get started?
First steps
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
Scala is Functional language
Scala is also Object-oriented language
Scala is strongly typed language
Runs on JVM, compiles to bytecode
In contrast to C++ more you learn Scala,
easier it gets.
Scala community member
Scala in production
yep, it’s used. A lot.
Hello world!
object HelloWorld extends App {
println(“Hello world!”)
}
Basic ideas
#1 Mutability is evil
#2 Everything returns data
#3 Functions are first-class citizens
#1 Mutability is evil
- Side effects
- Need in defensive copies
- Hell in multithreading
- Need to manage changing state
#1 Mutability is evil
val count = 9000
count = 9001 // won’t compile
var count = 100
count = 101 // compile
#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)
#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)
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)
#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
Scala Basic Types
#1 Basic types are objects
#2 Scala defines Unified type system
#3 Types inference
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
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!?
Type inference
#1 Type inference reduce code
and makes refactoring easier!
#2 Inference is resolved by compiler
in the end we will get a defined type
Data flow and data structures
Borrowed a lot from Java:
- if else
- for
- while
- try, catch
But they return some values and have
advanced syntax
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”
Scala OOP basics
#1 Better classes
#2 Object == Built-in singleton
#3 Traits
#4 Case classes
#5 Multiple inheritance
#1 Better classes
class 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
#2 Objects
object 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
#3 Traits
trait 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.
#3 Abstract class
abstract class Boo {
def config()
}
class Foo extends Boo with Logging {
def config() = {} // implemented in child class
}
#4 Case classes
What is the difference?
case class Chair(height: Int, b:Buyer)
vs
class Chair(val height:Int, val b:Buyer)
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
Scala pattern matching
switch => match
Pattern matching
Is used to match on:
class or (partial) value of it, or
specific condition
Pattern matching
Start with simple:
val value = 42;
val matchResult = value match {
case 42 => “matched!”
case _ => “not matched:(”
}
matchResult = ????
It also returns a
value!
Pattern matching
case class Chair(h:Int, color:String)
val myChair = Chair(42, “black”);
val matchResult = value match {
case c: Chair => “matched!”
case _ => “not matched:(”
}
matchResult = ????
Pattern matching
case 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 = ????
Now imagine how many if () else
statements and logical conditions you can
save with it?
Functions, lambdas and all the
stuff
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
Use of lambda or how to define a function?
(x: Int, y: String) => x * x
Define 0 .. * params Do some stuff and
return results
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
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!
Partial Function Application
def 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
Curried functions
def multiply(a:Int)(b:Int): Int = a +b
val fn = multiply(2)(2) // returns 4
Useful when we don’t have both values
Variable params length
def 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
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
Scala collections
Idea was taken from Java and re-
implemented properly
Idea was taken from Java and re-
implemented properly
Similar abstractions with functional
nature
Scala Collections:
Scala Collections:
Immutable
import scala.collection.mutable._
Mutable
import scala.collection.immutable._
Prefer immutable, unless you
need mutability for performance
Lists, Maps, Sets, Seq, ….
- defined functional methods on collections
- chain transformations
- transformations as functions
- Immutable: return new modified list
- Mutable: modify existing
Lists - Let’s define it
val 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
Lists - Manipulate on it
val 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]
Maps
val 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
Again Options?
WTF?
Monads
Before we start with Options, Try and
Futures,
let’s remember childhood :)
Monads, wrap some values
and add extra features,
aka “Superpower”
Value might be anything
Simplified, Monads wrap anything with
some additional context.
It allows to manipulate on that value
Similar concepts:
Promises in js, Optional in Java, etc
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]
In Scala:
def map
def flatMap
def flatten
def reduce
def reduceLeft
def reduceRight
def filter
def fold
No panic, let’s just use it
Options
You have a value or not:
- Option[TypeOfYourValue]
- Some(yourValue)
- None
Replacement of Null in Java, Js, python
You have a value or not:
val maybeString: Option[String] = Some(“I’m string”)
val maybeString: Option[String] = None
val maybeString: Option[String] = someFunction()
Option
val maybeString: Option[String] = someFunction()
maybeString match {
case Some(s) => println(s)
case None => prtinln(“No values found :(”)
}
Option is a monad
case class Company(name: String)
val maybeString: Option[String] = someFunction()
val maybeCompany: Option[Company] =
maybeString.map(str => Company(name))
Options - is an exoskeleton!
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 !!!
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
Try
Try - we maybe we something done
Try[TypeOfYourValue] might be:
- Success(someValues)
- Failure(e: Exception)
Replacement of try {} catch {} in Java
Try example
val 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”)
}
Try example
val result = Try(parseSomeStuff()) // Failure(ex)
result.map(parsedVal => toUpperCase(parsedVal))
Real world example
import java.io.InputStream
def inputStreamForURL(url: String): Try[Try[Try[InputStream]]] = {
parseURL(url).map { u =>
Try(u.openConnection()).map(conn => Try(conn.getInputStream))
}
}
Future
In future you maybe have a value
- Future[TypeOfYourValue]
- Success(yourValue)
- Failure(exception)
Replacement of Future in Java
Basic use of Future
val futureVal = Future { get(url) }
futureVal on Complete {
case Success(v) => println(v)
case Failure(ex) => log.error(ex)
}
Future advanced usage
val futureVal = Future { get(url) }
futureVal.map(v => {
println(v)
v
} ).recover { case e => log.error(e) }
Options, Futures, Trys, Lists and a lot
more follow idea of Monads
So they also supports compositions!
Thanks!
Q & A

Scala for curious

  • 1.
    Scala for curious valyou = new Developer[Any] with ScalaKnowledge
  • 2.
    What is Scala? Isit hard to get started? First steps
  • 3.
    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
  • 4.
    Scala is Functionallanguage Scala is also Object-oriented language Scala is strongly typed language Runs on JVM, compiles to bytecode
  • 5.
    In contrast toC++ more you learn Scala, easier it gets. Scala community member
  • 6.
    Scala in production yep,it’s used. A lot.
  • 7.
    Hello world! object HelloWorldextends App { println(“Hello world!”) }
  • 8.
    Basic ideas #1 Mutabilityis evil #2 Everything returns data #3 Functions are first-class citizens
  • 9.
    #1 Mutability isevil - Side effects - Need in defensive copies - Hell in multithreading - Need to manage changing state
  • 10.
    #1 Mutability isevil val count = 9000 count = 9001 // won’t compile var count = 100 count = 101 // compile
  • 11.
    #2 Everything returnsdata - Everything is “evaluated” expressions - Everything returns values or functions - Functions are values - return is not needed (last statement does the job)
  • 12.
    #2 Everything returnsdata val result = if (condition) value1 else value2 lazy val result = for (i <- 1 to 10) yield i def sin(x: Double) = Math.sin(x)
  • 13.
    Expressions everywhere: // evaluatesto 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)
  • 14.
    #3 Functions arefirst-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
  • 15.
  • 16.
    #1 Basic typesare objects #2 Scala defines Unified type system #3 Types inference
  • 19.
    Scala defines it’sown 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
  • 20.
    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!?
  • 21.
    Type inference #1 Typeinference reduce code and makes refactoring easier! #2 Inference is resolved by compiler in the end we will get a defined type
  • 22.
    Data flow anddata structures
  • 23.
    Borrowed a lotfrom Java: - if else - for - while - try, catch But they return some values and have advanced syntax
  • 24.
    Tuple (Pairs) A wayto 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”
  • 25.
  • 26.
    #1 Better classes #2Object == Built-in singleton #3 Traits #4 Case classes #5 Multiple inheritance
  • 27.
    #1 Better classes classChair(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
  • 28.
    #2 Objects object 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
  • 29.
    #3 Traits trait 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.
  • 30.
    #3 Abstract class abstractclass Boo { def config() } class Foo extends Boo with Logging { def config() = {} // implemented in child class }
  • 31.
    #4 Case classes Whatis the difference? case class Chair(height: Int, b:Buyer) vs class Chair(val height:Int, val b:Buyer)
  • 32.
    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
  • 33.
  • 34.
    Pattern matching Is usedto match on: class or (partial) value of it, or specific condition
  • 35.
    Pattern matching Start withsimple: val value = 42; val matchResult = value match { case 42 => “matched!” case _ => “not matched:(” } matchResult = ???? It also returns a value!
  • 36.
    Pattern matching case classChair(h:Int, color:String) val myChair = Chair(42, “black”); val matchResult = value match { case c: Chair => “matched!” case _ => “not matched:(” } matchResult = ????
  • 37.
    Pattern matching case classChair(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 = ????
  • 38.
    Now imagine howmany if () else statements and logical conditions you can save with it?
  • 39.
  • 40.
    Functions are good. Scaladefines them as first-class citizen. You can define them and assign to some value: val square = (x: Int) => x * x
  • 41.
    Use of lambdaor how to define a function? (x: Int, y: String) => x * x Define 0 .. * params Do some stuff and return results
  • 42.
    Functions might beparams 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
  • 43.
    Functions might beparams 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!
  • 44.
    Partial Function Application defadd(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
  • 45.
    Curried functions def multiply(a:Int)(b:Int):Int = a +b val fn = multiply(2)(2) // returns 4 Useful when we don’t have both values
  • 46.
    Variable params length defdoubleAll(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
  • 47.
    Functions and methods Functionsassigned in context of the class - methods or They can be assigned to the defs or values in context of another function
  • 48.
  • 49.
    Idea was takenfrom Java and re- implemented properly
  • 50.
    Idea was takenfrom Java and re- implemented properly
  • 51.
    Similar abstractions withfunctional nature
  • 52.
  • 53.
    Scala Collections: Immutable import scala.collection.mutable._ Mutable importscala.collection.immutable._ Prefer immutable, unless you need mutability for performance
  • 54.
    Lists, Maps, Sets,Seq, …. - defined functional methods on collections - chain transformations - transformations as functions - Immutable: return new modified list - Mutable: modify existing
  • 55.
    Lists - Let’sdefine it val 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
  • 56.
    Lists - Manipulateon it val 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]
  • 57.
    Maps val 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
  • 58.
  • 59.
  • 60.
    Before we startwith Options, Try and Futures, let’s remember childhood :)
  • 62.
    Monads, wrap somevalues and add extra features, aka “Superpower” Value might be anything
  • 63.
    Simplified, Monads wrapanything with some additional context. It allows to manipulate on that value
  • 64.
    Similar concepts: Promises injs, Optional in Java, etc
  • 65.
    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]
  • 66.
    In Scala: def map defflatMap def flatten def reduce def reduceLeft def reduceRight def filter def fold
  • 68.
    No panic, let’sjust use it
  • 69.
  • 70.
    You have avalue or not: - Option[TypeOfYourValue] - Some(yourValue) - None Replacement of Null in Java, Js, python
  • 71.
    You have avalue or not: val maybeString: Option[String] = Some(“I’m string”) val maybeString: Option[String] = None val maybeString: Option[String] = someFunction()
  • 72.
    Option val maybeString: Option[String]= someFunction() maybeString match { case Some(s) => println(s) case None => prtinln(“No values found :(”) }
  • 73.
    Option is amonad case class Company(name: String) val maybeString: Option[String] = someFunction() val maybeCompany: Option[Company] = maybeString.map(str => Company(name)) Options - is an exoskeleton!
  • 74.
    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 !!!
  • 75.
    Even better composition valmaybeHeight: 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
  • 76.
  • 77.
    Try - wemaybe we something done Try[TypeOfYourValue] might be: - Success(someValues) - Failure(e: Exception) Replacement of try {} catch {} in Java
  • 78.
    Try example val 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”) }
  • 79.
    Try example val result= Try(parseSomeStuff()) // Failure(ex) result.map(parsedVal => toUpperCase(parsedVal))
  • 80.
    Real world example importjava.io.InputStream def inputStreamForURL(url: String): Try[Try[Try[InputStream]]] = { parseURL(url).map { u => Try(u.openConnection()).map(conn => Try(conn.getInputStream)) } }
  • 81.
  • 82.
    In future youmaybe have a value - Future[TypeOfYourValue] - Success(yourValue) - Failure(exception) Replacement of Future in Java
  • 83.
    Basic use ofFuture val futureVal = Future { get(url) } futureVal on Complete { case Success(v) => println(v) case Failure(ex) => log.error(ex) }
  • 84.
    Future advanced usage valfutureVal = Future { get(url) } futureVal.map(v => { println(v) v } ).recover { case e => log.error(e) }
  • 85.
    Options, Futures, Trys,Lists and a lot more follow idea of Monads
  • 86.
    So they alsosupports compositions!
  • 87.
  • 88.