Kotlin 1.0 Beta 3 is Out!

Andrey Breslav

We are glad to present another update of Kotlin 1.0 Beta. We are working towards finalizing the standard library and getting rid of old deprecated constructs in the language, as well as bug fixes, performance improvements and future-proof checks.

Full list of changes is available here.
See closed issues here.

Library Changes

We are working hard on the standard library to get it into the best shape before 1.0. This involves some experimentation, so new deprecations happen and new functions are added. We are planning to make the final clean-up of the standard library in the 1.0 build (or RC): remove all the deprecations and other legacy stuff.

Here we give only one highlight from the changes: contains() and other similar extensions now accept supertypes of the element of the collection.

// strs: Collection<String>
// ns: String?
// cs: CharSequence
// i: Int
strs.contains(ns) // accepted now
strs.contains(cs) // accepted now
str.contains(i) // ERROR (in fact, a deprecation warning, but will be an error soon)

We found that the previously proposed containsRaw approach is inefficient, and opted for making contains() a bit more permissive, while keeping the initially intended safety. Note that the collection interfaces themselves are intact, and all this is done solely through extension functions. Use Code Cleanup to migrate your code.

Language Changes

Some highlights from the language changes, the full list is available here.
Many things that we deprecated before, have now become errors. Use Code Cleanup to migrate.

When expressions

This kind of code has proven to be problematic, so we decided to deprecate it:

when {
    foo.isValid(), foo.isReady() -> process(foo)
    ...
}

Many people tend to think that the condition “foo.isValid(), foo.isReady()” means that foo is both valid and ready, while actually the comma means or. The workaround is trivial: simply use || instead:

when {
    foo.isValid() || foo.isReady() -> process(foo)
    ...
}

Code Cleanup will migrate it for you.

Annotations

A bug has been fixed that prevented us from using arrays in default values for annotation parameters:

annotation class Entry(val value: String)

annotation class Example(
        val entries: Array<Entry> = arrayOf(Entry("a"), Entry("b")) // OK now
)

Enum.values()

Recently we changed the traditional Java’s Enum.values() to be a property: Enum.values, but now we are rolling this change back, because there’s an unpleasant corner case: a constant in an enum may be named values, and there’s no way to access one of the two then. We considered different options, and decided that changing values back to a function is the cleanest.

So, the values property is now deprecated, and values() function β€” un-deprecated.

Visibilities and scoping rules

We are cleaning up and fixing minor issues in visibilities and scoping rules, so

  • protected members are allowed in companion objects
  • Calls to non-@JvmStatic protected members of companion objects from subclasses are marked as errors (unsupported)
  • private setters are now deprecated for open properties
  • Local sealed classes are deprecated (never were usable)
  • Overriding setter cannot weaken visibility
  • Inner classes are no longer allowed inside enum entries
  • Use of uninitialized variables in lambdas / object literals / local functions is forbidden

Android Extensions

We have merged the main Kotlin plugin for IntelliJ IDEA and the Kotlin Extensions For Android plugin. The latter is now obsolete as its functionality is available from the main Kotlin plugin.

Also, we have added support for Android product flavors: now properties from different flavours are available in different packages.

For example, if we have two flavors in the build.gradle file:

productFlavors {
    free {
        versionName "1.0-free"
    }
    pro {
        versionName "1.0-pro"
    }
}

We can now use synthetic properties not only for layouts in the main source set, but also for the flavor layouts:

// Import synthetic properties for the `activity_free.xml` layout in the `free` flavor
import kotlinx.android.synthetic.free.activity_free.versionMarker

class FreeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...

        setContentView(R.layout.activity_free)

        ...

        versionMarker.text = "Free version"
    }
}

Note that all layouts for the main source set are now located under the kotlinx.android.synthetic.main package, and the old package naming convention is deprecated.

What’s new in the IDE

  • Android Extensions plugin has been merged into the main Kotlin plugin and no longer needs to be installed separately
  • We’ve added option to choose Kotlin when creating a new Gradle project:
    Screen Shot 2015-12-02 at 19.54.03

  • Debugger: stacktrace navigation now supports stack frames from inline functions. Also there were a bunch of improvements in a stepping through inline functions.

  • Three new property initialization Quick Fixes have been added:

  • Introduce Variable (Ctrl+Alt+V / Cmd+Alt+V) now supports multi-declaration expressions:

  • Also it allows choosing container for expression in lambda or anonymous functions:

  • Beta 3 brings support of Introduce Variable/Parameter/Property/Function from string template fragments

  • Finally, one experimental feature has been added β€” basic support for Kotlin script files (.kts) in the IDE

Comments below can no longer be edited.

51 Responses to Kotlin 1.0 Beta 3 is Out!

  1. Olivier Binda says:

    December 7, 2015

    Does MyEnum.values() allocate an array at each call or does it return an array that is only allocated at most once ?

    • Andrey Breslav says:

      December 7, 2015

      In Kotlin, as well as in Java, the array is defensively copied each time one calls values() (same for the deprecated values property). Otherwise the array might be changed by the client, since JVM does not have constant arrays.

    • palador says:

      December 7, 2015

      Yes they do. That’s why I added a values value to the companion objects of all my enum classes :/

      • Olivier Binda says:

        December 9, 2015

        I’ll have to do it too… (in the flatbuffers code generator for Kotlin) and that defeats somewhat the deprecation of value… ^^;

  2. Albert Nee says:

    December 7, 2015

    Will we see union and intersection types soon? That’s a must imo.

    • Andrey Breslav says:

      December 7, 2015

      These are not planned for the near future, and we don’t see too many use cases that they’d help with.

      • Albert Nee says:

        December 7, 2015

        What, no many use cases?

        Union types are immensely useful. See how Ceylon does it – it’s a fundamental typesystem improvement that even TypeScript has picked up.

        I can’t use Ceylon because nobody else is using it, so I can’t convince team to use it (not supporting android doesn’t help), but union types are good πŸ™‚

        • Andrey Breslav says:

          December 7, 2015

          We’ll be very glad to evaluate your use cases and compare the present solutions we have with the ones that make use of union types.

          • Albert Nee says:

            December 7, 2015

            The “use case” is any case where multiple types are needed.

            http://blogs.msdn.com/b/typescript/archive/2014/11/18/what-s-new-in-the-typescript-type-system.aspx explains it better than I can.

            The combination of union and intersection types is especially useful to put constraints on generics.

            • Andrey Breslav says:

              December 7, 2015

              If we’d have to refrain from overloading, like TypeScript has, this would have been a very valid motivation, but we have overloading. For the JS case we are looking into ways of having a light-weight version of unions to cover the need thereof. Otherwise, these cases are covered very well already.

              • Albert Nee says:

                December 7, 2015

                Even for variance in generics?

              • Andrey Breslav says:

                December 8, 2015

                Please clarify your question

  3. M. says:

    December 7, 2015

    Probably too late but it would be good to if you could replace “when” by “case” or something else.

    Many BDD frameworks use “given/when/then” notation to define scenraios and having “when” as keyword in Kotlin means they need to come up with another combination (like given/on/it in spock).

    • Andrey Breslav says:

      December 7, 2015

      Looks like it’s too late indeed

    • Albert Nee says:

      December 7, 2015

      Very good point M. Since Code Cleanup could easily migrate this, I don’t understand why it’s too late.

      • M. says:

        December 7, 2015

        I said too late, because it needs to be discussed (not sure if everyone is in favor of changing it) and if it get accepted then current syntax needs to be deprecated in next beta or RC release and then completely removed in the release after. This may probably take few months and I believe the kotlin team is going to release version 1.0 soon and not quite sure if they like to have another 2 beta release even. πŸ™‚

        But we can still create a improvement ticket and ask community to vote for it.

        • Andrey Breslav says:

          December 7, 2015

          You surely can

        • Albert Nee says:

          December 7, 2015

          Good point M πŸ™‚

          • Mohammad Shamsi says:

            December 8, 2015

            @Albert, @Andrey

            It got fixed so fast :).
            https://youtrack.jetbrains.com/issue/KT-10301

            • Andrey Breslav says:

              December 8, 2015

              It doesn’t mean you can’t discuss it

            • Nikolay says:

              December 18, 2015

              you can use when instead

              or even

              import org.mockito.Mockito.when as whenever

  4. Jeremy Lyman says:

    December 8, 2015

    Did annotations on types make it into this release? It was mentioned in the following SO post.

  5. Samuel Pastva says:

    December 8, 2015

    Hi, since the use of uninitialized variables in lambdas / object literals / local functions is forbidden, what is the best way to do this now?

    val repeatedCallback: Runnable = Runnable {
    //do some stuff
    handler.postDelayed(repeatedCallback, DELAY)
    }

    Of course I can create a new inner class implementing runnable and instead of repeatedCallback, I put there “this”. But that is a little “too verbose” for me :). Is there maybe a better way? I was also trying to use “this” directly, but that does not work since it’s a lambda/literal.

  6. Dimitar Dimitrov says:

    December 8, 2015

    The tag release notes on Github say “Langauge”

  7. Tobias Bieniek says:

    December 8, 2015

    I’m now getting errors like this after upgrading from beta2 to beta3:


    java.lang.NoSuchMethodError: kotlin.IntRange.getEndInclusive()Ljava/lang/Integer;
    at kotlin.StringsKt__StringsKt.substring(Strings.kt:297)
    at kotlin.StringsKt.substring(Unknown Source)
    at kotlin.StringsKt__StringsKt.split(Strings.kt:1112)
    at kotlin.StringsKt.split(Unknown Source)
    at kotlin.StringsKt__StringsKt.split$default(Strings.kt:1111)
    at kotlin.StringsKt.split$default(Unknown Source)

    Unfortunately I’ve not been able to reproduce this locally, but those errors popped up on TravisCI and AppVeyor using Java 7. (see https://travis-ci.org/Turbo87/intellij-emberjs/builds/95628706 for example)

    • Andrey Breslav says:

      December 9, 2015

      Thanks for the report, we’ll investigate this and get back to you

    • ilya.gorbunov says:

      December 9, 2015

      Looks like you’ve got an outdated kotlin-runtime.jar somewhere in classpath. Try to make a clean build.
      If it doesn’t help, try to inspect which jar an IntRange class was loaded from. To do this evaluate on a buildserver either of following:
      IntRange::class.java.protectionDomain.codeSource.location
      or
      IntRange::class.java.getResource("/kotlin/IntRange.class")

      • Tobias Bieniek says:

        December 9, 2015

        As I mentioned before, this only happened on the CI servers and those servers always do clean builds since I’m not caching anything there.

      • Tobias Bieniek says:

        December 11, 2015

        it looks like the instructions at https://github.com/intellij-rust/intellij-rust/pull/176 resolve this problem. apparently kotlin-runtime needs to be specified explicitly as a dependency.

  8. Christian says:

    December 9, 2015

    The Kotlin website should show the latest Kotlin version on the home page. I’m just trying to figure it out, but it is not as easy as it could be.

  9. Nishad Gurav says:

    December 9, 2015

    Hi,
    After updating I’ve been getting this error..
    java.lang.NoClassDefFoundError: Failed resolution of: Lcom/packagename/R$id;

    Can you please help?

    • Nishad Gurav says:

      December 9, 2015

      Caused by: java.lang.ClassNotFoundException: Didn’t find class “com.packagename.R$id” on path: DexPathList[[zip file “/data/app/com.packagename-2/base.apk”],nativeLibraryDirectories=[/vendor/lib, /system/lib]]

      • Andrey Breslav says:

        December 10, 2015

        Could you post this in our forum, slack or issue tracker? With a more detailed description of the steps that lead to the exception, and a stacktrace

      • Carl Rice says:

        December 12, 2015

        If anyone else is having this same issue (like I was), here is the solution https://youtrack.jetbrains.com/issue/KT-10320#comment=27-1244409

        • Nishad Gurav says:

          December 13, 2015

          Thanks! This worked! πŸ™‚

  10. jack128 says:

    December 9, 2015

    Here we give only one highlight from the changes: contains() and other similar extensions now accept supertypes of the element of the collection.

    Now this code
    “val list = listOf(1, 2, 3).contains(null)”
    is valid.
    I dont think what it’s good idea.

    • jack128 says:

      December 9, 2015

      typos..

      >
      Now this code
      β€œlistOf(1, 2, 3).contains(null)”
      is valid.

  11. Dennis Lysenko says:

    December 10, 2015

    Anywhere I can find a kotlin roadmap? Similar to the swift roadmap at https://github.com/apple/swift-evolution

    • Andrey Breslav says:

      December 10, 2015

      We haven’t published a roadmap for post-1.0 features yet

  12. Yuesheng Qi says:

    December 15, 2015

    Looking forward to formal Kotlin 1.0.
    So I can introduce it to others.
    Now I am playing it happily and waiting for the big moment.

  13. Lee says:

    December 16, 2015

    Will you support Experimental Plugin android?
    http://tools.android.com/tech-docs/new-build-system/gradle-experimental

  14. Dale King says:

    December 20, 2015

    Is anyone able to get Kotlin to actually generate the kotlinx.android.synthetic properties? I have tried and Android Studio knows nothing about any kotlinx package.

    • yanex says:

      December 22, 2015

      What have you tried? If you have some test project in which Android Extensions does not work as expected, you can send it to yan.zhulanow@jetbrains.com and I will investigate the problem.