Java is everywhere
▶ On the web
▶ On your phone
▶ On embedded devices
Slide 3
Slide 3 text
Resistence is futile
Like it or not, one day you will have to use Java
▶ Enterprise loves it
▶ Limited expressivity is a bless for maintenance
▶ It is extremely backwards compatible
▶ Lots of 1.4 code is still in the wild
Slide 4
Slide 4 text
Now for the bad sides
▶ Limited expressivity
▶ Limited type-inference
▶ Excessive verbosity
▶ Backwards compatibility is holding it back
Slide 5
Slide 5 text
Type Inference
val i = 10;
val m = new HashMap();
Slide 6
Slide 6 text
Type Inference
val i = 10;
val m = new HashMap();
In Java (6) we had to write
int i = 10;
Map m = new HashMap();
Slide 7
Slide 7 text
Type Inference (2)
but you could easily write
public class Maps {
public static Map map() { return new HashMap(); }
}
...
Map m = map();
which would work as intended
Slide 8
Slide 8 text
Politics has been holding it back
Map m = someWeirdMethodCall();
«the redundant type serves as valuable documentation […]
the redundancy allows the programmer to declare the
intended type, and thereby benefit from a cross check
performed by the compiler 1»
— Gilad Bracha
1http:/
/bugs.java.com/bugdatabase/view_bug.do?bug_id=4459053
Slide 9
Slide 9 text
No content
Slide 10
Slide 10 text
Checked Exceptions
public FileInputStream(String name) throws FileNotFoundException
No other mainstream programming language has
implemented it later
Slide 11
Slide 11 text
Java Collections
▶ Optional operations
▶ Basically Java way to say #fuckit
boolean java.util.List#add(E e)
▶ Appends the specified element to the end of this list
▶ Throws UnsupportedOperationException if the add
operation is not supported
Slide 12
Slide 12 text
No content
Slide 13
Slide 13 text
Another Example (properties)
The dreaded JavaBeans convention:
Person john = new Person("John Doe", "some street");
String name = john.getName();
john.setAddress("some other street");
A feature we find in modern programming languages
String name = person.name;
person.address = "some address";
Slide 14
Slide 14 text
Scala
case class Person(name: String, var address: String)
// generates the methods
def name: String
def address: String
def address_=(address: String): String
...
val john = Person("John Doe", "some street")
val name = john.name
john.address = "some other street"
Slide 15
Slide 15 text
C#
class Person
{
public string Name { get; }
public string Address { get; set; }
public Person(string name, string address) { ... }
}
...
var john = new Person("John Doe", "some street");
string name = john.Name;
john.Address = "some other street";
Slide 16
Slide 16 text
…and, of course, Visual Basic 6
Private m_Name As String
Public Property Get Name() As String
Name = m_Name
End Property
Public Property Let Name(ByVal s As String)
m_Name = s
End Property
...
Dim name As String = person.Name
person.Address = "some other street"
Slide 17
Slide 17 text
Scala to the rescue!
▶ Scala is awesome
▶ statically typed, «feels dynamic» (Bruce Eckel)
▶ Scala has a vibrant community and it’s 10 year old
▶ It’s gaining traction in the industry (sort of)
▶ so, what’s wrong with Scala?
Slide 18
Slide 18 text
Scala is not really interoperable
▶ You may try to convince me that it is simple, but if you
have to deal with code like this2
def map[B, That](f: A ⇒ B)(implicit bf: CanBuildFrom[Repr, B, That]): That
…then you are actively scaring people away
▶ Try and invoke this from Java. It’s impossible
▶ SI-43893 Resolution: NOT A BUG
2“The longest suicide note in history” http:/
/stackoverflow.com/q/1722726
3https:/
/issues.scala-lang.org/browse/SI-4389
Slide 19
Slide 19 text
Operator overloading is awesome
▶ but developers are idiots4
4scala-graph.org
Slide 20
Slide 20 text
Kotlin
▶ Developed by JetBrains
▶ (IntelliJ IDEA, PhpStorm, RubyMine…)
▶ Developed with enterprise in mind
▶ A better Java
▶ It takes hint from Scala, C#, Groovy
▶ (some Groovy devs are involved)
▶ Statically typed
Milestone 9 out (v0.9 — Oct, 15th)
Slide 21
Slide 21 text
Hello World
fun main(args: Array) {
println("Hello World")
}
Slide 22
Slide 22 text
Type Inference
val aNumber = 10
equivalent to
final int aNumber = 10; // notice the final modifier here
Slide 23
Slide 23 text
Nullable Types in Java
▶ Tony Hoare’s million dollar mistake (in Algol)
▶ The null reference
▶ There is nothing wrong with a bottom value
▶ The problem is null handling
Equivalent to annotating your Java 85 code with @NotNull and
@Nullable
@NotNull Map<@NotNull String, @NotNull Person> myMap = new HashMap<>();
5also possible with JetBrains’ own annotations from Java 6 onward
Slide 24
Slide 24 text
Nullable Types in Java
▶ Tony Hoare’s million dollar mistake (in Algol)
▶ The null reference
▶ There is nothing wrong with a bottom value
▶ The problem is null handling
Equivalent to annotating your Java 85 code with @NotNull and
@Nullable
@NotNull Map<@NotNull String, @NotNull Person> myMap = new HashMap<>();
5also possible with JetBrains’ own annotations from Java 6 onward
Slide 25
Slide 25 text
Nullable Types in Kotlin
val s1: String = null // compiler error
val s2: String? = null // compiles
// nullable result
val anUnsafeResult = someStringFunction()
val c: Char? = anUnsafeResult?.charAt(0)
// non-nullable result
val aSafeResult = anotherStringFunction()
val c2: Char = aSafeResult.charAt(0)
// nullable result with default
val c3: Char = anUnsafeResult ?: 'x' // default value
Slide 26
Slide 26 text
Extension Functions
fun String.reverse() {
return StringBuilder(this).reverse().toString()
}
or simply
fun String.reverse() = StringBuilder(this).reverse().toString()
Slide 27
Slide 27 text
Function literals
val numbers = listOf(1,2,3,4)
val even = numbers filter { (x) -> x % 2 == 0 }
or just
val even = numbers filter { it % 2 == 0 }
Slide 28
Slide 28 text
Data Classes in Kotlin
data class Person(val name: String, var address: String)
equals() and toString() are auto-generated
val myFoo = Foo("John Doe", "was here") // no `new` here
val theName = myFoo.name
myFoo.address = "was there"
▶ getName(), getAddress() and setAddressString() are
auto-generated for Java compatibility.
Slide 29
Slide 29 text
Arguments
fun foo(value: String, optionalValue: String = "default value") { ... }
...
foo("bar")
foo(value="my value", optionalValue="anotherValue")
And it works for constructors, too. Goodbye, builder pattern!
Slide 30
Slide 30 text
Inheritance
open class Animal(name: String) {
open fun eat(Food food) = "nom nom"
}
class Dog(name: String) : Animal(name) {
fun bark() = "woof!"
}
Slide 31
Slide 31 text
Traits
trait Animal {
// abstract values are allowed, but state cannot be initialized
val name: String
// function bodies are allowed
fun eat(Food food): String {
return "nom nom"
}
}
I hear you saying “that’s already in Java 8”. This is Java 6
compatible, though.
Slide 32
Slide 32 text
Smart Casts
if (lassie is Dog) {
println(lassie.bark()) // compiler knows about bark()
}
Slide 33
Slide 33 text
when
trait BinTree
class Node(val value: T, val left: BinTree, val right: BinTree): BinTree
class Leaf(val value: T) : Node(value)
...
fun depth(t: BinTree): Int =
when (t) {
is Leaf -> 1
is Node -> max(path(t.left), path(t.right))
else -> throw UnsupportedOperationException() // no other known types
}
Slide 34
Slide 34 text
Native Singleton Objects
object MainApp : Application {
fun hello() = "hello"
}
...
println(MainApp.hello())
Use case: static methods
Slide 35
Slide 35 text
Native Delegation
trait Base {
fun print()
}
class BaseImpl(val x : Int) : Base {
override fun print() { print(x) }
}
class Derived(b : Base) : Base by b
fun main() {
val b = BaseImpl(10)
Derived(b).print() // prints 10
}
Slide 36
Slide 36 text
Delegated Properties
class User(val map: Map) {
val name: String by Delegates.mapVal(map)
val age: Int by Delegates.mapVal(map)
}
Slide 37
Slide 37 text
Operator Overloading
by convention:
Expression Translated to
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.mod(b)
a..b a.rangeTo(b)
Slide 38
Slide 38 text
Operator Overloading (2)
Symbol Translated to
a[i] a.get(i)
a[i, j] a.get(i, j)
a[i_1, ..., i_n] a.get(i_1, ..., i_n)
a[i] = b a.set(i, b)
a[i, j] = b a.set(i, j, b)
a[i_1, ..., i_n] = b a.set(i_1, ..., i_n, b)
Slide 39
Slide 39 text
Type-Safe Builders (DSLs)
fun result(args: Array) =
html {
head { title {+"XML encoding with Kotlin"} }
body {
h1 {+"XML encoding with Kotlin"}
p {+"this format can be used as an alternative markup to XML"}
a(href = "http://jetbrains.com/kotlin") {+"Kotlin"}
p {
for (arg in args)
+arg
}
}
}
Slide 40
Slide 40 text
Ceylon
▶ Red Hat / JBoss
▶ Project Lead: Gavin King (Hybernate, Seam)
▶ Another strongly, statically-typed programming language
▶ Interesting type system
▶ …brought to you in a somewhat weird syntax
▶ v1.1 out (Oct, 9th 2014)
Slide 41
Slide 41 text
Hello World
void hello() {
print("hello world");
}
Slide 42
Slide 42 text
Classes
class Counter(Integer initialValue=0) {
variable value count = initialValue; //`value` auto infers type
shared Integer currentValue {
return count;
}
shared void increment() {
count++;
}
}
If you are wondering why shared you are not alone
Properties
▶ Properties
value count = 0;
shared variable value hello = "Hello"; // I CAN HAZ MODIFIERS
▶ automatic getters and setters
▶ getHello$() and setHello$()
▶ no, really
Slide 46
Slide 46 text
Annotations
"The user login action"
by ("Gavin King")
throws (`class DatabaseException`,
"if database access fails")
see (`function LogoutAction.logout`)
scope (session)
action { description="Log In"; url="/login"; }
shared deprecated
void login(Request request, Response response) { ... }
Slide 47
Slide 47 text
Union and Intersection Types
Person|Organization personOrOrganization = ... ;
Printable&Sized&Persistent printableSizedPersistent = ... ;
YSK: Java has them. But only for generics…
class C { ... }
Slide 48
Slide 48 text
Nullable Types
void hello(String? name) {
if (exists name) {
print("Hello, ``name``!");
}
else {
print("Hello, world!");
}
}
In Ceylon String? is a shorthand for String|Null
Slide 49
Slide 49 text
No content
Slide 50
Slide 50 text
Enumerated Subtypes
(Algebraic Data Types)
abstract class Node() of Leaf | Branch {}
...
Node node = ... ;
switch (node)
case (is Leaf) { ... }
case (is Branch) { .... }
Slide 51
Slide 51 text
Operator Overloading
Through Interfaces
▶ Summable supports the infix + operator (plus(X)),
▶ Comparable supports the comparison operators
(compare(X)),
▶ Correspondence supports the index operator,
▶ Ranged supports the segment and span operators
Slide 52
Slide 52 text
Native Module System
▶ Project Jigsaw, OSGi, JBoss Modules
▶ Ceylon produces modules natively
▶ .car files (basically .jar + extra metadata)
▶ Actually, Kotlin has an identical concept, but it is not yet
released
Slide 53
Slide 53 text
Roundup: Kotlin
▶ Overall, Kotlin feels like an incremental improvement over
Java
▶ pretty true, you can basically mix them
▶ they will work almost seamlessly
▶ Most features are already in Java as “best practices” or
idioms
▶ What Kotlin does is to raise them at the language level,
with some sugar
Slide 54
Slide 54 text
Roundup: Ceylon
▶ I have mixed feelings for Ceylon
▶ Interesting type system
▶ Elegant design
▶ Strange, arbitrary syntactic choices
▶ Interoperability Java → Ceylon is fine,
▶ Ceylon → Java: I had some problems