Slide 1

Slide 1 text

Practical
 Advanced Kotlin
 in Practice Sebastiano Poggi @seebrock3r

Slide 2

Slide 2 text

Before we begin! ● Make sure you have a computer ● Make sure you have an IDE: IntelliJ IDEA, Android Studio ● Make sure it’s up to date ● Make sure the Kotlin plugin is enabled and up to date, too ● Clone the repo: http:!"bit.ly/advanced-kotlin-workshop You have 40 minutes …more or less

Slide 3

Slide 3 text

Topics of the workshop ● Properties: lateinit, delegates ● Type system: type erasure and reified types ● Enum vs sealed classes ● Functions: top level functions, mixing in some functional code ● DSLs ● Destructuring and numbered components ● Opinions™

Slide 4

Slide 4 text

Properties ● val vs var ○ val is like final in Java ○ Immutable reference ○ No guarantees on the value immutability ○ var are mutable variables ○ Mutable reference and value

Slide 5

Slide 5 text

Properties ● What if you don’t have a value right away? ○ lateinit var myVar ○ E.g., Dagger, Context-dependent values, etc ○ Zero overhead, can change afterwards ○ Check if initialised with !#myVar.isInitialized ○ For primitive types use by notNull() instead

Slide 6

Slide 6 text

Properties ● What if a value is expensive to produce and only used in some cases? ○ val myVal by lazy { … } ● Caches value once calculated, then can’t change anymore ● Synchronised (thread-safe) by default ⚠ ○ Can be made faster with LazyThreadSafetyMode.NONE ○ Check your threading model!

Slide 7

Slide 7 text

Type system ● Inherits JVM limitations ○ Type erasure loses type parameters’ information at runtime ● Is stricter in some regards ○ Has explicit covariance/contravariance keywords: in and out ○ No need to care much about them... except when you do ○ Seb’s top tip: try until the compiler is happy

Slide 8

Slide 8 text

Type system ● Reified types ○ Only available for inline functions ○ Allows compiler to resolve type parameters ○ No need to pass in classes explicitly as arguments ○ No need to specify type parameters explicitly (in most cases)

Slide 9

Slide 9 text

Enum and sealed classes ● Enumerations are enum classes ○ They work the same as in Java ● Sealed classes ○ Best of both worlds ○ Known set of values at compile time ○ Can be objects or (data) classes or a mix of them ● Use sealed classes for “enums with data” ○ E.g., kotlin.Result

Slide 10

Slide 10 text

Functions ● Member functions are declared on a class you own ● Extension functions can be declared on any class ○ Even final/closed classes ○ Statically dispatched ○ fun AnyClass.myFun() → static void myFun(AnyClass receiver)

Slide 11

Slide 11 text

Functions ● Functions don’t need to be in a class ○ Called top-level functions ○ Translate to static methods on JVM ○ In a synthetic class called like the file ○ E.g., a function in Functs.kt goes into FunctsKt ● Functions can take functions as parameters ○ Higher-order functions

Slide 12

Slide 12 text

DSLs ● Create domain-specific languages ○ Extension functions for scoping ○ Higher-order functions to compose behaviour ○ E.g.:
 fun user(block: User.() !% Unit): User { … }
 val user = user { name = "Roborbio" }

Slide 13

Slide 13 text

Functional code ● Kotlin is OO but has FP facilities ○ Top-level functions ○ Function types & lambdas ○ Higher-order functions ○ Rich collection processing APIs ● Sequences ○ Lazy streams ○ Can only be “played” once

Slide 14

Slide 14 text

Functional code ● Pure functions ○ Regular functions ○ No “outside” dependencies ○ No side effects ■ If you need them, isolate and make them explicit ● Great for some use cases ○ Data processing ○ Pipelines

Slide 15

Slide 15 text

Collection/sequence APIs ● Same idioms as general FP ○ Mapping, filtering, grouping, aggregating, reducing ● Collection type-specific APIs ○ Lists: get by position, sublist, binary search, … ○ Maps: key/value aware functionality ○ Sets: intersect, union, subtract

Slide 16

Slide 16 text

Destructuring declarations ● Special functions: componentN() ○ Access constructor properties in order ○ Data classes have them by default ● Destructuring declarations ○ Unpack classes’ components ○ data class User(val name: String, val surname: String, val email: String)
 val (name, surname) = myUser

Slide 17

Slide 17 text

and now… segment I like to call opinions!

Slide 18

Slide 18 text

and now… opinions! In a segment I like to call EVERYBODY HAS OPINIONSTM BUT I AM THE SPEAKER SO YOU ALL
 HAVE TO LISTEN TO MY RANTS NOW

Slide 19

Slide 19 text

Everybody has Opinions! ● Extension functions ○ They’re awesome! But… ○ Hard to discover, “break” encapsulation ○ Avoid abusing them, same as util classes ○ Prefer smaller scopes ○ …unless used as entry point to 3rd party API ○ Consider top-level functions instead ○ Factor in Java interop

Slide 20

Slide 20 text

Everybody has Opinions! ● Delegate properties ○ They’re cool but don’t abuse them ○ Can obscure meaning and behaviour ● Lazy ○ Don’t make inexpensive stuff lazy ○ Prefer lateinit for “initialised later” idiom

Slide 21

Slide 21 text

Everybody has Opinions! ● DSLs ○ You don’t always need a DSL for that ○ Avoid being too “smart” and side effects ● Operator overloading ○ Don’t unless it’s extremely obvious what you’re doing ○ Avoid at all costs if any risk of surprising users ○ Must be obvious that it’s an overload

Slide 22

Slide 22 text

Ready Player one Sebastiano Poggi
 @seebrock3r http:!"bit.ly/advanced-kotlin-workshop