Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Deep Dive Into Pattern Matching & Destructuring

Deep Dive Into Pattern Matching & Destructuring

Pattern Matching and Destructuring are two simple, yet powerful features in functional programming languages. There are several ways we can leverage them to make cleaner code. It also encourages you to think data as a first-class citizen and provide the essential tooling.

In this session, we are going to learn what these techniques bring to the table by looking at some real-world use-cases in Kotlin & Clojure.

Tamizhvendan S

November 14, 2019
Tweet

More Decks by Tamizhvendan S

Other Decks in Programming

Transcript

  1. Lead Consultant www.ajira.tech Tamizhvendan S Passionate, Pragmatic and Polyglot Programmer

    https://www.demystifyfp.com tamizhvendan Deep Dive Into Pattern Matching And Destructuring
  2. 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
  3. 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
  4. 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") }
  5. 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") }
  6. 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") }
  7. Primitives & Collections 42, 3.14, "Lorum Ipsum", true [0, 1,

    42] {"firstName" : "John", "lastName" : "Doe"}
  8. 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); } }
  9. 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)); } }
  10. 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; } }
  11. 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.
  12. 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
  13. 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
  14. 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() }
  15. 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") } } }
  16. 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") } } }
  17. 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
  18. 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") }