Kotlin 1.0 Beta Candidate is Out!


We are happy to present Kotlin Beta Candidate. An official 1.0 Beta will be out soon. By now, the binary format is finalized, no major language changes are planned, and only a few changes in the standard library are coming.

In this post we describe the changes since M14, including

  • imports from objects,
  • new safer collection interfaces,
  • inlining for Java constants,
  • better support for Java statics,
  • and more.

Language changes

We are rolling out some breaking changes along with new important features.

Operators and infix functions

Since M14, Kotlin requires the operator modifier on functions that are used for operator overloading. From now on the same is required for infix functions:

Now, we have relaxed this requirement for Java functions: any Java function with a suitable signature can be used as an operator, but not as infix.

Some operator names have been changed to avoid ambiguities:

  • we should now use unaryPlus and unaryMinus instead of just plus and minus for unary functions, i.e. -Foo() is now Foo().unaryMinus();
  • for delegated properties, getValue and setValue should be used instead of just get and set.

The Code cleanup action will help you migrate your code.

Also, operator signatures are now checked by the compiler at the declaration site. Some of these checks may be relaxed in the future, but we believe that what we have now is a pretty good starting point.

Imports from objects

Kotlin now supports importing individual members of objects by name (but not *-imports from objects):

In this example we imported all members named foo from the named object mypackage.MyObject.

To import from companion objects of classes, we have to specify their full name:

Rich @Deprecated

We have been migrating a lot of code lately :) So Kotlin’s @Deprecated annotation has become really powerful: not only does it require a message and allow to specify a replacement through ReplaceWith("..."), it also has a level now: WARNING, ERROR or HIDDEN.

  • WARNING is default and works as a normal deprecation: there will be warnings at call sites, and the IDE will strike it out,
  • ERROR is the same, but a compilation error is reported instead of a warning,
  • HIDDEN is what previously was @HiddenDeclaration: it simply makes this declaration invisible to clients at compile time.

Smart casts for captured local var’s

Smart casts now work even on local var‘s that are captured in lambdas, if they are not mutated in those lambdas:

Multiple main() functions in the same package

We can now define a main() function with standard signature in each file (with the exception of @file:JvmMultileClass). This is very useful when experimenting with code:

Varargs and spread operator

To recap: when calling a vararg function, we can use the spread operator that converts an array to a vararg:

The semantics of the spread operator have been fixed so that it always guarantees that an array that foo sees will not be modified or observed by the “outside world”. We can assume that a defensive copy is made every time the spread operator is used (in fact, some optimizations may be implemented later to reduce memory traffic).

As a result, authors of Kotlin libraries can rely on the vararg arrays being safe to store without defensive copying.
NOTE: This guarantee is not fulfilled when Kotlin functions are called from java, because no spread operators are used there. This means that if a function is intended to be used from both Java and Kotlin, its contract for Java clients should include a note that the array should be copied before being passed to it.

“sparam” annotation target has been renamed to “setparam”

To annotate a setter parameter of a property, use setparam use-site target instead of sparam:

@UnsafeVariance annotation

Sometimes we need to suppress declaration-site variance checks in our classes. For example, to make Set.contains typesafe while keeping read-only sets co-variant, we had to do it:

This puts some responsibility on the implementor of contains, because with this check suppressed the actual type of element may be anything at all at runtime, but it’s sometimes necessary to achieve convenient signatures. See more on the type-safety of collections below.

So, we introduced the @UnsafeVariance annotation on types for this purpose. It’s been deliberately made long and stands out to warn agains abusing it.

Miscellaneous checks and restrictions

Many checks were added, some of these restrictions may be lifted later.

Type parameter declarations. We decided to restrict the syntax of type parameter declarations so that all such declarations are consistent, so

  • fun foo<T>() is deprecated in favor of fun <T> foo():
  • All constraints on type parameters should occur either in “where” or inside “<…>”:

Dynamic type checks for arrays. Array element types are reified in Java, but their Kotlin-specific properties, like nullability, is not. So, we removed the special treatment of arrays that allowed checks like a is Array<String>, and now arrays work as all other generic classes: we can check for a is Array<*> and a cast like a as Array<String> is marked as unchecked. We added a JVM-specific function isArrayOf<T>() that check that a given array can contain elements of type T in Java:

Delegated properties. The conventions for delegated properties now use KProperty<*> instead of PropertyMetadata in getValue and setValue:

Code cleanup will help you migrate.

Callable references. Some usages of :: are forbidden for now, to be enabled later when we implement bound references. Most notably, ::foo should not be used for now when foo is a member of a class. Only MyClass::foo should be used. References to members of objects are also unsupported temporarily (they will work as bound references too). We can use lambdas as a workaround for the time being.

If-expressions. We unified the semantics of if and when by requiring an else when if is used as an expression:

Nothing-returning functions. When a function is known to throw an exception or loop forever, it’s return type may be Nothing, which means that it never returns normally. To make the tooling smarter, we require that such functions always have their return type specified explicitly:

This is now a warning that will be promoted to error after we migrate our code with Code cleanup

Visibility checks were restricted so that, for example, a public declaration can not expose a local, private or internal type. Access to internal declarations is checked in the compiler as well as in the IDE;

See more here.

Collections

The major change in this version is that we have cleaned up collections and other core APIs so that, for example, size is now a property, and contains is type-safe: it takes E instead of Any?. This has been a major effort to make the library feel like Kotlin while keeping it compatible with Java. There’s quite some compiler magic behind it, but we are pleased with the result.

Example:

Analogous code works in Java, because Set<E>.contains (which in is compiled to) takes Object, not E, the element type of the set. This has proven to be error-prone, so we decided to make Kotlin collection interfaces safer (while keeping full compatibility with Java collections). As a result, our contains takes an E, and the example above is incorrect in Kotlin.

At the moment the Kotlin compiler reports a deprecation warning on in in the example above, because we have provided transitional extension functions in the standard library to help everyone migrate, but soon this will be an error. Code cleanup is our friend here: it will replace 1 in strs with strs.containsRaw(1). containsRaw is a new function in the standard library that we can use when we really need the Java-like behavior: we can check membership of any object in any set by using containsRaw.

Bottomline:

  • Collection.contains, Map.get and some other collection methods are now safer;
  • We can use containsRaw, getRaw, etc to get the untyped behavior;
  • Collection.size, Array.size, String.length, Map.Entry.key etc are now properties;
  • List.remove(Int) has been renamed to removeAt(int) to avoid clashes with List<Int>.remove that removes by item, not by index;
  • Code cleanup will migrate all the code.

All normal Java collections work without changes: the compiler knows how to find a “property” size on a java.util.ArrayList.

Java interop

There have been many important changes that concern how Kotlin declarations are visible from Java and vice versa.

Inlining constants defined in libraries

From now on we inline Java constants (public static final fields of primitive and String types) that come from libraries. This will help Android developers that have been suffering from API incompatibilities:

Will now work on any version on Android runtime (used to crash on runtimes younger than Lollipop).

Smaller runtime

We are only starting there, but the foundation has been laid for the work on reducing the size of the kotlin-runtime library. It is now only 200K smaller than it was in M14, but there are more things we’ll do to make it smaller (and it won’t break compatibility).

Static methods, fields and classes

Kotlin is now very friendly to Java statics:

  • we can use inherited nested classes, static methods and fields from Java classes inside their Kotlin subclasses;
  • we can access inherited Java static methods and fields through subclass name: SubClass.SUPER_CLASS_CONSTANT;
  • we can access members of companion objects of superclasses from within Kotlin subclasses;
  • but the only qualified name a class can be accessed by is its canonical name, i.e. we can’t say SubClass.SupersInnerClass.

This closes many issues we used to have with big inheritance-based frameworks like Android.

Interface inheritance rules are compatible with Java 8

To make Kotlin future-proof, we added some requirements that comply with the Java 8’s ones, to be able to later compile function bodies in Kotlin interfaces to Java default methods.

In some cases it leads to Kotlin requiring more explicit overrides than before, and, sadly, methods of Any can’t be implemented in interfaces any more (this wouldn’t work in Java 8).

Side note: the default implementations of interface methods are accessible from Java through as static members of MyIntf.DefaultImpls.

More convenient getter names for booleans

When a property in Kotlin is, for example, named isValid, its Java getter will now be isValid() and not getIsVaild().

@JvmField and objects

We have made the strategy for generating pure fields (as opposed to get/set pairs) more predictable: from now on only properties annotated as @JvmField, lateinit or const are exposed as fields to Java clients. Older versions used heuristics and created static fields in objects unconditionally, which is against our initial design goal of having binary-compatibility-friendly APIs by default.

Also, singleton instances are now accessible by the name INSTANCE (instead of INSTANCE$).

We had to prohibit the usage of @JvmField in interfaces, because we can’t guarantee proper initialization semantics for them.

Int is Serializable

Now the type Int and other basic types are Serializable on the JVM. This should help many frameworks.

No “package facades”

Classes like KotlinPackage etc are gone. We have finished the transition onto the new class-file layout, and the previously deprecated “package facades” are now removed. Use FileNameKt and/or @file:JvmName (with the optional @file:JvmMultifileClass).

Internals are now mangled

Since Java doesn’t have internal visibility (yet), we had to mangle the names of internal declarations to avoid unexpected clashes in overrides when we extend a class from another module. Technically, internal members are available to Java clients, but they look ugly, which is the minimal price we could pay for predictability of library evolution.

Other deprecations and restrictions

  • @Synchronized and @Volatile are not applicable for abstract declarations;
  • As the final step of getting rid of external annotations, @KotlinSignature is deprecated and will be removed;
  • Generic types whose arguments contains Nothing are compiled to raw Java types now, since Java doesn’t have a proper counterpart of `Nothing;

IDE Changes

  • Now Parameter Info works almost everywhere, including brackets, this and super calls

  • Completion now supports callable references (after ::)

  • We can easily generate equals() and hashCode() methods

  • Also the IDE helps generate Secondary Constructor based on superclass constructor and currently uninitialized properties

  • Support for configurable “import *” for importing static members of Java classes and enums

  • The last but not least, unit testing experience is much smoother now. List of improvements: “Create Test” action, tests are runnable via gutter icons, navigation between tests and test subjects (⇧⌘T/⇧^T) and also quickfixes to add dependencies on JUnit and TestNG when needed

Libraries

Thanks to the aforementioned changes in spread operator semantics, listOf() now is more efficient, because is doesn’t have to defensively copy the input array.

Regex API has been improved, so that we can now say regex in string instead of regex.hasMatch(string).

Tools

  • Compiler daemon is now enabled by default in the IDE
  • Parallel Compilation of Independent Modules is now supported in the daemon
  • Options related to external annotations are removed from tools like Maven and Gradle

Installation

Kotlin is bundled with IntelliJ IDEA 15 RC. For IntelliJ IDEA 14, please update through the Plugin Manager.

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.

71 Responses to Kotlin 1.0 Beta Candidate is Out!

  1. Krtko says:

    Looks good! I like that you guys are focused on reducing the size of the Kotlin runtime!

    What’s the current plan/roadmap for compiling to JavaScript?

    I hope you guys can eventually figure out how implement native inlined constants into your rolling compilation.

    Thanks for making Android programming awesome :)

  2. Salomon BRYS says:

    Congratulations, guys ! Kotlin 1.0 is in sight, that’s tremendous news :)
    All changes announced look good to me :)
    I’m really excited about Kotlin finally reaching 1.0 :)
    On a side note : I’d like to know what will the future hold for Kotlin once it has reached 1.0. Not in terms of features but in term of development (pace, involvment, etc.). I guess that’s a story for another time.
    Congrats again to everybody at JB 😉

  3. Jayson Minard says:

    Some libraries updated for this release of Kotlin:
    Jackson-module-kotlin 2.6.3-1
    Injekt 1.8.0
    Klutter 0.8.0
    Kovert 0.6.0
    Kovenant 2.9.0

  4. Olivier Binda says:

    it’s nice to get more safety for maps and sets…
    Got bitten by that a few times and it used to take time to find where the bugs came from

  5. That’s really wonderful news :)

  6. Pedro Veloso says:

    Love it! Love the better support for Android as well :)
    Keep up the good work.

  7. Eugene Krivenja says:

    I moved my Android project to Kotlin 1.0.0-beta-1038 and faced with an issue. On emulator with Android before KitKat the install fails with an error:
    – Command line – Failure [INSTALL_FAILED_DEXOPT]
    – Jenkins – com.android.ddmlib.InstallException: INSTALL_FAILED_DEXOPT

    Looks like some bytecode generation issue?

  8. mzgreen says:

    What about better support for Annotation Processing?

  9. OvermindDL1 says:

    I am confused why kotlin exists when scala has near identical syntax, has been around longer, can seem to do everything that kotlin can as well as a tremendous amount more. Can anyone clarify?

    • Krtko says:

      https://kotlinlang.org/docs/reference/comparison-to-scala.html This seems like a pretty fair answer to your question

    • Watch just about any of the videos they have out there. They have some beefs against Scala.

    • Dmitry says:

      Kotlin has much better Android support than Scala. And for me that is a killer feature.

    • Steven Holmes says:

      Wildly different philosophies. Compared to Java, Scala is all about power, doing things that Java cannot do. In that way, it is philosophically similar to groovy, albeit with an impressively powerful (and complex) type system. It can do almost anything, as you’ve already noted. Simplicity, conciseness, performance, java interoperability, backwards compatibility, library size, and tool support are all afterthoughts in Scala, or at least secondary to powerful language features. Kotlin is much more pragmatic. In Kotlin these things are first class concerns, and powerful language features are balanced against, and sometimes secondary to, these things.

  10. Pingback: Kotlin 1.0 Beta Candidate is Out! | JAVA

  11. Mykhailo says:

    Great news!
    Special thanks for relaxing “operator” restriction for java methods.

  12. Matt Freeman says:

    Congrats. How many full-time developers at Jetbrains are currently working on Kotlin and its ecosystem? Do you have any internal buy-in – i.e. are parts of Intellij being written in Kotlin (I am aware externally that parts of Cursive Clojure are)? Is the Kotlin support 1st class in IntelliJ – i.e. comparable experience to that of Java?

    • We have a team of over 20 developers. Parts of IntelliJ IDEA and other products are written in Kotlin, some of them have >90% Kotlin code in them.

      I believe that Kotlin IDE support is 1st class, and to my mind is is totally comparable to that of Java (it’s a subjective qualitative assessment), while it definitely has fewer features than Java support that started at least 10 years earlier.

      • Max M. says:

        Is there any chance to get something like a paper or a blog with some numbers?
        I’m asking because having somewhat “real numbersW would greatly improve our (developers) standpoint against our higher ups / clients / product owners / … to justify the use of kotlin in production.

        Like in “Hey, the stuff we build stuff in IS build in kotlin!”

  13. Pingback: Beta Candidate für Kotlin 1.0 erhältlich - JAXenter

  14. Dex Wood says:

    I was recently using a sealed class, and I was using the equality of its child classes. Since data classes can no longer inherit from other classes, you must override equals, hashCode, and toString to get a nice behavior of those classes. I also saw an example of someone implementing a Maybe class where the Just method was a data class for comparison and representation at https://medium.com/@octskyward/kotlin-fp-3bf63a17d64a#.806i8gq9r

    Is there a way to somehow allow data classes to inherit sealed outer classes? Maybe have the child classes of a sealed class get a nice hashCode, toString, and equals implementation. What are some other use cases of sealed classes that would cause problems for this idea? This use of sealed classes seems like it will be very common.

    My use of the code follows:


    enum class RelayState { COOLING, HEATING }
    sealed class PowerState {
    data class ON(val relayState: RelayState) : PowerState()
    object OFF : PowerState()
    }

    vs

    enum class RelayState { COOLING, HEATING }
    sealed class PowerState {
    class ON(val relayState: RelayState) : PowerState() {
    override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (other !is ON) return false

    }

  15. Michel says:

    Finally have you made a decision concerning marking result expressions ?
    “^” or “<-” ?

  16. Grdykopląs Namorzyn says:

    Something very strange is happening after last update. The IDE highlights error in places where compiler doesn’t complain. When I correct the errors according to IDE, the compiler won’t compile.

    Example functions (in a clas derived from javaList)
    IDE: size() cannot be invoked as a function, Compiler: Function invocation size() expected
    IDE: assumes that List.remove(int) is actually List.removeAt(int) (?!), Compiler: unresolved reference removeAt

    So I have either compilable code with lots of error highlighted or uncompilable code that is shown as OK in Idea…

    • Looks like either the standard library was not updated (e.g. you have different versions in the IDE plug-in and in Gradle), or IDE caches got stuck (in this case *File -> Invalidate Caches -> Invalidate and Restart)

      • Grdykopląs Namorzyn says:

        Which one is new then in my case? Library or plugin? Invalidating cache didn’t help.

        • How is your project configured? Do you use Gradle? If yes, you can see the library version in your build file. And the version of the plug-in can be seen in Plugin Manager

  17. Pingback: Links of the Week, W44 2015 | One More Game-Dev and Programming Blog

  18. Cuper says:

    May I ask why import object.* is not allowed?

    Since Kotlin plugin can’t add import object.A automatically, we still have to write import statements one by one for every imported object methods and variables.

    • Roman Belov says:

      import object.* leads to importing hashCode, equals et al. Mostly it would be very confusing.
      And most likely special intention action will be implemented for auto imports from objects.

    • Objects may inherit things from supertypes, e.g. equals()/hashCode() will be imported every time you ‘*’-import from an object, we decided that this would be too confusing. The IDE should be fixed soon

  19. Viachaslau says:

    How about also add autoconversion between simple types? int -> float, float -> double
    it’s a little anoing
    fun foo(x:Float)

    foo(1) //error
    fii(1f) //no error

    • Unfortunately, this is incompatible with the fact that we do not distinguish between primitive types and classes

    • Grdykopląs Namorzyn says:

      And I think it’s a bad idea, too. I just hate how many errors I get in Java because of automatic conversions. I’ve never grasped what is converted to what. Kotlin way seems much better,

  20. Cuong says:

    Why do we need * prefix to be able to pass arrays as varargs? I am learning Kotlin by solving problems in Kotlin Koans and I find it difficult to express my solution for _29_OperatorsOverloading problem[1]. With my extension functions, I am unable to make Kotlin evaluate: today + YEAR * 2 + WEEK * 3 + DAY * 5

    fun MyDate.plus(vararg timeIntervals: TimeInterval): MyDate {
    return timeIntervals.fold(this, {date, timeInterval -> date.addTimeIntervals(timeInterval, 1)})
    }

    fun TimeInterval.times(num: Int): Array {
    return Array(num, {this})
    }

    [1] – https://github.com/JetBrains/workshop-jb/blob/master/src/iii_conventions/_29_OperatorsOverloading.kt

    • Why we need the spread operator: because, for example, if a function takes vararg of Any, then any array may be either an element of a vararg or a container for all vararg elements:

  21. Cuong says:

    My previous comment got removed for some reasons so I ask again. Why do we need * prefix to pass arrays as varargs?

  22. Matt says:

    I would love to see the spread operator for maps for named arguments.

  23. Grdykopląs Namorzyn says:

    I think I’ve found an issue with 1.0 deleteAt(Int) vs delete(int) magic, filled it under KT-9824

  24. Guest says:

    This might not be the correct place to ask this: but how can I use KTypes and such to distinguish class types and such?

    Lets say I get a function and loop through its parameters. Each KParameter has a KType, which should correspond with a class but without that class object itself I cant necessarily check inheritance and others, whats the point?

    • The reflection API is not complete at this point, more information, such as detailed type information, will be added later. As a workaround you could use Java reflection now (there’s an API to convert a Kotlin reflection object to a Java reflection object).

  25. drakeet says:

    Can not install android apk file below Android 4.4

    Failure [INSTALL_FAILED_UID_CHANGED]

  26. Jan Kovar says:

    Hi,
    can you please check this issue?
    https://youtrack.jetbrains.com/issue/KT-9758
    Issue appeared in beta candidate and it appears in 1.0.0-beta-1103 as well.
    I know that Javascript compilation is not your priority right now but hope it get resolved in 1.0 :)
    Thanks

Comments are closed.