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

A Builder's Intro to Kotlin (Gradle Summit 2017)

A Builder's Intro to Kotlin (Gradle Summit 2017)

Kotlin's popularity has been exploding in the past year. From last year's announcement that Gradle would support it as a build language, to its adoption on large platforms like Android and Spring, to its general applicability for writing IDE and build system plugins, it's hard to find an area that isn't adopting the language in some form.

This talk will be an introduction to the language in the context of Gradle. After covering the language syntax and features and their benefits, we'll look at why it's great for authoring Gradle plugins. Finally, we'll set the stage for Gradle's Kotlin build script support for which there are other full talks at the conference.

Video: https://youtu.be/UAec6OpJiA8

Jake Wharton

June 22, 2017
Tweet

More Decks by Jake Wharton

Other Decks in Programming

Transcript

  1. class User {
 public String getName() {
 // ...
 }


    public void setName(String name) {
 // ...
 }
 } // ^^^ Java
  2. class User {
 public String getName() {
 // ...
 }X


    public void setName(String name) {
 // ...
 }Y
 }Z // ^^^ Java vvv Kotlin val user = User()
 println("Name is " + user.name)
  3. class User {
 public String getName() {
 // ...
 }X


    public void setName(String name) {
 // ...
 }Y
 }Z // ^^^ Java vvv Kotlin val user = User()
 println("Name is " + user.name)X
  4. class User {
 public String getName() {
 // ...
 }X


    public void setName(String name) {
 // ...
 }Y
 }Z // ^^^ Java vvv Kotlin val user = User()
 println("Name is ${user.name}")X
  5. class User {
 public String getName() {
 // ...
 }X


    public void setName(String name) {
 // ...
 }Y
 }Z // ^^^ Java vvv Kotlin val user = User()
 println("Name is $user")X
  6. class User {
 public String getName() {
 // ...
 }X


    public void setName(String name) {
 // ...
 }Y
 }Z // ^^^ Java vvv Kotlin val user = User()
 println("Name is $user")X
  7. class User {
 var name = "Jake"
 } // ^^^

    Kotlin vvv Java User user = new User(); System.out.println("Name is " + user.getName());
  8. class User {
 var name = "Jake"
 } // ^^^

    Kotlin vvv Java User user = new User(); System.out.println("Name is " + user.getName());
  9. class User {
 var name = "Jake"
 } // ^^^

    Kotlin vvv Java User user = new User(); System.out.println("Name is " + user.getName()); user.setName("Jane");
  10. class User {
 var name = "Jake"
 } // ^^^

    Kotlin vvv Java User user = new User(); System.out.println("Name is " + user.getName()); user.setName("Jane");
  11. fun Date.isTuesday(): Boolean {
 return day == 2
 } val

    epoch = Date(1970, 0, 0)
 if (epoch.isTuesday()) {
 println("The epoch was a Tuesday.")
 } else {
 println("The epoch was not a Tuesday.")
 }
  12. fun Date.isTuesday(): Boolean {
 return day == 2
 } val

    epoch = Date(1970, 0, 0)
 if (epoch.isTuesday()) {
 println("The epoch was a Tuesday.")
 } else {
 println("The epoch was not a Tuesday.")
 }
  13. fun Date.isTuesday(): Boolean {
 return day == 2
 } val

    epoch = Date(1970, 0, 0)
 if (epoch.isTuesday()) {
 println("The epoch was a Tuesday.")
 } else {
 println("The epoch was not a Tuesday.")
 } // ^^^ Kotlin vvv Java DateKt.isTuesday(date)
  14. fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
 // ...


    }A val items = listOf(1, 2, 3) val odds = items.filter({ item -> item % 2 != 0 })B
  15. fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
 // ...


    }A val items = listOf(1, 2, 3) val odds = items.filter({ item -> item % 2 != 0 })B
  16. fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
 // ...


    }A val items = listOf(1, 2, 3) val odds = items.filter({ it % 2 != 0 })B
  17. fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
 // ...


    }A val items = listOf(1, 2, 3) val odds = items.filter()B{ it % 2 != 0 }
  18. fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
 // ...


    }A val items = listOf(1, 2, 3) val odds = items.filter { it % 2 != 0 }
  19. fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
 // ...


    }A val items = listOf(1, 2, 3) val oddList = items.filter { it % 2 != 0 } val oddSet = items.filterTo(mutableListOf()) { it % 2 != 0 }
  20. fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
 // ...


    }A val items = listOf(1, 2, 3) val odds = items.filter { it % 2 != 0 }
  21. inline fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
 //

    ...
 }A val items = listOf(1, 2, 3) val odds = items.filter { it % 2 != 0 }
  22. inline fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> { val

    destination = mutableListOf<T>() for (item in this) { if (predicate(item)) destination.add(item) }B return destination }A val items = listOf(1, 2, 3) val odds = items.filter { it % 2 != 0 } val destination = mutableListOf< >() for (item in ) { if ( item ) destination.add(item) }G destination
  23. inline fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> { val

    destination = mutableListOf<T>() for (item in this) { if (predicate(item)) destination.add(item) }B return destination }A val items = listOf(1, 2, 3) val destination = mutableListOf<Int>() for (item in items) { if (item % 2 != 0) destination.add(item) }G val odds = destination filter it
  24. fun <T> List<T>.filterIsInstance(c: Class<T>): List<T> {
 val destination = mutableListOf<T>()

    for (item in this) { if (c.isInstance(item)) destination.add(item) } return destination
 }A
  25. fun <T> List<T>.filterIsInstance(c: Class<T>): List<T> {
 val destination = mutableListOf<T>()

    for (item in this) { if (c.isInstance(item)) destination.add(item) }G return destination
 }A
  26. fun <T> List<T>.filterIsInstance(): List<T> {
 val destination = mutableListOf<T>() for

    (item in this) { if (item in T) destination.add(item) }G return destination
 }A c: Class<T>
 c.isInstance( )
  27. fun <T> List<T>.filterIsInstance(): List<T> {
 val destination = mutableListOf<T>() for

    (item in this) { if (item in T) destination.add(item) }G return destination
 }A
  28. inline fun <T> List<T>.filterIsInstance(): List<T> {
 val destination = mutableListOf<T>()

    for (item in this) { if (item in T) destination.add(item) }G return destination
 }A
  29. inline fun <reified T> List<T>.filterIsInstance(): List<T> {
 val destination =

    mutableListOf<T>() for (item in this) { if (item in T) destination.add(item) }G return destination
 }A
  30. inline fun <reified T> List<T>.filterIsInstance(): List<T> {
 val destination =

    mutableListOf<T>() for (item in this) { if (item in T) destination.add(item) }G return destination
 }A
  31. inline fun <reified T> List<T>.filterIsInstance(): List<T> {
 val destination =

    mutableListOf<T>() for (item in this) { if (item in T) destination.add(item) } return destination
 }A val list = listOf(1, 2f, 3, 4f) val ints = list.filterIsInstance<Int>()
  32. inline fun <reified T> List<T>.filterIsInstance(): List<T> {
 val destination =

    mutableListOf<T>() for (item in this) { if (item in T) destination.add(item) } return destination
 }A val list = listOf(1, 2f, 3, 4f) val ints = list.filterIsInstance<Int>() ALOAD 7 # item INSTANCEOF java/lang/Integer IFEQ L8 ALOAD 5 # destination ALOAD 7 # item INVOKEINTERFACE java/util/Collection.add (Ljava/lang/Object;)Z
  33. @3a71f4dd data class User(val name: String) val jake = User("Jake")

    println("Hello, $jake!") Hello, User(name=Jake)!
  34. class UserPersisence(db: SqlDatabase) { private val deleteByName = db.createStatement("DELETE FROM

    user WHERE name = ?") fun delete(name: String) { deleteByName.bind(1, name) deleteByName.execute() } }
  35. class UserPersisence(db: SqlDatabase) { private val deleteByName = db.createStatement("DELETE FROM

    user WHERE name = ?") fun delete(name: String) { deleteByName.bind(1, name) deleteByName.execute() }B }A
  36. class UserPersisence(db: SqlDatabase) { private val deleteByName by lazy {

    db.createStatement("DELETE FROM user WHERE name = ?") }C fun delete(name: String) { deleteByName.bind(1, name) deleteByName.execute() }B }A
  37. val deleteByName by lazy { db.createStatement("DELETE FROM user WHERE name

    = ?") }C var name by Delegates.observable("Jane") { prop, old, new -> println("Name changed from $old to $new") }
  38. val deleteByName by lazy { db.createStatement("DELETE FROM user WHERE name

    = ?") }C var name by Delegates.observable("Jane") { prop, old, new -> println("Name changed from $old to $new") } var address by Delegates.notNull<String>()
  39. val deleteByName by lazy { db.createStatement("DELETE FROM user WHERE name

    = ?") }C var name by Delegates.observable("Jane") { prop, old, new -> println("Name changed from $old to $new") } var address by Delegates.notNull<String>() val nameView by bindView<TextView>(R.id.name)
  40. val deleteByName by lazy { db.createStatement("DELETE FROM user WHERE name

    = ?") }C var name by Delegates.observable("Jane") { prop, old, new -> println("Name changed from $old to $new") } var address by Delegates.notNull<String>() val nameView by bindView<TextView>(R.id.name)
  41. fun main(vararg args: String) = runBlocking<Unit> { val jobs =

    List(100_000) { launch(CommonPool) { delay(1000L) print(".") } } jobs.forEach { it.join() } }
  42. apply plugin: 'org.jetbrains.kotlin.jvm' apply plugin: 'org.jetbrains.kotlin.android' apply plugin: 'kotlin2js' apply

    plugin: 'konan' # Different classpath dependency or apply plugin: 'org.jetbrains.kotlin.platform.common' apply plugin: 'org.jetbrains.kotlin.platform.jvm' apply plugin: 'org.jetbrains.kotlin.platform.js' apply plugin: 'konan' # Different classpath dependency
  43. apply plugin: 'org.jetbrains.kotlin.jvm' apply plugin: 'org.jetbrains.kotlin.kapt' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility

    = JavaVersion.VERSION_1_8 dependencies { compile deps.kotlin.stdLibJre8 compile deps.javaPoet compile deps.autoCommon compileOnly deps.autoService kapt deps.autoService testCompile deps.junit testCompile deps.truth testCompile deps.compileTesting }
  44. apply plugin: 'org.jetbrains.kotlin.jvm' apply plugin: 'org.jetbrains.kotlin.kapt' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility

    = JavaVersion.VERSION_1_8 dependencies { compile deps.kotlin.stdLibJre8 compile deps.javaPoet compile deps.autoCommon compileOnly deps.autoService kapt deps.autoService testCompile deps.junit testCompile deps.truth testCompile deps.compileTesting }
  45. apply(plugin: 'org.jetbrains.kotlin.jvm')X apply plugin: 'org.jetbrains.kotlin.kapt' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility =

    JavaVersion.VERSION_1_8 dependencies { compile deps.kotlin.stdLibJre8 compile deps.javaPoet compile deps.autoCommon compileOnly deps.autoService kapt deps.autoService testCompile deps.junit testCompile deps.truth testCompile deps.compileTesting }
  46. apply(singletonMap('plugin', 'org.jetbrains.kotlin.jvm'))X apply plugin: 'org.jetbrains.kotlin.kapt' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility =

    JavaVersion.VERSION_1_8 dependencies { compile deps.kotlin.stdLibJre8 compile deps.javaPoet compile deps.autoCommon compileOnly deps.autoService kapt deps.autoService testCompile deps.junit testCompile deps.truth testCompile deps.compileTesting }
  47. apply(singletonMap('plugin', 'org.jetbrains.kotlin.jvm'))X apply plugin: 'org.jetbrains.kotlin.kapt' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility =

    JavaVersion.VERSION_1_8 dependencies { compile deps.kotlin.stdLibJre8 compile deps.javaPoet compile deps.autoCommon compileOnly deps.autoService kapt deps.autoService testCompile deps.junit testCompile deps.truth testCompile deps.compileTesting }
  48. apply(singletonMap('plugin', 'org.jetbrains.kotlin.jvm'))X apply plugin: 'org.jetbrains.kotlin.kapt' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility =

    JavaVersion.VERSION_1_8 dependencies { compile deps.kotlin.stdLibJre8 compile deps.javaPoet compile deps.autoCommon compileOnly deps.autoService kapt deps.autoService testCompile deps.junit testCompile deps.truth testCompile deps.compileTesting }
  49. apply(singletonMap('plugin', 'org.jetbrains.kotlin.jvm'))X apply plugin: 'org.jetbrains.kotlin.kapt' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility =

    JavaVersion.VERSION_1_8 dependencies { compile deps.kotlin.stdLibJre8 compile(deps.javaPoet) compile deps.autoCommon compileOnly deps.autoService kapt deps.autoService testCompile deps.junit testCompile deps.truth testCompile deps.compileTesting }
  50. apply(singletonMap('plugin', 'org.jetbrains.kotlin.jvm'))X apply plugin: 'org.jetbrains.kotlin.kapt' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility =

    JavaVersion.VERSION_1_8 dependencies { compile deps.kotlin.stdLibJre8 compile(deps.javaPoet) compile deps.autoCommon compileOnly deps.autoService kapt deps.autoService testCompile deps.junit testCompile deps.truth testCompile deps.compileTesting }
  51. android { // ... testOptions { unitTests.all { systemProperty('robolectric.dependency.repo.id', 'example-nexus')

    systemProperty('robolectric.dependency.repo.url', 'https://nexus.example.com/content/groups/public') } } }
  52. android { // ... testOptions { unitTests.all { systemProperty('robolectric.dependency.repo.id', 'example-nexus')

    systemProperty('robolectric.dependency.repo.url', 'https://nexus.example.com/content/groups/public') } } }
  53. android { // ... testOptions { unitTests.all { systemProperty('robolectric.dependency.repo.id', 'example-nexus')

    systemProperty('robolectric.dependency.repo.url', 'https://nexus.example.com/content/groups/public') }
 
 }
  54. apply plugin: 'org.jetbrains.kotlin.jvm' apply plugin: 'org.jetbrains.kotlin.kapt' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility

    = JavaVersion.VERSION_1_8 dependencies { compile deps.kotlin.stdLibJre8 compile deps.javaPoet compile deps.autoCommon compileOnly deps.autoService kapt deps.autoService testCompile deps.junit testCompile deps.truth testCompile deps.compileTesting }A java build.gradle
  55. apply { plugin('org.jetbrains.kotlin.jvm') plugin('org.jetbrains.kotlin.kapt') } java { sourceCompatibility = JavaVersion.VERSION_1_8

    targetCompatibility = JavaVersion.VERSION_1_8 } dependencies { compile(deps.kotlin.stdLibJre8) compile(deps.javaPoet) compile(deps.autoCommon) compileOnly(deps.autoService) kapt(deps.autoService) testCompile(deps.junit) testCompile(deps.truth) testCompile(deps.compileTesting) }A build.gradle.kts
  56. apply { plugin('org.jetbrains.kotlin.jvm') plugin('org.jetbrains.kotlin.kapt') } java { sourceCompatibility = JavaVersion.VERSION_1_8

    targetCompatibility = JavaVersion.VERSION_1_8 } dependencies { compile(deps.kotlin.stdLibJre8) compile(deps.javaPoet) compile(deps.autoCommon) compileOnly(deps.autoService) kapt(deps.autoService) testCompile(deps.junit) testCompile(deps.truth) testCompile(deps.compileTesting) }A build.gradle.kts
  57. apply { plugin('org.jetbrains.kotlin.jvm') plugin('org.jetbrains.kotlin.kapt') } java { sourceCompatibility = JavaVersion.VERSION_1_8

    targetCompatibility = JavaVersion.VERSION_1_8 } dependencies { compile(deps.kotlin.stdLibJre8) compile(deps.javaPoet) compile(deps.autoCommon) compileOnly(deps.autoService) kapt(deps.autoService) testCompile(deps.junit) testCompile(deps.truth) testCompile(deps.compileTesting) }A build.gradle.kts
  58. apply { plugin('org.jetbrains.kotlin.jvm') plugin('org.jetbrains.kotlin.kapt') } java { sourceCompatibility = JavaVersion.VERSION_1_8

    targetCompatibility = JavaVersion.VERSION_1_8 } dependencies { compile(deps.kotlin.stdLibJre8) compile(deps.javaPoet) compile(deps.autoCommon) compileOnly(deps.autoService) kapt(deps.autoService) testCompile(deps.junit) testCompile(deps.truth) testCompile(deps.compileTesting) }A build.gradle.kts
  59. apply { plugin('org.jetbrains.kotlin.jvm') plugin('org.jetbrains.kotlin.kapt') } java { sourceCompatibility = JavaVersion.VERSION_1_8

    targetCompatibility = JavaVersion.VERSION_1_8 } dependencies { compile(deps.kotlin.stdLibJre8) compile(deps.javaPoet) compile(deps.autoCommon) compileOnly(deps.autoService) kapt(deps.autoService) testCompile(deps.junit) testCompile(deps.truth) testCompile(deps.compileTesting) }A build.gradle.kts
  60. apply { plugin('org.jetbrains.kotlin.jvm') plugin('org.jetbrains.kotlin.kapt') } java { sourceCompatibility = JavaVersion.VERSION_1_8

    targetCompatibility = JavaVersion.VERSION_1_8 } dependencies { compile(deps.kotlin.stdLibJre8) compile(deps.javaPoet) compile(deps.autoCommon) compileOnly(deps.autoService) kapt(deps.autoService) testCompile(deps.junit) testCompile(deps.truth) testCompile(deps.compileTesting) }A build.gradle.kts
  61. +