Impressions and conclusions
after year on production
I wanted, but they deserve for a separate presentation
Java is slowly collapsing giant
Text
Text
Text
Text
Google Search and Book Selling is indicator of what people are interested in
There is so much mature JVM programming languages
Both Scala and Groovy limp on:
They are fun, but not pragmatic
Cmd + Shift + A
Ctrl + Shift + A
Configure Kotlin in the project
Cmd + Shift + A
Ctrl + Shift + A
Convert Java File to Kotlin File
Kotlin have most of the modern languages features (and some custom), while keeping build and execution time close Java.
fun main(args: Array<String>) {
println("Hello world")
}
for (i in 1..10) {
print(i)
}
// 12345678910
for (i in 10 downTo 1 step 2) {
print(i)
}
// 108642
for (c in 'A'..'Z') {
print(c)
}
// ABCDEFGHIJKLMNOPQRSTUVWXYZ
for (c in "Some text") {
print("$c.")
}
// S.o.m.e. .t.e.x.t.
val capitolToCountry = listOf(
"Washington" to "United States of America",
"Warsaw" to "Poland",
"London" to "Great Britan"
)
for ((capitol, country) in capitolToCountry) {
println("Capitol of $country is $capitol")
}
// Capitol of United States of America is Washington
// Capitol of Poland is Warsaw
// Capitol of Great Britan is London
listOf(User("Marcin", "Moskala"), User("Michal", "Michalski"), User("Ania", "Mania"))
.filter { it.name.startsWith("M") }
.map { (name, surname) -> "$name $surname" }
.joinToString(separator = " and ")
.let(::print)
val s = (1..10) // Range from 1 to 10
.filter { it % 2 == 0 } // [2, 4, 6, ...]
.map { it * it } // [4, 16, 36, ...]
.sum() // 220
fun <T : Comparable<T>> List<T>.quickSort(): List<T> {
if (size < 2) return this
val pivot = first()
val (smaller, greater) = subList(1, size).partition { it <= pivot }
return smaller.quickSort() + pivot + greater.quickSort()
}
Short
Good-looking
Minimal syntax
Lot's of possibilities
Language safeness - more errors can be prevented by checks at compile time instead of falling at run time. Also language is referred as safe when it is promoting way of coding that is know as more secure.
val name: String = "Marcin"
Read only
var name: String = "Marcin"
Changeable
var person: Person
Must be inilialized
var person: Person = null
Not null type cannot be null
var person: Person? = null
? after type makes it nullable
person.name
Nullable must be unpacked
person?.name
Safe call (null if person is null)
person!!.name
Unsafe call (exception if person is null)
if(person != null) {
person.name
}
Smart Cast (after nullability check, object is casted to not-null)
if(person == null)
return
person.name
if(person != null && person.name == "Marcin")
if(person == null || person.surname == "Bąk")
person?.name ?: "unknown"
val name = person?.name ?: throw Error("No person or name is null")
val name = person?.name ?: return
Null safety prevents from NPE - most common Java error.
Null safety makes Kotlin code much safer while it cost nearly nothing. It is Simple and smart.
One catch - when we assume that some value form API or Java lib is not-null and we will have case where it is then we have an exception even if we don't use it.
Null safety promotes val usage over var, because in val there is no Smart Casting in case of multithreading.
Kotlin often promotes using val over var. It is good for thread safety and also really good practice.
// Java
public class PersonJava {
private String name;
private String surname;
private int age;
PersonJava(String name, String surname, int age) {
this.setName(name);
this.setSurname(surname);
this.setAge(age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Person {
var name: String
var surname: String
var age: Int
constructor(name: String, surname: String, age: Int) {
this.name = name
this.surname = surname
this.age = age
}
}
Yap, this is exactly the same
Getters and setters are there
class Person(name: String, surname: String, age: Int) {
var name: String = name
var surname: String = surname
var age: Int = age
}
Still the same
Primary constructor
class Person(val name: String, val surname: String, val age: Int)
Yap, this is exactly the same
Getters and setters are there
var name: String? = null
get() = name?.capitalize()
set(value) {
if(value == null || value.length == 0) return
field = value
}
We can still edit getters and setters
Kotlin property = Java private field + accessors
accessors = getter for var, getter + setter for var
class Person(val name: String, val surname: String) {
val fullName: String
get() = "$name $surname"
}
Here Kotlin property is just a setter
Kotlin syntax for defining classes is zero-boilerplate.
Kotlin properties are much more powerful then Java fields.
This leads to short, elegant and easily changeable code.
val name = "Marcin"
val name: String = "Marcin"
listOf(1, 2, 3, 4, 5, 6).filter { it > 3 }.map { it * 2 }.sum()
val double: (Int)->Int = { i -> i * 2 }
val double = { i: Int -> i * 2 }
Having static typing and good inference system, we can achieve all benefits from static typing while getting most of benefits form dynamic.
Type is inferred
fun double(i: Int) = i * 2
class A() {
fun triple(i: Int) = i * 3
fun twelveTimes(i: Int): Int {
fun fourTimes(i: Int) = double(double(i))
return triple(fourTimes(i))
}
}
fun main(args: Array<String>) {
double(1) // 2
A().twelveTimes(2) // 24
}
Top-level function
Mamber function
Local function
fun main(args: Array<String>) {
var a: Int = 0
val inc = { a++ }
val dec = { a--}
val prt = { println(a) }
button1.onClick = { inc(); prt() }
button2.onClick = { dec(); prt() }
}
fun main(args: Array<String>) {
var a: Int = 0
button1.onClick = { print(a++) }
button2.onClick = { print(a--) }
}
fun getCounter(): ()->Int {
var i: Int = 0
return { i++ }
}
// Java
interface OnClickListener {
fun onClick(v: View)
}
// Java
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// Code
}
};
val listener = View.OnClickListener { /* Code */ }
// Java
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getBaseContext(), "Button clicked", Toast.LENGTH_LONG).show();
}
});
button.setOnClickListener { toast("Button clicked") }
Kotlin allows fully functional programming.
It's function syntax it short and simple.
Kotlin lambdas not only shorter, but also much more powerful then Java anonymous objects or Java 8 lambdas.
Kotlin made a bridge to simply use Java methods with function interfaces.
Whole function system makes Kotlin syntax shorter and more readable. It also prevents from redundancy.
StringUtils.capitalize(str)
val replacedStr = StringUtils.replaceAll(str, "name" to name, "surname" to surname)
val capitalizedStr = StringUtils.capitalize(replacedStr)
str.capitalize()
str.replaceAll("{name}" to name, "{surname}" to surname)
.capitalize()
fun String.noLongerThen(max: Int): String {
return this.substring(0, Math.min(max, this.length))
}
fun main(args: Array<String>) {
println("Joe".noLongerThen(4)) // Joe
println("James".noLongerThen(4)) // Jame
println("Ashley".noLongerThen(4)) // Ashl
}
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
fun Context.toast(text: String) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
toast(text)
in practice
view.visibility = Visible.GONE
ViewUtlis.hide(view)
We often do
No better
view.hide()
ViewUtlis.hide(view)
Better
Good looking
Less redundant
Simple
val Context.appVersion: String
get() = packageManager.getPackageInfo(packageName, 0).versionName
var View.isVisible: Boolean
get() = visibility == View.VISIBLE
set(value) {
visibility = if (value) View.VISIBLE else View.GONE
}
Kotlin Extension Functions lead to good looking, less redundant and simple code.
They allow to extend libraries with own functionalities.
It is dangerous - each project have it's own extension functions, so it is leading to different programming style.
Concise
Safe
Interoperable
Kotlin is a practical language designed to solve real-world problems.
Kotlin is based on years of industry experience.
Kotlin is shifting lot's of responsibilities from programmer to IDE.
Kotlin syntax is minimal
Kotlin syntax is easily changeable
Kotlin syntax is safe
Kotlin is perfectly working with Java APIs, tools and libraries. Also Kotlin can be always used from Java. It is keeping all that Java gives, while adding it's own features.