Typing in Java, Kotlin and Scala

67
Typing in Java, Kotlin and Scala Hanneli Tavante Breandan Considine

Transcript of Typing in Java, Kotlin and Scala

Page 1: Typing in Java, Kotlin and Scala

Typing in Java,Kotlin and Scala

Hanneli Tavante

Breandan Considine

Page 2: Typing in Java, Kotlin and Scala

Hi!@breandan @hannelita

Page 3: Typing in Java, Kotlin and Scala

DisclaimerWe will work on a single example

and rebuild it several times

It is not a language war!

We are going to discusssome architecture concepts

Page 4: Typing in Java, Kotlin and Scala

Agenda

Representing Layouts in JavaMoving to KotlinCovariance and contravariance in ScalaCovariance and contravariance in KotlinByteCode and type erasureWhy is this important?

Page 5: Typing in Java, Kotlin and Scala

Mobile

Vertical Horizontal

Layout

Page 6: Typing in Java, Kotlin and Scala

How can werepresent that in

Java?

Page 7: Typing in Java, Kotlin and Scala

Layout

Vertical

Horizontal

Page 8: Typing in Java, Kotlin and Scala

class Layout { //superclass}

class Vertical extends Layout {

}

class Horizontal extends Layout {

}

Page 9: Typing in Java, Kotlin and Scala

Vertical

Horizontal

Layout

Page 10: Typing in Java, Kotlin and Scala

Inheritance... mehTight couplingReusing base class for unrelated child

Page 11: Typing in Java, Kotlin and Scala

Can we come up with abetter layout?

class Vertical implements Layout {

}

interface Layout {

}

class Horizontal implements Layout {

}

Page 12: Typing in Java, Kotlin and Scala

Vertical

Horizontal

Layout

Page 13: Typing in Java, Kotlin and Scala

Does this objecthave these skills?

Does this objectunderstand this

protocol ?

Page 14: Typing in Java, Kotlin and Scala

Name refactor

class Vertical implements Orientation {

}

interface Orientation {

}

class Horizontal implements Orientation {

}

Page 15: Typing in Java, Kotlin and Scala

It is time to addsome methods

rotate()

rotate() applied to a Horizontal -> Vertical

rotate() applied to a Vertical -> Horizontal

Page 16: Typing in Java, Kotlin and Scala

Where should weplace the method

rotate() ?

Page 17: Typing in Java, Kotlin and Scala

class Vertical implements Orientation {

}

interface Orientation {

}

class Horizontal implements Orientation {

}

Page 18: Typing in Java, Kotlin and Scala

class Vertical implements Orientation {

Horizontal rotate() { return new Horizontal(); }

}

interface Orientation {

}

class Horizontal implements Orientation {

Vertical rotate() { return new Vertical(); }

}

Page 19: Typing in Java, Kotlin and Scala

class Vertical implements Orientation {

Horizontal rotate() { return new Horizontal(); }

}

interface Orientation { Orientation rotate();

}

class Horizontal implements Orientation {

Vertical rotate() { return new Vertical(); }

}

Page 20: Typing in Java, Kotlin and Scala

Can we make itbetter?

Page 21: Typing in Java, Kotlin and Scala

We also could useGenerics

class Layout<T> {

}

Page 22: Typing in Java, Kotlin and Scala

class Layout<T> {

}

class Vertical {

}

class Horizontal {

}

Page 23: Typing in Java, Kotlin and Scala

Layout

Vertical

Horizontal

Page 24: Typing in Java, Kotlin and Scala

How do we restrict aLayout either

Layout<Vertical> orLayout<Horizontal>

Page 25: Typing in Java, Kotlin and Scala

class Vertical implements Orientation {

}

interface Orientation {

}

class Horizontal implements Orientation {

}

class Layout<T extends Orientation> {

}

Page 26: Typing in Java, Kotlin and Scala

Can we have a generic Layout rotate() ?

Page 27: Typing in Java, Kotlin and Scala

class Vertical implements Orientation {

Horizontal rotate() { return new Vertical(); }}

class Horizontal implements Orientation {

Vertical rotate() { return new Horizontal(); }}

interface Orientation { Orientation rotate();}

class Layout<T extends Orientation> { public Layout(T t){ this.t = t; } Orientation rotate(){ t.rotate(); }}

Page 28: Typing in Java, Kotlin and Scala

We want to achieve:

Layout<Horizontal> layoutHorizontal = new Layout<Horizontal>(new Horizontal());

layoutHorizontal.rotate();

layoutHorizontal.rotate();Orientation result

=Layout<Vertical> layoutvertical

We want:(Layout<Vertical>)

=

Explicit casting

:(

Page 29: Typing in Java, Kotlin and Scala

Is there any wayto avoid that?

Page 30: Typing in Java, Kotlin and Scala

Agenda

Representing Layouts in JavaMoving to KotlinCovariance and contravariance in ScalaCovariance and contravariance in KotlinByteCode and type erasureWhy is this important?

Page 31: Typing in Java, Kotlin and Scala

In Kotlin:

class Vertical : Orientation { override fun rotate() = Horizontal()}

class Horizontal : Orientation { override fun rotate() = Vertical()}

interface Orientation { fun rotate(): Orientation}

class Layout<out T : Orientation>(val t: T) {}

Page 32: Typing in Java, Kotlin and Scala

In Kotlin:class Layout<out T : Orientation>(val t: T) {}

Page 33: Typing in Java, Kotlin and Scala

In Kotlin:class Layout<out T : Orientation>(val t: T) {}

@JvmName("rotateVertical")fun Layout<Horizontal>.rotate(): Vertical = this.t.rotate()

@JvmName("rotateHorizontal")fun Layout<Vertical>.rotate(): Horizontal = this.t.rotate()

Extension functions

Page 34: Typing in Java, Kotlin and Scala

In Kotlin:val horizontal = Layout(Horizontal())val vertical = Layout(Vertical())

// Type safe rotation!var v: Layout<Vertical> = horizontal.rotate()var h: Layout<Horizontal> = vertical.rotate()h = horizontal.rotate().rotate()v = vertical.rotate().rotate()

Page 35: Typing in Java, Kotlin and Scala

In Kotlin:val horizontal = Layout(Horizontal())val vertical = Layout(Vertical())

// Type safe rotation!var v: Layout<Vertical> = horizontal.rotate()var h: Layout<Horizontal> = vertical.rotate()h = horizontal.rotate().rotate()v = vertical.rotate().rotate()

/* Does not compile!v = horizontal.rotate().rotate()h = vertical.rotate().rotate()*/

Page 36: Typing in Java, Kotlin and Scala

Agenda

Representing Layouts in JavaMoving to KotlinCovariance and contravariance in ScalaCovariance and contravariance in KotlinByteCode and type erasureWhy is this important?

Page 37: Typing in Java, Kotlin and Scala

Redesign In Scala:trait Orientation {}

Page 38: Typing in Java, Kotlin and Scala

Redesign In Scala:trait Orientation {}

class Vertical extends Orientation {}

class Horizontal extends Orientation {}

Page 39: Typing in Java, Kotlin and Scala

Redesign In Scala:trait Orientation {}

class Vertical extends Orientation {}

class Horizontal extends Orientation {}

abstract class Layout[+T <: Orientation] { def layout: T}

Page 40: Typing in Java, Kotlin and Scala

Redesign In Scala:trait Orientation {}

class Vertical extends Orientation {}

class Horizontal extends Orientation {}

abstract class Layout[T <: Orientation] { def layout: T}

class VerticalLayout(v: Vertical) extends Layout[Vertical] { override def layout = v}

class HorizontalLayout(h: Horizontal) extends Layout[Horizontal] { override def layout = h}

Page 41: Typing in Java, Kotlin and Scala
Page 42: Typing in Java, Kotlin and Scala

Orientation

Vertical

Horizontal

Page 43: Typing in Java, Kotlin and Scala

Orientation

Vertical

Horizontal

Layout

Page 44: Typing in Java, Kotlin and Scala

Horizontal

Layout

Vertical

Orientation

LayoutVertical LayoutHorizontal

Page 45: Typing in Java, Kotlin and Scala

In Scalaval layout: Layout[Orientation] = new HorizontalLayout(new Horizontal)

Compile error: "Expression doesn't conformto the expected type"

Page 46: Typing in Java, Kotlin and Scala

In Scalaval layout: Layout[Orientation] = new HorizontalLayout(new Horizontal)

abstract class Layout[T <: Orientation] { def layout: T}

We need to tell the compiler thatLayout[Horizontal] is a subtype

Layout[Orientation]

Page 47: Typing in Java, Kotlin and Scala

In Scalaval layout: Layout[Orientation] = new HorizontalLayout(new Horizontal)

abstract class Layout[+T <: Orientation] { def layout: T}

We need to tell the compiler thatLayout[Horizontal] is a subtype

Layout[Orientation]

(Covariance)

Page 48: Typing in Java, Kotlin and Scala

In Scalaabstract class Layout[+T <: Orientation] { def layout: T

def rerender(layout: T)}

Method to re-render the actual screen,keeping the layout.

Page 49: Typing in Java, Kotlin and Scala

In Scalaabstract class Layout[+T <: Orientation] { def layout: T

def rerender(layout: T)}

Compile error: "Covariant type occurs incontravariant position"

Page 50: Typing in Java, Kotlin and Scala
Page 51: Typing in Java, Kotlin and Scala

In Scalaabstract class Layout[+T <: Orientation] { def layout: T

def rerender[T >: Orientation](layout: T)

}

Why does the injected argument needs tobe contravariant?

Page 52: Typing in Java, Kotlin and Scala

In Scalaabstract class Layout[+T <: Orientation] { def layout: T

def rerender(layout: T)

}

var layoutWrapper: Layout[Orientation] = new HorizontalLayout(new Horizontal) layoutWrapper.rerender(new Vertical)

^That is not right.That is why input arguments are

contravariant.

Page 53: Typing in Java, Kotlin and Scala

Scala and Kotlin helpyou actively thinkabout covariance

and contravariance

Page 54: Typing in Java, Kotlin and Scala

Agenda

Representing Layouts in JavaMoving to KotlinCovariance and contravariance in ScalaCovariance and contravariance in KotlinByteCode and type erasureWhy is this important?

Page 55: Typing in Java, Kotlin and Scala

Back to Kotlininterface Orientation { fun rotate(): Orientation}

object Vertical : Orientation { override fun rotate() = Horizontal}

object Horizontal : Orientation { override fun rotate() = Vertical}

Page 56: Typing in Java, Kotlin and Scala

Back to Kotlininterface Orientation { fun rotate(): Orientation}

object Vertical : Orientation { override fun rotate() = Horizontal}

object Horizontal : Orientation { override fun rotate() = Vertical}

class Layout<out T : Orientation>(val t: T) {}

Page 57: Typing in Java, Kotlin and Scala

Back to Kotlinopen class Builder<out T : Layout<*>> { open fun build(): T = build()}

Page 58: Typing in Java, Kotlin and Scala

Back to Kotlinopen class Builder<out T : Layout<*>> { open fun build(): T = build()}

open class Renderer<in T> { open fun render(t: T) { println(t) }}

Page 59: Typing in Java, Kotlin and Scala

Back to Kotlinopen class Builder<out T : Layout<*>> { open fun build(): T = build()}

open class Renderer<in T> { open fun render(t: T) { println(t) }}

fun covariance(horizontalBuilder: Builder<Layout<Horizontal>>, layoutBuilder: Builder<Layout<Orientation>>) { // Layout<Horizontal> is a subtype of Layout<Orientation> ✓ val bldr: Builder<Layout<Orientation>> = horizontalBuilder // Layout<Orientation> is a supertype of Layout<Horizontal> ✗ val hlbr: Builder<Layout<Horizontal>> = layoutBuilder //ERROR}

Page 60: Typing in Java, Kotlin and Scala

Back to Kotlinopen class Builder<out T : Layout<*>> { open fun build(): T = build()}

open class Renderer<in T> { open fun render(t: T) { println(t) }}

fun contrav(layoutRenderer: Renderer<Layout<Orientation>>, horizontalRenderer: Renderer<Layout<Horizontal>>) { // Layout<Orientation> is a supertype of Layout<Horizontal> ✓ val hlrd: Renderer<Layout<Horizontal>> = layoutRenderer // Layout<Horizontal> is a subtype of Layout<Orientation> ✗ val lrdr: Renderer<Layout<Orientation>> = horizontalRenderer}

Page 61: Typing in Java, Kotlin and Scala

Agenda

Representing Layouts in JavaMoving to KotlinCovariance and contravariance in ScalaCovariance and contravariance in KotlinByteCode and type erasureWhy is this important?

Page 62: Typing in Java, Kotlin and Scala

JVM Languageswill loose the T

parameter! class Layout {}

(type erasure)

Page 63: Typing in Java, Kotlin and Scala

StrategiesTypeTags and Shapeless libraries in ScalaExtension functions in KotlinReified generics in KotlinReflectionManually store T in a field

Page 64: Typing in Java, Kotlin and Scala

Agenda

Representing Layouts in JavaMoving to KotlinCovariance and contravariance in ScalaCovariance and contravariance in KotlinByteCode and type erasureWhy is this important?

Page 65: Typing in Java, Kotlin and Scala

To sum up

Think about different coding approachesDifferent architecturesNew conceptsUnderstand the goods and the bad parts of alanguage and when to use each of them

Page 67: Typing in Java, Kotlin and Scala

Thank you :)Questions?