Lead Consultant
www.ajira.tech
Tamizhvendan S
Passionate, Pragmatic and Polyglot Programmer
https://www.demystifyfp.com
tamizhvendan
Deep Dive Into
Pattern Matching And Destructuring
Slide 2
Slide 2 text
Pattern Matching And Destructuring
It’s not new!
Slide 3
Slide 3 text
val texts = arrayOf(
"The flight arrived at 12734722.",
"The meeting starts at 20730700."
)
texts.forEach { printTimestamp(it) }
Hour: 12, Minute: 34, Second: 22
Hour: 20, Minute: 30, Second: 00
Slide 4
Slide 4 text
fun printTimestamp(text : String) {
val atIndex = text.indexOf("at")
val timestamp =
text
.subSequence(atIndex + 3, atIndex + 11)
.split(':')
val hour = timestamp[0]
val minute = timestamp[1]
val second = timestamp[2]
println("Hour: $hour, Minute: $minute, Second: $second")
}
A Naive Approach
Slide 5
Slide 5 text
A Naive Approach
fun printTimestamp(text : String) {
val atIndex = text.indexOf("at")
val timestamp =
text
.subSequence(atIndex + 3, atIndex + 11)
.split(':')
val hour = timestamp[0]
val minute = timestamp[1]
val second = timestamp[2]
println("Hour: $hour, Minute: $minute, Second: $second")
}
Slide 6
Slide 6 text
Regex to the Rescue
fun printTimestamp(text : String) {
val pattern = "(\\d\\d)7(\\d\\d)7(\\d\\d)"
val regex = pattern.toRegex()
val timestamp = regex.find(text)UUVgroupValues
val hour = timestamp[1]
val minute = timestamp[2]
val second = timestamp[3]
println("Hour: $hour, Minute: $minute, Second: $second")
}
Slide 7
Slide 7 text
Pattern Made The Difference
fun printTimestamp(text : String) {
val pattern = "(\\d\\d)7(\\d\\d)7(\\d\\d)"
val regex = pattern.toRegex()
val timestamp = regex.find(text)UUVgroupValues
val hour = timestamp[1]
val minute = timestamp[2]
val second = timestamp[3]
println("Hour: $hour, Minute: $minute, Second: $second")
}
Slide 8
Slide 8 text
Pattern Matching And Destructuring
is not limited to “string” alone
Slide 9
Slide 9 text
Pattern Matching And Destructuring
can be applied to “data”
Representing Data Using Primitives
val timestamp = arrayOf(12, 34, 22)
Slide 15
Slide 15 text
Representing Data Using Primitives
val timestamp = arrayOf(12, 34, 22)
hour
Slide 16
Slide 16 text
Representing Data Using Primitives
val timestamp = arrayOf(12, 34, 22)
hour
minute
Slide 17
Slide 17 text
Representing Data Using Primitives
val timestamp = arrayOf(12, 34, 22)
hour
minute
second
Slide 18
Slide 18 text
Representing Data Using Objects
import java.time.LocalTime;
class Program {
public static void main(String[] args) {
LocalTime timestamp = LocalTime.of(12, 34, 22);
int hour = timestamp.getHour();
int minute = timestamp.getMinute();
int second = timestamp.getSecond();
System.out.println(timestamp);
}
}
Slide 19
Slide 19 text
Guess the output
import java.time.LocalTime;
class Program {
public static void main(String[] args) {
LocalTime t1 = LocalTime.of(12, 34, 22);
LocalTime t2 = LocalTime.of(12, 34, 22);
System.out.println(t1.equals(t2));
}
}
Slide 20
Slide 20 text
It’s true!
package java.time;
U` UUa
public final class LocalTime {
U` UUa
@Override
public boolean equals(Object obj) {
if (this Uc obj) {
return true;
}
if (obj instanceof LocalTime) {
LocalTime other = (LocalTime) obj;
return hour Uc other.hour Ud minute Uc other.minute Ud
second Uc other.second Ud nano Uc other.nano;
}
return false;
}
}
Slide 21
Slide 21 text
Value Object
An object that represents a
descriptive aspect of the domain
with no conceptual identity is
called a Value Object.
Value Object are instantiated to
represent elements of the design
that we care about only for what
they are, not who or which they
are.
Slide 22
Slide 22 text
Data Class in Kotlin
Slide 23
Slide 23 text
Representing Data in Kotlin
data class LocalTime(val hour: Byte, val minute: Byte, val second: Byte)
Slide 24
Slide 24 text
Representing Data in Kotlin
data class LocalTime(val hour: Byte, val minute: Byte, val second: Byte)
val t1 = LocalTime(12, 34, 22)
val t2 = LocalTime(12, 34, 22)
println(t1 Uc t2) U` prints true
Slide 25
Slide 25 text
Representing Data in Clojure
Slide 26
Slide 26 text
Representing Data in Clojure
Slide 27
Slide 27 text
Data
More than name-value pairs!
Slide 28
Slide 28 text
A Login API Response
Slide 29
Slide 29 text
A Login API Response
Login Success
Slide 30
Slide 30 text
A Login API Response
Login Success First-time Login
Slide 31
Slide 31 text
A Login API Response
Login Success First-time Login
Bad Credentials
Slide 32
Slide 32 text
A Login API Response
Login Success First-time Login
Bad Credentials Login Failure
Slide 33
Slide 33 text
Representing Login Response
Slide 34
Slide 34 text
Handling Login Response
Slide 35
Slide 35 text
Representing Login Response
Slide 36
Slide 36 text
Representing Login Response
Slide 37
Slide 37 text
Representing Login Response
Slide 38
Slide 38 text
Representing Login Response
Slide 39
Slide 39 text
Representing Login Response
Slide 40
Slide 40 text
Handling Login Response
Slide 41
Slide 41 text
Handling Login Response
Slide 42
Slide 42 text
Decouple handler logic
from object
Slide 43
Slide 43 text
Visitor Pattern
In object-oriented programming and software engineering,
the visitor design pattern is a way of separating an algorithm from
an object structure on which it operates. A practical result of this
separation is the ability to add new operations to existing object
structures without modifying the structures. It is one way to follow
the open/closed principle. - Wikipedia
Slide 44
Slide 44 text
Handling Login Response - Visitor
Slide 45
Slide 45 text
Handling Login Response - Visitor
Slide 46
Slide 46 text
Handling Login Response - Visitor
Slide 47
Slide 47 text
No content
Slide 48
Slide 48 text
Decouple handler logic
from object.
Slide 49
Slide 49 text
Handling Login Response
Slide 50
Slide 50 text
Handling Login Response
Slide 51
Slide 51 text
Representing Login Response
sealed class LoginResponse {
data class LoginSuccess(val jwtToken: String)7 LoginResponse()
data class FirsTimeLogin(val sessionId: UUID)7 LoginResponse()
data class BadCredentials(val message: String)7 LoginResponse()
data class ServerError(val error: String)7 LoginResponse()
}
Slide 52
Slide 52 text
Handling Login Response
fun handleLogin(res : LoginResponse) {
when(res) {
is LoginResponse.LoginSuccess Uj
println("Redirect to dashboard with token ${res.jwtToken}")
is LoginResponse.FirsTimeLogin Uj
println("Redirect to changekpassword with session id ${res.sessionId}")
is LoginResponse.BadCredentials Uj
println("Show bad credentials error ${res.message}")
is LoginResponse.ServerError Uj {
println("Log error: ${res.error}")
println("Show something went wrong")
}
}
}
Slide 53
Slide 53 text
Pattern Matching - Sub Types
fun handleLogin(res : LoginResponse) {
when(res) {
is LoginResponse.LoginSuccess Uj
println("Redirect to dashboard with token ${res.jwtToken}")
is LoginResponse.FirsTimeLogin Uj
println("Redirect to changekpassword with session id ${res.sessionId}")
is LoginResponse.BadCredentials Uj
println("Show bad credentials error ${res.message}")
is LoginResponse.ServerError Uj {
println("Log error: ${res.error}")
println("Show something went wrong")
}
}
}
Slide 54
Slide 54 text
fun handleLogin(res : LoginResponse) {
when(res) {
is LoginResponse.LoginSuccess Uj
println("Redirect to dashboard with token ${res.jwtToken}")
is LoginResponse.FirsTimeLogin Uj
println("Redirect to changekpassword with session id ${res.sessionId}")
is LoginResponse.BadCredentials Uj
println("Show bad credentials error ${res.message}")
is LoginResponse.ServerError Uj {
println("Log error: ${res.error}")
println("Show something went wrong")
}
}
}
sealed class LoginResponse {
data class LoginSuccess(val jwtToken: String)7 LoginResponse()
data class FirsTimeLogin(val sessionId: UUID)7 LoginResponse()
data class BadCredentials(val message: String)7 LoginResponse()
data class ServerError(val error: String)7 LoginResponse()
}
V/S
Slide 55
Slide 55 text
Pattern Matching - Value
Slide 56
Slide 56 text
Pattern Matching - Guards
Slide 57
Slide 57 text
Pattern Matching - Vector
(x = 10, y = 10)
(x = 10, y = 20, z = 30)
Slide 58
Slide 58 text
Pattern Matching - Vector
(x = 10, y = 10)
(x = 10, y = 20, z = 30)
Slide 59
Slide 59 text
1
2
3
Pattern Matching - First & Rest
Slide 60
Slide 60 text
1
2
3
Pattern Matching - First & Rest
Slide 61
Slide 61 text
Pattern Matching - Map
Rectangle with height 12 & width 12
Circle with radius 12
Slide 62
Slide 62 text
Pattern Matching - Map
Rectangle with height 12 & width 12
Circle with radius 12
fun printTimestamp(text : String) {
val pattern = "(\\d\\d)7(\\d\\d)7(\\d\\d)"
val regex = pattern.toRegex()
val timestamp = regex.find(text)UUVgroupValues
val hour = timestamp[1]
val minute = timestamp[2]
val second = timestamp[3]
println("Hour: $hour, Minute: $minute, Second: $second")
}