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

An Overview of Multiplatform Kotlin

Rafael Toledo
September 21, 2018

An Overview of Multiplatform Kotlin

Presented at TheConf 2018

Rafael Toledo

September 21, 2018
Tweet

More Decks by Rafael Toledo

Other Decks in Programming

Transcript

  1. Kotlin? • Open Source language, created back in 2010 by

    JetBrains • Statically typed, safe, and pragmatic • It's design is inspired by languages like Java, Scala, C#, and Groovy • Object Oriented with some Functional features 3
  2. Cool features 8 DATA CLASSES TYPE ALIAS LAMBDA DSL NULL

    SAFETY PROPERTIES EXTENSION FUNCTIONS
  3. Why to use Kotlin for Android development? • Compatibility -

    Java 6 • Performance • Interoperability • Footprint: standard library & runtime costs only ~100Kb • Compilation Time is not a problem anymore • Learning curve 10
  4. Why to use Kotlin for JVM development? • Expressivity •

    Scalability & Performance - Kotlin Coroutines • Interoperability with existing codebase • Gradual migration • Tooling • Learning curve 11
  5. Why to use Kotlin for JavaScript development • Supports ECMAScript

    5.1 on Kotlin 1.2 - ECMAScript 2015 support soon • Optimized JavaScript - DCE (Dead Code Elimination) • Legible and debuggable JavaScript • Compatibility with existing JavaScript code • Same features as the JVM Standard Library - including Coroutines 15
  6. Kotlin for JavaScript - what about types? • It's possible

    to interact with any JavaScript code • Statically-typed APIs / TypeScript -> https://github.com/kotlin/ts2kt • Dynamic types for any other scenarios 16
  7. KotlinJS - React class HelloComponent: RComponent<RProps, RState>() { override fun

    RBuilder.render() { div(classes = "content") { h1 { +"Hello!" } } } } fun RBuilder.hello() = child(HelloComponent::class) { } 19
  8. KotlinJS - NodeJS fun main(args: Array<String>) { val express =

    require("express") val app = express() app.get("/", { req, res -> res.type("text/plain") res.send("i am a beautiful butterfly") }) app.listen(3000, { println("Listening on port 3000") }) } 20
  9. Why to use Kotlin for native development? • Native code,

    without VM • LLVM based backend • Interoperability with any native code and libraries - you can generate the binding interface using .h files • MacOS / iOS • Latest version is 0.8.2 - in active development 21
  10. Kotlin Native supported targets • Windows (x86_64) • Linux (x86_64,

    arm32, MIPS, and MIPS little endian) • MacOS (x86_64) • iOS (arm32, arm64, x64) • Android (arm32 e arm64) • STM32 • WebAssembly (wasm32) 22
  11. Kotlin Native - C interop components.main { targets = ['macos_x64',

    'linux_x64'] dependencies { cinterop('libcurl-interop') { defFile 'src/main/c_interop/libcurl.def' target('linux_x64') { includeDirs.headerFilterOnly '/usr/include' } target('macos_x64') { includeDirs.headerFilterOnly '/opt/local/include', '/usr/local/include' } } } 23
  12. Kotlin Native - C interop headers = curl/curl.h headerFilter =

    curl/* linkerOpts.osx = -L/opt/local/lib -L/usr/local/opt/curl/lib -lcurl linkerOpts.linux = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu -lcurl 24
  13. Kotlin Native - C interop fun fetch() { val res

    = curl_easy_perform(curl) if (res != CURLE_OK) println("curl_easy_perform() failed") } fun CPointer<ByteVar>.toKString(length: Int): String { val bytes = this.readBytes(length) return bytes.stringFromUtf8() } 25
  14. Multiplatform Kotlin • Support introduced in 1.2 • JVM &

    JavaScript (Native is "kind of" working) • common, platform and regular modules 29
  15. Multiplatform Modules common: Contains common code that can runs on

    any platform. Also can hold common interfaces and class signatures that must have a specific implementation in each platform platform: Contains the specific implementation of some interface defined by a common module regular: A regular module that contains only code to a specific platform 30
  16. Multiplatform Module - Gradle buildscript { ext.kotlin_version = '1.2.70' repositories

    { mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } apply plugin: 'kotlin-platform-common' repositories { mavenCentral() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version" testCompile "org.jetbrains.kotlin:kotlin-test-common:$kotlin_version" } 31
  17. Multiplatform Module - Gradle buildscript { ext.kotlin_version = '1.2.70' repositories

    { mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } apply plugin: 'kotlin-platform-common' repositories { mavenCentral() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version" testCompile "org.jetbrains.kotlin:kotlin-test-common:$kotlin_version" } 32
  18. Multiplatform Module - JVM target ... apply plugin: 'kotlin-platform-jvm' repositories

    { mavenCentral() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" expectedBy project(":common") testCompile "junit:junit:4.12" testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" } 33
  19. Multiplatform Module - JVM target ... apply plugin: 'kotlin-platform-jvm' repositories

    { mavenCentral() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" expectedBy project(":common") testCompile "junit:junit:4.12" testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" } 34
  20. Multiplatform Module - JavaScript target ... apply plugin: 'kotlin-platform-js' repositories

    { mavenCentral() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version" expectedBy project(":common") testCompile "org.jetbrains.kotlin:kotlin-test-js:$kotlin_version" } 35
  21. Multiplatform Module - JavaScript target ... apply plugin: 'kotlin-platform-js' repositories

    { mavenCentral() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version" expectedBy project(":common") testCompile "org.jetbrains.kotlin:kotlin-test-js:$kotlin_version" } 36
  22. Multiplatform Module - Native target ... buildscript { repositories {

    maven { url 'https://jetbrains.bintray.com/kotlin-native-dependencies' } } dependencies { classpath 'org.jetbrains.kotlin:kotlin-native-gradle-plugin:0.9.1' } } apply plugin: 'kotlin-platform-native' dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" expectedBy project(":common") } ... 37
  23. Multiplatform Module - Native target ... apply plugin: 'kotlin-platform-native' dependencies

    { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" expectedBy project(":common") } sourcesets.main.component { baseName.set('MyCommonModule') target 'ios_arm64', 'ios_x64' outputKinds = [ FRAMEWORK ] } ... 38
  24. Multiplatform Module - Common code package com.example.foo expect class Foo(bar:

    String) { fun frob() } fun main(args: Array<String>) { Foo("Hello").frob() } 39
  25. Multiplatform Module - specific implementation package com.example.foo actual class Foo

    actual constructor(val bar: String) { actual fun frob() { println("Frobbing the $bar") } } 40
  26. Why to use Kotlin DSL on Gradle? • Speed up

    analysis time and compilation time of build scripts, compared to Groovy • IDE friendly, better autocomplete • Unify the language used in the project • 1.0 RC6 included in Gradle 4.10.1, final to be included in Gradle 5.0 (next version) 44
  27. Gradle - Groovy (default) // build.gradle allprojects { buildscript {

    ext.kotlin_version = '1.2.70' repositories { mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } repositories { mavenLocal() } } 45
  28. Gradle - Kotlin DSL // build.gradle.kts allprojects { buildscript {

    val kotlin_version by extra { "1.2.70" } repositories { mavenCentral() } dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") } } repositories { mavenLocal() } } 46