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

Introduction to Kotlin/JS for frontend development

Introduction to Kotlin/JS for frontend development

Is there room for another alternative to JavaScript these days when TypeScript covers all the needs we have of a modern, type-safe language? Kotlin was unveiled by JetBrains in 2011 as an alternative to Java on the JVM, and has since evolved to include Android, native (including iOS), and JavaScript (node or browser).

In this talk I will introduce the Kotlin language to frontend developers and demonstrate the pros and cons to using this for your next project. We'll learn about the unique features of Kotlin, how it deals with concurrency, and how the JavaScript can be a compile target using Kotlin/JS.

Erik Hellman

March 03, 2020
Tweet

More Decks by Erik Hellman

Other Decks in Programming

Transcript

  1. Introduction to Kotlin/JS for
    frontend development
    @ErikHellman
    speakerdeck.com/erikhellman/js-for-frontend-development

    View Slide

  2. View Slide

  3. View Slide

  4. View Slide

  5. View Slide

  6. kotlinlang.org

    View Slide

  7. Compile
    target

    View Slide

  8. fun sayHello(name: String): String {
    return "Hello, " + name + "!";
    }

    View Slide

  9. fun sayHello(name: String): String {
    return "Hello, $name!";
    }

    View Slide

  10. fun sayHello(name: String): String
    = "Hello, $name!";

    View Slide

  11. fun sayHello(name: String): String
    = "Hello, $name!"

    View Slide

  12. fun nullAllowed(name: String?) {
    println("Hello, ${name ?: "You"}!")
    }
    Nullability

    View Slide

  13. fun fetchData(url: String?): Data? {
    return url?.let { fetch(it) }
    }
    Nullability

    View Slide

  14. fun collectionsDemo(strings: List) {
    strings
    .filter { it.length > 5 }
    .map { it.toLowerCase() }
    .forEach { println(it) }
    }
    Collections - operations

    View Slide

  15. fun addToList(strings: List,
    name:String): List {
    return strings + name
    }
    Collections - modifications

    View Slide

  16. fun buildKitten(name: String,
    color:Color = Color.Black,
    sex: Sex = Sex.Female,
    race: Race = Race.Siberian): Kitten {
    return Kitten(name, color, sex, race)
    }
    val kitten = buildKitten("Lucy", color = Color.Gray)
    Functions - default & named arguments

    View Slide

  17. fun createThing(id:String, callback: (thing:Thing) -> Unit) {
    val thing = Thing(id)
    callback(thing)
    }
    val callback = { thing: Thing ->
    println(thing)
    }
    createThing("first", callback)
    Functions - lambdas

    View Slide

  18. fun createThing(id:String, callback: (thing:Thing) -> Unit) {
    val thing = Thing(id)
    callback(thing)
    }
    createThing("first", { thing -> println(thing) })
    Functions - lambdas

    View Slide

  19. fun createThing(id:String, callback: (thing:Thing) -> Unit) {
    val thing = Thing(id)
    callback(thing)
    }
    createThing("first", { println(it) })
    Functions - lambdas

    View Slide

  20. fun createThing(id:String, callback: (thing:Thing) -> Unit) {
    val thing = Thing(id)
    callback(thing)
    }
    createThing("first") { println(it) }
    Functions - lambdas

    View Slide

  21. class Pair(val first:String, val second:String)
    fun createPair(first:String, second:String): Pair {
    return Pair(first, second)
    }
    Functions - extension functions

    View Slide

  22. class Pair(val first:String, val second:String)
    fun String.pairedWith(other:String) = Pair(this, other)
    fun createPair(first:String, second:String): Pair {
    return first.pairedWith(second)
    }
    Functions - extension functions

    View Slide

  23. class Pair(val first:String, val second:String)
    infix fun String.pairedWith(other:String)
    = Pair(this, other)
    fun createPair(first:String, second:String): Pair {
    return first pairedWith second
    }
    Functions - infix functions

    View Slide

  24. class Pair(val first:String, val second:String) {
    operator fun contains(text:String): Boolean {
    return text == first || text == second
    }
    }
    fun testPair() {
    val pair = Pair("Hello", "World")
    if ("World" in pair) {
    println("Match!")
    }
    }
    Functions - operator overloading

    View Slide

  25. class Thing
    Classes & Interfaces

    View Slide

  26. class Thing(val name: String, val id: Int)
    Classes - constructor

    View Slide

  27. class Thing {
    var name: String? = null
    var id: Int? = null
    }
    Classes - properties

    View Slide

  28. class Thing {
    var name: String? = null
    var id: Int? = null
    companion object {
    fun build(name: String, id: Int): Thing {
    return Thing().also {
    it.name = name
    it.id = id
    }
    }
    }
    }
    Classes - companion object

    View Slide

  29. Classes - immutable data classes
    data class Thing(val name: String, val id: Int)
    val firstThing = Thing("Erik", 1)
    val secondThing = firstThing.copy(name = "John")

    View Slide

  30. Async functions - Kotlin Coroutines
    fun fetchDemo(url) {
    window.fetch(url)
    .then { response -> response.text() }
    .then { text -> println(text) }
    .catch { error -> println("Error: $error") }
    }

    View Slide

  31. Async functions - Kotlin Coroutines
    suspend fun fetchAndShowData(url: String) {
    try {
    val response = window.fetch(url).await()
    val text = response.text().await()
    println("Test data: $text")
    } catch (error: Exception) {
    println("Error: $error")
    }
    }

    View Slide

  32. Kotlin/JS - compiler input
    fun main() {
    println("Hello, World - From Kotlin/JS!")
    }

    View Slide

  33. class Response(val value: T)
    interface Api {
    fun load(url: String): Response
    }
    interface Ui {
    fun show(data: T)
    }
    DSLs!

    View Slide

  34. fun dslDemo(api: Api, ui: Ui) {
    load ("http:=/api.server.com/v1/things/1") {
    api.load(it)
    } then {
    ui.show(it)
    }
    }
    DSLs!

    View Slide

  35. fun load(
    url:String,
    loadFunc: (url:String) => Response): Deferred {
    return async { loadFunc(url).value }
    }
    infix fun Deferred.then(lambda: (T) => Unit) {
    launch {
    lambda([email protected]());
    }
    }
    DSLs!

    View Slide

  36. fun dslDemo(api: Api, ui: Ui) {
    load ("http:=/api.server.com/v1/things/1") {
    api.load(it)
    } then {
    ui.show(it)
    }
    }
    DSLs!

    View Slide

  37. fun Application.main() {
    routing {
    get("/") {
    call.respondHtml {
    head {
    title { +"Ktor: html" }
    }
    body {
    p { +"Hello from Ktor html sample application" }
    }
    }
    }
    }
    }
    Ktor.io - Web DSL in practice!

    View Slide

  38. Kotlin/JS compiler
    $ kotlinc-js Main.kt -output main.js

    View Slide

  39. Kotlin/JS - compiler output
    if (typeof kotlin === 'undefined') {
    throw new Error("Error loading module 'main'. Its dependency
    'kotlin' was not found. Please, check whether 'kotlin' is loaded
    prior to 'main'.");
    }
    var main = function (_, Kotlin) {
    'use strict';
    var println = Kotlin.kotlin.io.println_s8jyv4$;
    function main() {
    println('Hello, World - From Kotlin/JS!');
    }
    _.main = main;
    main();
    Kotlin.defineModule('main', _);
    return _;
    }(typeof main === 'undefined' ? {} : main, kotlin);

    View Slide

  40. Kotlin/JS - build.gradle.kts
    plugins {
    kotlin("js") version "1.3.50"
    }
    group = "se.hellsoft"
    version = "1.0.0"
    kotlin {
    target {
    browser()
    }
    sourceSets["main"].dependencies {
    implementation(kotlin("stdlib-js"))
    }
    }
    repositories {
    jcenter()
    }

    View Slide

  41. But why?

    View Slide

  42. Compile
    target

    View Slide

  43. Thank you for listening!
    Any questions?

    View Slide

  44. Resources

    https://speakerdeck.com/erikhellman/js-for-frontend-development

    https://play.kotlinlang.org/

    https://kotlinlang.org/

    https://kotlinconf.com/

    View Slide