M6.2 Available

Today we release Kotlin M6.2 which brings some interesting and important features. The newly released IntelliJ IDEA 13 is now supported too. Let’s take a look.

Language Enhancements

There are some long awaited and important changes to the language.

Tail Call Optimization

Good news to all fans of functional programming: Kotlin now supports tail call optimization (TCO). This means that we can now write code in functional style without the risk of blowing up the call stack. For example, here’s what a left fold on an iterator may look like:

tailRecursive
fun Iterator.foldl(acc : A, f : (e : T, acc : A) -> A) : A =
        if (!hasNext()) acc
        else foldl(f(next(), acc), f)

Note that the function is annotated with [tailRecursive]: this is mandatory when you want tail calls to be optimized. We do not perform TCO silently, for two reasons:

  • Debugging. Since tail-call-optimized functions do not make actual recursive calls, debuggers won’t show any stack frames representing recursion, you won’t be able to inspect local variables on previous levels of recursion etc. Thus we believe the least surprising way of coming about this is make it explicit in the code.
  • Safety. We all know a funny thing about code: it often does not do what it appears to be doing ;) Same with tail calls: often times a call looks as if it were a tail call, but in fact it isn’t. This means that no optimization can be made, and performance would be compromised. With [tailRecursive] annotation the compiler knows where calls must be optimizable and warns you when you make a mistake.

We hope functional-oriented libraries like funKTionale will benefit from this feature, as well as Kotlin’s standard library.

Thanks to Sergey Mashkov for the contributions in making this happen.

Constant Expressions

As you know, Kotlin is very strict on types: even numeric types are not coerced to each other implicitly. This is necessary both to implement our approach of having all types defined in the same way (as classes) and to avoid strange artifacts that Java presents sometimes. Fortunately, we can eliminate most of the little inconveniences this brings by being smart with constant expressions. Now this work is finalized, and you can do things like this:

val x: Long = -1

or

val b: Byte = -1

In fact, what happens under the hood is that the compiler computes the value of the constant expression on the right, checks that it fits the range of the expected type (Long or Byte) and converts the constant. The same does not happen with non-constants because they can not be checked.

Also, the compiler warns you when there is an arithmetic overflow:

val monthInMilliseconds = 1000 * 60 * 60 * 24 * 30 // WARNING

Here the result exceed the range of type Int, and the compiler warns you about it. You can fix the overflow by making the first number Long:

val monthInMillisecondsL = 1000.toLong() * 60 * 60 * 24 * 30 // OK

But this yes, well, too long. We now support the familiar “L” suffix to the numbers:

val monthInMilliseconds = 1000L * 60 * 60 * 24 * 30 // OK

Note that the “l” suffix for Longs, notorious for its looking so much like “1″ in many fonts, is not allowed.

Similarly, there’s the “F” suffix for floats. Since little “f” does not look like any digit and altogether looks more pleasant, it is not forbidden. :)

The story above is all good for integral types, but floating-point values are tricky, as we all know. For example:

println(0.1 < 0.1f) // prints "true"

It has a lot to do with the binary nature of these decimal-looking numbers, and the cases where conversions are lossless do not look intuitive to humans. Thus, we do not convert floating-point values automatically. Double is used by default, if you want a float, say so explicitly:

val fl: Float = 1.0f

Java Interoperability

Mutability Annotations

You remember that collections in Kotlin have read-only interfaces. What about Java libraries that expose collections? Along with well-known @Nullable/@NotNull, Kotlin now provides annotations to mark Java collections @ReadOnly or @Mutable.

Given the following Java code

public List<EMail> activeEmails() {
    ...
}

when calling it from Kotlin, the return value is List<EMail> and Kotlin treats this as a MutableList. We can now decorate the method with a @ReadOnly annotation, so that the list can not be mutated through this reference:

@ReadOnly
public List<EMail> activeEmails() {
   ...
}

which means that we can no longer call the add() on it for instance

image

We can do the same when it comes to parameters. Take the following Java method

void processEmails(List<EMail> emails) {
    ...
}

in Kotlin, this would be represented as

fun processEmails(emails: List<EMail>)

which can be turned into

fun processEmails(emails: MutableList<EMail>)

by annotating the original Java code with @Mutable

void processEmails(@Mutable List<EMail> emails) {
    ...
}

By the way, these annotations provide excellent documentation for your Java code, too.

Kotlin’s knowledge of nullable types available to Java

The compiler now emits @Nullable and @NotNull annotations in the Java byte code. This allows IntelliJ IDEA to make use of  these and warn of nullability violations when calling Kotlin code from Java.

For instance

class Customer {
   fun checkSocialSecurity(accountNumber: String) { ... }
}

when called from Java

Customer customer = new Customer();
customer.checkSocialSecurity(null); // WARNING

would cause a warning.

Android SDK

We now provide annotations for the entire Android SDK, making it even easier and safer to work on Android projects.

Java to Kotlin Converter

Last but not least, and while not entirely related to Java Interop, we have also improved the Java to Kotlin converter, providing cleaner code and nicer formatting.

JavaScript  Improvements

We’re continuing to improve the JavaScript compiler support. You can now configure whether you want sourcemaps generated and where you’d want these placed via the Kotlin Compiler page in Settings | Preferences

image

Additionally you can specify output file prefix and postfixes for the generated Kotlin JavaScript code.

We’ve also fixed a couple of JavaScript related issues including

  • Default arguments to functions are now fixed
  • super-constructor calls are supported
  • Class objects in traits are supported

Ant Support  Improvements

Java Compiler

Importing tasks using typeDef instead of taskDef gives us access to not only the existing<kotlinc> task but also the new <withKotlin/> task for Ant which allows the compilation of Kotlin files when using the Java compiler task <javac>, using the src attributes defined in the latter.

JavaScript Compiler

You can also compile Kotlin to JavaScript using Ant. There is a new task <kotlin2js> which given  src and output attributes, will compile Kotlin to JavaScript. A variety of additional options are also available, similar to those in the IDE for enabling sourcemaps, prefix and suffix of generated files, etc.

IDE Enhancements

We can now provide IntelliJ IDEA with additional command line parameters to the compiler as well as whether we want warnings to be generated

image

In addition, some other IDE features have been enhanced/updated:

  • Smart Completion: While only started, we are working towards providing smarter completion in Kotlin, along the lines of what we  already provide for Java.

image

  • Find Usages: Improved  performance. Ability to find local and private declarations, support for value/type parameters and property getters/setters, along with some bug fixes.
  • Change Signature Refactoring: Now supports function hierarchies.
  • Rename Refactoring: Fixes issues when renaming Kotlin classes and functions from Java code as well as renaming Kotlin base functions with overrides.

While we’ve only covered some of the improvements with this release, there have been an additional 120 issues resolved including features and bug fixes, since Milestone 6.1.

Download

If you are using IntelliJ 13, you already have Kotlin M6.2 available out of the box. Otherwise, you can download the Compiler from the release page and the plugin from the IntelliJ IDEA repository.

This entry was posted in General and tagged . Bookmark the permalink.

12 Responses to M6.2 Available

  1. Yudhistira Arya says:

    Currently, one of the critical reason that prevent me from using Kotlin to develop serious application is the lack of mocking support (library, etc…).

    Is there going to be any effort on this?

  2. Andrey Ponomarev says:

    Each time I see a new milestone announcement I hope to find “Extract Function” refactoring. According to KT-1425 it could be implemented in M3, but now it’s M6.2

  3. Andrew C says:

    Probably a silly question, but are the @Mutable and @ReadOnly annotations also available to KAnnotator? Thanks.

    • Alexey Sedunov says:

      KAnnotator is capable of collection mutability inference and, in particular, is aware of @Mutable/@ReadOnly annotations. However at the moment this feature is not exposed by KAnnotator IDEA plugin. We’are planning to add it in the near future.

  4. Oliver Plohmann says:

    Support for tail call optimization was a nice surprise. Kotlin now as well has an important thing to offer for people that are into FP. Please continue to keep the language simple yet expressive as in the past and it’ll turn out great :-).

  5. Gordon Oliver says:

    Is there an example of using 2D and 3D arrays in Kotlin?

  6. Guangyu HE says:

    is M6.2 not compatible with Android studio 5.0?
    *.kt files will not be highlighted, and I can’t foung config kotlin commands in tools menu.
    BTW, I use “org.jetbrains.kotlin:kotlin-gradle-plugin:0.7.115″

    • Hadi Hariri says:

      Hi,

      Currently M6.2 isn’t compatible with that version of Android Studio. Next release will be.
      It’s better to use the kotlin-plugin for the IDE and kotlin-gradle plugin of the same version. Are you pointing to the nightly builds?

      • Guangyu HE says:

        Thanks for the quick response.

        Because I want to use Android Studio 0.5.0 and gradle 1.11, old kotlin-gradle plugin doesn’t support it. So I get the newest kotlin-gradle-plugin in the repo, which is compatible with Android studio 0.5.0.

        Now we have adopted Kotlin to develop android software, so we hope that Kotlin can be compatible with the newest studio version.

        Many thanks for Kotlin develop team. WE like it very much.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>