SlideShare a Scribd company logo
© Instil Software 2020
A TYPESCRIPT FAN'S
KOTLINJS ADVENTURES
should you make the
switch?
D
@GarthGilmour
@BoyleEamonn
– TS brings types and compilation to JS
– Improves upon the existing strengths of JS
– Makes us more productive and happy
– Leverages existing JS frameworks
– Interop with JS is a design goal
we love typescript
it solves real problems for us
– Kotlin improves upon Java in many ways
– Adds null safety, DSLs, coroutines etc...
– Makes us more productive and happy
– Leverages existing JVM frameworks
– But interop with Java is a design goal
we love kotlin
it solves real problems for us
JVM
Java
Bytecode
Kotlin
(JVM)
Kotlin
(JS)
Browser
JavaScript
Interpreter
Kotlin
(Native)
Machine Code
& Runtime
OS
Kotlin
(Android)
ART
Dalvik
Bytecode
breaking down
the problem
experiment: is kotlinjs worth it?
– Build an app in both TypeScript and KotlinJS
– Go beyond “hello world”
– Incorporate common JS libraries
– Compare the experience
– Tooling
– Language features
– Community
what problem does it solve?
breakout clone
browser based clone
breakout clone
browser based clone
– React
– https://reactjs.org
– Redux
– https://redux.js.org
– React-Three-Fiber
– https://github.com/react-spring/react-three-fiber
frameworks we used
declarative UI
state separation
const geometry = new THREE.BoxGeometry(BAT_WIDTH, 1, 1);
export const Bat: FC = () => {
const position = useSelector((state: State) => state.batPosition);
return (
<mesh position={[position, 0, BAT_Z]} geometry={geometry}>
{woodMaterial}
</mesh>
);
};
creating a
kotlinjs react project
– Template project from IntelliJ
– Grade project using Kotlin DSL
– Easily integrate NPM packages
creating new project
the wizard
Alternative JS targets
multiplatform libraries
COMMON
KOTLIN
KOTLIN ANDROID
KOTLIN JS
KOTLIN NATIVE
KOTLIN JVM
NATIVE
ARTEFACT
JS BUNDLE
JAR
kotlin js plugin
plugins {
kotlin("js") version "1.5.0"
}
// ...
kotlin {
js(LEGACY) {
binaries.executable()
browser {
commonWebpackConfig {
cssSupport.enabled = true
}}}}
There is a new IR compiler
kotlin gradle dsl
$ ./gradlew tasks –all
…
Kotlin browser tasks
--------------------
browserDevelopmentRun - start development webpack dev server
browserDevelopmentWebpack - build webpack development bundle
browserDistributeResources
browserDistribution
browserProductionRun - start production webpack dev server
browserProductionWebpack - build webpack production bundle
browserRun
browserWebpack
add packages from multiple sources
kotlinjs, multiplatform and npm
dependencies {
testImplementation(kotlin("test-js"))
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("org.jetbrains:kotlin-react:17.0.1-pre.148-kotlin-1.4.30")
implementation("org.jetbrains:kotlin-react-dom:17.0.1-pre.148-kotlin-1.4.30")
implementation("org.jetbrains:kotlin-redux:4.0.5-pre.148-kotlin-1.4.30")
implementation("org.jetbrains:kotlin-react-redux:7.2.2-pre.148-kotlin-1.4.30")
implementation(npm("bootstrap", "4.6.0"))
implementation(npm("jquery", "1.9.1 - 3"))
implementation(npm("popper.js", "^1.16.1"))
implementation(npm("lodash", "^4.7.0"))
}
get down to coding
main
import kotlinx.browser.document
import kotlinx.browser.window
import react.dom.render
import react.router.dom.browserRouter
fun main() {
window.onload = {
render(document.getElementById("root")) {
browserRouter {
// ...
}
}
}
}
get down to coding
easy access to standard browser apis
import kotlinx.browser.document
import kotlinx.browser.window
import react.dom.render
import react.router.dom.browserRouter
fun main() {
window.onload = {
render(document.getElementById("root")) {
browserRouter {
// ...
}
}
}
}
Moved from kotlin.browser to
kotlinx.browser in 1.4
get down to coding
easy access to react library
import kotlinx.browser.document
import kotlinx.browser.window
import react.dom.render
import react.router.dom.browserRouter
fun main() {
window.onload = {
render(document.getElementById("root")) {
browserRouter {
// ...
}
}
}
}
standard library documentation
excellent compatibility docs
standard library documentation
excellent compatibility docs
community
Round
1
its popularity continues to grow
rising star on language rankings
…
18 Kotlin
…
https://redmonk.com/sogrady/2021/03/01
/language-rankings-1-21/
The RedMonk
Programming Language
Rankings: January 2021
its popularity continues to grow
rising star on language rankings
https://insights.stackoverflow.com/survey/2020
Stack Overflow Developer
Survey 2020
Most Used Language
13th Kotlin
1st JavaScript
8th TypeScript
its popularity continues to grow
loved by its users
https://insights.stackoverflow.com/survey/2020
Stack Overflow Developer
Survey 2020
Most Loved Language
2nd TypeScript
4th Kotlin
10th JavaScript
1st Rust
TS is good at retaining adopters
TypeScript in 2020
72.2% would use again
15.5% interested
https://2020.stateofjs.com/en-US/
– TypeScript is more popular than KotlinJS
– As a superset of JS, reusing knowledge and assets is easier
– And the transition for JS developers to TS is easier
– TypeScript is well established in the JavaScript world
– Many libraries include TypeScript definitions
– DefinitelyTyped contains many more
community, maturity and support
typescript > kotlin
interop with javascript
Round
2
– Only a few first class wrappers provided
– It is easy to add NPM packages yourself
– But how easy is it to consume that code in Kotlin?
importing npm js packages
gradle dsl
dependencies {
. . .
implementation(npm("react-three-fiber", "4.2.20"))
implementation(npm("react-use-gesture", "7.0.15"))
implementation(npm("three", "0.119.1"))
}
really easy
external declarations
@file:JsModule("react-three-fiber")
@file:JsNonModule
...
external val Canvas: RClass<RProps>
external fun extend(objects: Any)
external fun useFrame(callback: (dynamic, Double) -> Unit)
external fun useThree(): dynamic
external interface PointerEvent {
val uv: Vector2
}
Specify the NPM package
Define any items you
wish to use
– Converts TypeScript d.ts files to Kotlin external declarations
– Still experimental
– At time of writing, on hold until IR compiler stabilises
dukat
automatic generation
https://kotlinlang.org/docs/js-external-declarations-with-dukat.html
– Command line tool
– Installable in isolation via npm
– Simply point to a .d.ts file and it will do the rest
dukat
usage
$ dukat index.d.ts index.module_my-library.kt
$ npm install dukat
dukat
export function getString(): string;
export function setString(input: string): void;
external fun getString(): String
external fun setString(input: String)
– Integrated into Gradle
– Generates definitions for configured packages
dukat
usage
Dukat tasks
-----------
generateExternals
generateExternalsIntegrated
dukat
export interface BasicInterface {
readonly field1: number;
method1(): boolean;
}
export function buildInterface(): BasicInterface;
export type ReadOnlyBasicInterface = Readonly<BasicInterface>;
external interface BasicInterface {
var field1: Number
fun method1(): Boolean
}
external fun buildInterface(): BasicInterface
typealias ReadOnlyBasicInterface = Readonly<BasicInterface>
– It’s a good help but has issues
– Limited by differences in the languages
– Not a seamless workflow
– This situation may improve as the tool and Kotlin evolves
not a silver bullet
square peg and a round hole
– KotlinJS supports a dynamic type
– You can use it in place of any type
– Assign it a value of any type
– Access and use members with any name
– Basically switches off type checking
– This can be used to quickly patch over APIs
dynamic
get out of jail type
external fun useFrame(callback: (dynamic, Double) -> Unit)
– Object literals are common in JavaScript
– KotlinJS has a helper function to create objects
– This is strongly typed (inferred) but requires fields to be var
jsObject
object literals in kotlinjs
Block(jsObject {
position = brick.location.toVector3()
color = brick.color
})
– We can embed JavaScript directly with the js function
– The code can even use Kotlin variables
– Must be a compile time constant
– Cannot be a runtime evaluated expression
js
embedding javascript
private fun getToken(): String? {
val tokenKey = TokenKey
return js("""
localStorage.getItem(tokenKey)
""")
}
– As a superset, TypeScript has to win this one
– The type system is geared to support JavaScript
– Lots of libraries already provide TypeScript definition files
– However, writing external declaration in KotlinJS is easy
– Dukat exists but has fundamental limitations
– You may have to write custom translation code on top
interop with javascript
typescript > kotlinjs
jsx vs dsl
Round
3
JSX
IN
TYPESCRIPT
export const Hud: FC = () => {
// ...
return (
<div>
<h2>Lives: {lives}</h2>
<h2>Score: {score}</h2>
<div>
<label>Speed:</label>
<input type="range" min={1} max={50} value={speedScalar * 10}
onChange={e => /* ... */}/>
</div>
<div>
<label>Sound Active:</label>
<input type="checkbox" checked={soundActive}
onChange={e => /* ... */}/>
</div>
</div>
);
};
JSX embeds markup
inside JS / TS code
val Hud = FC {
// ...
div {
h2 { +"Lives: $lives" }
h2 { +"Score: $score" }
div {
label { +"Speed:" }
input(type = InputType.range) {
attrs {
min = "1"
max = "50"
value = (speedScalar * 10).toString()
onChangeFunction = {/* ... */}
}}}
div {
label { +"Sound Active:" }
input(type = InputType.checkBox) {
attrs {
checked = soundActive
onChangeFunction = {/* ... */}
}}}}
}
fun RBuilder.Hud() = child(Hud)
REACT
DSL
IN
KOTLIN
In Kotlin a DSL
provides equivalent
functionality
kotlin DSL’s are very cool
a major advantage
REACT
DSL
IN
KOTLIN
inline fun RBuilder.div(
classes: String? = null,
block: RDOMBuilder<DIV>.() -> Unit
): ReactElement
Extension function
Last param is a
lambda with receiver
// Here, “this” is the containing object
div {
// Here, “this” is a RDOMBuilder<DIV>
}
Optional param via default
REACT
DSL
IN
KOTLIN
inline fun RBuilder.div(
classes: String? = null,
block: RDOMBuilder<DIV>.() -> Unit
): ReactElement
// Here, “this” is the containing object
div {
// Here, “this” is a RDOMBuilder<DIV>
}
But some parts are
cumbersome...
val Hud = FC {
// ...
div {
h2 { +"Lives: $lives" }
h2 { +"Score: $score" }
div {
label { +"Speed:" }
input(type = InputType.range) {
attrs {
min = "1“
max = "50"
value = (speedScalar * 10).toString()
onChangeFunction = {/* ... */}
}}}
// ...
}
fun RBuilder.Hud() = child(Hud)
REACT
DSL
IN
KOTLIN
val Hud = FC {
// ...
div {
h2 { +"Lives: $lives" }
h2 { +"Score: $score" }
div {
label { +"Speed:" }
input(type = InputType.range) {
attrs {
min = "1"
max = "50"
value = (speedScalar * 10).toString()
onChangeFunction = {/* ... */}
}}}
// ...
}
fun RBuilder.Hud() = child(Hud)
REACT
DSL
IN
KOTLIN
Single ‘bucket’
for attributes
val Hud = FC {
// ...
div {
h2 { +"Lives: $lives" }
h2 { +"Score: $score" }
div {
label { +"Speed:" }
input(type = InputType.range) {
attrs {
min = "1"
max = "50"
value = (speedScalar * 10).toString()
onChangeFunction = {/* ... */}
}}}
// ...
}
fun RBuilder.Hud() = child(Hud)
REACT
DSL
IN
KOTLIN
Overloaded operators to attach data
val Hud = FC {
// ...
div {
h2 { +"Lives: $lives" }
h2 { +"Score: $score" }
div {
label { +"Speed:" }
input(type = InputType.range) {
attrs {
min = "1"
max = "50"
value = (speedScalar * 10).toString()
onChangeFunction = {/* ... */}
}}}
// ...
}
fun RBuilder.Hud() = child(Hud)
REACT
DSL
IN
KOTLIN
Additional extension
function required
val Hud = FC {
// ...
div {
h2 { +"Lives: $lives" }
h2 { +"Score: $score" }
div {
label { +"Speed:" }
input(type = InputType.range) {
attrs {
min = "1"
max = "50"
value = (speedScalar * 10).toString()
onChangeFunction = {/* ... */}
}}}
// ...
}
fun RBuilder.Hud() = child(Hud)
REACT
DSL
IN
KOTLIN
Attributes must be
given as strings*
interface InputHTMLAttributes<T> extends HTMLAttributes<T> {
max?: number | string;
min?: number | string;
value?: string | ReadonlyArray<string> | number;
...
}
Type union
type PropsWithChildren<P> = P & { children?: ReactNode };
Type intersection
// Type exports erased!
external fun interfaceUnionInput(input: First)
external fun interfaceUnionInput(input: Second)
external fun interfaceUnionOutput(): dynamic /* First | Second */
export type InterfaceUnion = First | Second;
export function interfaceUnionInput(input: InterfaceUnion): void;
export function interfaceUnionOutput(): InterfaceUnion;
Kotlin supports
proper overloads
Not supported on
the return type
external fun interfaceIntersectionInput(input: First /* First & Second */)
external fun interfaceIntersectionOutput(): First /* First & Second */
export type InterfaceIntersection = First & Second;
export function interfaceIntersectionInput(input: InterfaceIntersection): void;
export function interfaceIntersectionOutput(): InterfaceIntersection;
Intersection
dropped
mapped and conditional types
even more power in typescript
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
type PromiseType<T extends Promise<any>> =
T extends Promise<infer U> ? U : never;
Type conditional
The languages are simply not
fully compatible
manual workarounds
useEffect
function useEffect(
effect: EffectCallback,
deps?: DependencyList
): void;
type EffectCallback = () => (void | Destructor);
type Destructor = () => void;
useEffect
union return workaround
fun useEffect(
dependencies: RDependenciesList? = null,
effect: () -> Unit
) {
// ...
}
fun useEffectWithCleanup(
dependencies: RDependenciesList? = null,
effect: () -> Rcleanup
) {
// ...
}
– Kotlin’s DSL support is a powerful general purpose tool
– But JSX is a single purpose solution that suits React better
– TypeScript’s advanced type system is very powerful
– Union, intersection and mapped types bring sanity to JS
– Kotlin types (unsurprisingly) sit awkwardly on top of JS
jsx vs dsl
typescript > kotlin
async await vs coroutines
Round
4
asynchronous programming
– Async await is a good async solution in JS & TS
– Engineered so it interops with Promises
– Succinct
promises and async/await
async function loadMap(url: string): Promise<void> {
const response = await fetch(url);
const map = await response.text();
// ...
}
coroutines
– Kotlin’s more general coroutines are better
– Works with other patterns than simply async
– In KotlinJS, it works easily with Promises
kotlin > typescript
suspend fun loadMap(url: String) {
val response = window.fetch(url).await()
val map = response.text().await()
// ...
}
coroutines
– Coroutines are more general and powerful
– They can be used with other patterns too
– With suspend functions we don’t need to “await”
kotlin > typescript
suspend fun loadMap(url: String) {
val map = client.get<String>(url)
// ...
}
Ktor Client
coroutines
– Coroutines can be applied to other patterns too
kotlin > typescript
fun infinite() = sequence {
var count = 0
while (true) {
yield(count++)
}
}
elegant syntax
Round
5
– Kotlin doesn’t have the ternary, but has more
– when for basic pattern matching
– if and when are expressions
– Unit instead of void
– Expression bodied functions
– This creates more symmetry in code
expressions
kotlin > typescript
typescript
chained ternaries
const App: FC = () => {
// ...
return (
<div>
// ...
{gameState === GameState.Start ? <StartScreen/> :
gameState === GameState.Playing ? <PlayingGame/> :
gameState === GameState.Dead ? <DeathScreen/> :
gameState === GameState.Win ? <WinScreen/> :
null}
</div>
);
};
kotlin
when expression
val App = FC {
// ...
div {
// ...
when (gameState) {
GameState.Start -> StartScreen()
GameState.Playing -> PlayingScreen()
GameState.Win -> WinScreen()
GameState.Dead -> EndScreen()
}
}
}
– Both languages support object destructuring
– Within blocks and in lambda parameters
– However, Kotlin’s is limited
– Supported via componentN methods
– Fixed order to properties extracted
– Data classes do this automatically
destructuring
typescript > kotlin
const {value, color} = brick;
const {value, location} = brick;
Arbitrary properties extracted
export const Brick: FC<Props> = ({index}) => {
}
Destructuring on parameters
const [first, ...remaining] = bricks;
Array destructuring
conclusion
they’re both very good
but in different ways
Community
Coroutines
JSX vs React DSL
Multiplatform
Advanced Type System
Extensions
Interop with JS
Expressions
Destructuring
Standard Library
Tooling
Functions
game changers
– Union Types with ‘|’ syntax
– Improvements to Sealed Types
– Extended Operator Overloading
– Name based Destructuring
– Collection Literals
– Structure Literals (Tuples?)
game changer 1
potential new language features
– Brings Google’s UI Toolkit to web
– In theory, enables reuse of UI code across stack
game changer 2
compose for web
https://compose-web.ui.pages.jetbrains.team/
Div(attrs = attrs) {
Label {
Input(
type = InputType.Checkbox,
attrs = {}
)
Span {
content()
}}}
Questions?

More Related Content

Similar to A TypeScript Fans KotlinJS Adventures

Cross Platform App Development with C++
Cross Platform App Development with C++Cross Platform App Development with C++
Cross Platform App Development with C++
Joan Puig Sanz
 
Kotlin: Why Do You Care?
Kotlin: Why Do You Care?Kotlin: Why Do You Care?
Kotlin: Why Do You Care?
intelliyole
 
Kotlin wonderland
Kotlin wonderlandKotlin wonderland
Kotlin wonderland
Jedsada Tiwongvokul
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVM
Sylvain Wallez
 
MattsonTutorialSC14.pptx
MattsonTutorialSC14.pptxMattsonTutorialSC14.pptx
MattsonTutorialSC14.pptx
gopikahari7
 
Rapid Web API development with Kotlin and Ktor
Rapid Web API development with Kotlin and KtorRapid Web API development with Kotlin and Ktor
Rapid Web API development with Kotlin and Ktor
Trayan Iliev
 
Jenkins Pipelines
Jenkins PipelinesJenkins Pipelines
Jenkins Pipelines
Steffen Gebert
 
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem novaKotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Víctor Leonel Orozco López
 
«Продакшн в Kotlin DSL» Сергей Рыбалкин
«Продакшн в Kotlin DSL» Сергей Рыбалкин«Продакшн в Kotlin DSL» Сергей Рыбалкин
«Продакшн в Kotlin DSL» Сергей Рыбалкин
Mail.ru Group
 
MattsonTutorialSC14.pdf
MattsonTutorialSC14.pdfMattsonTutorialSC14.pdf
MattsonTutorialSC14.pdf
George Papaioannou
 
Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36
Halil Kaya
 
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Tudor Dragan
 
An Ensemble Core with Docker - Solving a Real Pain in the PaaS
An Ensemble Core with Docker - Solving a Real Pain in the PaaS An Ensemble Core with Docker - Solving a Real Pain in the PaaS
An Ensemble Core with Docker - Solving a Real Pain in the PaaS
Erik Osterman
 
Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010
Chris Ramsdale
 
Angular 2 for Java Developers
Angular 2 for Java DevelopersAngular 2 for Java Developers
Angular 2 for Java Developers
Yakov Fain
 
Code quality par Simone Civetta
Code quality par Simone CivettaCode quality par Simone Civetta
Code quality par Simone Civetta
CocoaHeads France
 
Continuous Integration With Jenkins Docker SQL Server
Continuous Integration With Jenkins Docker SQL ServerContinuous Integration With Jenkins Docker SQL Server
Continuous Integration With Jenkins Docker SQL Server
Chris Adkin
 
NodeJS for Beginner
NodeJS for BeginnerNodeJS for Beginner
NodeJS for Beginner
Apaichon Punopas
 
Kotlin The Whole Damn Family
Kotlin The Whole Damn FamilyKotlin The Whole Damn Family
Kotlin The Whole Damn Family
Garth Gilmour
 
Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!
Roberto Franchini
 

Similar to A TypeScript Fans KotlinJS Adventures (20)

Cross Platform App Development with C++
Cross Platform App Development with C++Cross Platform App Development with C++
Cross Platform App Development with C++
 
Kotlin: Why Do You Care?
Kotlin: Why Do You Care?Kotlin: Why Do You Care?
Kotlin: Why Do You Care?
 
Kotlin wonderland
Kotlin wonderlandKotlin wonderland
Kotlin wonderland
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVM
 
MattsonTutorialSC14.pptx
MattsonTutorialSC14.pptxMattsonTutorialSC14.pptx
MattsonTutorialSC14.pptx
 
Rapid Web API development with Kotlin and Ktor
Rapid Web API development with Kotlin and KtorRapid Web API development with Kotlin and Ktor
Rapid Web API development with Kotlin and Ktor
 
Jenkins Pipelines
Jenkins PipelinesJenkins Pipelines
Jenkins Pipelines
 
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem novaKotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
 
«Продакшн в Kotlin DSL» Сергей Рыбалкин
«Продакшн в Kotlin DSL» Сергей Рыбалкин«Продакшн в Kotlin DSL» Сергей Рыбалкин
«Продакшн в Kotlin DSL» Сергей Рыбалкин
 
MattsonTutorialSC14.pdf
MattsonTutorialSC14.pdfMattsonTutorialSC14.pdf
MattsonTutorialSC14.pdf
 
Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36
 
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
 
An Ensemble Core with Docker - Solving a Real Pain in the PaaS
An Ensemble Core with Docker - Solving a Real Pain in the PaaS An Ensemble Core with Docker - Solving a Real Pain in the PaaS
An Ensemble Core with Docker - Solving a Real Pain in the PaaS
 
Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010
 
Angular 2 for Java Developers
Angular 2 for Java DevelopersAngular 2 for Java Developers
Angular 2 for Java Developers
 
Code quality par Simone Civetta
Code quality par Simone CivettaCode quality par Simone Civetta
Code quality par Simone Civetta
 
Continuous Integration With Jenkins Docker SQL Server
Continuous Integration With Jenkins Docker SQL ServerContinuous Integration With Jenkins Docker SQL Server
Continuous Integration With Jenkins Docker SQL Server
 
NodeJS for Beginner
NodeJS for BeginnerNodeJS for Beginner
NodeJS for Beginner
 
Kotlin The Whole Damn Family
Kotlin The Whole Damn FamilyKotlin The Whole Damn Family
Kotlin The Whole Damn Family
 
Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!
 

More from Garth Gilmour

Compose in Theory
Compose in TheoryCompose in Theory
Compose in Theory
Garth Gilmour
 
Shut Up And Eat Your Veg
Shut Up And Eat Your VegShut Up And Eat Your Veg
Shut Up And Eat Your Veg
Garth Gilmour
 
Lies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerLies Told By The Kotlin Compiler
Lies Told By The Kotlin Compiler
Garth Gilmour
 
The Heat Death Of Enterprise IT
The Heat Death Of Enterprise ITThe Heat Death Of Enterprise IT
The Heat Death Of Enterprise IT
Garth Gilmour
 
Lies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerLies Told By The Kotlin Compiler
Lies Told By The Kotlin Compiler
Garth Gilmour
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScript
Garth Gilmour
 
Generics On The JVM (What you don't know will hurt you)
Generics On The JVM (What you don't know will hurt you)Generics On The JVM (What you don't know will hurt you)
Generics On The JVM (What you don't know will hurt you)
Garth Gilmour
 
Using Kotlin, to Create Kotlin, to Teach Kotlin, in Space
Using Kotlin, to Create Kotlin,to Teach Kotlin,in SpaceUsing Kotlin, to Create Kotlin,to Teach Kotlin,in Space
Using Kotlin, to Create Kotlin, to Teach Kotlin, in Space
Garth Gilmour
 
Is Software Engineering A Profession?
Is Software Engineering A Profession?Is Software Engineering A Profession?
Is Software Engineering A Profession?
Garth Gilmour
 
Social Distancing is not Behaving Distantly
Social Distancing is not Behaving DistantlySocial Distancing is not Behaving Distantly
Social Distancing is not Behaving Distantly
Garth Gilmour
 
The Great Scala Makeover
The Great Scala MakeoverThe Great Scala Makeover
The Great Scala Makeover
Garth Gilmour
 
Transitioning Android Teams Into Kotlin
Transitioning Android Teams Into KotlinTransitioning Android Teams Into Kotlin
Transitioning Android Teams Into Kotlin
Garth Gilmour
 
Simpler and Safer Java Types (via the Vavr and Lambda Libraries)
Simpler and Safer Java Types (via the Vavr and Lambda Libraries)Simpler and Safer Java Types (via the Vavr and Lambda Libraries)
Simpler and Safer Java Types (via the Vavr and Lambda Libraries)
Garth Gilmour
 
The Three Horse Race
The Three Horse RaceThe Three Horse Race
The Three Horse Race
Garth Gilmour
 
The Bestiary of Pure Functional Programming
The Bestiary of Pure Functional Programming The Bestiary of Pure Functional Programming
The Bestiary of Pure Functional Programming
Garth Gilmour
 
BelTech 2019 Presenters Workshop
BelTech 2019 Presenters WorkshopBelTech 2019 Presenters Workshop
BelTech 2019 Presenters Workshop
Garth Gilmour
 
The Philosophy of DDD
The Philosophy of DDDThe Philosophy of DDD
The Philosophy of DDD
Garth Gilmour
 
10 Big Ideas from Industry
10 Big Ideas from Industry10 Big Ideas from Industry
10 Big Ideas from Industry
Garth Gilmour
 
'Full Stack Kotlin' Workshop at KotlinConf
'Full Stack Kotlin' Workshop at KotlinConf'Full Stack Kotlin' Workshop at KotlinConf
'Full Stack Kotlin' Workshop at KotlinConf
Garth Gilmour
 
FFS The Browser and Everything In It Is Wrong - We've Ruined Software Enginee...
FFS The Browser and Everything In It Is Wrong - We've Ruined Software Enginee...FFS The Browser and Everything In It Is Wrong - We've Ruined Software Enginee...
FFS The Browser and Everything In It Is Wrong - We've Ruined Software Enginee...
Garth Gilmour
 

More from Garth Gilmour (20)

Compose in Theory
Compose in TheoryCompose in Theory
Compose in Theory
 
Shut Up And Eat Your Veg
Shut Up And Eat Your VegShut Up And Eat Your Veg
Shut Up And Eat Your Veg
 
Lies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerLies Told By The Kotlin Compiler
Lies Told By The Kotlin Compiler
 
The Heat Death Of Enterprise IT
The Heat Death Of Enterprise ITThe Heat Death Of Enterprise IT
The Heat Death Of Enterprise IT
 
Lies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerLies Told By The Kotlin Compiler
Lies Told By The Kotlin Compiler
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScript
 
Generics On The JVM (What you don't know will hurt you)
Generics On The JVM (What you don't know will hurt you)Generics On The JVM (What you don't know will hurt you)
Generics On The JVM (What you don't know will hurt you)
 
Using Kotlin, to Create Kotlin, to Teach Kotlin, in Space
Using Kotlin, to Create Kotlin,to Teach Kotlin,in SpaceUsing Kotlin, to Create Kotlin,to Teach Kotlin,in Space
Using Kotlin, to Create Kotlin, to Teach Kotlin, in Space
 
Is Software Engineering A Profession?
Is Software Engineering A Profession?Is Software Engineering A Profession?
Is Software Engineering A Profession?
 
Social Distancing is not Behaving Distantly
Social Distancing is not Behaving DistantlySocial Distancing is not Behaving Distantly
Social Distancing is not Behaving Distantly
 
The Great Scala Makeover
The Great Scala MakeoverThe Great Scala Makeover
The Great Scala Makeover
 
Transitioning Android Teams Into Kotlin
Transitioning Android Teams Into KotlinTransitioning Android Teams Into Kotlin
Transitioning Android Teams Into Kotlin
 
Simpler and Safer Java Types (via the Vavr and Lambda Libraries)
Simpler and Safer Java Types (via the Vavr and Lambda Libraries)Simpler and Safer Java Types (via the Vavr and Lambda Libraries)
Simpler and Safer Java Types (via the Vavr and Lambda Libraries)
 
The Three Horse Race
The Three Horse RaceThe Three Horse Race
The Three Horse Race
 
The Bestiary of Pure Functional Programming
The Bestiary of Pure Functional Programming The Bestiary of Pure Functional Programming
The Bestiary of Pure Functional Programming
 
BelTech 2019 Presenters Workshop
BelTech 2019 Presenters WorkshopBelTech 2019 Presenters Workshop
BelTech 2019 Presenters Workshop
 
The Philosophy of DDD
The Philosophy of DDDThe Philosophy of DDD
The Philosophy of DDD
 
10 Big Ideas from Industry
10 Big Ideas from Industry10 Big Ideas from Industry
10 Big Ideas from Industry
 
'Full Stack Kotlin' Workshop at KotlinConf
'Full Stack Kotlin' Workshop at KotlinConf'Full Stack Kotlin' Workshop at KotlinConf
'Full Stack Kotlin' Workshop at KotlinConf
 
FFS The Browser and Everything In It Is Wrong - We've Ruined Software Enginee...
FFS The Browser and Everything In It Is Wrong - We've Ruined Software Enginee...FFS The Browser and Everything In It Is Wrong - We've Ruined Software Enginee...
FFS The Browser and Everything In It Is Wrong - We've Ruined Software Enginee...
 

Recently uploaded

Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
ToXSL Technologies
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
Yara Milbes
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
Quickdice ERP
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative AnalysisOdoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Envertis Software Solutions
 
Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
Ayan Halder
 
Lecture 2 - software testing SE 412.pptx
Lecture 2 - software testing SE 412.pptxLecture 2 - software testing SE 412.pptx
Lecture 2 - software testing SE 412.pptx
TaghreedAltamimi
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
XfilesPro
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
Green Software Development
 

Recently uploaded (20)

Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative AnalysisOdoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
 
Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
 
Lecture 2 - software testing SE 412.pptx
Lecture 2 - software testing SE 412.pptxLecture 2 - software testing SE 412.pptx
Lecture 2 - software testing SE 412.pptx
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
 

A TypeScript Fans KotlinJS Adventures

  • 1. © Instil Software 2020 A TYPESCRIPT FAN'S KOTLINJS ADVENTURES should you make the switch?
  • 3. – TS brings types and compilation to JS – Improves upon the existing strengths of JS – Makes us more productive and happy – Leverages existing JS frameworks – Interop with JS is a design goal we love typescript it solves real problems for us
  • 4. – Kotlin improves upon Java in many ways – Adds null safety, DSLs, coroutines etc... – Makes us more productive and happy – Leverages existing JVM frameworks – But interop with Java is a design goal we love kotlin it solves real problems for us
  • 5.
  • 8. experiment: is kotlinjs worth it? – Build an app in both TypeScript and KotlinJS – Go beyond “hello world” – Incorporate common JS libraries – Compare the experience – Tooling – Language features – Community what problem does it solve?
  • 11. – React – https://reactjs.org – Redux – https://redux.js.org – React-Three-Fiber – https://github.com/react-spring/react-three-fiber frameworks we used
  • 12. declarative UI state separation const geometry = new THREE.BoxGeometry(BAT_WIDTH, 1, 1); export const Bat: FC = () => { const position = useSelector((state: State) => state.batPosition); return ( <mesh position={[position, 0, BAT_Z]} geometry={geometry}> {woodMaterial} </mesh> ); };
  • 14. – Template project from IntelliJ – Grade project using Kotlin DSL – Easily integrate NPM packages creating new project the wizard
  • 16. multiplatform libraries COMMON KOTLIN KOTLIN ANDROID KOTLIN JS KOTLIN NATIVE KOTLIN JVM NATIVE ARTEFACT JS BUNDLE JAR
  • 17. kotlin js plugin plugins { kotlin("js") version "1.5.0" } // ... kotlin { js(LEGACY) { binaries.executable() browser { commonWebpackConfig { cssSupport.enabled = true }}}} There is a new IR compiler
  • 18. kotlin gradle dsl $ ./gradlew tasks –all … Kotlin browser tasks -------------------- browserDevelopmentRun - start development webpack dev server browserDevelopmentWebpack - build webpack development bundle browserDistributeResources browserDistribution browserProductionRun - start production webpack dev server browserProductionWebpack - build webpack production bundle browserRun browserWebpack
  • 19. add packages from multiple sources kotlinjs, multiplatform and npm dependencies { testImplementation(kotlin("test-js")) implementation("io.ktor:ktor-client-core:$ktorVersion") implementation("org.jetbrains:kotlin-react:17.0.1-pre.148-kotlin-1.4.30") implementation("org.jetbrains:kotlin-react-dom:17.0.1-pre.148-kotlin-1.4.30") implementation("org.jetbrains:kotlin-redux:4.0.5-pre.148-kotlin-1.4.30") implementation("org.jetbrains:kotlin-react-redux:7.2.2-pre.148-kotlin-1.4.30") implementation(npm("bootstrap", "4.6.0")) implementation(npm("jquery", "1.9.1 - 3")) implementation(npm("popper.js", "^1.16.1")) implementation(npm("lodash", "^4.7.0")) }
  • 20. get down to coding main import kotlinx.browser.document import kotlinx.browser.window import react.dom.render import react.router.dom.browserRouter fun main() { window.onload = { render(document.getElementById("root")) { browserRouter { // ... } } } }
  • 21. get down to coding easy access to standard browser apis import kotlinx.browser.document import kotlinx.browser.window import react.dom.render import react.router.dom.browserRouter fun main() { window.onload = { render(document.getElementById("root")) { browserRouter { // ... } } } } Moved from kotlin.browser to kotlinx.browser in 1.4
  • 22. get down to coding easy access to react library import kotlinx.browser.document import kotlinx.browser.window import react.dom.render import react.router.dom.browserRouter fun main() { window.onload = { render(document.getElementById("root")) { browserRouter { // ... } } } }
  • 26. its popularity continues to grow rising star on language rankings … 18 Kotlin … https://redmonk.com/sogrady/2021/03/01 /language-rankings-1-21/ The RedMonk Programming Language Rankings: January 2021
  • 27. its popularity continues to grow rising star on language rankings https://insights.stackoverflow.com/survey/2020 Stack Overflow Developer Survey 2020 Most Used Language 13th Kotlin 1st JavaScript 8th TypeScript
  • 28. its popularity continues to grow loved by its users https://insights.stackoverflow.com/survey/2020 Stack Overflow Developer Survey 2020 Most Loved Language 2nd TypeScript 4th Kotlin 10th JavaScript 1st Rust
  • 29. TS is good at retaining adopters TypeScript in 2020 72.2% would use again 15.5% interested https://2020.stateofjs.com/en-US/
  • 30. – TypeScript is more popular than KotlinJS – As a superset of JS, reusing knowledge and assets is easier – And the transition for JS developers to TS is easier – TypeScript is well established in the JavaScript world – Many libraries include TypeScript definitions – DefinitelyTyped contains many more community, maturity and support typescript > kotlin
  • 32. – Only a few first class wrappers provided – It is easy to add NPM packages yourself – But how easy is it to consume that code in Kotlin? importing npm js packages gradle dsl dependencies { . . . implementation(npm("react-three-fiber", "4.2.20")) implementation(npm("react-use-gesture", "7.0.15")) implementation(npm("three", "0.119.1")) }
  • 33. really easy external declarations @file:JsModule("react-three-fiber") @file:JsNonModule ... external val Canvas: RClass<RProps> external fun extend(objects: Any) external fun useFrame(callback: (dynamic, Double) -> Unit) external fun useThree(): dynamic external interface PointerEvent { val uv: Vector2 } Specify the NPM package Define any items you wish to use
  • 34. – Converts TypeScript d.ts files to Kotlin external declarations – Still experimental – At time of writing, on hold until IR compiler stabilises dukat automatic generation https://kotlinlang.org/docs/js-external-declarations-with-dukat.html
  • 35. – Command line tool – Installable in isolation via npm – Simply point to a .d.ts file and it will do the rest dukat usage $ dukat index.d.ts index.module_my-library.kt $ npm install dukat
  • 36. dukat export function getString(): string; export function setString(input: string): void; external fun getString(): String external fun setString(input: String)
  • 37. – Integrated into Gradle – Generates definitions for configured packages dukat usage Dukat tasks ----------- generateExternals generateExternalsIntegrated
  • 38. dukat export interface BasicInterface { readonly field1: number; method1(): boolean; } export function buildInterface(): BasicInterface; export type ReadOnlyBasicInterface = Readonly<BasicInterface>; external interface BasicInterface { var field1: Number fun method1(): Boolean } external fun buildInterface(): BasicInterface typealias ReadOnlyBasicInterface = Readonly<BasicInterface>
  • 39. – It’s a good help but has issues – Limited by differences in the languages – Not a seamless workflow – This situation may improve as the tool and Kotlin evolves not a silver bullet square peg and a round hole
  • 40. – KotlinJS supports a dynamic type – You can use it in place of any type – Assign it a value of any type – Access and use members with any name – Basically switches off type checking – This can be used to quickly patch over APIs dynamic get out of jail type external fun useFrame(callback: (dynamic, Double) -> Unit)
  • 41. – Object literals are common in JavaScript – KotlinJS has a helper function to create objects – This is strongly typed (inferred) but requires fields to be var jsObject object literals in kotlinjs Block(jsObject { position = brick.location.toVector3() color = brick.color })
  • 42. – We can embed JavaScript directly with the js function – The code can even use Kotlin variables – Must be a compile time constant – Cannot be a runtime evaluated expression js embedding javascript private fun getToken(): String? { val tokenKey = TokenKey return js(""" localStorage.getItem(tokenKey) """) }
  • 43. – As a superset, TypeScript has to win this one – The type system is geared to support JavaScript – Lots of libraries already provide TypeScript definition files – However, writing external declaration in KotlinJS is easy – Dukat exists but has fundamental limitations – You may have to write custom translation code on top interop with javascript typescript > kotlinjs
  • 45. JSX IN TYPESCRIPT export const Hud: FC = () => { // ... return ( <div> <h2>Lives: {lives}</h2> <h2>Score: {score}</h2> <div> <label>Speed:</label> <input type="range" min={1} max={50} value={speedScalar * 10} onChange={e => /* ... */}/> </div> <div> <label>Sound Active:</label> <input type="checkbox" checked={soundActive} onChange={e => /* ... */}/> </div> </div> ); }; JSX embeds markup inside JS / TS code
  • 46. val Hud = FC { // ... div { h2 { +"Lives: $lives" } h2 { +"Score: $score" } div { label { +"Speed:" } input(type = InputType.range) { attrs { min = "1" max = "50" value = (speedScalar * 10).toString() onChangeFunction = {/* ... */} }}} div { label { +"Sound Active:" } input(type = InputType.checkBox) { attrs { checked = soundActive onChangeFunction = {/* ... */} }}}} } fun RBuilder.Hud() = child(Hud) REACT DSL IN KOTLIN In Kotlin a DSL provides equivalent functionality
  • 47. kotlin DSL’s are very cool a major advantage
  • 48. REACT DSL IN KOTLIN inline fun RBuilder.div( classes: String? = null, block: RDOMBuilder<DIV>.() -> Unit ): ReactElement Extension function Last param is a lambda with receiver // Here, “this” is the containing object div { // Here, “this” is a RDOMBuilder<DIV> } Optional param via default
  • 49. REACT DSL IN KOTLIN inline fun RBuilder.div( classes: String? = null, block: RDOMBuilder<DIV>.() -> Unit ): ReactElement // Here, “this” is the containing object div { // Here, “this” is a RDOMBuilder<DIV> }
  • 50. But some parts are cumbersome...
  • 51. val Hud = FC { // ... div { h2 { +"Lives: $lives" } h2 { +"Score: $score" } div { label { +"Speed:" } input(type = InputType.range) { attrs { min = "1“ max = "50" value = (speedScalar * 10).toString() onChangeFunction = {/* ... */} }}} // ... } fun RBuilder.Hud() = child(Hud) REACT DSL IN KOTLIN
  • 52. val Hud = FC { // ... div { h2 { +"Lives: $lives" } h2 { +"Score: $score" } div { label { +"Speed:" } input(type = InputType.range) { attrs { min = "1" max = "50" value = (speedScalar * 10).toString() onChangeFunction = {/* ... */} }}} // ... } fun RBuilder.Hud() = child(Hud) REACT DSL IN KOTLIN Single ‘bucket’ for attributes
  • 53. val Hud = FC { // ... div { h2 { +"Lives: $lives" } h2 { +"Score: $score" } div { label { +"Speed:" } input(type = InputType.range) { attrs { min = "1" max = "50" value = (speedScalar * 10).toString() onChangeFunction = {/* ... */} }}} // ... } fun RBuilder.Hud() = child(Hud) REACT DSL IN KOTLIN Overloaded operators to attach data
  • 54. val Hud = FC { // ... div { h2 { +"Lives: $lives" } h2 { +"Score: $score" } div { label { +"Speed:" } input(type = InputType.range) { attrs { min = "1" max = "50" value = (speedScalar * 10).toString() onChangeFunction = {/* ... */} }}} // ... } fun RBuilder.Hud() = child(Hud) REACT DSL IN KOTLIN Additional extension function required
  • 55. val Hud = FC { // ... div { h2 { +"Lives: $lives" } h2 { +"Score: $score" } div { label { +"Speed:" } input(type = InputType.range) { attrs { min = "1" max = "50" value = (speedScalar * 10).toString() onChangeFunction = {/* ... */} }}} // ... } fun RBuilder.Hud() = child(Hud) REACT DSL IN KOTLIN Attributes must be given as strings*
  • 56. interface InputHTMLAttributes<T> extends HTMLAttributes<T> { max?: number | string; min?: number | string; value?: string | ReadonlyArray<string> | number; ... } Type union type PropsWithChildren<P> = P & { children?: ReactNode }; Type intersection
  • 57. // Type exports erased! external fun interfaceUnionInput(input: First) external fun interfaceUnionInput(input: Second) external fun interfaceUnionOutput(): dynamic /* First | Second */ export type InterfaceUnion = First | Second; export function interfaceUnionInput(input: InterfaceUnion): void; export function interfaceUnionOutput(): InterfaceUnion; Kotlin supports proper overloads Not supported on the return type
  • 58. external fun interfaceIntersectionInput(input: First /* First & Second */) external fun interfaceIntersectionOutput(): First /* First & Second */ export type InterfaceIntersection = First & Second; export function interfaceIntersectionInput(input: InterfaceIntersection): void; export function interfaceIntersectionOutput(): InterfaceIntersection; Intersection dropped
  • 59. mapped and conditional types even more power in typescript type Readonly<T> = { readonly [P in keyof T]: T[P]; }; type PromiseType<T extends Promise<any>> = T extends Promise<infer U> ? U : never; Type conditional
  • 60. The languages are simply not fully compatible
  • 61. manual workarounds useEffect function useEffect( effect: EffectCallback, deps?: DependencyList ): void; type EffectCallback = () => (void | Destructor); type Destructor = () => void;
  • 62. useEffect union return workaround fun useEffect( dependencies: RDependenciesList? = null, effect: () -> Unit ) { // ... } fun useEffectWithCleanup( dependencies: RDependenciesList? = null, effect: () -> Rcleanup ) { // ... }
  • 63. – Kotlin’s DSL support is a powerful general purpose tool – But JSX is a single purpose solution that suits React better – TypeScript’s advanced type system is very powerful – Union, intersection and mapped types bring sanity to JS – Kotlin types (unsurprisingly) sit awkwardly on top of JS jsx vs dsl typescript > kotlin
  • 64. async await vs coroutines Round 4
  • 65. asynchronous programming – Async await is a good async solution in JS & TS – Engineered so it interops with Promises – Succinct promises and async/await async function loadMap(url: string): Promise<void> { const response = await fetch(url); const map = await response.text(); // ... }
  • 66. coroutines – Kotlin’s more general coroutines are better – Works with other patterns than simply async – In KotlinJS, it works easily with Promises kotlin > typescript suspend fun loadMap(url: String) { val response = window.fetch(url).await() val map = response.text().await() // ... }
  • 67. coroutines – Coroutines are more general and powerful – They can be used with other patterns too – With suspend functions we don’t need to “await” kotlin > typescript suspend fun loadMap(url: String) { val map = client.get<String>(url) // ... } Ktor Client
  • 68. coroutines – Coroutines can be applied to other patterns too kotlin > typescript fun infinite() = sequence { var count = 0 while (true) { yield(count++) } }
  • 70. – Kotlin doesn’t have the ternary, but has more – when for basic pattern matching – if and when are expressions – Unit instead of void – Expression bodied functions – This creates more symmetry in code expressions kotlin > typescript
  • 71. typescript chained ternaries const App: FC = () => { // ... return ( <div> // ... {gameState === GameState.Start ? <StartScreen/> : gameState === GameState.Playing ? <PlayingGame/> : gameState === GameState.Dead ? <DeathScreen/> : gameState === GameState.Win ? <WinScreen/> : null} </div> ); };
  • 72. kotlin when expression val App = FC { // ... div { // ... when (gameState) { GameState.Start -> StartScreen() GameState.Playing -> PlayingScreen() GameState.Win -> WinScreen() GameState.Dead -> EndScreen() } } }
  • 73. – Both languages support object destructuring – Within blocks and in lambda parameters – However, Kotlin’s is limited – Supported via componentN methods – Fixed order to properties extracted – Data classes do this automatically destructuring typescript > kotlin
  • 74. const {value, color} = brick; const {value, location} = brick; Arbitrary properties extracted export const Brick: FC<Props> = ({index}) => { } Destructuring on parameters const [first, ...remaining] = bricks; Array destructuring
  • 76. they’re both very good but in different ways
  • 77. Community Coroutines JSX vs React DSL Multiplatform Advanced Type System Extensions Interop with JS Expressions Destructuring Standard Library Tooling Functions
  • 79. – Union Types with ‘|’ syntax – Improvements to Sealed Types – Extended Operator Overloading – Name based Destructuring – Collection Literals – Structure Literals (Tuples?) game changer 1 potential new language features
  • 80. – Brings Google’s UI Toolkit to web – In theory, enables reuse of UI code across stack game changer 2 compose for web https://compose-web.ui.pages.jetbrains.team/ Div(attrs = attrs) { Label { Input( type = InputType.Checkbox, attrs = {} ) Span { content() }}}

Editor's Notes

  1. Lots to love in JavaScript – ubiquitous, popularity/community, succinct syntax, object literals, destructuring But it’s dynamic typing. I’m a fan of static typing
  2. Lots to love in JavaScript – ubiquitous, popularity/community, succinct syntax, object literals, destructuring But it’s dynamic typing. I’m a fan of static typing
  3. Maybe give demo at this point
  4. Maybe give demo at this point
  5. Emphasize how good it is you can start writing code
  6. Emphasize how good it is you can start writing code
  7. Emphasize how good it is you can start writing code
  8. Ask the question – top spot?
  9. Ask the question – top spot?
  10. TypeScript is more capable when it comes to type programming Not easy to integrate customisations (which are common) If kotlin evolves to support more TS features, less customisation will be necessary
  11. More libraries may come out
  12. We can trim it down but grouping closing braces We could also group params but So first off, THIS IS PRETTY COOL that we can do this
  13. Of course we can use this to create DSLs for anything Lots out there
  14. Of course we can use this to create DSLs for anything Lots out there
  15. Cumberbatch for cumbersome
  16. Cumberbatch for cumbersome
  17. Cumberbatch for cumbersome
  18. Cumberbatch for cumbersome
  19. Cumberbatch for cumbersome
  20. Union done as overloads – good! Output simply dynamic - bad
  21. It’s not to say you can achieve the desired behaviour