SlideShare a Scribd company logo
© Instil Software 2020
Kotlin / Android Update
Belfast Google Dev Group
I/O Extended 2022
– The K2 compiler previewed in 1.7
– Why you should care about it
– Looking inside the black box
– The concept of ‘lowering’
– Quick note on Android
– Other game changers
agenda
what’s new in Kotlin 1.7
@GarthGilmour
https://instil.co
1
What’s New?
– The interop story is so good
– Call into legacy Java code easily
– Call into JavaScript easily
– Call in C and Swift easily
– Really concise, yet clear syntax
– Less is more
– “Borrows” the best bits
– Less baggage
why kotlin?
so much to like
Null Safety
String Templates
Default parameters
Extensions
Free Functions
Coroutines
Single Expression Functions
Reified generics
Data classes and Properties
Type Inference
Smart Casts
Operator overloading
This is what we want Kotlin to become in the
future. The universal solution for every
platform.
ANDREY
BRESLAV
Former Lead Language Designer of Kotlin, JetBrains
JVM
Java
Bytecode
Kotlin
(JVM)
Kotlin
(JS)
Browser
JavaScript
Interpreter
Kotlin
(Native)
Machine Code
& Runtime
OS
Kotlin
(Android)
ART
Dalvik
Bytecode
the pre 1.7 approach
no unified back end
Front
End
Abstract Syntax
Tree (AST)
1101011111
001010110
101010110
Semantic Info
JVM
Back End
JS
Back End
Native
Back End
the 1.7 approach
unified back end
Back Ends
Front
End
Front IR
JVM Specific
JS Specific
LVVM Specific
Shared
IR
“Compiler internals do not concern me Garth”
the 1.7 approach
– Consistency across different platforms
– Faster adoption of language features
– A universal API for compiler plugins
– Richer and more reliable tooling
– Improvements in compile times
benefits for developers
MyClass.kt
(original)
MyClass.kt
(refactored)
Front IR
IDE
Plug-In
how to include the K2 compiler
plugins {
kotlin("jvm") version "1.7.0"
application
}
tasks.withType<KotlinCompile> {
kotlinOptions.useK2 = true
}
2
Peeking Inside
the –X compiler option
the –Xlist-phases compiler option
IrLowering: IR lowering
ValidateIrBeforeLowering: Validate IR before lowering
ProcessOptionalAnnotations: Record metadata of ...
ExpectDeclarationsRemoving: Remove expect declaration from ...
SerializeIr: If specified by compiler options ...
ScriptsToClasses: Put script declarations into classes ...
FileClass: Put file level function ...
JvmStaticInObject: Make JvmStatic functions ...
RepeatedAnnotation: Enclose repeated annotations ...
PerformByIrFile: Perform phases by IrFile ...
TypeAliasAnnotationMethodsLowering: Generate method stubs ...
FunctionExpression: Transform IrFunctionExpression to ...
JvmOverloadsAnnotation: Handle JvmOverloads annotations ...
MainMethodGeneration: Generate main bridges to ...
MakePropertyDelegateMethodsStatic: Make `$delegate` methods for ...
RenameFields: Rename private fields ...
FakeInliningLocalVariablesLowering: Add fake locals to identify the ...
GenerateMultifileFacades: Generate JvmMultifileClass facades ...
ResolveInlineCalls: Statically resolve calls to ...
BytecodeInliningPreparation: Label all loops for non-local ...
ValidateIrAfterLowering: Validate IR after lowering ...
lots more lowerings
dumping the IR
summary of commands
kotlinc –X
kotlinc –Xlist-phases
kotlinc –Xphases-to-dump-after=ValidateIrAfterLowering <PATH>
list experimental arguments
list compiler phases
dump output when a phase is complete
the Visitor Pattern in Kotlinc
interface IrElementVisitor<out R, in D> {
fun visitElement(element: IrElement, data: D): R
fun visitDeclaration(declaration: IrDeclarationBase, data: D): R
fun visitClass(declaration: IrClass, data: D): R
fun visitFunction(declaration: IrFunction, data: D): R
fun visitConstructor(declaration: IrConstructor, data: D): R
fun visitProperty(declaration: IrProperty, data: D): R
}
one visit method for every type of node
3
De-Sugaring
& Lowering
– Many language features are ‘syntactical sugar’
– They don’t add a capability but provide a convenience
– For example, a foreach loop rather than an Iterator object
lowering vs. de-sugaring
understanding the difference
– These language features can be de-sugared
– We rewrite more complex constructs as simpler ones
– Lowering is where we do this within the same language
lowering vs. de-sugaring
understanding the difference
– The Kotlin compiler uses lowerings internally
– To restrict its work to a subset of the language
– We cannot (yet) drill into these in detail
– But we can look at de-sugaring in general
lowering vs. de-sugaring
understanding the difference
– Nothing is ever hidden in software
– We can decompile bytecode from the Kotlin compiler
– This lets us see how Kotlin features work ‘under the hood’
– Similar options exist for other platforms
decompiling Kotlin programs
via the IntelliJ tools
introducing javap
the java bytecode decompiler
% javap
Usage: javap <options> <classes>
where possible options include:
...
-p -private Show all classes and members
-c Disassemble the code
-s Print internal type signatures
...
--module-path <path> Specify where to find application modules
--system <jdk> Specify where to find system modules
...
-cp <path> Specify where to find user class files
...
Free Functions
//Program.kt
fun printMsg(text: String) = println(text)
fun main() = printMsg("Bonjour Kotlin Dev Day!")
free functions
Bonjour Kotlin Dev Day!
public final class ProgramKt {
public static final void printMsg(String);
Code:
15: return
public static final void main();
Code:
5: return
public static void main(String[]);
Code:
3: return
}
free functions
Nested Functions
fun main() {
fun printMsg(text: String) = println(text)
printMsg("Bonjour Kotlin Dev Day!")
}
nested functions
Bonjour Kotlin Dev Day!
public final class ProgramKt {
public static final void main();
Code:
0: ldc #8 // String Bonjour Kotlin Dev Day!
2: invokestatic #12 // Method main$printMsg:(String;)V
5: return
public static void main(java.lang.String[]);
Code:
0: invokestatic #15 // Method main:()V
3: return
nested functions
private static final void main$printMsg(java.lang.String);
Code:
0: iconst_0
1: istore_1
2: getstatic #23 // Field System.out
5: aload_0
6: invokevirtual #29 // Method PrintStream.println:(Object)V
9: return
}
nested functions
Nested Functions
(extended)
fun main() {
demo(123)
demo(45.6)
}
fun demo(input: Int) {
fun printMsg(text: String) = println(text)
printMsg("Hello Kotlin Dev Day!")
}
fun demo(input: Double) {
fun printMsg(text: String) = println(text)
printMsg("Bonjour Kotlin Dev Day!")
}
nested functions - extended
Hello Kotlin Dev Day!
Bonjour Kotlin Dev Day!
public static final void demo(int);
Code:
0: ldc #17 // String Hello Kotlin Dev Day!
2: invokestatic #21 // Method demo$printMsg:(String;)V
5: return
public static final void demo(double);
Code:
0: ldc #25 // String Bonjour Kotlin Dev Day!
2: invokestatic #28 // Method "demo$printMsg-0":(String;)V
5: return
nested functions - extended
private static final void demo$printMsg(String);
Code:
0: iconst_0
1: istore_1
2: getstatic #40 // Field System.out
5: aload_0
6: invokevirtual #46 // Method PrintStream.println:(Object;)V
9: return
private static final void demo$printMsg-0(String);
Code:
0: iconst_0
1: istore_1
2: getstatic #40 // Field System.out
5: aload_0
6: invokevirtual #46 // Method PrintStream.println:(Object;)V
9: return
}
nested functions - extended
Extension Methods
class Person(val name: String)
fun Person.sayHello() = println("Hello from $name")
fun String.times(num: Int) = (1..num).joinToString { "$this" }
fun main() {
val person = Person("Jane")
person.sayHello()
println("Dave".times(3))
}
extension methods
Hello from Jane
Dave, Dave, Dave
public static final void sayHello(Person);
Code:
...
25: return
public static final String times(String, int);
Code:
...
40: return
extension methods
Destructuring
destructuring
data class Person(val name: String, val age: Int)
fun main() {
val person = Person("Lucy", 36)
val (x, y) = person
println(x)
println(y)
}
Lucy
36
destructuring
public final Person {
private final String name;
private final int age;
public Person(String, int);
public final String getName();
public final int getAge();
public final String component1();
public final int component2();
public final Person copy(String, int);
public static Person copy$default(Person, String, int, int, Object);
public java.lang.String toString();
public int hashCode();
public boolean equals(java.lang.Object);
}
destructuring
public final class ProgramKt {
public static final void main();
Code:
...
15: invokevirtual #18 // Person.component1:()String;
18: astore_2
19: aload_1
20: invokevirtual #22 // Person.component2:()I
23: istore_3
...
44: return
public static void main(java.lang.String[]);
Code:
0: invokestatic #46 // Method main:()V
3: return
}
Object Declarations
object declarations
object Math {
fun add(no1: Int, no2: Int) = no1 + no2
}
fun main() {
println(Math.add(12,34))
}
46
object declarations
public final class Math {
public static final Math INSTANCE;
private Math();
public final int add(int, int);
static {};
Code:
0: new #2 // class Math
3: dup
4: invokespecial #17 // Method "<init>":()V
7: putstatic #20 // Field INSTANCE:Math;
10: return
}
object declarations
public final class ProgramKt {
public static final void main();
Code:
0: getstatic #12 // Field Math.INSTANCE:Math;
3: bipush 12
5: bipush 34
7: invokevirtual #16 // Method Math.add:(II)I
10: istore_0
11: iconst_0
12: istore_1
13: getstatic #22 // Field System.out;
16: iload_0
17: invokevirtual #28 // Method PrintStream.println:(I)V
20: return
public static void main(String[]);
}
Companion Objects
class Employee(val name: String, val dept: String) {
companion object {
fun buildForHR(name: String) = Employee(name, "HR")
fun buildForIT(name: String) = Employee(name, "IT")
}
override fun toString() = "$name working in $dept"
}
fun main() {
val emp1 = Employee.buildForHR("Dave")
val emp2 = Employee.buildForIT("Jane")
println(emp1)
println(emp2)
}
companion objects
Dave working in HR
Jane working in IT
public final class Employee {
public static final Employee$Companion Companion;
private final String name;
private final String dept;
public Employee(String, String);
public final String getName();
public final String getDept();
public String toString();
static {};
Code:
0: new #45 // class Employee$Companion
3: dup
4: aconst_null
5: invokespecial #48 // Employee$Companion."<init>"
8: putstatic #52 // Field Companion:Employee$Companion;
11: return
}
companion objects
Companion Objects
(renamed)
class Employee(val name: String, val dept: String) {
companion object EmployeeFactory {
fun buildForHR(name: String) = Employee(name, "HR")
fun buildForIT(name: String) = Employee(name, "IT")
}
override fun toString() = "$name working in $dept"
}
fun main() {
val emp1 = Employee.buildForHR("Dave")
val emp2 = Employee.buildForIT("Jane")
println(emp1)
println(emp2)
}
companion objects (renamed)
Dave working in HR
Jane working in IT
public final class Employee {
private final Ljava/lang/String; name
private final Ljava/lang/String; dept
public final static Employee$EmployeeFactory; EmployeeFactory
public toString()Ljava/lang/String;
public final getName()Ljava/lang/String;
public final getDept()Ljava/lang/String;
public <init>(Ljava/lang/String;Ljava/lang/String;)V
// access flags 0x8
static <clinit>()V
NEW Employee$EmployeeFactory
DUP
ACONST_NULL
INVOKESPECIAL Employee$EmployeeFactory.<init> (...)V
PUTSTATIC Employee.EmployeeFactory : Employee$EmployeeFactory;
RETURN
MAXSTACK = 3
MAXLOCALS = 0
}
companion objects (renamed)
Delegated Properties
class Person(val name: String, job: String) {
var job: String by LoggingDelegate(job)
}
fun main() {
val person = Person("Jane", "Junior Developer")
person.job = "Senior Developer"
println(person.job)
}
Delegated Properties
Creating logger for property 'job'
Writing to 'job'
Reading from 'job'
Senior Developer
class LoggingDelegate<T>(var value: T) : ReadWriteProperty<Any?, T> {
operator fun provideDelegate(
thisRef: Any?,
prop: KProperty<*>
): ReadWriteProperty<Any?, T> {
println("Creating logger for property '${prop.name}'")
return this
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
println("Writing to '${property.name}'")
this.value = value
}
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
println("Reading from '${property.name}'")
return value
}
}
Delegated Properties
public final class Person {
...
private final Lkotlin/properties/ReadWriteProperty; job$delegate
public <init>(Ljava/lang/String;Ljava/lang/String;)V
...
NEW language/delegated/properties/LoggingDelegate
...
Delegated Properties
public final getJob()Ljava/lang/String;
...
ALOAD 0
GETFIELD language/delegated/properties/Person.job$delegate
ALOAD 0
GETSTATIC language/delegated/properties/Person.$$delegatedProperties
ICONST_0
AALOAD
INVOKEINTERFACE kotlin/properties/ReadWriteProperty.getValue (...)Object;
CHECKCAST java/lang/String
ARETURN
...
Delegated Properties
public final setJob(Ljava/lang/String;)V
...
GETFIELD language/delegated/properties/Person.job$delegate
ALOAD 0
GETSTATIC language/delegated/properties/Person.$$delegatedProperties
ICONST_0
AALOAD
ALOAD 1
INVOKEINTERFACE kotlin/properties/ReadWriteProperty.setValue (...)V
RETURN
...
}
Delegated Properties
Lambdas With Receivers
data class Person(val name: String, var age: Int)
fun demo(person: Person, action: Person.() -> Unit) = person.apply(action)
fun main() {
val person = Person("Jane", 25)
demo(person) {
age += 10
println(this)
}
}
lambdas with receivers
Person(name=Jane, age=35)
public final class ProgramKt {
public static final Person demo(
Person,
kotlin.jvm.functions.Function1<? super Person, kotlin.Unit>
);
Code:
...
21: invokeinterface #24,2 //Function1.invoke:(Object;)Object;
...
public static final void main();
Code:
...
13: getstatic #42 // Field ProgramKt$main$1.INSTANCE:ProgramKt$main$1;
16: checkcast #20 // class kotlin/jvm/functions/Function1
19: invokestatic #44 // Method demo:(Person;Function1;)Person;
...
lambdas with receivers
public interface Function1<P1, R> extends Function<R> {
public abstract R invoke(P1);
}
lambdas with receivers
javap -cp kotlin-stdlib-1.5.10.jar -c -p kotlin.jvm.functions.Function1
public interface kotlin.Function<R> {
}
javap -cp kotlin-stdlib-1.5.10.jar -c -p kotlin.jvm.functions.Function
public interface Function2<P1, P2, R> extends Function<R> {
public abstract R invoke(P1, P2);
}
lambdas with receivers
javap -cp kotlin-stdlib-1.5.10.jar -c -p kotlin.jvm.functions.Function2
public interface Function3<P1, P2, P3, R> extends Function<R> {
public abstract R invoke(P1, P2, P3);
}
javap -cp kotlin-stdlib-1.5.10.jar -c -p kotlin.jvm.functions.Function3
Lambdas With Receivers
(21+1 params)
typealias EvilLambda = Person.(
p1: Int,
p2: Int,
p3: Int,
p4: Int,
...
p14: Int,
p15: Int,
p16: Int,
p17: Int,
p18: Int,
p19: Int,
p20: Int,
p21: Int
) -> Unit
lambdas with receivers (21+1 params)
fun demo(
person: Person,
action: EvilLambda
) = person.action(1, 2, 3, 4 ... 14, 15, 16, 17, 18, 19, 20, 21)
fun main() {
val person = Person("Jane", 25)
demo(person) { a, b, c, d ... n, o, p, q, r, s, t, u ->
age += 10
println(this)
}
}
lambdas with receivers (21+1 params)
public final static demo(Person;Lkotlin/jvm/functions/Function22;)V
...
ALOAD 1
ALOAD 0
ICONST_1
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
ICONST_2
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
...
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
BIPUSH 20
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
BIPUSH 21
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
INVOKEINTERFACE kotlin/jvm/functions/Function22.invoke (...)Object;
POP
RETURN
lambdas with receivers (21+1 params)
Lambdas With Receivers
(22+1 params)
typealias EvilLambda = Person.(
p1: Int,
p2: Int,
p3: Int,
p4: Int,
...
p14: Int,
p15: Int,
p16: Int,
p17: Int,
p18: Int,
p19: Int,
p20: Int,
p21: Int,
p22: Int,
) -> Unit
lambdas with receivers (22+1 params)
fun demo(
person: Person,
action: EvilLambda
) = person.action(1, 2, 3, 4 ... 14, 15, 16, 17, 18, 19, 20, 21, 22)
fun main() {
val person = Person("Jane", 25)
demo(person) { a, b, c, d ... n, o, p, q, r, s, t, u, v ->
age += 10
println(this)
}
}
lambdas with receivers (22+1 params)
public final static demo(Person;Lkotlin/jvm/functions/FunctionN;)V
ALOAD 1
ALOAD 0
ICONST_1
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
ICONST_2
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
...
BIPUSH 20
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
BIPUSH 21
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
BIPUSH 22
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
INVOKEINTERFACE kotlin/jvm/functions/FunctionN.invoke (...)Object;
POP
RETURN
lambdas with receivers (22+1 params)
4
Android 13
(with thanks to Kelvin Harron)
– A new predictive back gesture
– Enables users to see where ‘back’ will take them
Android 13
opt-in on back behaviour
– Open-source application, in Kotlin and Compose
– Designed to show (Googles view on) best practices
Android 13
‘Now in Android’
– API is now stable
– Performance improvements are promised
– Recomposition highlighter to find poorly optimised views
– Lazy Layouts for efficiently showing lists of items
Android 13
Compose 1.2 Beta
– Allows classes and methods to be precompiled
– These are bundled with your release to speed startup
– Most crucial user journeys profiled via Macrobenchmark
Android 13
Baseline Profiles
– Edit and observe changes to composable functions
– Will significantly simplify and speed up UI development
– Works on previews, emulators and devices
– But still a work in progress
Android 13
Live Edit
5
Future Game
Changers
game changer 1
multiplatform libraries
COMMON
KOTLIN
KOTLIN ANDROID
KOTLIN JS
KOTLIN NATIVE
KOTLIN JVM
NATIVE
ARTEFACT
JS BUNDLE
JAR
– Union Types with ‘|’ syntax
– Improvements to Sealed Types
– Extended Operator Overloading
– Name based Destructuring
– Collection Literals
– Structure Literals (Tuples?)
game changer 2
potential new language features
– Brings Google’s UI Toolkit to web
– In theory, enables reuse of UI code across stack
game changer 3
compose for web
https://compose-web.ui.pages.jetbrains.team/
Div(attrs = attrs) {
Label {
Input(
type = InputType.Checkbox,
attrs = {}
)
Span {
content()
}}}
6
Conclusions
– Kotlin is emerging from a period of consolidation
– Which opens the door to lots of good things
– Better tooling, new features, faster builds etc...
– Android continues to innovate on top of Kotlin
– Compose could be ‘one DSL to rule them all’
conclusions
...great things lie ahead
Questions?

More Related Content

Similar to Kotlin / Android Update

Kotlin for Android devs
Kotlin for Android devsKotlin for Android devs
Kotlin for Android devs
Adit Lal
 
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
 
Fall in love with Kotlin
Fall in love with KotlinFall in love with Kotlin
Fall in love with Kotlin
Hari Vignesh Jayapalan
 
Koin Quickstart
Koin QuickstartKoin Quickstart
Koin Quickstart
Matthew Clarke
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
Doug Hawkins
 
Roslyn: el futuro de C# y VB.NET by Rodolfo Finochietti
Roslyn: el futuro de C# y VB.NET by Rodolfo FinochiettiRoslyn: el futuro de C# y VB.NET by Rodolfo Finochietti
Roslyn: el futuro de C# y VB.NET by Rodolfo Finochietti
.NET Conf UY
 
Roslyn: el futuro de C#
Roslyn: el futuro de C#Roslyn: el futuro de C#
Roslyn: el futuro de C#
Rodolfo Finochietti
 
Object-oriented Basics
Object-oriented BasicsObject-oriented Basics
Object-oriented Basics
Jamie (Taka) Wang
 
R. herves. clean code (theme)2
R. herves. clean code (theme)2R. herves. clean code (theme)2
R. herves. clean code (theme)2
saber tabatabaee
 
Geecon - Improve your Android-fu with Kotlin
Geecon - Improve your Android-fu with KotlinGeecon - Improve your Android-fu with Kotlin
Geecon - Improve your Android-fu with Kotlin
Nicolas Fränkel
 
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
LogeekNightUkraine
 
TypeScript Vs. KotlinJS
TypeScript Vs. KotlinJSTypeScript Vs. KotlinJS
TypeScript Vs. KotlinJS
Garth Gilmour
 
KotlinForJavaDevelopers-UJUG.pptx
KotlinForJavaDevelopers-UJUG.pptxKotlinForJavaDevelopers-UJUG.pptx
KotlinForJavaDevelopers-UJUG.pptx
Ian Robertson
 
.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#
Bertrand Le Roy
 
Kotlin for Android Developers - 3
Kotlin for Android Developers - 3Kotlin for Android Developers - 3
Kotlin for Android Developers - 3
Mohamed Nabil, MSc.
 
C++11: Feel the New Language
C++11: Feel the New LanguageC++11: Feel the New Language
C++11: Feel the New Languagemspline
 
A quick and fast intro to Kotlin
A quick and fast intro to Kotlin A quick and fast intro to Kotlin
A quick and fast intro to Kotlin
XPeppers
 
Being Expressive in Code
Being Expressive in CodeBeing Expressive in Code
Being Expressive in Code
Eamonn Boyle
 

Similar to Kotlin / Android Update (20)

Kotlin for Android devs
Kotlin for Android devsKotlin for Android devs
Kotlin for Android devs
 
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?
 
Fall in love with Kotlin
Fall in love with KotlinFall in love with Kotlin
Fall in love with Kotlin
 
Koin Quickstart
Koin QuickstartKoin Quickstart
Koin Quickstart
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Roslyn: el futuro de C# y VB.NET by Rodolfo Finochietti
Roslyn: el futuro de C# y VB.NET by Rodolfo FinochiettiRoslyn: el futuro de C# y VB.NET by Rodolfo Finochietti
Roslyn: el futuro de C# y VB.NET by Rodolfo Finochietti
 
Roslyn: el futuro de C#
Roslyn: el futuro de C#Roslyn: el futuro de C#
Roslyn: el futuro de C#
 
Object-oriented Basics
Object-oriented BasicsObject-oriented Basics
Object-oriented Basics
 
R. herves. clean code (theme)2
R. herves. clean code (theme)2R. herves. clean code (theme)2
R. herves. clean code (theme)2
 
TechTalk - Dotnet
TechTalk - DotnetTechTalk - Dotnet
TechTalk - Dotnet
 
Geecon - Improve your Android-fu with Kotlin
Geecon - Improve your Android-fu with KotlinGeecon - Improve your Android-fu with Kotlin
Geecon - Improve your Android-fu with Kotlin
 
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
 
TypeScript Vs. KotlinJS
TypeScript Vs. KotlinJSTypeScript Vs. KotlinJS
TypeScript Vs. KotlinJS
 
KotlinForJavaDevelopers-UJUG.pptx
KotlinForJavaDevelopers-UJUG.pptxKotlinForJavaDevelopers-UJUG.pptx
KotlinForJavaDevelopers-UJUG.pptx
 
.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#
 
Kotlin for Android Developers - 3
Kotlin for Android Developers - 3Kotlin for Android Developers - 3
Kotlin for Android Developers - 3
 
C++11: Feel the New Language
C++11: Feel the New LanguageC++11: Feel the New Language
C++11: Feel the New Language
 
A quick and fast intro to Kotlin
A quick and fast intro to Kotlin A quick and fast intro to Kotlin
A quick and fast intro to Kotlin
 
Being Expressive in Code
Being Expressive in CodeBeing Expressive in Code
Being Expressive in Code
 

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
 
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
 
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
 
Kotlin The Whole Damn Family
Kotlin The Whole Damn FamilyKotlin The Whole Damn Family
Kotlin The Whole Damn Family
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
 
Down With JavaScript!
Down With JavaScript!Down With JavaScript!
Down With JavaScript!
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
 
The Heat Death Of Enterprise IT
The Heat Death Of Enterprise ITThe Heat Death Of Enterprise IT
The Heat Death Of Enterprise IT
 
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
 
Kotlin The Whole Damn Family
Kotlin The Whole Damn FamilyKotlin The Whole Damn Family
Kotlin The Whole Damn Family
 
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...
 
Down With JavaScript!
Down With JavaScript!Down With JavaScript!
Down With JavaScript!
 

Recently uploaded

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
 
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
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
pavan998932
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
kalichargn70th171
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
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
 
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
 
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
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
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
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 

Recently uploaded (20)

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
 
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...
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
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
 
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
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
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 ⚡️
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 

Kotlin / Android Update

  • 1. © Instil Software 2020 Kotlin / Android Update Belfast Google Dev Group I/O Extended 2022
  • 2. – The K2 compiler previewed in 1.7 – Why you should care about it – Looking inside the black box – The concept of ‘lowering’ – Quick note on Android – Other game changers agenda what’s new in Kotlin 1.7
  • 5.
  • 6. – The interop story is so good – Call into legacy Java code easily – Call into JavaScript easily – Call in C and Swift easily – Really concise, yet clear syntax – Less is more – “Borrows” the best bits – Less baggage why kotlin? so much to like Null Safety String Templates Default parameters Extensions Free Functions Coroutines Single Expression Functions Reified generics Data classes and Properties Type Inference Smart Casts Operator overloading
  • 7. This is what we want Kotlin to become in the future. The universal solution for every platform. ANDREY BRESLAV Former Lead Language Designer of Kotlin, JetBrains
  • 9. the pre 1.7 approach no unified back end Front End Abstract Syntax Tree (AST) 1101011111 001010110 101010110 Semantic Info JVM Back End JS Back End Native Back End
  • 10. the 1.7 approach unified back end Back Ends Front End Front IR JVM Specific JS Specific LVVM Specific Shared IR
  • 11. “Compiler internals do not concern me Garth”
  • 12. the 1.7 approach – Consistency across different platforms – Faster adoption of language features – A universal API for compiler plugins – Richer and more reliable tooling – Improvements in compile times benefits for developers
  • 13.
  • 15.
  • 16. how to include the K2 compiler plugins { kotlin("jvm") version "1.7.0" application } tasks.withType<KotlinCompile> { kotlinOptions.useK2 = true }
  • 20. IrLowering: IR lowering ValidateIrBeforeLowering: Validate IR before lowering ProcessOptionalAnnotations: Record metadata of ... ExpectDeclarationsRemoving: Remove expect declaration from ... SerializeIr: If specified by compiler options ... ScriptsToClasses: Put script declarations into classes ... FileClass: Put file level function ... JvmStaticInObject: Make JvmStatic functions ... RepeatedAnnotation: Enclose repeated annotations ... PerformByIrFile: Perform phases by IrFile ... TypeAliasAnnotationMethodsLowering: Generate method stubs ... FunctionExpression: Transform IrFunctionExpression to ... JvmOverloadsAnnotation: Handle JvmOverloads annotations ... MainMethodGeneration: Generate main bridges to ... MakePropertyDelegateMethodsStatic: Make `$delegate` methods for ... RenameFields: Rename private fields ... FakeInliningLocalVariablesLowering: Add fake locals to identify the ... GenerateMultifileFacades: Generate JvmMultifileClass facades ... ResolveInlineCalls: Statically resolve calls to ... BytecodeInliningPreparation: Label all loops for non-local ... ValidateIrAfterLowering: Validate IR after lowering ... lots more lowerings
  • 22. summary of commands kotlinc –X kotlinc –Xlist-phases kotlinc –Xphases-to-dump-after=ValidateIrAfterLowering <PATH> list experimental arguments list compiler phases dump output when a phase is complete
  • 23.
  • 24.
  • 25.
  • 26. the Visitor Pattern in Kotlinc interface IrElementVisitor<out R, in D> { fun visitElement(element: IrElement, data: D): R fun visitDeclaration(declaration: IrDeclarationBase, data: D): R fun visitClass(declaration: IrClass, data: D): R fun visitFunction(declaration: IrFunction, data: D): R fun visitConstructor(declaration: IrConstructor, data: D): R fun visitProperty(declaration: IrProperty, data: D): R } one visit method for every type of node
  • 28. – Many language features are ‘syntactical sugar’ – They don’t add a capability but provide a convenience – For example, a foreach loop rather than an Iterator object lowering vs. de-sugaring understanding the difference
  • 29. – These language features can be de-sugared – We rewrite more complex constructs as simpler ones – Lowering is where we do this within the same language lowering vs. de-sugaring understanding the difference
  • 30. – The Kotlin compiler uses lowerings internally – To restrict its work to a subset of the language – We cannot (yet) drill into these in detail – But we can look at de-sugaring in general lowering vs. de-sugaring understanding the difference
  • 31. – Nothing is ever hidden in software – We can decompile bytecode from the Kotlin compiler – This lets us see how Kotlin features work ‘under the hood’ – Similar options exist for other platforms decompiling Kotlin programs via the IntelliJ tools
  • 32.
  • 33. introducing javap the java bytecode decompiler % javap Usage: javap <options> <classes> where possible options include: ... -p -private Show all classes and members -c Disassemble the code -s Print internal type signatures ... --module-path <path> Specify where to find application modules --system <jdk> Specify where to find system modules ... -cp <path> Specify where to find user class files ...
  • 35. //Program.kt fun printMsg(text: String) = println(text) fun main() = printMsg("Bonjour Kotlin Dev Day!") free functions Bonjour Kotlin Dev Day!
  • 36. public final class ProgramKt { public static final void printMsg(String); Code: 15: return public static final void main(); Code: 5: return public static void main(String[]); Code: 3: return } free functions
  • 38. fun main() { fun printMsg(text: String) = println(text) printMsg("Bonjour Kotlin Dev Day!") } nested functions Bonjour Kotlin Dev Day!
  • 39. public final class ProgramKt { public static final void main(); Code: 0: ldc #8 // String Bonjour Kotlin Dev Day! 2: invokestatic #12 // Method main$printMsg:(String;)V 5: return public static void main(java.lang.String[]); Code: 0: invokestatic #15 // Method main:()V 3: return nested functions
  • 40. private static final void main$printMsg(java.lang.String); Code: 0: iconst_0 1: istore_1 2: getstatic #23 // Field System.out 5: aload_0 6: invokevirtual #29 // Method PrintStream.println:(Object)V 9: return } nested functions
  • 42. fun main() { demo(123) demo(45.6) } fun demo(input: Int) { fun printMsg(text: String) = println(text) printMsg("Hello Kotlin Dev Day!") } fun demo(input: Double) { fun printMsg(text: String) = println(text) printMsg("Bonjour Kotlin Dev Day!") } nested functions - extended Hello Kotlin Dev Day! Bonjour Kotlin Dev Day!
  • 43. public static final void demo(int); Code: 0: ldc #17 // String Hello Kotlin Dev Day! 2: invokestatic #21 // Method demo$printMsg:(String;)V 5: return public static final void demo(double); Code: 0: ldc #25 // String Bonjour Kotlin Dev Day! 2: invokestatic #28 // Method "demo$printMsg-0":(String;)V 5: return nested functions - extended
  • 44. private static final void demo$printMsg(String); Code: 0: iconst_0 1: istore_1 2: getstatic #40 // Field System.out 5: aload_0 6: invokevirtual #46 // Method PrintStream.println:(Object;)V 9: return private static final void demo$printMsg-0(String); Code: 0: iconst_0 1: istore_1 2: getstatic #40 // Field System.out 5: aload_0 6: invokevirtual #46 // Method PrintStream.println:(Object;)V 9: return } nested functions - extended
  • 46. class Person(val name: String) fun Person.sayHello() = println("Hello from $name") fun String.times(num: Int) = (1..num).joinToString { "$this" } fun main() { val person = Person("Jane") person.sayHello() println("Dave".times(3)) } extension methods Hello from Jane Dave, Dave, Dave
  • 47. public static final void sayHello(Person); Code: ... 25: return public static final String times(String, int); Code: ... 40: return extension methods
  • 49. destructuring data class Person(val name: String, val age: Int) fun main() { val person = Person("Lucy", 36) val (x, y) = person println(x) println(y) } Lucy 36
  • 50. destructuring public final Person { private final String name; private final int age; public Person(String, int); public final String getName(); public final int getAge(); public final String component1(); public final int component2(); public final Person copy(String, int); public static Person copy$default(Person, String, int, int, Object); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); }
  • 51. destructuring public final class ProgramKt { public static final void main(); Code: ... 15: invokevirtual #18 // Person.component1:()String; 18: astore_2 19: aload_1 20: invokevirtual #22 // Person.component2:()I 23: istore_3 ... 44: return public static void main(java.lang.String[]); Code: 0: invokestatic #46 // Method main:()V 3: return }
  • 53. object declarations object Math { fun add(no1: Int, no2: Int) = no1 + no2 } fun main() { println(Math.add(12,34)) } 46
  • 54. object declarations public final class Math { public static final Math INSTANCE; private Math(); public final int add(int, int); static {}; Code: 0: new #2 // class Math 3: dup 4: invokespecial #17 // Method "<init>":()V 7: putstatic #20 // Field INSTANCE:Math; 10: return }
  • 55. object declarations public final class ProgramKt { public static final void main(); Code: 0: getstatic #12 // Field Math.INSTANCE:Math; 3: bipush 12 5: bipush 34 7: invokevirtual #16 // Method Math.add:(II)I 10: istore_0 11: iconst_0 12: istore_1 13: getstatic #22 // Field System.out; 16: iload_0 17: invokevirtual #28 // Method PrintStream.println:(I)V 20: return public static void main(String[]); }
  • 57. class Employee(val name: String, val dept: String) { companion object { fun buildForHR(name: String) = Employee(name, "HR") fun buildForIT(name: String) = Employee(name, "IT") } override fun toString() = "$name working in $dept" } fun main() { val emp1 = Employee.buildForHR("Dave") val emp2 = Employee.buildForIT("Jane") println(emp1) println(emp2) } companion objects Dave working in HR Jane working in IT
  • 58. public final class Employee { public static final Employee$Companion Companion; private final String name; private final String dept; public Employee(String, String); public final String getName(); public final String getDept(); public String toString(); static {}; Code: 0: new #45 // class Employee$Companion 3: dup 4: aconst_null 5: invokespecial #48 // Employee$Companion."<init>" 8: putstatic #52 // Field Companion:Employee$Companion; 11: return } companion objects
  • 60. class Employee(val name: String, val dept: String) { companion object EmployeeFactory { fun buildForHR(name: String) = Employee(name, "HR") fun buildForIT(name: String) = Employee(name, "IT") } override fun toString() = "$name working in $dept" } fun main() { val emp1 = Employee.buildForHR("Dave") val emp2 = Employee.buildForIT("Jane") println(emp1) println(emp2) } companion objects (renamed) Dave working in HR Jane working in IT
  • 61. public final class Employee { private final Ljava/lang/String; name private final Ljava/lang/String; dept public final static Employee$EmployeeFactory; EmployeeFactory public toString()Ljava/lang/String; public final getName()Ljava/lang/String; public final getDept()Ljava/lang/String; public <init>(Ljava/lang/String;Ljava/lang/String;)V // access flags 0x8 static <clinit>()V NEW Employee$EmployeeFactory DUP ACONST_NULL INVOKESPECIAL Employee$EmployeeFactory.<init> (...)V PUTSTATIC Employee.EmployeeFactory : Employee$EmployeeFactory; RETURN MAXSTACK = 3 MAXLOCALS = 0 } companion objects (renamed)
  • 63. class Person(val name: String, job: String) { var job: String by LoggingDelegate(job) } fun main() { val person = Person("Jane", "Junior Developer") person.job = "Senior Developer" println(person.job) } Delegated Properties Creating logger for property 'job' Writing to 'job' Reading from 'job' Senior Developer
  • 64. class LoggingDelegate<T>(var value: T) : ReadWriteProperty<Any?, T> { operator fun provideDelegate( thisRef: Any?, prop: KProperty<*> ): ReadWriteProperty<Any?, T> { println("Creating logger for property '${prop.name}'") return this } override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { println("Writing to '${property.name}'") this.value = value } override fun getValue(thisRef: Any?, property: KProperty<*>): T { println("Reading from '${property.name}'") return value } } Delegated Properties
  • 65. public final class Person { ... private final Lkotlin/properties/ReadWriteProperty; job$delegate public <init>(Ljava/lang/String;Ljava/lang/String;)V ... NEW language/delegated/properties/LoggingDelegate ... Delegated Properties
  • 66. public final getJob()Ljava/lang/String; ... ALOAD 0 GETFIELD language/delegated/properties/Person.job$delegate ALOAD 0 GETSTATIC language/delegated/properties/Person.$$delegatedProperties ICONST_0 AALOAD INVOKEINTERFACE kotlin/properties/ReadWriteProperty.getValue (...)Object; CHECKCAST java/lang/String ARETURN ... Delegated Properties
  • 67. public final setJob(Ljava/lang/String;)V ... GETFIELD language/delegated/properties/Person.job$delegate ALOAD 0 GETSTATIC language/delegated/properties/Person.$$delegatedProperties ICONST_0 AALOAD ALOAD 1 INVOKEINTERFACE kotlin/properties/ReadWriteProperty.setValue (...)V RETURN ... } Delegated Properties
  • 69. data class Person(val name: String, var age: Int) fun demo(person: Person, action: Person.() -> Unit) = person.apply(action) fun main() { val person = Person("Jane", 25) demo(person) { age += 10 println(this) } } lambdas with receivers Person(name=Jane, age=35)
  • 70. public final class ProgramKt { public static final Person demo( Person, kotlin.jvm.functions.Function1<? super Person, kotlin.Unit> ); Code: ... 21: invokeinterface #24,2 //Function1.invoke:(Object;)Object; ... public static final void main(); Code: ... 13: getstatic #42 // Field ProgramKt$main$1.INSTANCE:ProgramKt$main$1; 16: checkcast #20 // class kotlin/jvm/functions/Function1 19: invokestatic #44 // Method demo:(Person;Function1;)Person; ... lambdas with receivers
  • 71. public interface Function1<P1, R> extends Function<R> { public abstract R invoke(P1); } lambdas with receivers javap -cp kotlin-stdlib-1.5.10.jar -c -p kotlin.jvm.functions.Function1 public interface kotlin.Function<R> { } javap -cp kotlin-stdlib-1.5.10.jar -c -p kotlin.jvm.functions.Function
  • 72. public interface Function2<P1, P2, R> extends Function<R> { public abstract R invoke(P1, P2); } lambdas with receivers javap -cp kotlin-stdlib-1.5.10.jar -c -p kotlin.jvm.functions.Function2 public interface Function3<P1, P2, P3, R> extends Function<R> { public abstract R invoke(P1, P2, P3); } javap -cp kotlin-stdlib-1.5.10.jar -c -p kotlin.jvm.functions.Function3
  • 74. typealias EvilLambda = Person.( p1: Int, p2: Int, p3: Int, p4: Int, ... p14: Int, p15: Int, p16: Int, p17: Int, p18: Int, p19: Int, p20: Int, p21: Int ) -> Unit lambdas with receivers (21+1 params)
  • 75. fun demo( person: Person, action: EvilLambda ) = person.action(1, 2, 3, 4 ... 14, 15, 16, 17, 18, 19, 20, 21) fun main() { val person = Person("Jane", 25) demo(person) { a, b, c, d ... n, o, p, q, r, s, t, u -> age += 10 println(this) } } lambdas with receivers (21+1 params)
  • 76. public final static demo(Person;Lkotlin/jvm/functions/Function22;)V ... ALOAD 1 ALOAD 0 ICONST_1 INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; ICONST_2 INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; ... INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; BIPUSH 20 INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; BIPUSH 21 INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; INVOKEINTERFACE kotlin/jvm/functions/Function22.invoke (...)Object; POP RETURN lambdas with receivers (21+1 params)
  • 78. typealias EvilLambda = Person.( p1: Int, p2: Int, p3: Int, p4: Int, ... p14: Int, p15: Int, p16: Int, p17: Int, p18: Int, p19: Int, p20: Int, p21: Int, p22: Int, ) -> Unit lambdas with receivers (22+1 params)
  • 79. fun demo( person: Person, action: EvilLambda ) = person.action(1, 2, 3, 4 ... 14, 15, 16, 17, 18, 19, 20, 21, 22) fun main() { val person = Person("Jane", 25) demo(person) { a, b, c, d ... n, o, p, q, r, s, t, u, v -> age += 10 println(this) } } lambdas with receivers (22+1 params)
  • 80. public final static demo(Person;Lkotlin/jvm/functions/FunctionN;)V ALOAD 1 ALOAD 0 ICONST_1 INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; ICONST_2 INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; ... BIPUSH 20 INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; BIPUSH 21 INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; BIPUSH 22 INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; INVOKEINTERFACE kotlin/jvm/functions/FunctionN.invoke (...)Object; POP RETURN lambdas with receivers (22+1 params)
  • 81. 4 Android 13 (with thanks to Kelvin Harron)
  • 82. – A new predictive back gesture – Enables users to see where ‘back’ will take them Android 13 opt-in on back behaviour
  • 83. – Open-source application, in Kotlin and Compose – Designed to show (Googles view on) best practices Android 13 ‘Now in Android’
  • 84. – API is now stable – Performance improvements are promised – Recomposition highlighter to find poorly optimised views – Lazy Layouts for efficiently showing lists of items Android 13 Compose 1.2 Beta
  • 85. – Allows classes and methods to be precompiled – These are bundled with your release to speed startup – Most crucial user journeys profiled via Macrobenchmark Android 13 Baseline Profiles
  • 86. – Edit and observe changes to composable functions – Will significantly simplify and speed up UI development – Works on previews, emulators and devices – But still a work in progress Android 13 Live Edit
  • 88. game changer 1 multiplatform libraries COMMON KOTLIN KOTLIN ANDROID KOTLIN JS KOTLIN NATIVE KOTLIN JVM NATIVE ARTEFACT JS BUNDLE JAR
  • 89. – Union Types with ‘|’ syntax – Improvements to Sealed Types – Extended Operator Overloading – Name based Destructuring – Collection Literals – Structure Literals (Tuples?) game changer 2 potential new language features
  • 90. – Brings Google’s UI Toolkit to web – In theory, enables reuse of UI code across stack game changer 3 compose for web https://compose-web.ui.pages.jetbrains.team/ Div(attrs = attrs) { Label { Input( type = InputType.Checkbox, attrs = {} ) Span { content() }}}
  • 92. – Kotlin is emerging from a period of consolidation – Which opens the door to lots of good things – Better tooling, new features, faster builds etc... – Android continues to innovate on top of Kotlin – Compose could be ‘one DSL to rule them all’ conclusions ...great things lie ahead