1 of 31

Kotlin in real projects

Pragmatic opinion on pragmatic language

Anton Keks @antonkeks

2 of 31

How can we save Java?

Why not use Kotlin :-)

3 of 31

It took Kotlin 6 years to get to 1.0

2010-2016

Given the amount of time, it should be perfect

4 of 31

SpaceX Falcon 9 rocket succeeded with landing in < 4 years�2012-2016

5 of 31

In comparison, from idea to 1.0

  • C: 1 year, 1972-1973
  • C++: 4 years, 1979-1983
  • Java: 4 years, from 1991 to 1995
  • Python: 3 years, 1991-1994
  • JavaScript: 10 days in 1995 :-)
  • Scala: 3.5 years, 2001-2004
  • Groovy: 3.5 years, 2003-2007
  • Clojure: 2.5 years, 2007-2009
  • Go: 2.5 years, 2009-2012

6 of 31

Why do I like Kotlin

  • Runs on JVM + mixed project support
  • Binary compatibility (unlike Scala)
  • Static typing (unlike Groovy)
  • Nullability checks at compile time (unlike Java)
  • Backwards compatibility (unlike Ruby, Python, etc)
  • Good IDE support (and getting better until as good as Java)
  • Relatively small runtime: 750k
  • Can be compiled to JavaScript
  • Almost: fast compilation (unlike Scala)
  • Will be improved much faster than Java (1.1 scheduled for Autumn)

7 of 31

Kotlin basics

  • fun main() {} - first class citizens
  • val vs var
  • val x: Type + type inference
  • class Dog(val name: String) - inline constructor
  • Public and final by default, declare open otherwise
  • No static, but objects and companion objects
  • Data classes auto-implement equals(), hashCode(), toString()
  • Properties, no fields
  • is == instanceof, as == casting
  • no checked exceptions, not primitive types

github.com/angryziber/kotlin-demo/tree/master/src/intro

8 of 31

Kotlin promises

9 of 31

Java interoperability

Currently, it’s Java 6 interoperability

Better than Scala, Clojure, etc

Probably worse than Groovy

Unexpectedly lots of differences �(access modifiers, keyword clashes)

Some code cannot be called, e.g. Cast.CastApi �(same name of interface and variable)

10 of 31

Java interop (2)

Java 8 APIs not yet supported by default, e.g. streams

As of 1.0.2, extension libs are provided for Java 7 and 8 APIs

All JVM based langs have trouble incorporating new Java features

Extension method future conflict problem unsolved yet

  • Mixed projects
  • Annotation processor support
  • Ctrl+Alt+Shift+K conversion in IDEA

11 of 31

Java interop (3): Collections

Immutable vs Mutable, but java.util in runtime

Some magic in compiler: hardcoded Scala-like implicits? ;-)

Why things like isEmpty() are not properties?

Functional methods are inline extension functions

Sequences, Ranges, Progressions vs Java 8 Streams

12 of 31

Java-like compilation speed

Not yet :-(

Probably faster than Scala, �but still noticeably slower �than Java

Uses daemon trick, like �Fast Scala Compiler

Gradle + Android�much better now

13 of 31

Java-like runtime performance

Probably mostly delivered

Heavy use of inlining by the compiler

Requires recompilation �when inlined function change

Collection operations not lazy

Runtime null checks?

14 of 31

Backwards compatibility

Still to be seen, not much before 1.0

Most likely, will be better than most

Hopefully not as good as Java

Innovation vs compatibility

Programming langs need a �dictator, not JEP

15 of 31

Kotlin’s exciting features

  • nullability
  • extension methods
  • closure passing syntax
  • = lots of constructs can be implemented using API, e.g. use, with, synchronized
  • = groovy-style builders
  • by - delegating properties
  • closures can mutate outer variables
  • when
  • operator overloading (only predefined)
  • default parameter values and named parameters

github.com/angryziber/kotlin-demo/tree/master/src/intro/advanced

16 of 31

Runtime nullability

You don’t expect KNPE in Runtime…

You get them more often than is normal, e.g. Mockito

Compiler flag to skip them in favor of Plain Old NPE? Especially for tests…

  • Look at “kotlinc -X” :-)

17 of 31

Fighting with nullability and immutability

Sometimes compiler doesn’t allow you to write code that you want

If framework forces you to initialize stuff in e.g. setUp() method

Or dependency injection

lateinit or by lazy

Hypothetical multithreading issues prevent smart casts from non-local vars

x?.let {}

18 of 31

Nullability and booleans

if (hint?.getBoolean())

  • Not possible, unlike Groovy

if (hint != null && hint.getBoolean())

  • Plain Old Java?

“${null}” == “null”

  • Unfortunately, compatible with StringBuilder

19 of 31

Ternary operator ( x ? y : z )

None in Kotlin

You can use longer syntax:�return if (condition) something else anything

Compare to Java:�return condition ? something : anything;

But Kotlin has Elvis, a shorthand: nullable ?: notnull

Where is consistency?

Why also not a?[0], but a!![0], or have to write a?.get(0)

20 of 31

Kotlin forgives Java more than itself

Compiler treats Kotlin and Java classes very differently

Code in Java, converted as-is to Kotlin, behaves differently

  • Getters/setters in Java can be used as properties
  • Same methods in Kotlin class cannot be used as properties

  • Java SAM interfaces can be used with lambdas
  • But Kotlin SAM interfaces not

21 of 31

Syntax inconsistency

Kotlinc can infer function return type if it uses =� fun hello() = 1

But cannot if it uses {}� fun hello(): Int { return 1 }

return: sometimes used, sometimes not (lambdas)

Lambdas vs anonymous functions

22 of 31

Lambdas

Syntax sometimes clumsier than Java 8 :-)

Borrowed from Groovy, allows for “extending syntax” with blocks

“return” in lambda is really a return! But only if used with an inlined function

Vs Anonymous functions

Function type != SAM interface, unlike Java

Typealiases in Kotlin 1.1 should help

23 of 31

Unit tests

All classes/methods final? No package-local visibility? Are we doomed?

Using JUnit directly not convenient

An obscure kotlin-test is provided

Mockito

Internal members vs Ant compilation

JetBrains also released Spek

24 of 31

Java vs Kotlin types

Java: primitives and wrappers

Kotlin: own types

varargs != array, main() function cannot have varargs, unlike Java

KClass vs java.lang.Class

Class::class.java is weird

25 of 31

Properties vs fields

How to control underlying fields?

@JvmField allows making fields in Kotlin

Property annotations

Private properties no longer have getters/setters in Kotlin 1.0?

Mandatory ‘is’ prefix for boolean properties derived from Java getters

Many Android/Swing getters/setters do not map to properties because of subtle signature diffs or overloads, e.g. TextView.setText, setAdapter, etc

Multiple setter support?

26 of 31

Bytecode quirks

Lots of annotations to make things more compatible with Java

internal - effectively, you cannot call them from Java

Objects get a static INSTANCE field

27 of 31

Java frameworks

Although, many are usable, there are problems

Keyword clashes (but you can use “import .. as”)

Runtime nullability checks sometimes break things (e.g. Mockito)

IDEA: inconvenient to use static imports

Many frameworks require adaptation modules for convenience in Kotlin

Annotating properties is not obvious (@field: etc can be used for clarity)

Writing Java API in Kotlin may require many annotations

28 of 31

IDE problems (fixable)

Incremental make skips some modified classes

Debugging: watches or Alt+F8 often fail in IDEA (e.g. internal properties)

Static imports for Java methods are inconvenient

Fewer inspections than Java, but improving

Code converter!!! But never produced compilable code for me,�LOC savings minimal by default, <10%

GUI designer doesn’t work with Kotlin

Running single JUnit test methods (partly fixed)

29 of 31

Run Kotlin without Runtime :-)

kotlinc -Xno-call-assertions -Xno-param-assertions hello.kt

Java HelloKt

30 of 31

Switching to Kotlin

No hype language

I was productive without reading the docs

A “better Groovy”, with static typing and great IDE support

Compiler/stdlib enforces explicit decisions instead of choosing unexpected ones implicitly (e.g. crossinline modifiers)

Gradual conversion is possible

  • Even Gradle is switching!

31 of 31

Thanks!