First glimpse of Kotlin 1.1: Coroutines, Type aliases and more


While Kotlin 1.0.X releases keep delivering incremental updates and tooling features, we are working on the new language features in Kotlin 1.1. Today we are presenting the first preview version of 1.1, it’s far from Beta, but the brave and curious ones can play with new exciting things (and hopefully give us their invaluable feedback).

Compatibility

This is not a stable version of Kotlin, and no compatibility guarantees are given here: in the future previews of 1.1, syntax, APIs, command-line switches and anything else may be changed. If you need a stable version of Kotlin, please stay on 1.0.X until further notice.

Feedback

The upside of this temporary lack of guarantees is that we can make immediate use of all the feedback you provide us! The best way to tell us what you think is through KEEP: please leave your comments on the issues associated with proposals mentioned below. The implementations in Kotlin 1.1 M01 are prototypes of the functionality described in the KEEPs.

Overview

The full changelog for 1.1 M01 is available here.

Coroutines

We all know that blocking is bad under a high load, that polling is a no-go, and the world is becoming more and more push-based and asynchronous. Many languages (starting with C# in 2012) support asynchronous programming through dedicated language constructs such as async/await keywords. In Kotlin, we generalized this concept so that libraries can define their own versions of such constructs, and async is not a keyword, but simply a function.

This design allows for integration of different asynchronous APIs: futures/promises, callback-passing, etc. It is also general enough to express lazy generators (yield) and cover some other use cases.

So, meet one of the bigger features of Kotlin 1.1: coroutines. This is a traditional CS term for “program components that generalize subroutines for nonpreemptive multitasking”, but we’ll not dive into theory here :)

The great thing about coroutines is that they can suspend without blocking a thread, and yet they look like normal sequential code. Please see a detailed description and examples in a dedicated KEEP repository and comment on the issues there.

We are prototyping coroutine-based libraries here, to be later included with the Standard Library. This includes JDK’s CompletableFuture, asynchronous IO (NIO), RxJava, and off-loading tasks from the UI thread in Swing. The repo contains examples as well as the libraries themselves. To play with it, follow the instructions in the readme file.

Type aliases

In Kotlin 1.1 we can write

This means that we can use Action<T> interchangeably with (T) -> Unit, i.e. it is a true alias. Type aliases are useful for abbreviating longer types that are used in multiple places in the code:

  • function types with complex signatures: UserAction = (User, Context) -> ActionResponse,
  • complex generic types:

In anticipation of your questions: this feature does not cover the use cases where the aliased type is not assignable to the original type (something similar to newtype in Haskell): e.g. if we try to implement units of measurement and say

it won’t do us much good, because Length can be freely assigned to Weight and vice versa. In fact, they can both be assigned to and from a regular Double. We understand the importance of such use cases, and are planning to cover them in the future, most likely through value classes, but that’s another story. For now we only have type aliases.

Read more and comment here.

Bound callable references

In Kotlin 1.0 one can obtain a reference to a function (or property) like this: String::length, i.e. using a name of the containing class. In 1.1 we are adding bound references: i.e. we’ll be able to say mystr::length where mystr is a variable (or any other expression). Such references are bound to their receiver, and thus are a special case of partial function application (that we are not supporting in the general case, at least for now).

Read more and comment here.

Local delegated properties & Inline properties

Delegated properties have proven to be a very useful abstraction, now we allow them inside functions/code blocks too. For example, we can say:

DSLs and scripts will also benefit from this feature.

Read more and comment here.

We also allow inlining property accessors now.

Relaxed rules for sealed classes and data classes

We now lift some restrictions on data classes and sealed classes.

Data classes can now be inherited from other classes. Note that automatically generated methods may override those defined in superclasses!

For sealed classes we broaden the scope where their inheritors may be defined: before it was only inside the sealed class itself, now it’s anywhere in the same file.

Read more and comment here and here.

Scripting

As you’ve probably heard, we all will soon be able to write Gradle build scripts in Kotlin which will considerably improve the IDE experience for editing such scripts and make them more reliable through static type checking. This project motivated us to work more on Kotlin scripting in general: we are developing the infrastructure to enable using Kotln scripts in the context of different tools, as well as the plain command-line support.

More details in the proposal.

Java 7/8 support

We are working on the improved support for Java 8: 1.1 fixes the issues with Stream APIs that we used to have (and mitigated with a support library), and adds support for generating default methods in Kotlin interfaces, so that Java clients can implement them seamlessly. Read and comment here.

To enable generation of version 8 class files, supply the -jvm-target 1.8 command line switch.

We are also adding new functions to the Standard Library, and as they rely on Java API version newer than 1.6, we introduce new artifacts: kotlin-stdlib-jre7 and kotlin-stdlib-jre8 that carry extra functionality such as AutoCloseable.use(), Regex named groups support and stream-related functions. Use these artifacts instead of kotlin-stdlib from your Maven/Gradle builds if you need the APIs they add.

Read and discuss the proposals related to stdlib here.

JavaScript

We are actively working on the JavaScript back-end: all the language features available in 1.0 are covered now, and we are close to getting JavaScript (runtime) module systems integrated into the picture. Note that all this functionality is also available in Kotlin 1.0.X.

Find the proposals related to JavaScript here.

Contributors

We are very grateful to GitHub users dotlin, Valdemar0204, ensirius and geoand for their contributions to this version!

How to try it

In Maven/Gradle. Add http://dl.bintray.com/kotlin/kotlin-eap-1.1 (see instructions under “Set me up!”) as a repository to your project. Use version 1.1-M01 for your Kotlin artifacts.

In the IDE. If you are running Kotlin 1.0.3, go to Tools → Kotlin → Configure Kotlin Plugin Updates, then select “Early Access Preview 1.1” in the Update channel drop-down list:

Configure-Plugin-Updates

Press Check for updates in the same dialog, and, when the new version is show, Install.

On try.kotlinlang.org. Use the drop-down list at the bottom-right corner to change the compiler version:
Screen Shot 2016-07-14 at 20.23.48

With SDKMan. Run sdk install kotlin 1.1-M01.

Your feedback is very welcome, as always.

Have a nice Kotlin!

About Andrey Breslav

Andrey is the lead language designer of Kotlin at JetBrains.
This entry was posted in Releases. Bookmark the permalink.

51 Responses to First glimpse of Kotlin 1.1: Coroutines, Type aliases and more

  1. Даниил Водопьян says:

    We also allow inlining property accessors now
    It looks like the discussion for this feature is halted due to the lack of technical motivation https://github.com/Kotlin/KEEP/issues/34. What is the chance this goes into 1.1 ?

    • It looks like the discussion for this feature is halted due to the lack of technical motivation

      Why do you think so? The chance is about > 70%.

      • Даниил Водопьян says:

        Well, I can’t find a “motivation” section anywhere, so I assume nobody bothered to make one.

  2. Sergey Grekov says:

    Bear in mind that async library actively uses CompletableFuture from JDK 8, so it will not work with earlier versions.

    No async/await on Android?(

    • Simón Oroño says:

      Maybe it was used just for prototyping?

    • Sergey Mashkov says:

      You can implement async/await functionality on top of other libraries: CompletableFuture implementation is just a reference implementation.

    • That’s an example prototype implementation. Will likely be included with the standard library, but the design allows you to write many async libraries for many platforms. Feel free to write one for Android before someone else did :)

      • Anyone working on a Bolts implementation?

        Bolts was designed after the .NET Task library which C#’s async is built upon. It would be great to use this model as a baseline inspiration since it is mature and has a lot of reference examples to go on (between Bolts and C# together). If anyone is working on this plz post a Github link – happy to contribute.

  3. Edwin Dalorzo says:

    Awesome! I am stoked to see the great progress the Kotlin team is making with the language. This steady pace is what helped me convince my team to start using Kotlin to build our next microservices project. After a few weeks using it, we don’t want to go back to Java.

    Keep up the good work guys. This is looking great! I can’t wait for the release 1.1 to be production ready.

  4. Awesome!
    I have a question here though

    Will a project using the kotlin-stdlib-jre7 or kotlin-stdlib-jre8 be able to generate jre6 bytecode?

    • Eugene Krivenja says:

      No, I guess

    • ilya.gorbunov says:

      Yes, actually these artifacts are compiled to JVM6 bytecode as well.

      • Kingsley Adio says:

        Good to know it’ll be JVM6 compatible.

        How will this work though? Constructs like jre7 try-with-resources or jre8 lambda and default methods will be compiled to Kotlin’s equivalent?
        How will this affect usage of the stream API? Will there be some sort of compatibility library bundled with the resulting binary? Or some sort of call site inclining maybe? Or does the app just crash at runtime?

        Thank you

        • Library and bytecode version are two separate things. JVM6 bytecode doesn’t mean Java 6 compatible. If you code compiled to JVM6 bytecode format uses Java 7 classes, it will fail on Java 6, because those classes will not be found.

          Default methods are a feature of JVM 8 bytecode format, so they are not present in any code compiled to JVM 6.

          • Kingsley Adio says:

            Ah. True. Pardon me. I just immediately assumed the lot. Thanks for the clarification.

  5. Mohammad Sarbandi says:

    I remember, there was so many discussions about array, list and map literals. any update about that?

    something like groovy or phantom literals would be awesome:
    val list = [1, 2, 3] // list and array
    val map = [1: “one”, 2: “two”] // map

  6. Daniel says:

    Nice work, guys!! 😀

  7. Pingback: JVM-Sprache Kotlin: Kotlin 1.1. – die erste Preview ist da! [Update] - JAXenter

  8. Vladimir says:

    I’m not sure that I like “implicit” coroutines nature. For user they look like a normal code, but it’s not a normal code. Some keyword to indicate suspension point may be. But I probably have to try that first.

  9. I’m so glad you guys found ways of doing all the coroutine-esque stuff with functions, AND with them still being nearly as easy to use as keywords. I like where this is going. You’re taking the functional style to heart.

  10. Jaen says:

    I don’t think this works with coroutines?

    Isn’t map a higher order function? In this case, the await is executed inside the closure passed to map, meaning that unless some “magic” is happening, map is returning a List<Continuation>, not List, and you can’t call .joinToString() on that.

    • I don’t think this works with coroutines?

      Well, it does :) map is a higher-order function indeed, but it’s also an inline function, and the compiler can emit a suspension point inside an inlined lambda.
      Also, await() does not return Continuation, but rather the result of its argument’s execution, i.e. startLongAsyncOperation(it), so yes you can call joinToString() on that.

  11. Mohammad Shamsi says:

    This is lovely. with type aliases I can add extension function to function types.

    • Даниил Водопьян says:

      That was possible in 1.0:

      • Mohammad Shamsi says:

        You are right. I had never tried that before.
        But the one with typealias is clearer and more readable.

        Thanks for the hint.

  12. Pingback: Revue de Presse Xebia | Blog Technique Xebia - Cabinet de conseil IT

  13. HE Guangyu says:

    Great works!

    On coroutine, org.fusesource.hawtdispatch is a cool implementation. We use it in a productive enviroment instead of Thread, the CPU load is decreased dramatically, about 1/10 of the origin.

    Also, it’s API is very simple to use.

    When I use Hawtdispatch, I can create many queues(a queue, like a light Executors), and I can run my code in the differnt queues. I think this is the most important part of coroutine.

    In HawtDispatch, we write:

    val queue1 = Dispatch.createQueue()

    queue1.execute {

    }

    In Kotlin coroutine, we write:
    async {
    }

    Can we control the executing order of differnt coroutine, liking Hawtdispatch does?

  14. Cliff says:

    Could it be that the lifting of inheritance for data classes is not yet present in 1.1-M01?

    A contrived example:

    data class Currency(var name: String) {}
    class Euro : Currency(“Euro”)

    I am getting “This type is final, so it cannot be inherited from.”

  15. Cliff says:

    TypeAliases are super cool and very welcome indeed. Much more than just a convenience. In an initial test, I notice that they are not exposed to Java calling classes. Anything special I need to do?

  16. kirillkh says:

    I added the line “maven { url “https://bintray.com/kotlin/kotlin-eap-1.1/” }” to my build.gradle (under buildscript.repositories), but it gives me an error:
    Error:Could not HEAD ‘https://bintray.com/kotlin/kotlin-eap-1.1/org/jetbrains/kotlin/kotlin-gradle-plugin/1.1-M01/kotlin-gradle-plugin-1.1-M01.pom’. Received status code 500 from server: Internal Server Error

    • kirillkh says:

      Figured it out: you need to add “dl.” as a sub-domain, i.e.
      maven { url “https://dl.bintray.com/kotlin/kotlin-eap-1.1/” }

  17. Hans says:

    Nice! I don’t really understand how this

    is better than

    Are kotlin-stdlib-jre7 and kotlin-stdlib-jre8 only for Kotlin 1.1? Also, and sorry if this is a bad question, but can I enable -jvm-target 1.8 via gradle.properties?

    Best regards
    Hans

    • On lazy: in the second case memoizedFoo gets computed only if it’s used.
      I’ll redirect the rest to my colleagues

    • ilya.gorbunov says:

      kotlin-stdlib-jre7 and kotlin-stdlib-jre8 indeed are only for Kotlin 1.1, as they depend on changes in kotlin-stdlib. In Kotlin 1.0 you can get part of that new API with the support library: https://github.com/Kotlin/kotlinx.support

      You can enable jvm-target 1.8 in gradle with the following option:

  18. Alwyn Schoeman says:

    Will the backwards compatibility to 1.6 ever become limiting to the enhancement or efficiency of the language? Or is it just a matter of whatever technology is in kotlin will also be available in 1.6 due to custom 1.6 runtimes?

    • We support higher targets (currently 1.8) along with 1.6. Some features may work significantly faster in 1.8, but the promise is that we provide for reasonable performance on 1.6 as long as there’s enough users to justify that. It has not hindered the design so far, and I do not expect it to.

  19. Bosh says:

    Please Please!
    I am very sorry ! I am a newbie here, so much interested here but who can help direct me to where i should start from to get it in shortly.
    I am new to kotlin and thinking of using it for Android Development.
    Thinking and very convinced kotlin is the better choice ahead of java.
    Hope someone can help on this.
    regards!
    Bosh

Comments are closed.