SlideShare a Scribd company logo
A Gentle Introduction
to Scala and FP
1/50
Hi, I'm Anton!
Functional
programmer
Scala enthusiast
Applications engineer
at Rakuten
@a7emenov
Find me on ,
and
Twitter
Telegram Github
2/50
Agenda
Introduce Scala as a language
Give examples of universal FP constructs
Show benefits of those constructs
Compare Scala to other languages
3/50
What is Scala as
a language?
4/50
Scala combines object-
oriented and functional
programming in one
concise, high-level
language.
5/50
What lies at the core of FP?
6/50
What lies at the core of FP?
Absence of side-effects in
computations
6/50
What lies at the core of FP?
Absence of side-effects in
computations
Function composition
6/50
What lies at the core of FP?
Absence of side-effects in
computations
Function composition
Immutable data
6/50
What lies at the core of FP?
Absence of side-effects in
computations
Function composition
Immutable data
Dark magic
6/50
What lies at the core of FP?
Absence of side-effects in
computations
Function composition
Immutable data
Dark magic
?
6/50
What lies at the core of FP?
Absence of side-effects in
computations
Function composition
Immutable data
Dark magic
All of it
7/50
Functional programming is a
way of solving problems which
centers around combining
side-effect-free constructs in a
declarative manner
8/50
Declarative vs. imperative
Imperative
for (int i = 1; i 5; i ) {
int temp = i * 2;
if (temp < 6) {
System.out.println(temp);
}
}
Declarative
(1 to 5)
.map(_ * 2)
.filter(_ < 6)
.foreach(println)
9/50
Deep dive
FP & Scala
Immutability
Pure functions
Referential transparency
Algebraic data types
Pattern matching
Recursion
10/50
Value mutation
Variables
Can be changed anytime
Can be changed from
any place that has a
reference
Exposing private state
requires explicit copying
Immutable values
Can't be changed
Create new values
instead of changing
the old ones
No mutable state
11/50
Value mutation
Variables Immutable values
12/50
Immutable values
Benefits
Reduce concurrency
issues
No shared mutable
state
Easier local reasoning
Drawbacks
Extra memory allocations
13/50
Pure functions
Side-effect freeSide-effect free - everything that a function does can be
observed in its return value:
TotalTotal - return values for every possible input
DeterministicDeterministic - given same inputs, return same
outputs
Locally scopedLocally scoped - no effect on the state outside of the
function's scope
14/50
Referential transparency
All calls to a function
can be substituted
with its return value
15/50
Referential transparency
Not transparent
def getInt(l: Int, r: Int): Int =
Random.between(l, r)
def increment(x: Int): Int = {
val res = x + 1
destroyTheWorld()
res
}
Transparent
def fact(n: Int): Int = {
var res = 1
var i = 1
while (i n) {
res = res * i
i = i + 1
}
res
}
16/50
Business value with pure functions
How can programs be
useful without any
side-effects?
17/50
Business value with pure functions
Describe side-effecting computations
instead of instantly running them
Combine all side-effects to produce a
single description
Run the resulting computation in the
main method
18/50
Business value with pure functions
def saveValue(key: String, value: Int): IO[Unit] = ?
def getValue(key: String): IO[Option[Int]] = ???
def rateLimit[A](program: IO[A]): IO[A] = ???
val program: IO[Option[Int]] =
ratelimit(
saveValue("key", 1) >> getValue("key")
)
val result: Option[Int] = program.runSyncUnsafe()
19/50
Business value with pure functions
saveValue("key", 1) >> getValue("key")
def saveValue(key: String, value: Int): IO[Unit] = ???
def getValue(key: String): IO[Option[Int]] = ???
def rateLimit[A](program: IO[A]): IO[A] = ???
val program: IO[Option[Int]] =
ratelimit(
)
val result: Option[Int] = program.runSyncUnsafe()
19/50
Business value with pure functions
def rateLimit[A](program: IO[A]): IO[A] = ???
def saveValue(key: String, value: Int): IO[Unit] = ???
def getValue(key: String): IO[Option[Int]] = ???
val program: IO[Option[Int]] =
ratelimit(
saveValue("key", 1) >> getValue("key")
)
val result: Option[Int] = program.runSyncUnsafe()
19/50
Business value with pure functions
val program: IO[Option[Int]] =
ratelimit(
saveValue("key", 1) >> getValue("key")
)
def saveValue(key: String, value: Int): IO[Unit] = ???
def getValue(key: String): IO[Option[Int]] = ???
def rateLimit[A](program: IO[A]): IO[A] = ???
val result: Option[Int] = program.runSyncUnsafe()
19/50
Business value with pure functions
val result: Option[Int] = program.runSyncUnsafe()
def saveValue(key: String, value: Int): IO[Unit] = ???
def getValue(key: String): IO[Option[Int]] = ???
def rateLimit[A](program: IO[A]): IO[A] = ???
val program: IO[Option[Int]] =
ratelimit(
saveValue("key", 1) >> getValue("key")
)
19/50
Pure functions
Benefits
Ultimate local
reasoning
Parallelizable
execution
Easy testing
Drawbacks
Extra object allocations
Require an effect system
or a library to operate
mutable state
20/50
Algebraic data types
Product typesProduct types - define how to create a value
(“has a field” relationship)
Sum typesSum types - define the range of values
(“is one of” relationship)
Product types + Sum types =
Algebraic data types
21/50
Product types
Traditional classes
public class Person {
// Which is the primary constructor?
// Are the constructors related?
public Person(Age age,
Year birthYear)
{ /* ... */ }
public Person(Year currentYear,
Age age)
{ /* ... */ }
public Person(Year currentYear,
Year birthYear)
{ /* ... */ }
}
22/50
Product types
Traditional classes
public class Person {
// Which is the primary constructor?
// Are the constructors related?
public Person(Age age,
Year birthYear)
{ /* ... */ }
public Person(Year currentYear,
Age age)
{ /* ... */ }
public Person(Year currentYear,
Year birthYear)
{ /* ... */ }
}
Product types
// Primary constructor defines the product
case class Person(age: Age,
birthYear: Year) {
// Supplementary constructors
// must use the primary constructor
def this(currentYear: Year, age: Age)
{ this(age, currentYear - age) }
def this(currentYear: Year, birthYear: Year
{ this(currentYear - birthYear, birthYear
}
22/50
Sum types
Traditional interfaces
public interface User
{ /* Common methods */ }
public class Client implements User
{ /* Client-specific methods */ }
public class Admin implements User
{ /* Admin-specific methods */ }
void process(User user) {
// How can this function reason about a
// possible implementations of User?
}
23/50
Sum types
Traditional interfaces
public interface User
{ /* Common methods */ }
public class Client implements User
{ /* Client-specific methods */ }
public class Admin implements User
{ /* Admin-specific methods */ }
void process(User user) {
// How can this function reason about a
// possible implementations of User?
}
Sum types
// "Sealed" allows the compiler to find
// all descendants of User
sealed trait User
{ /* Common methods */ }
case class Client extends User
{ /* Client-specific methods */ }
case class Admin extends User
{ /* Admin-specific methods */ }
def process(user: User): IO[Unit] = {
// The function now has knowledge that
// there are only 2 options for "user"
}
23/50
Pattern matching
Data construction
sealed trait User
case class Client(email: String
role: String)
extends User
case class Admin(name: String,
scopes: List[String])
extends User
val client: User =
Client("test@email.com", "manager")
val admin: User =
Admin("Jane", List("emails", "orders")
Data deconstruction
def process(u: User): IO[Unit] = u match {
case Client(email, "manager")
logManager(email)
case Admin(name, Nil)
logAdmin(name, "No scopes")
case Admin(name, List("emails"))
logAdmin(name, "Only 'emails' scope")
case Admin(name, scopes)
if scopes.contains("orders")
logAdmin(name, "Has 'orders' scope")
case _
logDefault("Default action")
}
24/50
Pattern matching
Benefits
Compile-time type
checks
Exhaustiveness checks
Enhanced code
readability
Extensible
Drawbacks
Extra memory allocations
25/50
Recursion
Declarative
Native mapping to
many real-world
problems
Can be as efficient as a
loop*
import scala.annotation.tailrec
@tailrec
def foldLeft[R](list: List[Int])
(acc: R)
(f: (R, Int) R): R =
list match {
case Nil
acc
case head :: tail
foldLeft(tail)(f(acc, head))(f)
}
// "12345"
foldLeft(List(1, 2, 3, 4, 5))(acc = "") {
(acc, num) acc + num.toString
}
26/50
FP in Scala - covered points
Immutability
Pure functions
Referential transparency
Algebraic data types
Pattern matching
Recursion over iteration
27/50
Scala
language
features
Higher-kinded types
For-comprehensions
Implicit values
Syntax extension
Macros
28/50
Higher-kinded types
Simple types:Simple types:
Int, String, User
Unary typeUnary type
constructors:constructors:
List[A], Future[A]
Binary typeBinary type
constructors:constructors:
Either[A, B], Tuple[A, B]
Higher-kinded typesHigher-kinded types:
trait Processor[L[_]] {
def run[A](l: L[A]): Unit
}
val listP = new Processor[List] {
def run[A](l: List[A]): Unit =
l.foreach(println)
}
listP.run(List(1, 2, 3))
listP.run(List("a", "b", "c"))
29/50
For comprehensions
def getProfile(userName: String): Option[Profile] = ???
def getComments(profile: Profile): Option[List[Comment]] = ???
def getBonus(profile: Profile): Option[Int] = ???
val updatedComments = for {
profile getUserProfile("Jack")
comments getComments(profile)
bonus getBonus(profile)
} yield comments.take(10)
.map( .increaseRating(bonus))
30/50
For comprehensions
Define coherent syntax for sequential
composition
Syntactic sugar for every type with map,
flatMap and withFilter methods
Can be used with any type supplying these
methods
Take advantage of pattern matching
31/50
Implicit values
Provide automatic
value forwarding
Resolved at compile-
time
Can be derived from
existing context
case class Foo(id: Int)
object Foo {
implicit val o: Ordering[Foo] =
Ordering.by(_.id)
}
def sortFoo(foos: List[Foo])
(implicit o: Ordering[Foo]) =
foos.sorted(o)
sortFoo(
32/50
Syntax extensions
Allow to create ad-hoc
methods for code
reuse and readability
Can be used for types
imported from other
projects/libraries
implicit class StringSyntax
(s: String) {
def filterDigits: String =
s.filter(_.isDigit)
}
// "123"
"1a2b3c".filterDigits
33/50
Macros
Eliminate boilerplate
code
Provide
implementations in
compile time
Allow to extract code
meta data
import io.circe._
import io.circe.generic.semiauto.
case class Foo(a: Int, b: String)
case class Bar(
id: Option[String], foo: Foo
)
val barDecoder: Decoder[Bar] =
deriveDecoder[Foo].map(foo
Bar(id = None, foo = foo)
)
34/50
Scala language - covered points
Higher-kinded types
For-comprehensions
Implicit values
Syntax extensions
Macros
35/50
Scala in
numbers
Development and
adoption rates
Effect on productivity
Performance
36/50
Scala adoption rates
Maintained intense release
schedule for over 15 years
Development of the
language is supported by the
European government and
enterprise investors[1]
As popular as Kotlin for
backend development[2] and
is 20% more widespread
company-wise[3]
1.
2.
3.
bit.ly/2Xr3bnH
bit.ly/2rPlUgW
api.github.com
stackshare.io/scala
37/50
Scala adoption rates
StackOverflow 2019[1] survey claims that
almost 60% of respondents have tried
Scala and are interested in working
with it
Approximately 4% of developers are use
Scala as their main language at work[2]
Source: insights.stackoverflow.com/survey/2019
38/50
Scala and productivity
Source: bit.ly/2qombqM
39/50
Scala’s functional programming style
allows writing 2 times less code[1]
Reading Scala code is 2 times faster on
average[1]
Research data[2] shows that Scala
projects need ~30% less bug fixes
1.
2.
bit.ly/37eiWTH
arxiv.org/pdf/1901.10220.pdf
40/50
Scala's performance
Uses JVM as the main
runtime platform
Can be compiled to a native
binary
Up to 35% performance
increase with GraalVM[1]
Utilizes incremental
compilation for only a few
seconds delay per build
1.
2.
graalvm.org/scala
bit.ly/330Ugue
41/50
Scala is a rapidly developed
language used and supported
by many, that can offer
substantial productivity
benefits while keeping
reasonable performance
42/50
Scala in real
world
Areas of application
Scala vs. Java & Kotlin
Scala vs. Python
Scala vs. Golang
Future prospects
43/50
Areas of application
ML pipelines
Resilient applications
Distributed systems
Small or simple systems
Low-level manipulation
UI-centered applications
44/50
Scala vs. Java & Kotlin
Java & Kotlin
Vast amount of libraries
for different needs
Reasonable performance
for most programming
tasks
Object-oriented
approach
JVM as runtime platform
Scala
Fully compatible with Java
and Kotlin libraries
Performance competitive
with Java/Kotlin
Allows for both FP and OOP
Target JVM, browser and
native environments
45/50
Scala vs. Python
Python
Ad-hoc Spark & Hadoop
integration
Easy to prototype ideas
Great number of math
and visualisation libraries
Relatively slow on big
volumes on data
Scala
Native Spark & Hadoop
integration
Compile-time verification
Mainly ML-oriented libraries
Performs well on terabytes
of data
46/50
Scala vs. Golang
Golang
Fixed imperative style
Blazing fast speed
Concurrency primitives
on the language level
Scala
Extensible declarative style
Reasonable performance
Libraries for scalability
47/50
Future prospects
Next major version of Scala is
coming at the end of 2020.
Take a look at:
dotty.epfl.ch
48/50
49/50
Thank you for
your
attention!
Any
questions?
@a7emenov
Find me on ,
and
Twitter
Telegram Github
50/50

More Related Content

PDF
Applicative style programming
PDF
Spark (Structured) Streaming vs. Kafka Streams - two stream processing platfo...
PDF
Airflow presentation
PDF
Enterprise Integration Patterns with Apache Camel
PPTX
Mainframe Solutions Introduction
PDF
Changelog Stream Processing with Apache Flink
PPTX
Exactly-Once Financial Data Processing at Scale with Flink and Pinot
PDF
Java 8 lambda expressions
Applicative style programming
Spark (Structured) Streaming vs. Kafka Streams - two stream processing platfo...
Airflow presentation
Enterprise Integration Patterns with Apache Camel
Mainframe Solutions Introduction
Changelog Stream Processing with Apache Flink
Exactly-Once Financial Data Processing at Scale with Flink and Pinot
Java 8 lambda expressions

What's hot (20)

PPTX
A Brief Intro to Scala
PDF
Introduction to programming with ZIO functional effects
PDF
Apache Flink internals
PPTX
Spring Boot
PPTX
Introduction to GraphQL
PDF
Getting The Best Performance With PySpark
PPTX
Spring boot
PPTX
Java 8 features
PPTX
Java 8 Lambda and Streams
PPTX
WebSphere Application Server Family (Editions Comparison)
PDF
Building Notebook-based AI Pipelines with Elyra and Kubeflow
PPTX
JanusGraph DataBase Concepts
PDF
Graphql
PDF
今さら聞けない!Windows server 2012 r2 hyper v入門
PPTX
Introduction to Spring Boot
PDF
Spark Performance Tuning .pdf
PPTX
Salesforce Integration using REST SOAP and HTTP callouts
PDF
Java 8 Lambda Expressions & Streams
PDF
Apache NiFi Meetup - Introduction to NiFi Registry
PPTX
Introduction to spring boot
A Brief Intro to Scala
Introduction to programming with ZIO functional effects
Apache Flink internals
Spring Boot
Introduction to GraphQL
Getting The Best Performance With PySpark
Spring boot
Java 8 features
Java 8 Lambda and Streams
WebSphere Application Server Family (Editions Comparison)
Building Notebook-based AI Pipelines with Elyra and Kubeflow
JanusGraph DataBase Concepts
Graphql
今さら聞けない!Windows server 2012 r2 hyper v入門
Introduction to Spring Boot
Spark Performance Tuning .pdf
Salesforce Integration using REST SOAP and HTTP callouts
Java 8 Lambda Expressions & Streams
Apache NiFi Meetup - Introduction to NiFi Registry
Introduction to spring boot
Ad

Similar to Gentle Introduction to Scala (20)

PDF
Power of functions in a typed world
PDF
Functional programming in Scala
PPTX
Functional programming
KEY
Scala: functional programming for the imperative mind
PPTX
Intro to Functional Programming
PDF
Introduction To Scala
PDF
Lecture 5: Functional Programming
PDF
Ankara Jug - Practical Functional Programming with Scala
PDF
Learning Functional Programming Without Growing a Neckbeard
PDF
Introduction à Scala - Michel Schinz - January 2010
PDF
Programming in scala - 1
PDF
Meet scala
PPT
Functional object
PDF
Functional programming is the most extreme programming
PPTX
Scala fundamentals
PDF
Scala Quick Introduction
PDF
Lecture 5
PPTX
Scala for curious
PPTX
Good functional programming is good programming
PPTX
Taxonomy of Scala
Power of functions in a typed world
Functional programming in Scala
Functional programming
Scala: functional programming for the imperative mind
Intro to Functional Programming
Introduction To Scala
Lecture 5: Functional Programming
Ankara Jug - Practical Functional Programming with Scala
Learning Functional Programming Without Growing a Neckbeard
Introduction à Scala - Michel Schinz - January 2010
Programming in scala - 1
Meet scala
Functional object
Functional programming is the most extreme programming
Scala fundamentals
Scala Quick Introduction
Lecture 5
Scala for curious
Good functional programming is good programming
Taxonomy of Scala
Ad

More from Fangda Wang (11)

PDF
[WWCode] How aware are you of your deciding model?
PDF
Under the hood of architecture interviews at indeed
PDF
How Indeed asks coding interview questions
PDF
Types are eating the world
PDF
From ic to tech lead
PDF
Introduction to japanese tokenizer
PDF
To pair or not to pair
PDF
Balanced Team
PDF
Functional programming and Elm
PDF
Elm at large (companies)
PPTX
Data science tools of the trade
[WWCode] How aware are you of your deciding model?
Under the hood of architecture interviews at indeed
How Indeed asks coding interview questions
Types are eating the world
From ic to tech lead
Introduction to japanese tokenizer
To pair or not to pair
Balanced Team
Functional programming and Elm
Elm at large (companies)
Data science tools of the trade

Recently uploaded (20)

PDF
Advanced methodologies resolving dimensionality complications for autism neur...
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
Modernizing your data center with Dell and AMD
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
cuic standard and advanced reporting.pdf
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Electronic commerce courselecture one. Pdf
PPTX
Cloud computing and distributed systems.
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Approach and Philosophy of On baking technology
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Machine learning based COVID-19 study performance prediction
Advanced methodologies resolving dimensionality complications for autism neur...
The AUB Centre for AI in Media Proposal.docx
NewMind AI Weekly Chronicles - August'25 Week I
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Modernizing your data center with Dell and AMD
Reach Out and Touch Someone: Haptics and Empathic Computing
cuic standard and advanced reporting.pdf
Encapsulation_ Review paper, used for researhc scholars
Electronic commerce courselecture one. Pdf
Cloud computing and distributed systems.
Understanding_Digital_Forensics_Presentation.pptx
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
“AI and Expert System Decision Support & Business Intelligence Systems”
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Approach and Philosophy of On baking technology
Dropbox Q2 2025 Financial Results & Investor Presentation
Mobile App Security Testing_ A Comprehensive Guide.pdf
Network Security Unit 5.pdf for BCA BBA.
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Machine learning based COVID-19 study performance prediction

Gentle Introduction to Scala

  • 1. A Gentle Introduction to Scala and FP 1/50
  • 2. Hi, I'm Anton! Functional programmer Scala enthusiast Applications engineer at Rakuten @a7emenov Find me on , and Twitter Telegram Github 2/50
  • 3. Agenda Introduce Scala as a language Give examples of universal FP constructs Show benefits of those constructs Compare Scala to other languages 3/50
  • 4. What is Scala as a language? 4/50
  • 5. Scala combines object- oriented and functional programming in one concise, high-level language. 5/50
  • 6. What lies at the core of FP? 6/50
  • 7. What lies at the core of FP? Absence of side-effects in computations 6/50
  • 8. What lies at the core of FP? Absence of side-effects in computations Function composition 6/50
  • 9. What lies at the core of FP? Absence of side-effects in computations Function composition Immutable data 6/50
  • 10. What lies at the core of FP? Absence of side-effects in computations Function composition Immutable data Dark magic 6/50
  • 11. What lies at the core of FP? Absence of side-effects in computations Function composition Immutable data Dark magic ? 6/50
  • 12. What lies at the core of FP? Absence of side-effects in computations Function composition Immutable data Dark magic All of it 7/50
  • 13. Functional programming is a way of solving problems which centers around combining side-effect-free constructs in a declarative manner 8/50
  • 14. Declarative vs. imperative Imperative for (int i = 1; i 5; i ) { int temp = i * 2; if (temp < 6) { System.out.println(temp); } } Declarative (1 to 5) .map(_ * 2) .filter(_ < 6) .foreach(println) 9/50
  • 15. Deep dive FP & Scala Immutability Pure functions Referential transparency Algebraic data types Pattern matching Recursion 10/50
  • 16. Value mutation Variables Can be changed anytime Can be changed from any place that has a reference Exposing private state requires explicit copying Immutable values Can't be changed Create new values instead of changing the old ones No mutable state 11/50
  • 18. Immutable values Benefits Reduce concurrency issues No shared mutable state Easier local reasoning Drawbacks Extra memory allocations 13/50
  • 19. Pure functions Side-effect freeSide-effect free - everything that a function does can be observed in its return value: TotalTotal - return values for every possible input DeterministicDeterministic - given same inputs, return same outputs Locally scopedLocally scoped - no effect on the state outside of the function's scope 14/50
  • 20. Referential transparency All calls to a function can be substituted with its return value 15/50
  • 21. Referential transparency Not transparent def getInt(l: Int, r: Int): Int = Random.between(l, r) def increment(x: Int): Int = { val res = x + 1 destroyTheWorld() res } Transparent def fact(n: Int): Int = { var res = 1 var i = 1 while (i n) { res = res * i i = i + 1 } res } 16/50
  • 22. Business value with pure functions How can programs be useful without any side-effects? 17/50
  • 23. Business value with pure functions Describe side-effecting computations instead of instantly running them Combine all side-effects to produce a single description Run the resulting computation in the main method 18/50
  • 24. Business value with pure functions def saveValue(key: String, value: Int): IO[Unit] = ? def getValue(key: String): IO[Option[Int]] = ??? def rateLimit[A](program: IO[A]): IO[A] = ??? val program: IO[Option[Int]] = ratelimit( saveValue("key", 1) >> getValue("key") ) val result: Option[Int] = program.runSyncUnsafe() 19/50
  • 25. Business value with pure functions saveValue("key", 1) >> getValue("key") def saveValue(key: String, value: Int): IO[Unit] = ??? def getValue(key: String): IO[Option[Int]] = ??? def rateLimit[A](program: IO[A]): IO[A] = ??? val program: IO[Option[Int]] = ratelimit( ) val result: Option[Int] = program.runSyncUnsafe() 19/50
  • 26. Business value with pure functions def rateLimit[A](program: IO[A]): IO[A] = ??? def saveValue(key: String, value: Int): IO[Unit] = ??? def getValue(key: String): IO[Option[Int]] = ??? val program: IO[Option[Int]] = ratelimit( saveValue("key", 1) >> getValue("key") ) val result: Option[Int] = program.runSyncUnsafe() 19/50
  • 27. Business value with pure functions val program: IO[Option[Int]] = ratelimit( saveValue("key", 1) >> getValue("key") ) def saveValue(key: String, value: Int): IO[Unit] = ??? def getValue(key: String): IO[Option[Int]] = ??? def rateLimit[A](program: IO[A]): IO[A] = ??? val result: Option[Int] = program.runSyncUnsafe() 19/50
  • 28. Business value with pure functions val result: Option[Int] = program.runSyncUnsafe() def saveValue(key: String, value: Int): IO[Unit] = ??? def getValue(key: String): IO[Option[Int]] = ??? def rateLimit[A](program: IO[A]): IO[A] = ??? val program: IO[Option[Int]] = ratelimit( saveValue("key", 1) >> getValue("key") ) 19/50
  • 29. Pure functions Benefits Ultimate local reasoning Parallelizable execution Easy testing Drawbacks Extra object allocations Require an effect system or a library to operate mutable state 20/50
  • 30. Algebraic data types Product typesProduct types - define how to create a value (“has a field” relationship) Sum typesSum types - define the range of values (“is one of” relationship) Product types + Sum types = Algebraic data types 21/50
  • 31. Product types Traditional classes public class Person { // Which is the primary constructor? // Are the constructors related? public Person(Age age, Year birthYear) { /* ... */ } public Person(Year currentYear, Age age) { /* ... */ } public Person(Year currentYear, Year birthYear) { /* ... */ } } 22/50
  • 32. Product types Traditional classes public class Person { // Which is the primary constructor? // Are the constructors related? public Person(Age age, Year birthYear) { /* ... */ } public Person(Year currentYear, Age age) { /* ... */ } public Person(Year currentYear, Year birthYear) { /* ... */ } } Product types // Primary constructor defines the product case class Person(age: Age, birthYear: Year) { // Supplementary constructors // must use the primary constructor def this(currentYear: Year, age: Age) { this(age, currentYear - age) } def this(currentYear: Year, birthYear: Year { this(currentYear - birthYear, birthYear } 22/50
  • 33. Sum types Traditional interfaces public interface User { /* Common methods */ } public class Client implements User { /* Client-specific methods */ } public class Admin implements User { /* Admin-specific methods */ } void process(User user) { // How can this function reason about a // possible implementations of User? } 23/50
  • 34. Sum types Traditional interfaces public interface User { /* Common methods */ } public class Client implements User { /* Client-specific methods */ } public class Admin implements User { /* Admin-specific methods */ } void process(User user) { // How can this function reason about a // possible implementations of User? } Sum types // "Sealed" allows the compiler to find // all descendants of User sealed trait User { /* Common methods */ } case class Client extends User { /* Client-specific methods */ } case class Admin extends User { /* Admin-specific methods */ } def process(user: User): IO[Unit] = { // The function now has knowledge that // there are only 2 options for "user" } 23/50
  • 35. Pattern matching Data construction sealed trait User case class Client(email: String role: String) extends User case class Admin(name: String, scopes: List[String]) extends User val client: User = Client("test@email.com", "manager") val admin: User = Admin("Jane", List("emails", "orders") Data deconstruction def process(u: User): IO[Unit] = u match { case Client(email, "manager") logManager(email) case Admin(name, Nil) logAdmin(name, "No scopes") case Admin(name, List("emails")) logAdmin(name, "Only 'emails' scope") case Admin(name, scopes) if scopes.contains("orders") logAdmin(name, "Has 'orders' scope") case _ logDefault("Default action") } 24/50
  • 36. Pattern matching Benefits Compile-time type checks Exhaustiveness checks Enhanced code readability Extensible Drawbacks Extra memory allocations 25/50
  • 37. Recursion Declarative Native mapping to many real-world problems Can be as efficient as a loop* import scala.annotation.tailrec @tailrec def foldLeft[R](list: List[Int]) (acc: R) (f: (R, Int) R): R = list match { case Nil acc case head :: tail foldLeft(tail)(f(acc, head))(f) } // "12345" foldLeft(List(1, 2, 3, 4, 5))(acc = "") { (acc, num) acc + num.toString } 26/50
  • 38. FP in Scala - covered points Immutability Pure functions Referential transparency Algebraic data types Pattern matching Recursion over iteration 27/50
  • 40. Higher-kinded types Simple types:Simple types: Int, String, User Unary typeUnary type constructors:constructors: List[A], Future[A] Binary typeBinary type constructors:constructors: Either[A, B], Tuple[A, B] Higher-kinded typesHigher-kinded types: trait Processor[L[_]] { def run[A](l: L[A]): Unit } val listP = new Processor[List] { def run[A](l: List[A]): Unit = l.foreach(println) } listP.run(List(1, 2, 3)) listP.run(List("a", "b", "c")) 29/50
  • 41. For comprehensions def getProfile(userName: String): Option[Profile] = ??? def getComments(profile: Profile): Option[List[Comment]] = ??? def getBonus(profile: Profile): Option[Int] = ??? val updatedComments = for { profile getUserProfile("Jack") comments getComments(profile) bonus getBonus(profile) } yield comments.take(10) .map( .increaseRating(bonus)) 30/50
  • 42. For comprehensions Define coherent syntax for sequential composition Syntactic sugar for every type with map, flatMap and withFilter methods Can be used with any type supplying these methods Take advantage of pattern matching 31/50
  • 43. Implicit values Provide automatic value forwarding Resolved at compile- time Can be derived from existing context case class Foo(id: Int) object Foo { implicit val o: Ordering[Foo] = Ordering.by(_.id) } def sortFoo(foos: List[Foo]) (implicit o: Ordering[Foo]) = foos.sorted(o) sortFoo( 32/50
  • 44. Syntax extensions Allow to create ad-hoc methods for code reuse and readability Can be used for types imported from other projects/libraries implicit class StringSyntax (s: String) { def filterDigits: String = s.filter(_.isDigit) } // "123" "1a2b3c".filterDigits 33/50
  • 45. Macros Eliminate boilerplate code Provide implementations in compile time Allow to extract code meta data import io.circe._ import io.circe.generic.semiauto. case class Foo(a: Int, b: String) case class Bar( id: Option[String], foo: Foo ) val barDecoder: Decoder[Bar] = deriveDecoder[Foo].map(foo Bar(id = None, foo = foo) ) 34/50
  • 46. Scala language - covered points Higher-kinded types For-comprehensions Implicit values Syntax extensions Macros 35/50
  • 47. Scala in numbers Development and adoption rates Effect on productivity Performance 36/50
  • 48. Scala adoption rates Maintained intense release schedule for over 15 years Development of the language is supported by the European government and enterprise investors[1] As popular as Kotlin for backend development[2] and is 20% more widespread company-wise[3] 1. 2. 3. bit.ly/2Xr3bnH bit.ly/2rPlUgW api.github.com stackshare.io/scala 37/50
  • 49. Scala adoption rates StackOverflow 2019[1] survey claims that almost 60% of respondents have tried Scala and are interested in working with it Approximately 4% of developers are use Scala as their main language at work[2] Source: insights.stackoverflow.com/survey/2019 38/50
  • 50. Scala and productivity Source: bit.ly/2qombqM 39/50
  • 51. Scala’s functional programming style allows writing 2 times less code[1] Reading Scala code is 2 times faster on average[1] Research data[2] shows that Scala projects need ~30% less bug fixes 1. 2. bit.ly/37eiWTH arxiv.org/pdf/1901.10220.pdf 40/50
  • 52. Scala's performance Uses JVM as the main runtime platform Can be compiled to a native binary Up to 35% performance increase with GraalVM[1] Utilizes incremental compilation for only a few seconds delay per build 1. 2. graalvm.org/scala bit.ly/330Ugue 41/50
  • 53. Scala is a rapidly developed language used and supported by many, that can offer substantial productivity benefits while keeping reasonable performance 42/50
  • 54. Scala in real world Areas of application Scala vs. Java & Kotlin Scala vs. Python Scala vs. Golang Future prospects 43/50
  • 55. Areas of application ML pipelines Resilient applications Distributed systems Small or simple systems Low-level manipulation UI-centered applications 44/50
  • 56. Scala vs. Java & Kotlin Java & Kotlin Vast amount of libraries for different needs Reasonable performance for most programming tasks Object-oriented approach JVM as runtime platform Scala Fully compatible with Java and Kotlin libraries Performance competitive with Java/Kotlin Allows for both FP and OOP Target JVM, browser and native environments 45/50
  • 57. Scala vs. Python Python Ad-hoc Spark & Hadoop integration Easy to prototype ideas Great number of math and visualisation libraries Relatively slow on big volumes on data Scala Native Spark & Hadoop integration Compile-time verification Mainly ML-oriented libraries Performs well on terabytes of data 46/50
  • 58. Scala vs. Golang Golang Fixed imperative style Blazing fast speed Concurrency primitives on the language level Scala Extensible declarative style Reasonable performance Libraries for scalability 47/50
  • 59. Future prospects Next major version of Scala is coming at the end of 2020. Take a look at: dotty.epfl.ch 48/50
  • 60. 49/50
  • 61. Thank you for your attention! Any questions? @a7emenov Find me on , and Twitter Telegram Github 50/50