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

Why we ditched JavaScript for Kotlin/JS

Louis CAD
February 05, 2023

Why we ditched JavaScript for Kotlin/JS

You might think that Kotlin is the programming language of Android… Well, it's only partially true, and that's not even Kotlin's raison d'être. Kotlin 1.0 (2016) had experimental support for JavaScript, and 6 years later, we're sticking to it on the WEB, in the backend, on Android of course, and now on (native) iOS as well!

Come to learn why you might, or might not want to follow suit. This talk will be both an up to date introduction to Kotlin, and sharing our experience with it on the WEB.

Louis CAD

February 05, 2023
Tweet

More Decks by Louis CAD

Other Decks in Programming

Transcript

  1. Why we ditched JavaScript for Kotlin/JS? FOSDEM 2023 - JavaScript

    DevRoom Presented by Louis CAD, Google Developer Expert for Kotlin
  2. Why we ditched JavaScript for Kotlin/JS? Wrong answers only •

    Because Kotlin is cool 😎 • Because of the hype 🏝 • Because we love to hate JavaScript • Because JavaScript was designed in just 7 days while Kotlin was in 6 years
  3. What can we do on the WEB with Kotlin? •

    A lot of complicated things • Manipulate the DOM • Draw on Canvas • Write readable and shareable business logic • Sky is the limit
  4. Why we ditched JavaScript for Kotlin/JS! 3 answers. 1. Safety

    and reliability ✅ 2. Language design ✍ • Concise syntax • Type safety • Cancellable async programming (aka. coroutines) • Many other features… 3. Code sharing 🤗 • Share what you want, native interoperability
  5. Kotlin compiles to these platforms • JVM (server, desktop, libraries…)

    • JavaScript (browser, nodeJS) • Android (& Wear OS) within ART (≃JVM) • Native • iOS, watchOS, macOS, tvOS • Linux • Windows • Android NDK
  6. Kotlin has direct interoperability with the following programming languages •

    Java • JavaScript • TypeScript (since Kotlin 1.8) • Objective-C • Swift • C
  7. Kotlin has direct interoperability with the following programming languages •

    Java (both ways) • JavaScript (both ways, some quirks) • TypeScript (both ways, some quirks) • Objective-C (both ways, some quirks) • Swift (through Objective-C, & also with dedicated community plugins) • C (both ways, some quirks)
  8. What direct interop means • Not reliant on third party

    plugins updates like in Cordova, Flutter, etc. • Use iOS, Android, JS, Java, & C APIs like they were built in Kotlin • Call new Kotlin code from Java, like it was built in Java* • Call new Kotlin code from Swift, like it was built in Swift* • Call new Kotlin code from JavaScript, like it was built in JavaScript* * limitations might apply
  9. Why we ditched JavaScript for Kotlin/JS! 3 answers. 1. Safety

    and reliability ✅ 2. Language design ✍ • Concise syntax • Type safety • Cancellable async programming (aka. coroutines) • Many other features… 3. Code sharing 🤗 • Share what you want, native interoperability
  10. Your users Applies to other dynamic typed programming languages (Bash,

    Python, etc…). Missing bolts, wing off? No problem Let me try to f ly it anyway. Let me try to run it anyway. JavaScript be like
  11. No users. Expected a pilot seat but got an economy

    seat. No takeo ff possible. Kotlin be like
  12. Compiling isn't just about browsing the WEB while waiting. You

    don't have to f ly the plane to realize… …that one wing wasn't attached securely.
  13. What should we do on the WEB with Kotlin? •

    WEB apps • Webpages/websites with lots of dynamic logic that can't move server-side • Anything that doesn't have to be less than 300kB (i.e. landing page) • Generate html with Kotlin code (even not Kotlin/JS) • Libraries for Kotlin consumers • Complex libraries for Typescript/JavaScript consumers
  14. Why we ditched JavaScript for Kotlin/JS! 3 answers. 1. Safety

    and reliability ✅ 2. Language design ✍ • Concise syntax • Type safety • Cancellable async programming (aka. coroutines) • Many other features… 3. Code sharing 🤗 • Share what you want, native interoperability
  15. Why we ditched JavaScript for Kotlin/JS! 2. Language design ✍

    • Concise syntax • Type safety • Cancellable async programming (aka. coroutines) • Many other features… 
 
 

  16. Classes open class Vehicle(val name: String) 
 
 class Car(name:

    String) : Vehicle(name), Comparable<Car> { 
 override fun compareTo(other: Car): Int { 
 TODO() 
 } 
 }
  17. Classes open class Vehicle(val name: String) 
 
 class Car(name:

    String) : Vehicle(name), Comparable<Car> { 
 override fun compareTo(other: Car) = TODO() 
 }
  18. Null safety • Nullable? types • NPE safe equals NPE:

    NullPointerException (similar to TypeError null/unde f ined in JS)
  19. Null safety var greeting: String? = "Hello World!" 
 greeting

    = null // ok 
 greeting.length // compilation error
  20. Null safety var greeting: String? = "Hello World!" 
 greeting

    = null greeting!!.length // compiles throws NullPointerException
  21. Null safety var greeting: String? = "Hello World!" 
 val

    chars: Int = greeting?.length // error
  22. Null safety var greeting: String? = "Hello World!" 
 val

    chars: Int = greeting?.length ?: 0 //ok Elvis operator
  23. Properties • Similar to f ields, but include getter and

    setters • Can be delegated (Google for "Kotlin delegated properties")
  24. Properties var stringRepresentation: String 
 get() = this.toString() 
 set(value)

    { 
 setDataFromString(value) // Parses the string and // assigns values to other properties. 
 }
  25. Extension functions • Static methods (no dynamic/surprising resolution) • “instance-method

    like” syntax • Works even on f inal classes (default in Kotlin)
  26. Extension functions if (3.isEven()) println("I don't believe you!") if (9.isMultipleOf(3))

    println("For sure!") fun Int.isMultipleOf(other: Int) = this % other == 0 fun Int.isEven() = isMultipleOf(2)
  27. Extension functions if (3.isEven()) println("I don't believe you!") if (9

    isMultipleOf 3) println("For sure!") infix fun Int.isMultipleOf(other: Int) = this % other == 0 fun Int.isEven() = isMultipleOf(2)
  28. Extension functions inline fun Int.hasFlag(flag: Int) = flag and this

    == flag 
 inline fun Int.withFlag(flag: Int) = this or flag 
 inline fun Int.minusFlag(flag: Int) = this and flag.inv() if (0b1011.hasFlag(0b0001)) println("I think so!") if (0xF003.hasFlag(0x0001)) println("Yes too") if (0x0000.hasFlag(0x0001)) println("Impossible")
  29. Higher-order functions fun logEntryAndExit( name: String, block: () -> Unit

    ) { } logEntryAndExit( "Calling fancy code", { fancyCode() } )
  30. Higher-order functions fun logEntryAndExit( name: String, block: () -> Unit

    ) { try { } finally { } } logEntryAndExit( "Calling fancy code", { fancyCode() } )
  31. Higher-order functions fun logEntryAndExit( name: String, block: () -> Unit

    ) { try { println("Start: $name") } finally { println("End: $name") } } logEntryAndExit( "Calling fancy code", { fancyCode() } )
  32. Higher-order functions fun logEntryAndExit( name: String, block: () -> Unit

    ) { try { println("Start: $name") block() } finally { println("End: $name") } } logEntryAndExit( "Calling fancy code", { fancyCode() } )
  33. Higher-order functions inline fun logEntryAndExit( name: String, block: () ->

    Unit ) { try { println("Start: $name") block() } finally { println("End: $name") } } logEntryAndExit( "Calling fancy code", { fancyCode() } )
  34. Higher-order functions inline fun logEntryAndExit( name: String, block: () ->

    Unit ) { try { println("Start: $name") block() } finally { println("End: $name") } } logEntryAndExit( name = "Calling fancy code", block = { fancyCode() } )
  35. Higher-order functions inline fun logEntryAndExit( name: String, block: () ->

    Unit ) { try { println("Start: $name") block() } finally { println("End: $name") } } logEntryAndExit("Calling fancy code") { fancyCode() }
  36. Lambdas The "anonymous" functions passed to higher-order functions • Can

    be inlined! Avoids unneeded memory allocation for better perfs.
  37. Lambdas aka. anonymous functions inline fun logEntryAndExit( name: String, block:

    () -> Unit ) { try { println("Start: $name") block() } finally { println("End: $name") } } logEntryAndExit("Calling fancy code") { fancyCode() }
  38. Lambdas aka. anonymous functions inline fun logEntryAndExit( name: String, block:

    () -> Unit ) { try { println("Start: $name") block() } finally { println("End: $name") } } logEntryAndExit( name = "Calling fancy code", block = { fancyCode() } )
  39. when expression fun cases(obj: Any) { 
 when (obj) {

    
 1 -> println("One") 
 "Hello" -> println("Greeting") 
 is Long -> println("Long") 
 !is String -> println("Not a string") 
 else -> println("Unknown") 
 } 
 }
  40. Smart casts fun getStringLength(obj: Any): Int? { 
 if (obj

    is String) 
 return obj.length // no cast to String is needed 
 return null 
 }
  41. What are coroutines? • Saves you from callback hell •

    A way to write asynchronous code sequentially, without nested callbacks • Similar to async/await from JavaScript and other languages • Also Structured Concurrency
  42. What is Structured Concurrency? • A system to prevent concurrency

    issues • Requires a parent scope to launch a new, concurrent coroutine • Propagates cancellation and crashes at the right place
  43. How to get started? Best way to learn and leverage

    is to try and experiment • Open IntelliJ IDEA (Community Edition is enough) • New Project > Kotlin > Browser application • Learn Kotlin syntax and basics at kotl.in/learn • Learn about Kotlin for JavaScript at kotl.in/js • Learn about Kotlin Multiplatform at kotl.in/multiplatform • Learn about coroutines and structured concurrency at kotl.in/coroutines, with Google search, and by watching Roman Elizarov's talks
  44. Questions, comments, ideas… Thank you for listening. LouisCAD on GitHub

    (social links on my pro fi le) Blog at blog.louiscad.com (you can subscribe) Kotlin