FUNCTIONAL ANDROID
Victoria Gonda
@TTGonda
Photo by taylor hernandez on Unsplash
Slide 2
Slide 2 text
@TTGonda
WHO AM I?
➤ Android Engineer at Buffer
➤ Author for Ray Wenderlich
➤ Chicago
➤ Dancer
Slide 3
Slide 3 text
@TTGonda
THANKS TO ANUP COWKUR
➤ His blog posts provided lots of help in the
research of this topic.
➤ Functional Programming for Android
Developers
Slide 4
Slide 4 text
@TTGonda
WHY FUNCTIONAL PROGRAMMING?
➤ We’re seeing an increase of the use of the
paradigm (Kotlin, RxJava, Λrrow)
➤ Features can be used to write cleaner, more
expressive code
➤ Simplifies concurrency
➤ Easier to test
Photo by Jennifer Pallian on Unsplash
Slide 5
Slide 5 text
@TTGonda
WHAT IS FUNCTIONAL PROGRAMMING?
➤ Came from lambda calculus
➤ Mimics the evaluation of mathematical
functions
➤ Easier to test
➤ Some key characteristics of FP
➤ Declarative
➤ Explicitness
➤ Concurrency
➤ Higher Order Functions
➤ Immutability
Photo by Patrick Tomasso on Unsplash
Slide 6
Slide 6 text
@TTGonda
WHAT ARE WE GOING TO TALK ABOUT?
➤ Pure functions
➤ No side effects
➤ Ordering
➤ Immutability
➤ Concurrency
➤ Higher order functions
➤ Error handling
Slide 7
Slide 7 text
@TTGonda
PURE FUNCTIONS
➤ Always gives the same output for a given
input
➤ Independent of the outside world
➤ No side effects
➤ Easy to test
Photo by Toa Heftiba on Unsplash
Slide 8
Slide 8 text
@TTGonda
PURE FUNCTIONS
fun blend(ingredients: List): Milkshake {
return Milkshake(milk.get(), icecream.get(), ingredients)
}
Slide 9
Slide 9 text
@TTGonda
PURE FUNCTIONS
fun blend(milk: Milk, icecream: IceCream,
ingredients: List): Milkshake {
return Milkshake(milk, icecream, ingredients)
}
Slide 10
Slide 10 text
@TTGonda
NO SIDE EFFECTS
➤ Don’t change anything outside
➤ Lessens the dependence on context
➤ Eliminates surprises
➤ You guessed it, easier to test
Photo by Annie Shelmerdine on Unsplash
Slide 11
Slide 11 text
@TTGonda
NO SIDE EFFECTS
fun blend(milk: Milk, icecream: IceCream,
ingredients: List): Milkshake {
return glasses.pop()
.fill(Milkshake(milk, icecream, ingredients))
}
Slide 12
Slide 12 text
@TTGonda
NO SIDE EFFECTS
fun blend(glass: Glass, milk: Milk, icecream: IceCream,
ingredients: List): Milkshake {
return glass.fill(Milkshake(milk, icecream, ingredients))
}
Slide 13
Slide 13 text
@TTGonda
ORDERING
➤ Things that can be executed in any order
➤ Something we get to do when we have pure
functions
➤ This means they can also be concurrent!
Photo by Gabriel Gurrola on Unsplash
@TTGonda
ORDERING
fun makeToast() {
cooks.pop()
.prepare(Toast)
}
Slide 16
Slide 16 text
@TTGonda
ORDERING
fun makeToast(cook: Cook) {
cook.prepare(Toast)
}
Slide 17
Slide 17 text
@TTGonda
IMMUTABILITY
➤ No changing things
➤ Want something different, make a new one
➤ You know it won’t change on you
➤ Watch for mutable child objects
Photo by Alireza Etemadi on Unsplash
Slide 18
Slide 18 text
@TTGonda
IMMUTABILITY
class Burger(var type: String)
Slide 19
Slide 19 text
@TTGonda
IMMUTABILITY
public class Burger {
private String type;
public Burger(String type) {
this.type = type;
}
public final String getType() {
return this.type;
}
public final void setType(String type) {
this.type = type;
}
}
Slide 20
Slide 20 text
@TTGonda
IMMUTABILITY
val burger = Burger("veggie")
burger.type = "beef"
Slide 21
Slide 21 text
@TTGonda
IMMUTABILITY
class Burger(val type: String)
Slide 22
Slide 22 text
@TTGonda
IMMUTABILITY
final public class Burger {
final private String type;
public Burger(String type) {
this.type = type;
}
public final String getType() {
return this.type;
}
}
Slide 23
Slide 23 text
@TTGonda
IMMUTABILITY
val burger = Burger("veggie")
burger.type = "beef"
Slide 24
Slide 24 text
@TTGonda
IMMUTABILITY
class Burger(var type: String?)
if (burger.type != null)
burger.type.length
Slide 25
Slide 25 text
@TTGonda
IMMUTABILITY
class Burger(val type: String?)
if (burger.type != null)
burger.type.length
Slide 26
Slide 26 text
@TTGonda
IMMUTABILITY
class Burger(var type: String, val toppings: MutableList)
val burger = Burger("veggie", mutableListOf())
burger.toppings.add("onion")
Slide 27
Slide 27 text
@TTGonda
IMMUTABILITY
class Burger(var type: String, val toppings: List)
val burger = Burger("veggie", listOf())
Slide 28
Slide 28 text
@TTGonda
IMMUTABILITY
final public class Burger {
final private String type;
final private List toppings;
public Burger(String type, List toppings) {
/* ... */
}
public final String getType() { /* ... */ }
public final List getToppings() {
List toppingsCopy = new ArrayList<>();
toppingsCopy.addAll(toppings);
return toppingsCopy;
}
}
Slide 29
Slide 29 text
@TTGonda
CONCURRENCY
➤ We want concurrency, but it can be hard
➤ Using pure functions with no side effects
and immutability helps
➤ We can do things on different threads,
without worrying about unexpected
behavior
➤ Locks aren’t required, so we don’t have to
worry about deadlock
Photo by ål nik on Unsplash
@TTGonda
CONCURRENCY
fun addToppings(burger: ImmutableBurger, toppings: List)
: Observable? {
val newBurger = burger.copy(toppings = toppings)
return Observable.just(newBurger)
.subscribeOn(kitchenThread)
}
Slide 33
Slide 33 text
@TTGonda
HIGHER ORDER FUNCTIONS
➤ Functions as first class citizens
➤ Pass functions into a function
➤ Share logic the way you do an object
➤ Lose single abstract method interfaces
Photo by Emmy Smith on Unsplash
Slide 34
Slide 34 text
@TTGonda
HIGHER ORDER FUNCTIONS
fun makePotatoes(potatoes: Potatoes,
cookPotatoes: (Potatoes) -> CookedPotatoes) {
val cleanPotatoes = washAndPeelPotatoes(potatoes)
val cookedPotatoes = cookPotatoes(cleanPotatoes)
eatPotatoes(cookedPotatoes)
}
@TTGonda
HIGHER ORDER FUNCTIONS
val customer = Customer()
customer.setOnFinishedEatingListener {
clearDishes()
bringCheck()
}
Slide 38
Slide 38 text
@TTGonda
ERROR HANDLING
➤ Everything is a value or computation
➤ Avoiding unexpected states
➤ Errors are treated as values
Photo by chuttersnap on Unsplash
@TTGonda
ERROR HANDLING
val result = deliver(burger)
if (!result.success) {
makeNew(burger)
}
Slide 44
Slide 44 text
@TTGonda
ERROR HANDLING
if (!deliver(burger).success) {
makeNew(burger)
}
Slide 45
Slide 45 text
@TTGonda
TOOLS
➤ Kotlin programming language
➤ RxJava library
➤ Λrrow library
Photo by Leti Kugler on Unsplash
Slide 46
Slide 46 text
@TTGonda
{ previousState, result ->
when (result) {
is FoldersResult.GetLastState -> previousState
is FoldersResult.LoadFoldersTask -> {
when {
result.status == TaskStatus.SUCCESS ->
FoldersUiModel.FoldersLoaded(result.folders)
result.status == TaskStatus.FAILURE ->
FoldersUiModel.Failed
result.status == TaskStatus.IN_FLIGHT ->
FoldersUiModel.InProgress
else -> FoldersUiModel.Idle()
}
}
}
}
Slide 47
Slide 47 text
@TTGonda
{ previousState, result ->
when (result) {
is FoldersResult.GetLastState -> previousState
is FoldersResult.LoadFoldersTask -> {
when {
result.status == TaskStatus.SUCCESS ->
FoldersUiModel.FoldersLoaded(result.folders)
result.status == TaskStatus.FAILURE ->
FoldersUiModel.Failed
result.status == TaskStatus.IN_FLIGHT ->
FoldersUiModel.InProgress
else -> FoldersUiModel.Idle()
}
}
}
}
Slide 48
Slide 48 text
@TTGonda
{ previousState, result ->
when (result) {
is FoldersResult.GetLastState -> previousState
is FoldersResult.LoadFoldersTask -> {
when {
result.status == TaskStatus.SUCCESS ->
FoldersUiModel.FoldersLoaded(result.folders)
result.status == TaskStatus.FAILURE ->
FoldersUiModel.Failed
result.status == TaskStatus.IN_FLIGHT ->
FoldersUiModel.InProgress
else -> FoldersUiModel.Idle()
}
}
}
}
Slide 49
Slide 49 text
@TTGonda
{ previousState, result ->
when (result) {
is FoldersResult.GetLastState -> previousState
is FoldersResult.LoadFoldersTask -> {
when {
result.status == TaskStatus.SUCCESS ->
FoldersUiModel.FoldersLoaded(result.folders)
result.status == TaskStatus.FAILURE ->
FoldersUiModel.Failed
result.status == TaskStatus.IN_FLIGHT ->
FoldersUiModel.InProgress
else -> FoldersUiModel.Idle()
}
}
}
}
Slide 50
Slide 50 text
@TTGonda
{ previousState, result ->
when (result) {
is FoldersResult.GetLastState -> previousState
is FoldersResult.LoadFoldersTask -> {
when {
result.status == TaskStatus.SUCCESS ->
FoldersUiModel.FoldersLoaded(result.folders)
result.status == TaskStatus.FAILURE ->
FoldersUiModel.Failed
result.status == TaskStatus.IN_FLIGHT ->
FoldersUiModel.InProgress
else -> FoldersUiModel.Idle()
}
}
}
}
Slide 51
Slide 51 text
@TTGonda
RESOURCES
➤ Functional Programming for Android Developers by Anup Cowkur
➤ Functional Reactive Programming with RxJava by Francisco González
➤ Functional Programming in Kotlin with Arrow by Jorge Castillo on Caster.io
Slide 52
Slide 52 text
THANKS!
Victoria Gonda
@TTGonda
Photo by taylor hernandez on Unsplash