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

Write Less Code with Kotlin and Spring Boot

Write Less Code with Kotlin and Spring Boot

As software developers, we aren't getting paid to write code; we're getting paid to deliver business value. Think of the last time you opened a codebase you weren't familiar with and had to wade through all of the boilerplate just to understand the core business logic or hunt down a critical bug. Less code means easier comprehension, quicker development, fewer bugs, and easier testing. Spring Boot is already very good at allowing us to deliver business quickly—why not take it to the next level with Kotlin? Kotlin has been described as a re-imagined Java. It's as if you took Java, fixed all of the things you didn't like about it, modernized the API, and made the result work seamlessly with your existing Java codebase. Combined with Spring Boot, Kotlin is a force multiplier for productivity and understanding.

This talk is aimed at Java and Spring Boot developers who might have heard of Kotlin but haven't tried it. You'll learn the basics of Kotlin and the features that make it compelling.

Todd Ginsberg

October 08, 2019
Tweet

More Decks by Todd Ginsberg

Other Decks in Technology

Transcript

  1. @ToddGinsberg
    Write Less Code with Kotlin
    and Spring Boot
    October 7, 2019
    Austin Convention Center
    Todd Ginsberg
    Principal Software Developer, Netspend

    View Slide

  2. @ToddGinsberg
    Kotlin and Spring Boot in 30 Minutes?!

    View Slide

  3. @ToddGinsberg
    Kotlin and Spring Boot in 30 Minutes?!
    No, that’s crazy!

    View Slide

  4. @ToddGinsberg
    Kotlin and Spring Boot in 30 Minutes?!
    No, that’s crazy!
    But stick around after!

    View Slide

  5. @ToddGinsberg
    Agenda
    - What Is Kotlin?

    View Slide

  6. @ToddGinsberg
    Agenda
    - What Is Kotlin?
    - Why Kotlin with Spring Boot?

    View Slide

  7. @ToddGinsberg
    Agenda
    - What Is Kotlin?
    - Why Kotlin with Spring Boot?
    - Syntax & Features

    View Slide

  8. @ToddGinsberg
    Agenda
    - What Is Kotlin?
    - Why Kotlin with Spring Boot?
    - Syntax & Features
    - Summary

    View Slide

  9. @ToddGinsberg
    Agenda
    - What Is Kotlin?
    - Why Kotlin with Spring Boot?
    - Syntax & Features
    - Summary
    - Questions?

    View Slide

  10. @ToddGinsberg
    Who is this Guy?
    Todd Ginsberg

    View Slide

  11. @ToddGinsberg
    Who is this Guy?
    Todd Ginsberg
    Just moved to Dallas from Chicago

    View Slide

  12. @ToddGinsberg
    Who is this Guy?
    Todd Ginsberg
    Just moved to Dallas from Chicago
    Principal Developer at Netspend
    - A payments company here in Austin!
    - We love Kotlin and Java!

    View Slide

  13. @ToddGinsberg
    What Is Kotlin?

    View Slide

  14. @ToddGinsberg
    What Is Kotlin?
    Statically typed language, developed by JetBrains

    View Slide

  15. @ToddGinsberg
    What Is Kotlin?
    Statically typed language, developed by JetBrains
    Released under Apache 2.0 license

    View Slide

  16. @ToddGinsberg
    What Is Kotlin?
    Statically typed language, developed by JetBrains
    Released under Apache 2.0 license
    Designed as a general purpose language

    View Slide

  17. @ToddGinsberg
    What Is Kotlin?
    Statically typed language, developed by JetBrains
    Released under Apache 2.0 license
    Designed as a general purpose language
    ● Targets JVM 6 or 8 bytecode

    View Slide

  18. @ToddGinsberg
    What Is Kotlin?
    Statically typed language, developed by JetBrains
    Released under Apache 2.0 license
    Designed as a general purpose language
    ● Targets JVM 6 or 8 bytecode
    ● Targets ECMAScript 5.1

    View Slide

  19. @ToddGinsberg
    What Is Kotlin?
    Statically typed language, developed by JetBrains
    Released under Apache 2.0 license
    Designed as a general purpose language
    ● Targets JVM 6 or 8 bytecode
    ● Targets ECMAScript 5.1
    ● Targets other native platforms thanks to LLVM

    View Slide

  20. @ToddGinsberg
    Major Features
    100% Interoperable with Java

    View Slide

  21. @ToddGinsberg
    Major Features
    100% Interoperable with Java
    Designed to avoid entire classes of defects

    View Slide

  22. @ToddGinsberg
    Major Features
    100% Interoperable with Java
    Designed to avoid entire classes of defects
    Lots of small improvements that add up

    View Slide

  23. @ToddGinsberg
    Major Features
    100% Interoperable with Java
    Designed to avoid entire classes of defects
    Lots of small improvements that add up
    Far less code to accomplish the same task in Java

    View Slide

  24. @ToddGinsberg
    Major Features
    Null-safe

    View Slide

  25. @ToddGinsberg
    Major Features
    Null-safe
    189,000+ issues on GitHub!

    View Slide

  26. @ToddGinsberg
    Major Features
    Null-safe
    189,000+ issues on GitHub!
    14,548 duplicates on Stack Overflow!

    View Slide

  27. @ToddGinsberg
    Major Features
    Pragmatic Improvements
    No shame in copying language features that
    make developers more productive

    View Slide

  28. @ToddGinsberg
    Major Features
    Positive Community

    View Slide

  29. @ToddGinsberg
    Major Features
    Positive Community
    Even on Stack Overflow!

    View Slide

  30. @ToddGinsberg
    Major Features
    Positive Community
    Even on Stack Overflow!
    RTFM

    View Slide

  31. @ToddGinsberg
    Why Kotlin
    with
    Spring Boot?

    View Slide

  32. @ToddGinsberg
    The Hard Work is Already Done!
    - Kotlin Support since Spring Framework 5.0

    View Slide

  33. @ToddGinsberg
    The Hard Work is Already Done!
    - Kotlin Support since Spring Framework 5.0
    - Nullability support between Java and Kotlin

    View Slide

  34. @ToddGinsberg
    The Hard Work is Already Done!
    - Kotlin Support since Spring Framework 5.0
    - Nullability support between Java and Kotlin
    - Excellent documentation

    View Slide

  35. @ToddGinsberg
    The Hard Work is Already Done!
    - Kotlin Support since Spring Framework 5.0
    - Nullability support between Java and Kotlin
    - Excellent documentation
    - Thorough examples

    View Slide

  36. @ToddGinsberg
    The Hard Work is Already Done!
    - Kotlin Support since Spring Framework 5.0
    - Nullability support between Java and Kotlin
    - Excellent documentation
    - Thorough examples
    - Even better support being added for Spring Boot 2.2

    View Slide

  37. @ToddGinsberg
    Similar Philosophies
    “The goal of library design is to give application developers
    ready-to-use tools that cover their most frequent use-cases
    and solve the most popular problems. If something is needed
    all the time by any kind of application, it should be simple and
    straightforward to code. The correct code shall be the easiest
    one to write, while advanced, rarely needed corner-cases can
    and should take longer.”

    View Slide

  38. @ToddGinsberg
    Similar Philosophies
    “The goal of library design is to give application developers
    ready-to-use tools that cover their most frequent use-cases
    and solve the most popular problems. If something is needed
    all the time by any kind of application, it should be simple and
    straightforward to code. The correct code shall be the easiest
    one to write, while advanced, rarely needed corner-cases can
    and should take longer.”
    -- Roman Elizarov (JetBrains)

    View Slide

  39. @ToddGinsberg
    Less Code == More Room For Business Value
    - Less code means less cognitive load

    View Slide

  40. @ToddGinsberg
    Less Code == More Room For Business Value
    - Less code means less cognitive load
    - The most common case is the default

    View Slide

  41. @ToddGinsberg
    Less Code == More Room For Business Value
    - Less code means less cognitive load
    - The most common case is the default
    - Fewer places for bugs to hide

    View Slide

  42. @ToddGinsberg
    Less Code == More Room For Business Value
    - Less code means less cognitive load
    - The most common case is the default
    - Fewer places for bugs to hide
    - Work that you once had to do is a top level concern of the
    language / framework

    View Slide

  43. @ToddGinsberg
    Less Code == More Room For Business Value
    - Less code means less cognitive load
    - The most common case is the default
    - Fewer places for bugs to hide
    - Work that you once had to do is a top level concern of the
    language / framework
    - These effects stack

    View Slide

  44. @ToddGinsberg
    Syntax

    View Slide

  45. @ToddGinsberg
    Variables and Values
    var place: String = "Austin"

    View Slide

  46. @ToddGinsberg
    Variables and Values
    var place: String = "Austin"
    place = "Texas" // OK!

    View Slide

  47. @ToddGinsberg
    Variables and Values
    var place: String = "Austin"
    place = "Texas" // OK!
    val name: String = "Todd"

    View Slide

  48. @ToddGinsberg
    Variables and Values
    var place: String = "Austin"
    place = "Texas" // OK!
    val name: String = "Todd"
    name = "Emma" // Compile Error!

    View Slide

  49. @ToddGinsberg
    Type Inference
    val d: Int = 2
    val text: String = "Todd has $d doughnuts"

    View Slide

  50. @ToddGinsberg
    Type Inference
    val d: Int = 2
    val text: String = "Todd has $d doughnuts"

    View Slide

  51. @ToddGinsberg
    Type Inference
    val d = 2
    val text = "Todd has $d doughnuts"

    View Slide

  52. @ToddGinsberg
    Equality
    val name1 = "EXAMPLE"
    val name2 = "example"

    View Slide

  53. @ToddGinsberg
    Equality
    val name1 = "EXAMPLE"
    val name2 = "example"
    // Structural Equality
    name1 == name2.toUpperCase() // True!

    View Slide

  54. @ToddGinsberg
    Equality
    val name1 = "EXAMPLE"
    val name2 = "example"
    // Structural Equality
    name1 == name2.toUpperCase() // True!
    // Referential Equality
    name1 === name2 // False!

    View Slide

  55. @ToddGinsberg
    Raw Strings
    val json = "{\n\"name\": \"Todd\"\n}"

    View Slide

  56. @ToddGinsberg
    Raw Strings
    val json = "{\n\"name\": \"Todd\"\n}"
    val json = """{ "name": "Todd" }"""

    View Slide

  57. @ToddGinsberg
    Raw Strings
    val json = "{\n\"name\": \"Todd\"\n}"
    val json =
    """
    {
    "name": "Todd"
    }
    """

    View Slide

  58. @ToddGinsberg
    Null Safety
    // Guaranteed to never be null
    var name: String = "Todd"

    View Slide

  59. @ToddGinsberg
    Null Safety
    // Guaranteed to never be null
    var name: String = "Todd"
    // May be null
    var salary: Int? = null

    View Slide

  60. @ToddGinsberg
    Null-Safe Traversal
    var city: String? = "Austin"

    View Slide

  61. @ToddGinsberg
    Null-Safe Traversal
    var city: String? = "Austin"
    // Not allowed, might be null!
    city.toUpperCase()

    View Slide

  62. @ToddGinsberg
    Null-Safe Traversal
    var city: String? = "Austin"
    // Not allowed, might be null!
    city.toUpperCase()
    // Safe traversal
    city?.toUpperCase()

    View Slide

  63. @ToddGinsberg
    Elvis
    val lowest : Int? = listOf(1, 2, 3).min()

    View Slide

  64. @ToddGinsberg
    Elvis
    val lowest : Int? = listOf(1, 2, 3).min()
    val lowest : Int = listOf(1, 2, 3).min() ?: 0

    View Slide

  65. @ToddGinsberg
    Combine Safe-Traversal and Elvis
    println(
    city?.toUpperCase() ?: ”UNKNOWN”
    )

    View Slide

  66. @ToddGinsberg
    Manual Override
    val lowest: Int? = listOf(1, 2, 3).min()

    View Slide

  67. @ToddGinsberg
    Hey Kotlin, Hold My Beer!
    val lowest: Int? = listOf(1, 2, 3).min()
    val lowest: Int = listOf(1, 2, 3).min()!!

    View Slide

  68. @ToddGinsberg
    Hey Kotlin, Hold My Beer!
    val lowest: Int? = listOf(1, 2, 3).min()
    val lowest: Int = listOf(1, 2, 3).min()!!
    val lowest: Int = emptyList().min()!!

    View Slide

  69. @ToddGinsberg
    Hey Kotlin, Hold My Beer!
    val lowest: Int? = listOf(1, 2, 3).min()
    val lowest: Int = listOf(1, 2, 3).min()!!
    val lowest: Int = emptyList().min()!!
    // NullPointerException!

    View Slide

  70. @ToddGinsberg
    Expressions - if
    val status = if (code == 42) {
    "Success"
    } else {
    "Fail"
    }

    View Slide

  71. @ToddGinsberg
    Expressions - try/catch
    val number = try {
    code.toInt()
    } catch (e: NumberFormatException) {
    0
    }

    View Slide

  72. @ToddGinsberg
    Expressions - when
    val result = when (x) {
    0 -> "x is 0”
    in 1..10 -> "x is between 1 and 10"
    in someSet -> "x is in someSet"
    is SomeType -> "x is an instance of SomeType"
    parseString(s) -> "the same as parseString"
    else -> "x doesn't match anything"
    }

    View Slide

  73. @ToddGinsberg
    Smart Casting
    when (x) {
    is Int -> print(x % 2 == 0)
    is String -> print(x.length + 1)
    is IntArray -> print(x.sum())
    }

    View Slide

  74. @ToddGinsberg
    Smart Casting
    when (x) {
    is Int -> print(x % 2 == 0)
    is String -> print(x.length + 1)
    is IntArray -> print(x.sum())
    }

    View Slide

  75. @ToddGinsberg
    Smart Casting
    if(x != null) {
    println(x.toString())
    }

    View Slide

  76. @ToddGinsberg
    Classes
    class Entity : SomeInterface {
    // ...
    }

    View Slide

  77. @ToddGinsberg
    Classes - Inheritance
    open class Entity : SomeInterface {
    // ...
    }
    class Customer : Entity() {
    // ...
    }

    View Slide

  78. @ToddGinsberg
    Properties
    public class Customer {
    private String name;
    public String getName() {
    return name;
    }
    public void setName(final String name) {
    this.name = name;
    }
    }

    View Slide

  79. @ToddGinsberg
    Properties
    class Customer {
    var name: String? = null
    }

    View Slide

  80. @ToddGinsberg
    Properties
    class Customer {
    var name: String? = null
    }
    val c = Customer()

    View Slide

  81. @ToddGinsberg
    Properties
    class Customer {
    var name: String? = null
    }
    val c = Customer()
    c.name = "Todd"

    View Slide

  82. @ToddGinsberg
    Properties
    class Customer {
    var name: String? = null
    }
    val c = Customer()
    c.name = "Todd"
    println("My name is ${c.name}")

    View Slide

  83. @ToddGinsberg
    Properties
    class Customer {
    var name: String? = null
    }

    View Slide

  84. @ToddGinsberg
    Properties
    class Customer {
    var name: String? = null
    set(value) {
    field = value?.toUpperCase()
    }
    }

    View Slide

  85. @ToddGinsberg
    Properties
    class Customer {
    var name: String? = null
    private set(value) {
    field = value?.toUpperCase()
    }
    }

    View Slide

  86. @ToddGinsberg
    Properties
    class Customer {
    var name: String? = null
    get() {
    return field?.toUpperCase()
    }
    }

    View Slide

  87. @ToddGinsberg
    Let’s Write a POJO!
    public class Person {
    public String firstName;
    public String lastName;
    }

    View Slide

  88. @ToddGinsberg
    Let’s Write a POJO!
    public class Person {
    private String firstName;
    private String lastName;
    public String getFirstName() {
    return firstName;
    }
    public void setFirstName(final String firstName) {
    this.firstName = firstName;
    }
    public String getLastName() {
    return lastName;
    }
    public void setLastName(final String lastName) {
    this.lastName = lastName;
    }
    }

    View Slide

  89. @ToddGinsberg
    Let’s Write a POJO!
    public class Person {
    private String firstName;
    private String lastName;
    public Person() { }
    public Person(final String firstName, final String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    }
    public String getFirstName() {
    return firstName;
    }
    public void setFirstName(final String firstName) {
    this.firstName = firstName;
    }
    public String getLastName() {
    return lastName;
    }
    public void setLastName(final String lastName) {
    this.lastName = lastName;
    }
    }

    View Slide

  90. @ToddGinsberg
    Let’s Write a POJO!
    import java.util.Objects;
    public class Person {
    private String firstName;
    private String lastName;
    public Person() { }
    public Person(final String firstName, final String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    }
    public String getFirstName() {
    return firstName;
    }
    public void setFirstName(final String firstName) {
    this.firstName = firstName;
    }
    public String getLastName() {
    return lastName;
    }
    public void setLastName(final String lastName) {
    this.lastName = lastName;
    }
    @Override
    public boolean equals(final Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    final Person person = (Person) o;
    return Objects.equals(firstName, person.firstName) &&
    Objects.equals(lastName, person.lastName);
    }
    @Override
    public int hashCode() {
    return Objects.hash(firstName, lastName);
    }
    }

    View Slide

  91. @ToddGinsberg
    Let’s Write a POJO!
    import java.util.Objects;
    public class Person {
    private String firstName;
    private String lastName;
    public Person() { }
    public Person(final String firstName, final String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    }
    public String getFirstName() {
    return firstName;
    }
    public void setFirstName(final String firstName) {
    this.firstName = firstName;
    }
    public String getLastName() {
    return lastName;
    }
    public void setLastName(final String lastName) {
    this.lastName = lastName;
    }
    @Override
    public boolean equals(final Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    final Person person = (Person) o;
    return Objects.equals(firstName, person.firstName) &&
    Objects.equals(lastName, person.lastName);
    }
    @Override
    public int hashCode() {
    return Objects.hash(firstName, lastName);
    }
    @Override
    public String toString() {
    return "Person{" +
    "firstName='" + firstName + '\'' +
    ", lastName='" + lastName + '\'' +
    '}';
    }
    }

    View Slide

  92. @ToddGinsberg
    Data Classes to the Rescue!
    data class Person(val firstName: String,
    val lastName: String)

    View Slide

  93. @ToddGinsberg
    Data Classes to the Rescue!
    data class Person(val firstName: String,
    val lastName: String)
    ● Getters (and Setters for vars) as Properties

    View Slide

  94. @ToddGinsberg
    Data Classes to the Rescue!
    data class Person(val firstName: String,
    val lastName: String)
    ● Getters (and Setters for vars) as Properties
    ● toString()

    View Slide

  95. @ToddGinsberg
    Data Classes to the Rescue!
    data class Person(val firstName: String,
    val lastName: String)
    ● Getters (and Setters for vars) as Properties
    ● toString()
    ● hashCode() and equals()

    View Slide

  96. @ToddGinsberg
    Data Classes to the Rescue!
    data class Person(val firstName: String,
    val lastName: String)
    ● Getters (and Setters for vars) as Properties
    ● toString()
    ● hashCode() and equals()
    ● And…

    View Slide

  97. @ToddGinsberg
    Copying Data Classes
    val me = Person("Todd", "Ginsberg")

    View Slide

  98. @ToddGinsberg
    Copying Data Classes
    val me = Person("Todd", "Ginsberg")
    val emma = me.copy(firstName = "Emma")
    // Person(”Emma", "Ginsberg")

    View Slide

  99. @ToddGinsberg
    Data Classes as @ConfigurationProperties
    @ConfigurationProperties("example.kotlin")
    data class KotlinExampleProperties(
    val name: String,
    val description: String = "Defaults Supported!",
    val myService: MyService
    )
    data class MyService(
    val apiToken: String,
    val uri: URI
    )

    View Slide

  100. @ToddGinsberg
    Data Classes as @ConfigurationProperties
    @ConfigurationProperties("example.kotlin")
    data class KotlinExampleProperties(
    val name: String,
    val description: String = "Defaults Supported!",
    val myService: MyService
    )
    data class MyService(
    val apiToken: String,
    val uri: URI
    )
    Boot
    2.2!

    View Slide

  101. @ToddGinsberg
    FUNctions!
    fun generateRandomNumber(): Int {
    return 4
    }

    View Slide

  102. @ToddGinsberg
    FUNctions!
    fun generateRandomNumber(): Int {
    return 4
    }
    fun generateRandomNumber(): Int = 4

    View Slide

  103. @ToddGinsberg
    FUNctions!
    fun generateRandomNumber(): Int {
    return 4
    }
    fun generateRandomNumber(): Int = 4
    fun generateRandomNumber() = 4

    View Slide

  104. @ToddGinsberg
    FUNctions - Default Values
    fun random(offset: Int = 0): Int =
    offset + 4

    View Slide

  105. @ToddGinsberg
    FUNctions - Default Values
    fun random(offset: Int = 0): Int =
    offset + 4
    random() // 4

    View Slide

  106. @ToddGinsberg
    FUNctions - Default Values
    fun random(offset: Int = 0): Int =
    offset + 4
    random() // 4
    random(1) // 5

    View Slide

  107. @ToddGinsberg
    FUNctions - Adding Parameters
    fun combine(first: Int,
    second: Int): Int =
    first + second

    View Slide

  108. @ToddGinsberg
    FUNctions - Adding Parameters
    fun combine(first: Int,
    second: Int,
    third: Int = 0): Int =
    first + second + third

    View Slide

  109. @ToddGinsberg
    FUNctions - Adding Parameters
    fun combine(first: Int,
    second: Int,
    third: Int = 0): Int =
    first + second + third
    combine(1, 2)
    combine(1, 2, 3)

    View Slide

  110. @ToddGinsberg
    FUNctions - Named Parameters
    fun combine(first: Int,
    second: Int): Int =
    first + second

    View Slide

  111. @ToddGinsberg
    FUNctions - Named Parameters
    fun combine(first: Int,
    second: Int): Int =
    first + second
    combine(1, 2) // 3

    View Slide

  112. @ToddGinsberg
    FUNctions - Named Parameters
    fun combine(first: Int,
    second: Int): Int =
    first + second
    combine(first = 1, second = 2) // 3

    View Slide

  113. @ToddGinsberg
    FUNctions - Named Parameters
    fun combine(first: Int,
    second: Int): Int =
    first + second
    combine(second = 2, first = 1) // 3

    View Slide

  114. @ToddGinsberg
    Extension FUNctions
    // Java
    public static boolean isEven(int i) {
    return i % 2 == 0;
    }

    View Slide

  115. @ToddGinsberg
    Extension FUNctions
    // Kotlin
    fun Int.isEven(): Boolean =
    this % 2 == 0

    View Slide

  116. @ToddGinsberg
    Extension FUNctions
    // Kotlin
    fun Int.isEven(): Boolean =
    this % 2 == 0
    2.isEven() // True!

    View Slide

  117. @ToddGinsberg
    The use Extension
    // Java
    try (Connection conn = getConnection()) {
    // ...
    }

    View Slide

  118. @ToddGinsberg
    The use Extension
    // Kotlin
    getConnection().use { conn ->
    // ...
    }

    View Slide

  119. @ToddGinsberg
    The apply Extension
    // Expression and Statements
    val p = Person()
    p.name = "Todd"
    p.age = 21

    View Slide

  120. @ToddGinsberg
    The apply Extension
    // Single Expression
    val p = Person().apply {
    name = "Todd"
    age = 21
    }

    View Slide

  121. @ToddGinsberg
    The apply Extension
    // Single Expression
    val p = Person().apply {
    name = "Todd"
    age = 21
    address = Address().apply {
    line1 = "5 Tall Cedar Rd."

    }
    }

    View Slide

  122. @ToddGinsberg
    One More Thing on FUNctions
    ● Functions are final by default.

    View Slide

  123. @ToddGinsberg
    One More Thing on FUNctions
    ● Functions are final by default.
    ● Arguments are always final.

    View Slide

  124. @ToddGinsberg
    One More Thing on FUNctions
    ● Functions are final by default.
    ● Arguments are always final.
    ● Functions can be defined in a file, outside of a class.

    View Slide

  125. @ToddGinsberg
    One More Thing on FUNctions
    ● Functions are final by default.
    ● Arguments are always final.
    ● Functions can be defined in a file, outside of a class.
    ● Functions can be defined within another function.

    View Slide

  126. @ToddGinsberg
    One More Thing on FUNctions
    ● Functions are final by default.
    ● Arguments are always final.
    ● Functions can be defined in a file, outside of a class.
    ● Functions can be defined within another function.
    ● Kotlin supports tail recursive functions.

    View Slide

  127. @ToddGinsberg
    What About Checked Exceptions?
    ?

    View Slide

  128. @ToddGinsberg
    What About Checked Exceptions?
    NO

    View Slide

  129. @ToddGinsberg
    Lambdas
    listOf(1, 2, 3, 4)
    .filter { x -> x % 2 == 0 }
    .map { y -> y * 2 }
    // List[4, 8]

    View Slide

  130. @ToddGinsberg
    Lambdas
    listOf(1, 2, 3, 4)
    .filter { x -> x % 2 == 0 }
    .map { y -> y * 2 }
    // List[4, 8]

    View Slide

  131. @ToddGinsberg
    Lambdas
    listOf(1, 2, 3, 4)
    .filter { it % 2 == 0 }
    .map { it * 2 }
    // List[4, 8]

    View Slide

  132. @ToddGinsberg
    So Many Things Left Out! :(
    - Property delegation
    - Class delegation
    - Operator overloading
    - Destructuring
    - Higher-order functions
    - Companion objects
    - Import aliases
    - Type aliases
    - Unsigned integer types
    - Coroutines
    - Massive STDLIB replaces
    your util classes
    - Reified generics
    - Inline classes
    - Infix functions
    - Sealed classes
    - Scoping functions
    - DSL support

    View Slide

  133. @ToddGinsberg
    Summary

    View Slide

  134. @ToddGinsberg
    Why Do I Use Kotlin?
    ● I write far less code.

    View Slide

  135. @ToddGinsberg
    Why Do I Use Kotlin?
    ● I write far less code.
    ● The code I write is more expressive and clear.

    View Slide

  136. @ToddGinsberg
    Why Do I Use Kotlin?
    ● I write far less code.
    ● The code I write is more expressive and clear.
    ● I avoid whole classes of defects.

    View Slide

  137. @ToddGinsberg
    Why Do I Use Kotlin?
    ● I write far less code.
    ● The code I write is more expressive and clear.
    ● I avoid whole classes of defects.
    ● Plays well with the tools I use (Spring, IDEA, Gradle)

    View Slide

  138. @ToddGinsberg
    Why Do I Use Kotlin?
    ● I write far less code.
    ● The code I write is more expressive and clear.
    ● I avoid whole classes of defects.
    ● Plays well with the tools I use (Spring, IDEA, Gradle)
    ● Writing Kotlin, for me, is more fun.

    View Slide

  139. @ToddGinsberg
    Fun == Fun
    % of developers who are developing with the
    language or technology but have not
    expressed interest in continuing to do so
    (Stack Overflow Developer Survey 2019)

    View Slide

  140. @ToddGinsberg
    Fun == Fun
    % of developers who are developing with the
    language or technology but have not
    expressed interest in continuing to do so
    (Stack Overflow Developer Survey 2019)
    Kotlin

    View Slide

  141. @ToddGinsberg
    Make “Bad” Choices Explicit or Impossible
    Fixed in Kotlin:
    -Singleton support built in
    -Override keyword mandatory
    -Properties over fields with getter/setter
    -Mutability is minimized (val + collections)
    -Inheritance prohibited by default
    -Builders are easy with default values
    -No checked exceptions
    -Structural equality is the same everywhere
    -Delegation support makes composition easier

    View Slide

  142. @ToddGinsberg
    Want to Learn More?
    https://play.kotlinlang.org

    View Slide

  143. @ToddGinsberg
    Want to Learn More?
    The State of Kotlin Support in
    Spring
    Go back in time for this
    (or check it out on YouTube next week!)

    View Slide

  144. @ToddGinsberg
    Want to Learn More?
    Fully Reactive: Spring, Kotlin, and
    JavaFX Playing Together
    Today from 4:20pm–5:30pm
    In this room!

    View Slide

  145. @ToddGinsberg
    Want to Learn More?
    Klingon Kotlin (in Anger, er,
    Passion) with Project Reactor and
    Spring Boot: Ha' HIja'!
    Tomorrow from 11:30am–12:40pm
    In this room!

    View Slide

  146. #springone
    @s1p
    @ToddGinsberg
    [email protected]
    https://todd.ginsberg.com
    http://bit.ly/S1P2019-Kotlin
    Thank You!

    View Slide