Kotlin Post-1.0 Roadmap


It’s been almost two months since Kotlin 1.0 was released, and the team is now switching from stabilisation and bug fixes to new feature work, so it’s a great time to talk about our plans for the future.

We’ve already published our Android roadmap, but there are many other areas where we’re applying our efforts. Our current development is organised in two main branches:

  • Kotlin 1.0.x which will be a series of releases containing bug fixes, updates to tooling, IDE support and other areas which do not affect the core language. 1.0.x releases will be published on a regular basis once every several weeks.
  • Kotlin 1.1 which will contain major new language features, along with all the improvements from the 1.0.x branch. This will be a feature-driven release, and we aren’t announcing any specific time frame for it.

Let’s look at the plans for each area in more detail, starting with the big ones.

New Language Features

Before we can start talking about specific features, the big disclaimer: everything we’re talking about here is still in the design phase, and features may end up being changed dramatically or dropped entirely as we move forward with the design, implementation and feedback gathering process. So, no guarantees.

async/await/yield

The most important feature that we’re designing right now is support for coroutines (async/await/yield). By now, the async/await pattern has found its way into many different languages, including C#, Python and Dart, and we want to support this in Kotlin as well. However, that’s not the end of the story: we want to put the specific code execution semantics into the library, rather than the compiler.

The compiler will take care of transforming the function used as a coroutine into a form allowing to suspend and resume its execution. The actual execution of a coroutine (the initial invocation, as well as resuming the execution after a suspension point) will be the responsibility of the support library. Therefore, the same mechanism will allow us to support many different patterns: generators (yield), asynchronously executed functions (async/await), Go-like channels and goroutines, as well as potentially others which haven’t even been invented yet.

Note that we’re still in the process of estimating the effort needed to implement this feature, and we don’t know whether it would be reasonable to support it in the 1.1 timeframe or it would be postponed to a later release.

Other Language Features

We’ve received quite a lot of feedback from Kotlin 1.0, and we were quite happy to see that a lot of the requests were asking for the same features. We’ve chosen the ones that come up the most often, and have prioritised them for Kotlin 1.1. Those we’re reasonably sure about are:

  • Data class hierarchy support will remove many of the current restrictions on data class inheritance, for example, allowing you to represent an algebraic data type as a series of data classes nested in a sealed class:
    sealed class C {
        data class A(val x: X, val y: Y) : C() { ... }
    }
  • Type aliases will allow to assign a short name to a type (for example, a function type, or a generic type with a long signature):
    typealias MouseEventHandler = (MouseEvent) -> Unit
  • Destructuring in lambdas will allow you to easily unpack a data class instance or another object supporting the destructuring protocol when it’s passed as a parameter to a lambda:
    myMap.forEach { (key, value) -> println(key+value) }
  • Bound method references will allow to create a method reference that invokes a method on a specific object instance, and doesn’t require passing it as a parameter:
    letters.filter("abc"::contains)
  • Local delegated properties will allow you to define a local variable as a delegated property:
    fun foo() { val x by lazy { … } }

Java 8/9 Support

As of version 1.0, Kotlin targets Java 6 only. This means that the generated bytecode does not make use of any features added in Java 7 or 8, and the standard library only exposes the APIs that existed in Java 6.

Over the course of 1.0.x and 1.1 releases and beyond, we plan to remove these restrictions, and to give you the choice of the JVM version that you’re targeting. Java 6 is still going to be supported, but if you choose to target Java 8, we’ll make use of that. The standard library will let you use the new Java 8 APIs, such as the stream API, and the compiler will use the newer bytecode features, such as the support for default methods in interfaces. We also plan to support Project Jigsaw (the JDK 9 module system) by the time JDK 9 is released.

JavaScript Support

When we started finalizing the 1.0 release, we decided to suspend work on JavaScript support and to focus on the JVM as the main supported platform for the release. Now that 1.0 is out, we’ve resumed work on JS, and we’re moving towards our goal of letting you write the business logic of your application only once and to run it both on the backend and in the user’s browser.

Our main priorities for the short term are filling in the missing language features and better integration with the overall JavaScript infrastructure (starting with support for JS module systems). We also plan to leverage the huge set of strongly-typed API definitions for most major JS libraries, which has been accumulated by the TypeScript community. We’ll provide a tool to convert those definitions into Kotlin code, letting you use the libraries from Kotlin with a fully typed API and very little effort spent on integration.

IDE Features

In the IDE space, our current priorities are as follows:

  • Framework support: We plan to extend the unparalleled level of Java enterprise framework support offered by IntelliJ IDEA Ultimate so that it works equally well for Kotlin. This will be a gradual process happening in parallel inside IntelliJ IDEA and inside the Kotlin plugin; the first batch of Spring support features is already available in Kotlin 1.0.2 EAP.
  • Intentions and Quickfixes: In our view, one of the main roles of an IDE is teaching you how to use the language well and helping you get back to speed if you make a mistake, by providing code improvement suggestions and automatic quickfixes. Kotlin 1.0 already contains a nice set of tools in this area, and we’re going to expand on it in the 1.0.x and 1.1 updates. As one example, we’re building tools that can convert imperative-style loops into code written in the functional style, using functions such as map and filter.
  • Other Improvements: Other things on our roadmap include new refactorings such as Inline Method, a more robust and flexible formatter, support for diagrams for Kotlin code, and more.

Other Tooling Improvements

The Android roadmap post already mentioned some of the improvements that we plan to make in our tools, such as support for incremental compilation with Gradle and support for Android Lint checks. Both of these features are already available in Kotlin 1.0.2 EAP, and will receive further improvements later on.

Summary

As you can see, there are quite a lot of exciting things coming, and there’s plenty of opportunity for you to get involved. Stop by our Slack chat, try out the EAP builds, file issues – the future of Kotlin depends on you, our users, and we’re always happy to hear anything that you have to say.

This entry was posted in Roadmap. Bookmark the permalink.

60 Responses to Kotlin Post-1.0 Roadmap

  1. M Platvoet says:

    Cool to see a public roadmap intention. Keep up the excellent work.

    I was also thinking, since “destructuring in lambda’s” is on the roadmap, that implementing wildcards is a welcomed and logical addition to the language. I suspect you guys have reserved the underscore for this.

    So that we can do something like: myMap.forEach { (_, value) -> println(value) }

    • Dmitry Jemerov says:

      You’re right that the underscore has been reserved with this use case in mind. However, at this time we don’t have a definite plan to support it in 1.1.

    • Pavel Sikun says:

      Underscore and destruction combo could be even more important in when( ) expression:

      `
      when (nameSurnameYearTuple) {
      (_, _, 2009) -> println(“${it.name} ${it.surname} registered in 2009”)
      (“Victor”, _, _) -> println( user is named Victor)
      }

  2. Vito says:

    Glad to see destructing coming in 1.1!

    Have the team given any thought to supporting first class functions in Kotlin? Also, data structure literals similar to Clojure?

  3. Christophe L. says:

    Excellent, i tried the first version with REST services, TornadoFX …

    Nothing related to AOP in this roadmap like function interceptors ? the only missing great feature, i think.

    • Dmitry Jemerov says:

      We have no plans to provide any AOP features in Kotlin at this time.

      • Dee Inguva says:

        I would like to thank the Kotlin team for not looking at adding AOP support.

        • Christophe L. says:

          Without AOP, how do you manage supervision function pb (log, metrics) and security control ? (the same you can do with services and filters but generalize with simple function).

          • Dmitry Jemerov says:

            The answer to the “how” question depends on the framework that you’re using. However, I’d like to point out that the vast majority of successful projects these days have been built with languages that do not have AOP support, and nevertheless were able to solve all of these issues.

            • Steve says:

              True, the Spring Framework provides AOP capabilities but with the decision to go with final by default greatly hinders the ease of applying the aspect.

  4. Maxim says:

    Dmitry, do you have any plans related to improvement of kotlin.reflect and Java Interoperability? I don’t want to write such spikes on Kotlin:

    obj.javaClass.kotlin.declaredMemberFunctions
    toClass.java.cast(from)
    A::class.java.isAssignableFrom(B::class.java)

    • Alexander Udalov says:

      Thanks for the report. Yes, we’re planning to expand the Kotlin reflection library. The pain points you mentioned have been brought up a few times and we’re going to address them in 1.1.

  5. Damian says:

    Hello,

    For bound references letters.filter(“abc”::contains) can’t we just do letters.filter(abc::contains)? Is there some kind of limitation to add quotes?

    Thank you for your work!

    • Dmitry Jemerov says:

      Of course, if you have a variable named ‘abc’, you would be able to refer to it without quotes. In the example, “abc” is a string literal.

  6. Gleb says:

    Hello,

    What about Design by Contract and AOP?

    Tnx

  7. Daniel Alves says:

    Cooooooool!!! Just waiting for enhancements on the JS transpiler (modules I’m looking at you!)!

  8. Kevin Herron says:

    The 1.1 plans are exciting. With the restrictions on data class hierarchies lifted and the improved destructuring I think we’ll have enough functionality to transition to Kotlin instead of Scala.

  9. Christian says:

    The forum is a great communication channel, too: https://discuss.kotlinlang.org/

  10. wruss says:

    Looking good!

    Will delegates for properties declared inside the constructor be supported?

    E.g. class Foo(val name: String by SomeDelegate()) {}.

  11. Oliver Plohmann says:

    Looks like Kotlin 1.1 will be an exciting new release. You are mentioning that Kotlin 1.1 will have “Go-like channels and goroutines, as well as potentially others which haven’t even been invented yet.”. This sounds very interesting! Goroutines are the killer feature that made Go that successful I would say and they would be of great value if brought to the JVM. Does that mean that you are going to incorporate Quasar from Parellel Universe in the Kotlin distribution or are you working on something new on your own?

    • Dmitry Jemerov says:

      I’m not saying that Kotlin 1.1 will have goroutines. I’m saying that Kotlin 1.1 may have compiler support that would allow a library to implement goroutine-like functionality. At this time it’s too early to say whether we would build such a library ourselves, work with the community to build it, or whether this would happen at all.

    • I hope we will have goroutines as a library soon after we implement coroutines in Kotlin

      • Oliver Plohmann says:

        All right, this sounds cool. So you will also need to have your own implementation of fibers and continuations. Continuations in Quasar as on the JVM in general relies on byte code instrumentation. This is something that some users might struggle with. Maybe there is a way round this. The problem with Quasar is that it cannot be used in conjunction with frameworks that on their own make heavy use of byte code manipulation such as hibernate. Not being able to use Quasar in conjunction with hibernate is a pitty as blocking database IO would be a typical use case for CSP-style concurrent programming. Do you think there is a way you could get around those things that are not that ideral in Quasar?

        • Check out our proposal here: https://github.com/Kotlin/kotlin-coroutines.

          Big difference with Quasar/Go: we only support stack-less continuations. This limits the user a bit (a fiber-blocking call can’t be made at arbitrary stack depth, only inside a coroutine itself), but eliminates the issues you speak about.

          So you will also need to have your own implementation of fibers and continuations

          I’m sure we’ll be able to reuse some existing implementation.

  12. Olivier Binda says:

    How are you going to define type aliases ?

    Would it be possible to have something like
    fun a() : LambdaType1 = {1} as LambdaType1
    fun b() : LambdaType2 = {1} as LambdaType2

    inline fun c(crossinline a : LambdaType1) {do something}
    c(a()) // compile
    c(b()) // doesn’t compile

    • Dmitry Petrov says:

      Type aliases will be equivalent to the corresponding underlying types.
      No new types (and no phantom types): we can’t enforce them in Java code.
      So, in your example, if LambdaType1 and LambdaType2 expand to equivalent types, both c(a()) and c(b()) are ok.

  13. jblaszczyk says:

    How about support for easy testing and mocking? Using Mockito with final-by-default classes is cumbersome and many people already complain about this a lot. No modern language so far has first-class support for testing and mocking so this is normally achieved by libraries that resort to bytecode instrumentation, proxies and other workarounds that always have some nasty pitfalls and limitations. I think this should be somehow supported by compiler.

    For example I can imagine “test class {}” and “test fun {}” would be granted private level access to members of tested objects. Also “test ” could hint the compiler to generate a spy/mock around it. I could write an informal proposal if there’s enough interest in it.

    • Dmitry Jemerov says:

      How do you imagine that this would be implemented? Note that Kotlin compiles private and final functions to methods which are actually private and final on the bytecode level, and the JVM enforces those access controls. We have no plans to relax those restrictions for the sake of easier mocking. And without relaxing them, it’s not clear how “granting private level access” could work in practice.

      • jblaszczyk says:

        I think the compiler would generate a testable/mockable variant of these classes. that’s how mocking frameworks actually work: they enhance the tested class, inject desired extensions and run test on these enhanced classes rather than on bare original.

        • Dmitry Jemerov says:

          How would the compiler do that? Private and final methods in the class under test are private and final. If the “testable/mockable variant” extended the class under test, it would not be able to extend or expose those methods. If it was an entirely separate class, its type would not be compatible with the type of the original class.

          Mocking frameworks either require the class being mocked to be non-final, or use exactly the kind of bytecode instrumentation that you’re aiming to avoid.

          • jblaszczyk says:

            we avoid bytecode instrumentation because it’s too limited, e.g. it can’t help already inlined methods. but the goals it tries to achive are desireable in the case of testing.

            note that tests are just tiny simple one-shot programs, they can have a class hierarchy sorts-of-separate from the one that will actually be built and bundled. in other words: the compiler can just pretend the testable variant IS the class for the sole case of running particular test class.

            • Cliff says:

              Please don’t add this into the language/compiler. If you’re creating unit tests for private members you’re doing it wrong!

              • jblaszczyk says:

                Valid unit tests should setup preconditions, verify internal invariants and postconditions, which are all often encapsulated within private fields. Corner cases, which certainly should be tested, often are achievable only by directly injecting them artificially into private fields.

                I can’t imagine testing classes implementing algorithms or finite automata without access to private state.

    • Please go ahead with writing a proposal. It would make sense to share it in the forum’s Language Design category

  14. David says:

    This is very exciting stuff!

    This might be a silly question, but what is the purpose of the javascript side of kotlin and how does this compare to e.g. nashorn?

    Specifically I’m thinking of the case of where you want to allow users to do scripting/plugins inside an app.

    • Dmitry Jemerov says:

      Kotlin’s JS support is, in a sense, the opposite of Nashorn. Nashorn allows you to run JS code on the JVM, whereas Kotlin’s JS support allows you to run your Kotlin code in the browser. The purpose of this is, for example, reusing the business logic of your app between the browser front-end and the JVM back-end.

      We do plan to provide more scripting support features in Kotlin, but this is entirely unrelated to the JS work.

      • Ruckus T-Boom says:

        Will it be possible to mix them?

        For example, I have a JavaFX app that allows for user extensions in JavaScript. I’m rewriting the app to Kotlin (using TornadoFX) and would like to allow users to write their own extensions in Kotlin. Will this be possible (either directly or through the Kotlin/JS bridge?

        • Dmitry Jemerov says:

          This will be possible, but you’ll need to manually run the Kotlin compiler from your application, and take care of executing the resulting JS. Right now I’m not aware of any plans to make this process more automated.

          • Ruckus T-Boom says:

            Fair enough. How would the compilation happen? Would it have to be compiled to a file, or could I more easily grab the .kt file, compile it, and stream the results to, say, Nashorn?

  15. Pingback: Around the web: Episode #16 | GX Consultancy – Blog

  16. Ian Clarke says:

    With the async/await/yield support, would be possible to suspend a coroutine, serialize it, send it across the network, and resume it on another machine?

    To ask it another way, will this enable “portable continuations”?

    • jblaszczyk says:

      that would certainly need a full fedged framework to achieve. Kotlin staff is more focused on compiler stuff. ‘portable continuations’ would certainly exceed the scope of mere language specification. also this is reminiscent of distributed processes and distributed memory which is somewhat criticised by those who have actually done it in enterprise for its shortcomings. interesting idea but distributed state is just another level of abstraction

    • Can’t promise anything at this point, but we bear this use case in mind

      • Ian Clarke says:

        Thanks Andrey, if you’d like to understand my motivation – you can read all about it at http://swarmframework.org/. It’s a proposal for a way to transparently scale software across multiple machines. Think of it as map-reduce but more flexible, and more automatic.

        Previously only Scala supported portable continuations through a compiler plugin, but unfortunately it has since been deprecated, and I’ve fallen out of love with Scala for all the reasons you can already guess at.

        • Steve says:

          You’ve got to be careful with language bloat, I think that’s where Scala is starting to come off the rails. It does feel like a framework’s responsibility… but perhaps the continuations can be flexible enough for a framework to come in and provide a distributed implementation.

          Out of curiosity, what are your primary reasons of moving away from Scala?

  17. jblaszczyk says:

    how about Quasar-like support for Erlang-style fibers? I mean a blocking API that translates into async or fiber-like wait(). Quasar resorts to bytecode instrumentation and injection to turn blocking API into robust fiber management. I think this instrumentation is excellent candidate for Kotlin compiler to improve concurrency model support.

    there are huge benefits of hiding asynchronocity behind ordinary imperative blocking APIS. C# team is already after this and I believe Kotlin could make its day in this area with explicit language support.

  18. Pingback: Issue #201 | 神刀安全网

  19. Awesome work, look forward to the progress!

  20. Marvin says:

    Hey – any ETA on the TypeScript converter? Kotlin-js is pretty much useless without library definitions. I know there’s a tool already out there but it barely works.

  21. Daniel Balke says:

    I often miss the feature to have an annotation like @JvmPackagePrivate that sets the access to package-private.

    That said, if you are going to support method references for instances, wouldn’t it be great to have something like this as well, namely method references that take an instance?

    Any::toString : (Any) -> String

  22. Pingback: Android技术周刊第13期 | 神刀安全网

Comments are closed.