Kotlin 1.0 Beta 4 is Out!

We are happy to announce Kotlin Beta 4, another step towards 1.0! We are now mostly focused on the infrastructure and future-proof changes. Full list of changes is available here. More details below.

It’s also time to let you know about what else we are going to do before 1.0.

Improved incremental compilation (Experimental)

We have rolled out a new precise algorithm for dependency detection that makes Kotlin’s incremental compilation much faster. It’s still experimental, but works pretty well for our use cases already. To try it out:

Settings | Build, Execution, Deployment | Compiler | Kotlin Compiler | Enable precise incremental compilation (experimental)

Soon: same incremental compilation support is coming to Gradle! Stay tuned.

Language

Some highlights from the full list of changes.

Changes in overload resolution

Due to a fix in the overload resolution algorithm, Kotlin now treats SAM-converted Java functions more like members (they used to behave like extensions before). This fix is important, because otherwise many cases were interpreted in cumbersome ways by the compiler.

Unfortunately, there’s at least one relatively common case that has broken as a result. The fix is very easy, though. Now the compiler complains about file.listFiles { it.name == "..." }.
The reason is rather complicated:

  • there are three overloads of listFiles in java.io.File
  • two of them take a SAM-interface, which we convert so that they can take a lambda
  • so, when a parameterless lambda is passed in we don’t know which one should be chosen
  • it worked before, because an old library extension function (dating back to the pre-SAM era) was selected instead of a SAM-converted member.

The workaround is simple, just specify the parameter, e.g.:

Properties can be used as parameterless function objects

Example: in Kotlin String::length is a property, not a function, but it’s convenient to be able to use it where a function is expected, e.g.

So, we now allow this. In other words, whenever some API expects a function of type (R) -> T we can use a reference to a property of R whose return type is T.

Reserving keywords for future use

We are planning to add new features in the future releases of Kotlin, so we decided to reserve the necessary keywords in advance. We understand that one can’t predict all of the future, but here’s our best guess (no detailed design for the future features is available yet, but we’ll do our best to make them as useful as can be):

  • yield is reserved as a keyword
  • sealed is reserved in front of “when
  • typeof is reserved as a keyword. In JS, use jsTypeOf()
  • async is reserved in front of “{” and “fun

So, now, instead of async {...} we’ll have to say async () {...}. We understand that it’s not as clean, but we didn’t find a better option. Code completion will insert () automatically.

Code Cleanup will help you migrate existing code.

Java Wildcards

There were issues with how Kotlin translated variant types, e.g. whether a List<Foo> should be List<? extends Foo> in Java or simply List<Foo>. Subtleties details aside, we did the following:

  • By default, we do not generate wildcards in return types and where they make no sense
  • When a wildcard is needed, one can enforce its presence with a type annotation: List<@JvmWildcard String> is always List<? extends String> in Java
  • When we need to get rid of a wildcards, we can use @JvmSuppressWildcards (this can be used on a type or any declaration that contains it)

Examples:

NOTE: this concerns not only collections, but all types that involve declaration-site variance

Library changes

We are cleaning up the Standard Library, and this includes some repackaging:

  • The kotlin.test package has been moved to a separate jar-file: kotlin-test.jar. A quick-fix is available in the IDE to add this dependency automatically.
  • In preparation to rearranging packages in the Standard Library, we have created the new packages and copied all functions to them. The old functions are kept for binary compatibility. No migration needed for Kotlin code, Code Cleanup is available for Java code.

Later, we are planning to extract one more JAR from the library: it will contain array utilities that are infrequently used, so we’d like to keep them outside the main JAR to reduce its size.

Some more highlights:

Kotlin’s Int::class may correspond to Java’s int.class or Integer.class in different contexts (and it’s justified). To facilitate use cases when a specific one of the two is needed, we have introduced two properties:

  • Int::class.javaPrimitiveType returns Int.class
  • Int::class.javaObjectType returns Integer.class

Also, we can now say things like IntArray(5) { it * 3 }, i.e. create initialized primitive arrays.

Future change: meaning of null in collections

The later versions of the JDK are making collections more and more null-intolerant. For example, here’s what the JavaDoc says about java.util.Map.computeIfAbsent:

If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null.

These contracts are intrinsic to atomicity properties of such operations, so we decided that we have to meet them too, otherwise we won’t be able to guarantee proper behavior for Kotlin’s extension functions when they operate on null-free concurrent collections. So, we are going to change the behavior of getOrPut and other such functions so that they treat null value the same as the value was not present.

To update your code, follow the recommendations given in deprecation warnings.

What’s new in the IDE

  • Quick-fix for renaming unresolved references was added. It’s handy for adjusting symbols’ names when pasting some code to a different context:

  • Now the IDE lets you create functions from unresolved callable references:

  • Go to Test and Create Test actions now work for top-level functions:

  • Convert anonymous function to lambda expression intention has been added

  • Go to class and Search everywhere now show Kotlin built-in types

  • In debugger: option ‘Skip simple getters’ is now supported, which means that debugger won’t stop at properties defined in constructors, properties without getters or whose getters that return the value of some field

What’s next

After the Beta period is over, there will an RC and then 1.0.

We would really like to make sure that no code compiled with pre-release versions of Kotlin are kept around after 1.0, so the RC compiler will force recompilation of all the old code. We will coordinate with library maintainers outside JetBrains to make sure that all the widely-used libraries will be recompiled in time.

We’ll also take the opportunity to remove some legacy at this point:

  • remove all the deprecations that we have accumulated in the process of evolving our libraries,
  • remove all the deprecations from the generated code (you might not have heard of those, but they exist!),
  • get rid of some legacy bytecode peculiarities that were found during the beta,
  • move some of the stdlib code around so that the packages there have more structure.

After that point, the only compatible changes to the standard library are deprecations and additions (this does not include reflection APIs). We are running an open review for the library API to make sure we haven’t missed anything important.

Merry Kotlin! :)

This entry was posted in Releases. Bookmark the permalink.

20 Responses to Kotlin 1.0 Beta 4 is Out!

  1. Christian says:

    yield is reserved as a keyword
    sealed is reserved in front of “when“
    typeof is reserved as a keyword. In JS, use jsTypeOf()
    async is reserved in front of “{” and “fun“

    Oooh, can’t wait!

  2. Jon Renner says:

    Out of curiosity, what are Kotlin’s plans with regards to backward compatibility? Once Kotlin code hits 1.0, will there be a lifetime guarantee of backwards campatibility? Or just compatible with Kotlin 1.x, and Kotlin 2.0 will have breaking changes?

    • It’s three questions in one, I guess:

      • What kinds of compatibility will be guaranteed?
      • For how long will these kinds of compatibility be guaranteed?
      • What will be the version numbers?

      So, kinds of compatibility (some examples):
      – ABI/API, backward: new code can compile and run against old binaries
      – ABI, forward: old binaries can run against new binaries
      – Source, backward: new compiler can compile code that the old compiler could compile

      So, ideally you have all three for all code all the time. Reality is a bit rougher. For example, in Java:
      – New binaries may not be able to run against an older JDK or on older JVM (bytecode version, new APIs in the JDK)
      – New compiler may refuse to compile old code: e.g. enum keyword was introduced in Java 1.5, and its compiler refused to compile the code that used it as a name, e.g. void enum() {}

      In Kotlin, we are planning to do the following:
      – Make sure that older code can run against newer versions of Kotlin runtime.
      – Make sure than newer compilers can read binaries created by older compilers (after 1.0).
      – Do our best to minimize source-incompatible changes (provide migration tools if such changes are necessary), i.e. when newer compiler rejects the code accepted by an older compiler. Even Java fails to do that occasionally, so we have no hope to avoid it altogether, but we’ll try really hard.

      Regarding the lifetime of such compatibility support: we intend to make it LONG. How long is LONG is a good question, and it’s hard to guess now. Years, but I don’t know how many years.
      In any case, if we ever retire support for some ancient thing, we will keep it around as deprecated for a (long) while, and will probably provide conversion tools to migrate the old code/binaries, forever.

      Regarding version numbers, I’d expect releases which have to break source compatibility might be marked as major versions, e.g. 6.0, but it doesn’t mean that 2.0 has to break anything; only that if it breaks anything, it should probably be named 2.0 (or 5.0). But no firm decisions on the versioning yet.

  3. JB says:

    What is the quick fix to add the new test dependency?

    • Nikolay Krasko says:

      Usages of functions from kotlin.test like assertEquals(), assertNull() and other will become unresolved after moving from beta3 to beta4, but activating “Add kotlin-test.jar to classpath” will try to fix such errors by adding dependency to kotlin-test.jar (screenshot).

  4. wongloong says:

    hi,i have a error in kotlin,when i used the map like this
    val map= mapOf<String,Int>(“a” to 1, “b” to 2);
    for ((k,v) in map){

    }
    it’s will be error:
    Error:(12, 19) Kotlin: For-loop range must have an iterator() method

    can u help me and explain me?
    tks

    • mikhail.glukhikh says:

      Looks like you have some old version of Kotlin. Please do the following: in IDEA, execute “Rebuild Project” and check the first string in “Messages” tool window, it should be like “Kotlin: Kotlin JPS plugin version 1.0.0-beta-4584”. If you version is much lower than 4584 or even not 1.0.0-beta, update the Kotlin plugin. If not, please send us the whole source file.

      • wongloong says:

        ok,very thank u.may be my idea plugin version to lower.
        i remember i has update the plugin but it’s may be failed.
        fuck the GFW.
        thank u
        wish kotlin is better and better.

  5. Juan Liska says:

    Kobalt is a great Build tool that already supports incremental compilation

    • That’s a misunderstanding of terms, I think.

      There are two different things:
      – incremental build: we rebuild only modules whose sources/dependencies have changed
      – incremental compilation: inside a single module, we recompile only those files that have been changed and those that depend on them (can be extended to dependent modules as well)

      Kobalt has the former, I believe, as the latter is highly non-trivial without support from the compiler (and not very trivial even with it either).

  6. jlough says:

    curious, what’s the timeline for 1.0 release? any rough estimate? e.g. could i expect this a year from now, 2 years. or < 6 months. not to hold you to any number you say, of course :)

    i say this because i’m more hesitant to switch over (even though i really want to), if the timeline for a final release is pretty distant.

  7. jlough says:

    Also, separate question..i’ve been wondering about this for a while.

    Is kotlin held back, either in feature sets or closer to the backend (performance wise), by its dependent target of jvm 1.6?

    What happens when 1.9 comes out (or whatever after), and possibly introduces something substantial. like, hypothetically, value types?

    Will kotlin have to make a choice between maintaining compatibility and making those who can target the newest jvm, suffer? or will just some subsets of features be version specific. Personally, i’d rather not be at a disadvantage just because people are still running ancient jvm versions, when I am able to target the newest.

    • We intend to support both platforms, and the feature set of Java6-Kotlin may be a subset of Java9/10-Kotlin.

      People are not running ancient JVMs, they run Android that does not support newest JVM byte code features

      • jlough says:

        Well, actually people are
        See enterprise :)

        Where IBM only recently got Java 7 support, and a lot of enterprise environments are only targeting Java 6.

        Anyways, thanks for the info. All sounds like good news to me.

  8. Ross says:

    Really not a fan of final-by-default/open keyword :(

    This isn’t C++, we’ve got JIT. It’s not going to help performance or correctness, it’s just going to be a massive pain like checked exceptions were in Java.

    Even worse, there’s no “just throw a RuntimeException” workaround.

  9. Geobert says:

    Great stuff here!

    I was wondering if when using Android Studio (2.0 Preview 4), does the bug report concerning Kotlin plugin are reported to you?

  10. Pingback: IntelliJ IDEA 15.0.3 und Update für IntelliJ IDEA 16 EAP verfügbar - JAXenter

  11. Viachaslau says:

    Right now kotlin compiled to js and java – do you plane to add some other lang compatibility? (c++ for example).
    How about compiling into native apps/libs (exe,dll… etc)?

Comments are closed.