SlideShare une entreprise Scribd logo
1  sur  47
Télécharger pour lire hors ligne
Kotlin from scratch 2
franco.lombardo@smeup.com - https://www.linkedin.com/in/francolombardo/
Functions
Last episode: the power of lambdas
val elapsedTime = measureTimeMillis {
execute(compilationUnit.main.stmts)
}
public fun measureTimeMillis(block: () -> Unit): Long {
val start = System.currentTimeMillis()
block()
return System.currentTimeMillis() - start
}
Last episode: the power of lambdas
val elapsedTime = measureTimeMillis {
execute(compilationUnit.main.stmts)
}
public fun measureTimeMillis(block: () -> Unit): Long {
val start = System.currentTimeMillis()
block()
return System.currentTimeMillis() - start
}
This is a function (lambda expression)
What is a lambda?
A lambda is a literal of a function type
val x: Int = 5
5 is a literal of type Int
val f: (Int) -> String = { "The number is $it" }
This is a literal of type (Int) -> String
(Well, on JVM it’s an instance of Function1<Int, String>)
What is a lambda?
A lambda is a literal of a function type
val x: Int = 5
val f: (Int) -> String = { "The number is $it" }
it: implicit name of a single parameter
What is a lambda?
A lambda is a literal of a function type
val x: Int = 5
We can use a more explicit syntax
val f: (Int) -> String = { number: Int ->
"The number is $number"
}
What is a lambda?
A lambda is a literal of a function type
val x: Int = 5
Here is the evaluation of the function (y is a String)
val f = { number: Int ->
"The number is $number"
}
val y = f(x)
What is a lambda?
A lambda is a literal of a function type
val x: Int = 5
The function here is unevaluated (z is a function)
val f = { number: Int ->
"The number is $number"
}
val z = f
What is a closure?
A closure is a lambda that accesses its closure, i.e. the
variables declared in the outer scope
val x: Int = 5
val f = { "The number is $x" }
val y = f()
What is a closure?
Be careful!
Prints The number is 10
var x = 5
val f = { "The number is $x" }
x = 10
println ("${f()}")
The power of lambdas
val elapsedTime = measureTimeMillis {
execute(compilationUnit.main.stmts)
}
public fun measureTimeMillis(block: () -> Unit): Long {
val start = System.currentTimeMillis()
block()
return System.currentTimeMillis() - start
}
The power of lambdas
val elapsedTime = measureTimeMillis {
execute(compilationUnit.main.stmts)
}
public fun measureTimeMillis(block: () -> Unit): Long {
val start = System.currentTimeMillis()
block()
return System.currentTimeMillis() - start
}
Higher order function: a function that has a function parameter (or result)
Last episode: the power of lambdas
val elapsedTime = measureTimeMillis ({
execute(compilationUnit.main.stmts)
})
“Explicit” syntax
public fun measureTimeMillis(block: () -> Unit): Long {
val start = System.currentTimeMillis()
block()
return System.currentTimeMillis() - start
}
It’s the last parameter of this function
Last episode: the power of lambdas
val elapsedTime = measureTimeMillis () {
execute(compilationUnit.main.stmts)
}
public fun measureTimeMillis(block: () -> Unit): Long {
val start = System.currentTimeMillis()
block()
return System.currentTimeMillis() - start
}
It’s the last parameter of this function,
so we can pass it outside the parentheses.
Last episode: the power of lambdas
val elapsedTime = measureTimeMillis (){
execute(compilationUnit.main.stmts)
}
public fun measureTimeMillis(block: () -> Unit): Long {
val start = System.currentTimeMillis()
block()
return System.currentTimeMillis() - start
}
Since it’s the only argument,
the parentheses can be omitted entirely:
Types of bodies
Types of bodies
See sample project: https://github.com/f-lombardo/kotlin-from-scratch
fun openDatabase(user: String, password: String): Database? =
if ("franco" == user && "secret" == password) {
sampleDatabase()
} else {
null
}
fun openDatabase(user: String, password: String): Database? {
if ("franco" == user && "secret" == password) {
return sampleDatabase()
}
return null
}
Block body
Expression body
Named arguments
println(
openDatabase("franco", "secret")
?.findComposerByName("Giuseppe Verdi")
?.findOperaByYear(1853)
?: "No results"
)
Which is the password?
Named arguments
println(
openDatabase(user = "franco", password = "secret")
?.findComposerByName("Giuseppe Verdi")
?.findOperaByYear(1853)
?: "No results"
)
Named arguments
println(
openDatabase(password = "secret", user = "franco")
?.findComposerByName("Giuseppe Verdi")
?.findOperaByYear(1853)
?: "No results"
)
Different order
Named arguments
println(
openDatabase(user = "franco", "secret")
?.findComposerByName("Giuseppe Verdi")
?.findOperaByYear(1853)
?: "No results"
)
NO! It doesn’t compile. If you start with named arguments
you should go on from there
println(
openDatabase("as400", user = "franco", password = "secret")
?.findComposerByName("Giuseppe Verdi")
?.findOperaByYear(1853)
?: "No results"
)
OK
Composition!!!
Composing null returning functions
println(
openDatabase("franco","secret")
?.findComposerByName("Giuseppe Verdi")
?.findOperaByYear(1853)
?: "No results"
)
fun Database.findComposerByName(name: String): Composer? =
this.composers.firstOrNull { it.name == name }
Extension function: we extend the Database class with a new method
Composing null returning functions
println(
openDatabase("franco","secret")
?.findComposerByName("Giuseppe Verdi")
?.findOperaByYear(1853)
?: "No results"
)
fun Database.findComposerByName(name: String): Composer? =
this.composers.firstOrNull { it.name == name }
Composer? → {Composer U null} (sum type)
findComposerByName is “total”
i.e. it maps each input value in one output value
Composing null returning functions
println(
openDatabase("franco","secret")
?.findComposerByName("Giuseppe Verdi")
?.findOperaByYear(1853)
?: "No results"
)
“or else”
“and then”
Total functions (not throwing exceptions) compose easily
Could we have a better composition?
println(
openDatabase("franco","secret")
?.findComposerByName("Giuseppe Verdi")
?.findOperaByYear(1853)
?: "No results"
)
“Good” functions compose easily
inline fun Database.findComposerBy(predicate: (Composer) -> Boolean) =
this.composers.firstOrNull(predicate)
fun similarName(name: String): (Composer) -> Boolean =
{ it.name.contains(name, ignoreCase = true) }
fun exactName(name: String): (Composer) -> Boolean =
{ it.name == name }
These functions have another function as a result
Higher order function
“Good” functions compose easily
println(
openDatabase("franco","secret")
?.findComposerBy(similarName("verdi"))
?.findOperaByYear(1853)
?: "No results"
)
println(
openDatabase("franco","secret")
?.findComposerBy(exactName("Giuseppe Verdi"))
?.findOperaByYear(1853)
?: "No results"
)
“Good” functions compose easily
println(
openDatabase("franco","secret")
?.findComposerBy(exactMatchToGiacomoPuccini)
?.findOperaByYear(1853)
?: "No results"
)
val exactMatchToGiacomoPuccini =
exactName("Giacomo Puccini")
Functions can be stored in variables
“Good” functions compose easily
fun exactMatchToGiuseppeVerdi(composer: Composer): Boolean =
composer.name == "Giuseppe Verdi"
println(
openDatabase("franco","secret")
?.findComposerBy(::exactMatchToGiuseppeVerdi)
?.findOperaByYear(1853)
?: "No results"
)
Passing a function as a parameter using its name
“Good” functions compose easily
You can use functions from the standard library too
fun exactMatchToGiuseppeVerdi(composer: Composer): Boolean =
composer.name == "Giuseppe Verdi"
openDatabase("franco","secret")
?.findComposerBy(::exactMatchToGiuseppeVerdi)
?.findOperaByYear(1853)
.run(::println)
“Good” functions compose easily
Extension function applicable to objects of any type:
it passes the object to the given function
fun exactMatchToGiuseppeVerdi(composer: Composer): Boolean =
composer.name == "Giuseppe Verdi"
openDatabase("franco","secret")
?.findComposerBy(::exactMatchToGiuseppeVerdi)
?.findOperaByYear(1853)
.run(::println)
“Good” functions compose easily
Not that good: prints null if no result is found
fun exactMatchToGiuseppeVerdi(composer: Composer): Boolean =
composer.name == "Giuseppe Verdi"
openDatabase("franco","secret")
?.findComposerBy(::exactMatchToGiuseppeVerdi)
?.findOperaByYear(1853)
.run(::println)
“Good” functions compose easily
fun Opera?.displayResult(): Unit =
if (this == null) {
println("No result")
} else {
println(this)
}
openDatabase("franco","secret")
?.findComposerBy(::exactMatchToGiuseppeVerdi)
?.findOperaByYear(1930)
.run(::displayResult)
“Good” functions compose easily
fun Opera?.displayResult(): Unit =
if (this == null) {
println("No result")
} else {
println(this)
}
openDatabase("franco","secret")
?.findComposerBy(::exactMatchToGiuseppeVerdi)
?.findOperaByYear(1930)
.run(::displayResult)
Extension function on a nullable type
“Good” functions compose easily
fun Opera?.displayResult(): Unit =
if (this == null) {
println("No result")
} else {
println(this)
}
openDatabase("franco","secret")
?.findComposerBy(::exactMatchToGiuseppeVerdi)
?.findOperaByYear(1930)
.run(::displayResult)
if statements are also expressions.
(The result here has type Unit)
Infix methods
infix fun Opera?.displayResultTo(printStream: PrintStream): Unit =
if (this == null) {
printStream.println("No result")
} else {
printStream.println(this)
}
openDatabase("franco","secret")
?.findComposerBy(exactMatchToGiacomoPuccini)
?.findOperaByYear(1901) displayResultTo System.err
“Good” functions compose easily
println(
openDatabase("franco","secret")
?.findComposerBy(exactMatchToGiacomoPuccini)
?.operas
?.maxBy (Opera::yearOfComposition)
?: "No results"
)
Functional API for collections (like map, sortBy, find…)
They get function parameters
A List
“Good” functions compose easily
println(
openDatabase("franco","secret")
?.findComposerBy(exactMatchToGiacomoPuccini)
?.operas
?.maxBy (Opera::yearOfComposition)
?: "No results"
)
Member reference: it’s like a lambda that has the object
as a parameter and invokes the method on it
A List
More functional APIs for collections
println(
openDatabase("franco","secret")
?.findComposerBy(exactMatchToGiacomoPuccini)
?.operas
?.sortedBy (Opera::yearOfComposition)
?.map (Opera::name)
?: "No results"
)
sortedBy doesn’t sort the original collection,
but it returns a sorted copy of it: immutable data!
Constructors are functions
class OperaHtmlDiv(val opera: Opera) {
override fun toString(): String =
"<div>${opera.name} ${opera.yearOfComposition}</div>"
}
println(
openDatabase("franco","secret")
?.findComposerBy(exactMatchToGiacomoPuccini)
?.operas
?.sortedBy (Opera::yearOfComposition)
?.map (::OperaHtmlDiv)
?: "No results"
)
We pass a constructor as a parameter
Do we really need all these checks?
println(
openDatabase("franco", "secret")
?.findComposerBy(exactMatchToGiacomoPuccini)
?.run {
operas
.sortedBy(Opera::yearOfComposition)
.map(::OperaHtmlDiv)
}
?: "No results"
)
Implicit this
The dark side of lambdas
fun Database.findComposerBy(predicate: (Composer) -> Boolean) =
this.composers.firstOrNull(predicate)
A new object is created here
openDatabase("franco", "secret")
?.findComposerBy {
it.name.toLowerCase().startsWith("v")
}
The dark side of lambdas
inline fun Database.findComposerBy(predicate: (Composer) -> Boolean) =
this.composers.firstOrNull(predicate)
Inlining the function the compiler doesn’t need a new object
openDatabase("franco", "secret")
?.findComposerBy {
it.name.toLowerCase().startsWith("v")
}
See https://www.baeldung.com/kotlin-inline-functions
• Use Inline with functions that have a lambda parameter
• With inline we can’t pass the lambda around,
so it can’t be the result of our higher order function
What is a “good” function?
• It is total, i.e. it maps each input value in one output value
(no exceptions)
• It works with immutable data types
(it doesn’t modify its parameters)
• It does not cause any observable side effects
• It returns the same result if given the same arguments
(it doesn’t depend on the environment)
• So it is referentially transparent, i.e. it can be replaced with its
corresponding value without changing the program's
behaviour
Good reads
Kotlin weekly
Great weekly newsletter: http://www.kotlinweekly.net/
Uberto Barbini on Medium
https://medium.com/@ramtop
Kotlin expertise blog by Simon Wirtz
https://kotlinexpertise.com/
Florina Muntenescu on Medium
https://medium.com/@florina.muntenescu
Kotlin blog by JetBrains
https://blog.jetbrains.com/kotlin/

Contenu connexe

Tendances

Implementing Software Machines in Go and C
Implementing Software Machines in Go and CImplementing Software Machines in Go and C
Implementing Software Machines in Go and CEleanor McHugh
 
Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6Paulo Morgado
 
.NET 2015: Будущее рядом
.NET 2015: Будущее рядом.NET 2015: Будущее рядом
.NET 2015: Будущее рядомAndrey Akinshin
 
Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Baruch Sadogursky
 
Rust concurrency tutorial 2015 12-02
Rust concurrency tutorial 2015 12-02Rust concurrency tutorial 2015 12-02
Rust concurrency tutorial 2015 12-02nikomatsakis
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?Adam Dudczak
 
TCO in Python via bytecode manipulation.
TCO in Python via bytecode manipulation.TCO in Python via bytecode manipulation.
TCO in Python via bytecode manipulation.lnikolaeva
 
Rust Mozlando Tutorial
Rust Mozlando TutorialRust Mozlando Tutorial
Rust Mozlando Tutorialnikomatsakis
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Roman Elizarov
 
Explaining ES6: JavaScript History and What is to Come
Explaining ES6: JavaScript History and What is to ComeExplaining ES6: JavaScript History and What is to Come
Explaining ES6: JavaScript History and What is to ComeCory Forsyth
 
Encrypt all transports
Encrypt all transportsEncrypt all transports
Encrypt all transportsEleanor McHugh
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6FITC
 

Tendances (20)

Implementing Software Machines in Go and C
Implementing Software Machines in Go and CImplementing Software Machines in Go and C
Implementing Software Machines in Go and C
 
Kotlin
KotlinKotlin
Kotlin
 
Go a crash course
Go   a crash courseGo   a crash course
Go a crash course
 
EcmaScript 6
EcmaScript 6 EcmaScript 6
EcmaScript 6
 
ECMAScript 6
ECMAScript 6ECMAScript 6
ECMAScript 6
 
Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6
 
.NET 2015: Будущее рядом
.NET 2015: Будущее рядом.NET 2015: Будущее рядом
.NET 2015: Будущее рядом
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
 
Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014
 
Rust concurrency tutorial 2015 12-02
Rust concurrency tutorial 2015 12-02Rust concurrency tutorial 2015 12-02
Rust concurrency tutorial 2015 12-02
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?
 
TCO in Python via bytecode manipulation.
TCO in Python via bytecode manipulation.TCO in Python via bytecode manipulation.
TCO in Python via bytecode manipulation.
 
Rust Mozlando Tutorial
Rust Mozlando TutorialRust Mozlando Tutorial
Rust Mozlando Tutorial
 
Java VS Python
Java VS PythonJava VS Python
Java VS Python
 
Why Learn Python?
Why Learn Python?Why Learn Python?
Why Learn Python?
 
Java Class Design
Java Class DesignJava Class Design
Java Class Design
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017
 
Explaining ES6: JavaScript History and What is to Come
Explaining ES6: JavaScript History and What is to ComeExplaining ES6: JavaScript History and What is to Come
Explaining ES6: JavaScript History and What is to Come
 
Encrypt all transports
Encrypt all transportsEncrypt all transports
Encrypt all transports
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6
 

Similaire à Kotlin from-scratch 2 - functions

From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFabio Collini
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming iiPrashant Kalkar
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...julien.ponge
 
golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptxGuy Komari
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionDmitry Sheiko
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기진성 오
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme SwiftMovel
 
The... Wonderful? World of Lambdas
The... Wonderful? World of LambdasThe... Wonderful? World of Lambdas
The... Wonderful? World of LambdasEsther Lozano
 
Pick up the low-hanging concurrency fruit
Pick up the low-hanging concurrency fruitPick up the low-hanging concurrency fruit
Pick up the low-hanging concurrency fruitVaclav Pech
 
3 kotlin vs. java- what kotlin has that java does not
3  kotlin vs. java- what kotlin has that java does not3  kotlin vs. java- what kotlin has that java does not
3 kotlin vs. java- what kotlin has that java does notSergey Bandysik
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to ImmutabilityKevlin Henney
 
Introduction to Go
Introduction to GoIntroduction to Go
Introduction to GoJaehue Jang
 
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티JaeYeoul Ahn
 
Operator Overloading In Scala
Operator Overloading In ScalaOperator Overloading In Scala
Operator Overloading In ScalaJoey Gibson
 
JDD 2016 - Pawel Byszewski - Kotlin, why?
JDD 2016 - Pawel Byszewski - Kotlin, why?JDD 2016 - Pawel Byszewski - Kotlin, why?
JDD 2016 - Pawel Byszewski - Kotlin, why?PROIDEA
 

Similaire à Kotlin from-scratch 2 - functions (20)

From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
Introduction to kotlin
Introduction to kotlinIntroduction to kotlin
Introduction to kotlin
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
 
golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptx
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
Kotlin, why?
Kotlin, why?Kotlin, why?
Kotlin, why?
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme Swift
 
The... Wonderful? World of Lambdas
The... Wonderful? World of LambdasThe... Wonderful? World of Lambdas
The... Wonderful? World of Lambdas
 
Pick up the low-hanging concurrency fruit
Pick up the low-hanging concurrency fruitPick up the low-hanging concurrency fruit
Pick up the low-hanging concurrency fruit
 
3 kotlin vs. java- what kotlin has that java does not
3  kotlin vs. java- what kotlin has that java does not3  kotlin vs. java- what kotlin has that java does not
3 kotlin vs. java- what kotlin has that java does not
 
Introduction to Kotlin
Introduction to KotlinIntroduction to Kotlin
Introduction to Kotlin
 
Lezione03
Lezione03Lezione03
Lezione03
 
Lezione03
Lezione03Lezione03
Lezione03
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
 
Introduction to Go
Introduction to GoIntroduction to Go
Introduction to Go
 
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
 
Operator Overloading In Scala
Operator Overloading In ScalaOperator Overloading In Scala
Operator Overloading In Scala
 
JDD 2016 - Pawel Byszewski - Kotlin, why?
JDD 2016 - Pawel Byszewski - Kotlin, why?JDD 2016 - Pawel Byszewski - Kotlin, why?
JDD 2016 - Pawel Byszewski - Kotlin, why?
 

Plus de Franco Lombardo

Kotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutinesKotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutinesFranco Lombardo
 
Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)
Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)
Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)Franco Lombardo
 
Unit testing on AS400? Yes we can! (With Kotlin)
Unit testing on AS400? Yes we can! (With Kotlin)Unit testing on AS400? Yes we can! (With Kotlin)
Unit testing on AS400? Yes we can! (With Kotlin)Franco Lombardo
 
Interprete Kotlin per l’RPG e libreria Web Components: Open Source per la m...
Interprete Kotlin per l’RPG  e libreria Web Components: Open Source per  la m...Interprete Kotlin per l’RPG  e libreria Web Components: Open Source per  la m...
Interprete Kotlin per l’RPG e libreria Web Components: Open Source per la m...Franco Lombardo
 
TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019
TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019
TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019Franco Lombardo
 
Un interprete Kotlin per il linguaggio RPG AS400 - IBM i
Un interprete Kotlin per il linguaggio RPG AS400 - IBM iUn interprete Kotlin per il linguaggio RPG AS400 - IBM i
Un interprete Kotlin per il linguaggio RPG AS400 - IBM iFranco Lombardo
 
Agile Happiness - Agile O'Day 2018
Agile Happiness - Agile O'Day 2018Agile Happiness - Agile O'Day 2018
Agile Happiness - Agile O'Day 2018Franco Lombardo
 
Rock scissors-paper-kata
Rock scissors-paper-kataRock scissors-paper-kata
Rock scissors-paper-kataFranco Lombardo
 
Primo Incontro Con Scala
Primo Incontro Con ScalaPrimo Incontro Con Scala
Primo Incontro Con ScalaFranco Lombardo
 

Plus de Franco Lombardo (15)

happiness_2023.pdf
happiness_2023.pdfhappiness_2023.pdf
happiness_2023.pdf
 
Kotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutinesKotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutines
 
Kotlin from-scratch
Kotlin from-scratchKotlin from-scratch
Kotlin from-scratch
 
Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)
Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)
Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)
 
Unit testing on AS400? Yes we can! (With Kotlin)
Unit testing on AS400? Yes we can! (With Kotlin)Unit testing on AS400? Yes we can! (With Kotlin)
Unit testing on AS400? Yes we can! (With Kotlin)
 
Interprete Kotlin per l’RPG e libreria Web Components: Open Source per la m...
Interprete Kotlin per l’RPG  e libreria Web Components: Open Source per  la m...Interprete Kotlin per l’RPG  e libreria Web Components: Open Source per  la m...
Interprete Kotlin per l’RPG e libreria Web Components: Open Source per la m...
 
TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019
TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019
TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019
 
Un interprete Kotlin per il linguaggio RPG AS400 - IBM i
Un interprete Kotlin per il linguaggio RPG AS400 - IBM iUn interprete Kotlin per il linguaggio RPG AS400 - IBM i
Un interprete Kotlin per il linguaggio RPG AS400 - IBM i
 
Agile Happiness - Agile O'Day 2018
Agile Happiness - Agile O'Day 2018Agile Happiness - Agile O'Day 2018
Agile Happiness - Agile O'Day 2018
 
Agile Happiness 2
Agile Happiness 2Agile Happiness 2
Agile Happiness 2
 
Agile Happiness
Agile HappinessAgile Happiness
Agile Happiness
 
Java per as400
Java per as400Java per as400
Java per as400
 
Rock scissors-paper-kata
Rock scissors-paper-kataRock scissors-paper-kata
Rock scissors-paper-kata
 
A First Date With Scala
A First Date With ScalaA First Date With Scala
A First Date With Scala
 
Primo Incontro Con Scala
Primo Incontro Con ScalaPrimo Incontro Con Scala
Primo Incontro Con Scala
 

Dernier

SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceanilsa9823
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 

Dernier (20)

SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 

Kotlin from-scratch 2 - functions

  • 1. Kotlin from scratch 2 franco.lombardo@smeup.com - https://www.linkedin.com/in/francolombardo/ Functions
  • 2.
  • 3. Last episode: the power of lambdas val elapsedTime = measureTimeMillis { execute(compilationUnit.main.stmts) } public fun measureTimeMillis(block: () -> Unit): Long { val start = System.currentTimeMillis() block() return System.currentTimeMillis() - start }
  • 4. Last episode: the power of lambdas val elapsedTime = measureTimeMillis { execute(compilationUnit.main.stmts) } public fun measureTimeMillis(block: () -> Unit): Long { val start = System.currentTimeMillis() block() return System.currentTimeMillis() - start } This is a function (lambda expression)
  • 5. What is a lambda? A lambda is a literal of a function type val x: Int = 5 5 is a literal of type Int val f: (Int) -> String = { "The number is $it" } This is a literal of type (Int) -> String (Well, on JVM it’s an instance of Function1<Int, String>)
  • 6. What is a lambda? A lambda is a literal of a function type val x: Int = 5 val f: (Int) -> String = { "The number is $it" } it: implicit name of a single parameter
  • 7. What is a lambda? A lambda is a literal of a function type val x: Int = 5 We can use a more explicit syntax val f: (Int) -> String = { number: Int -> "The number is $number" }
  • 8. What is a lambda? A lambda is a literal of a function type val x: Int = 5 Here is the evaluation of the function (y is a String) val f = { number: Int -> "The number is $number" } val y = f(x)
  • 9. What is a lambda? A lambda is a literal of a function type val x: Int = 5 The function here is unevaluated (z is a function) val f = { number: Int -> "The number is $number" } val z = f
  • 10. What is a closure? A closure is a lambda that accesses its closure, i.e. the variables declared in the outer scope val x: Int = 5 val f = { "The number is $x" } val y = f()
  • 11. What is a closure? Be careful! Prints The number is 10 var x = 5 val f = { "The number is $x" } x = 10 println ("${f()}")
  • 12. The power of lambdas val elapsedTime = measureTimeMillis { execute(compilationUnit.main.stmts) } public fun measureTimeMillis(block: () -> Unit): Long { val start = System.currentTimeMillis() block() return System.currentTimeMillis() - start }
  • 13. The power of lambdas val elapsedTime = measureTimeMillis { execute(compilationUnit.main.stmts) } public fun measureTimeMillis(block: () -> Unit): Long { val start = System.currentTimeMillis() block() return System.currentTimeMillis() - start } Higher order function: a function that has a function parameter (or result)
  • 14. Last episode: the power of lambdas val elapsedTime = measureTimeMillis ({ execute(compilationUnit.main.stmts) }) “Explicit” syntax public fun measureTimeMillis(block: () -> Unit): Long { val start = System.currentTimeMillis() block() return System.currentTimeMillis() - start } It’s the last parameter of this function
  • 15. Last episode: the power of lambdas val elapsedTime = measureTimeMillis () { execute(compilationUnit.main.stmts) } public fun measureTimeMillis(block: () -> Unit): Long { val start = System.currentTimeMillis() block() return System.currentTimeMillis() - start } It’s the last parameter of this function, so we can pass it outside the parentheses.
  • 16. Last episode: the power of lambdas val elapsedTime = measureTimeMillis (){ execute(compilationUnit.main.stmts) } public fun measureTimeMillis(block: () -> Unit): Long { val start = System.currentTimeMillis() block() return System.currentTimeMillis() - start } Since it’s the only argument, the parentheses can be omitted entirely:
  • 18. Types of bodies See sample project: https://github.com/f-lombardo/kotlin-from-scratch fun openDatabase(user: String, password: String): Database? = if ("franco" == user && "secret" == password) { sampleDatabase() } else { null } fun openDatabase(user: String, password: String): Database? { if ("franco" == user && "secret" == password) { return sampleDatabase() } return null } Block body Expression body
  • 19. Named arguments println( openDatabase("franco", "secret") ?.findComposerByName("Giuseppe Verdi") ?.findOperaByYear(1853) ?: "No results" ) Which is the password?
  • 20. Named arguments println( openDatabase(user = "franco", password = "secret") ?.findComposerByName("Giuseppe Verdi") ?.findOperaByYear(1853) ?: "No results" )
  • 21. Named arguments println( openDatabase(password = "secret", user = "franco") ?.findComposerByName("Giuseppe Verdi") ?.findOperaByYear(1853) ?: "No results" ) Different order
  • 22. Named arguments println( openDatabase(user = "franco", "secret") ?.findComposerByName("Giuseppe Verdi") ?.findOperaByYear(1853) ?: "No results" ) NO! It doesn’t compile. If you start with named arguments you should go on from there println( openDatabase("as400", user = "franco", password = "secret") ?.findComposerByName("Giuseppe Verdi") ?.findOperaByYear(1853) ?: "No results" ) OK
  • 24. Composing null returning functions println( openDatabase("franco","secret") ?.findComposerByName("Giuseppe Verdi") ?.findOperaByYear(1853) ?: "No results" ) fun Database.findComposerByName(name: String): Composer? = this.composers.firstOrNull { it.name == name } Extension function: we extend the Database class with a new method
  • 25. Composing null returning functions println( openDatabase("franco","secret") ?.findComposerByName("Giuseppe Verdi") ?.findOperaByYear(1853) ?: "No results" ) fun Database.findComposerByName(name: String): Composer? = this.composers.firstOrNull { it.name == name } Composer? → {Composer U null} (sum type) findComposerByName is “total” i.e. it maps each input value in one output value
  • 26. Composing null returning functions println( openDatabase("franco","secret") ?.findComposerByName("Giuseppe Verdi") ?.findOperaByYear(1853) ?: "No results" ) “or else” “and then” Total functions (not throwing exceptions) compose easily
  • 27. Could we have a better composition? println( openDatabase("franco","secret") ?.findComposerByName("Giuseppe Verdi") ?.findOperaByYear(1853) ?: "No results" )
  • 28. “Good” functions compose easily inline fun Database.findComposerBy(predicate: (Composer) -> Boolean) = this.composers.firstOrNull(predicate) fun similarName(name: String): (Composer) -> Boolean = { it.name.contains(name, ignoreCase = true) } fun exactName(name: String): (Composer) -> Boolean = { it.name == name } These functions have another function as a result Higher order function
  • 29. “Good” functions compose easily println( openDatabase("franco","secret") ?.findComposerBy(similarName("verdi")) ?.findOperaByYear(1853) ?: "No results" ) println( openDatabase("franco","secret") ?.findComposerBy(exactName("Giuseppe Verdi")) ?.findOperaByYear(1853) ?: "No results" )
  • 30. “Good” functions compose easily println( openDatabase("franco","secret") ?.findComposerBy(exactMatchToGiacomoPuccini) ?.findOperaByYear(1853) ?: "No results" ) val exactMatchToGiacomoPuccini = exactName("Giacomo Puccini") Functions can be stored in variables
  • 31. “Good” functions compose easily fun exactMatchToGiuseppeVerdi(composer: Composer): Boolean = composer.name == "Giuseppe Verdi" println( openDatabase("franco","secret") ?.findComposerBy(::exactMatchToGiuseppeVerdi) ?.findOperaByYear(1853) ?: "No results" ) Passing a function as a parameter using its name
  • 32. “Good” functions compose easily You can use functions from the standard library too fun exactMatchToGiuseppeVerdi(composer: Composer): Boolean = composer.name == "Giuseppe Verdi" openDatabase("franco","secret") ?.findComposerBy(::exactMatchToGiuseppeVerdi) ?.findOperaByYear(1853) .run(::println)
  • 33. “Good” functions compose easily Extension function applicable to objects of any type: it passes the object to the given function fun exactMatchToGiuseppeVerdi(composer: Composer): Boolean = composer.name == "Giuseppe Verdi" openDatabase("franco","secret") ?.findComposerBy(::exactMatchToGiuseppeVerdi) ?.findOperaByYear(1853) .run(::println)
  • 34. “Good” functions compose easily Not that good: prints null if no result is found fun exactMatchToGiuseppeVerdi(composer: Composer): Boolean = composer.name == "Giuseppe Verdi" openDatabase("franco","secret") ?.findComposerBy(::exactMatchToGiuseppeVerdi) ?.findOperaByYear(1853) .run(::println)
  • 35. “Good” functions compose easily fun Opera?.displayResult(): Unit = if (this == null) { println("No result") } else { println(this) } openDatabase("franco","secret") ?.findComposerBy(::exactMatchToGiuseppeVerdi) ?.findOperaByYear(1930) .run(::displayResult)
  • 36. “Good” functions compose easily fun Opera?.displayResult(): Unit = if (this == null) { println("No result") } else { println(this) } openDatabase("franco","secret") ?.findComposerBy(::exactMatchToGiuseppeVerdi) ?.findOperaByYear(1930) .run(::displayResult) Extension function on a nullable type
  • 37. “Good” functions compose easily fun Opera?.displayResult(): Unit = if (this == null) { println("No result") } else { println(this) } openDatabase("franco","secret") ?.findComposerBy(::exactMatchToGiuseppeVerdi) ?.findOperaByYear(1930) .run(::displayResult) if statements are also expressions. (The result here has type Unit)
  • 38. Infix methods infix fun Opera?.displayResultTo(printStream: PrintStream): Unit = if (this == null) { printStream.println("No result") } else { printStream.println(this) } openDatabase("franco","secret") ?.findComposerBy(exactMatchToGiacomoPuccini) ?.findOperaByYear(1901) displayResultTo System.err
  • 39. “Good” functions compose easily println( openDatabase("franco","secret") ?.findComposerBy(exactMatchToGiacomoPuccini) ?.operas ?.maxBy (Opera::yearOfComposition) ?: "No results" ) Functional API for collections (like map, sortBy, find…) They get function parameters A List
  • 40. “Good” functions compose easily println( openDatabase("franco","secret") ?.findComposerBy(exactMatchToGiacomoPuccini) ?.operas ?.maxBy (Opera::yearOfComposition) ?: "No results" ) Member reference: it’s like a lambda that has the object as a parameter and invokes the method on it A List
  • 41. More functional APIs for collections println( openDatabase("franco","secret") ?.findComposerBy(exactMatchToGiacomoPuccini) ?.operas ?.sortedBy (Opera::yearOfComposition) ?.map (Opera::name) ?: "No results" ) sortedBy doesn’t sort the original collection, but it returns a sorted copy of it: immutable data!
  • 42. Constructors are functions class OperaHtmlDiv(val opera: Opera) { override fun toString(): String = "<div>${opera.name} ${opera.yearOfComposition}</div>" } println( openDatabase("franco","secret") ?.findComposerBy(exactMatchToGiacomoPuccini) ?.operas ?.sortedBy (Opera::yearOfComposition) ?.map (::OperaHtmlDiv) ?: "No results" ) We pass a constructor as a parameter
  • 43. Do we really need all these checks? println( openDatabase("franco", "secret") ?.findComposerBy(exactMatchToGiacomoPuccini) ?.run { operas .sortedBy(Opera::yearOfComposition) .map(::OperaHtmlDiv) } ?: "No results" ) Implicit this
  • 44. The dark side of lambdas fun Database.findComposerBy(predicate: (Composer) -> Boolean) = this.composers.firstOrNull(predicate) A new object is created here openDatabase("franco", "secret") ?.findComposerBy { it.name.toLowerCase().startsWith("v") }
  • 45. The dark side of lambdas inline fun Database.findComposerBy(predicate: (Composer) -> Boolean) = this.composers.firstOrNull(predicate) Inlining the function the compiler doesn’t need a new object openDatabase("franco", "secret") ?.findComposerBy { it.name.toLowerCase().startsWith("v") } See https://www.baeldung.com/kotlin-inline-functions • Use Inline with functions that have a lambda parameter • With inline we can’t pass the lambda around, so it can’t be the result of our higher order function
  • 46. What is a “good” function? • It is total, i.e. it maps each input value in one output value (no exceptions) • It works with immutable data types (it doesn’t modify its parameters) • It does not cause any observable side effects • It returns the same result if given the same arguments (it doesn’t depend on the environment) • So it is referentially transparent, i.e. it can be replaced with its corresponding value without changing the program's behaviour
  • 47. Good reads Kotlin weekly Great weekly newsletter: http://www.kotlinweekly.net/ Uberto Barbini on Medium https://medium.com/@ramtop Kotlin expertise blog by Simon Wirtz https://kotlinexpertise.com/ Florina Muntenescu on Medium https://medium.com/@florina.muntenescu Kotlin blog by JetBrains https://blog.jetbrains.com/kotlin/