Call for Feedback: Upcoming Changes in Kotlin

As mentioned before, we are wrapping up with the language design, and this post is a head-up for the upcoming changes + request for your feedback.

Backing fields

I mentioned some time ago that we are not happy with the present syntax of backing fields, which is $propertyName:

The biggest issue is that this syntax clashes with the syntax of string templates.

So, we decided to change the rules here:

  • the $foo syntax will be deprecated and then dropped
  • instead, we can access the backing field by the name field inside getters/setters:

Note that field is just an implicitly defined variable (very much like it in lambdas).

Some use cases are not supported by this approach: we used to be able to access backing fields anywhere in the class, and now it’s only visible in getters/setters. We have examined Kotlin code on GitHub, and realized that only a tiny fraction of use cases were not covered, and for these we can always resort to “backing property”:

Operators and infix functions

This has been debated a lot in the past, and we finally decided that we want to introduce some more discipline into how operator overloading and infix function calls work in Kotlin. At the moment any function named plus that can be called as can also be called as a + b. We will require such functions to be marked with the operator modifier, otherwise the operator notation will not be available for them. This makes operator use more disciplined and eliminates the possibility of random punctuation creeping into APIs. The most common example would be having a method called get but totally not intending it for use as square brackets.

Same for infix function calls: we will require a function to be marked as infix. This will reduce the unintended diversity of styles in common APIs:

  • list add 1 vs list.add(1)
  • list map {...} vs {...}
  • etc

Infix functions will be still callable with the old standard syntax x.or(y), but the tooling will be hinting to you that the intended syntax is infix.

Note that common functions in the standard library (e.g. map or filter) will not be marked as infix, because using them as such sometimes causes cryptic errors if such an expression is followed by a dot:

If some Java method is not marked as operator or infix, we can always define an extension that is, and the standard library will provide such extensions for most popular cases.


Compile-time constants are important when it comes to annotations: only they can be used as arguments (along with very few extra expressions, namely arrays and annotation constructors). So far we took the same “implicit” approach to detecting them as Java does: if a val in an object or on the top level only has only constants in its initializer, it is a compile-time constant. This is fragile and presents a possibility of breaking APIs without knowing, so we decided to require the const modifiers on such vals:

Note: const values can only have the following types: “primitives”, String, enums, class literals.

invokeExtension() convention

This has been pretty obscure so far, but we are going to change it anyways. For now if a value needs to be callable as an extension function, it has to have a member that is an extension and is named invoke:

This is inconvenient in some cases, so we are going to change this to

As a side-effect, it will be possible to add such function as an extension:

Internal visibility and mangling

Internal members are compiled to public at the moment, which may lead to accidental overrides:

The compiler will not require override on Derived::foo because the parent function is not visible, but in the byte code these have the same signature, and the runtime will bind them as overrides, which was not intended by the authors. The problem is most painful when modules X and Y evolve independently (e.g. one is a library and the other — user’s project), so that when Y is compiled foo was not yet present in X.

To avoid this, we decided to mangle names of internal members so that they do not clash with superclass members.

Update: mangling will likely cause this members to be impossible to call from Java. This seems to be hard to fix, but the workaround is straightforward: just make it public or protected.

Other changes

  • Default implementation classes for interfaces on Java 6 will be named Foo.DefaultImpls instead of Foo$$TImpl
  • _, __, ___ will be forbidden as an identifiers, i.e. we can use _foo, but not _ alone (reserved for future use)
  • We are going to drop final, protected and internal in interfaces: these can not be expressed on the JVM, so we postpone their implementation until later
  • We are going to drop identityEquals() function in favor of ===


Your opinions and use cases are most welcome!

About Andrey Breslav

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

91 Responses to Call for Feedback: Upcoming Changes in Kotlin

  1. Rostislav says:

    I wonder, why there is requirement for val in const val? It seems const var doesn’t make sense.

  2. Sergey Igushkin says:

    My opinion on infix functions is that making functions non-infix by default will scare developers from using infix functions at all: I can hardly imagine someone who will look at the declaration each time to see if a function is infix or will declare infix functions knowing that it is not the way which people will call them, some kind of a vicious circle that will make infix functions extinct.

    And example with add seems quite the reverse to me: when there’s an infix function in a line of code it is clear that everything to the right is the argument, which makes code much easier to read: you don’t need to look for commas or closing parenthesis to determine what are the arguments.

    That’s why I’m completely against the infix function calls limitation.

    • when there’s an infix function in a line of code it is clear that everything to the right is the argument

      This is not really so: foo bar baz goo roo — only baz is the argument for bar

      Regarding your concerns about people not knowing that a function can be called as infix, this is what tooling is for: it will hint the users towards the intended syntax

      • Sergey Igushkin says:

        when there’s an infix function in a line of code it is clear that everything to the right is the argument

        Sorry, didn’t express myself clear enough. It was said about the case when there’s only one infix function call. Here’s the example:
        list add large(expression), with(nested(calls()))
        list.add(large(expression), with(nested(calls())))

        • Sergey Igushkin says:

          Oh, parenthesis are incorrect in the example, but the key point is there: there is a single complex expression to the right of infix function call.

      • Sergey Igushkin says:

        Also, people already can use only dot function call syntax if they wish, so is the limitation necessary? I suppose that tooling would solve the problem: an intention like “convert all function calls to dot syntax” or possibly “always show dot in libraries code” would suffice.

  3. Jayson Minard says:

    I think you are missing one thing that is a very common error we see (having a lot of Kotlin code, the most common bug in all cases by far, although caught by developers soon after) is:

    The implicit emitting of values from expressions when nested has horrible readability right now. Confusing, chances of errors. And no help from the compiler when wrong in many cases. But it easily could.

  4. Jayson Minard says:

    Dropping “final” from interfaces breaks default methods that are inline. This is incredibly useful since you can provide default versions of methods that use reified types and then force only the core methods of the interface to be implemented. For example, in Injekt library:

    Was this use case overlooked? You can’t inline without final in an interface.

    • The fact that you can inline something of an interface looks scary on its own. :)

      Why not use an extension function in your case?

      • Jayson Minard says:

        That works.

        • Jayson Minard says:

          oops, hit send early.

          The reason I didn’t use extensions because tooling isn’t so great for discovering the possible cases that haven’t yet been imported that are extensions. It is good for finding them after I type them, but doesn’t help with discovery.

          Tooling then needs to improve so I’m not doing 30 imports on the package to get each extension.

          • Jayson Minard says:

            would help if code code could indicate that “if you import me, I want this other thing imported by the tool as well” so the tool can suggest to the user that it is likely he’ll want a bunch of other things to come along for the ride.

      • Jayson Minard says:

        One case not covered, is that sometimes you want to avoid filling the whole Kotlin world with an extension, such as an extension “public final inline fun T.registerAsSingleton() {. ..} ”

        So this is in the interface so that you can have a builder:

        public interface InjektModule {
        final internal fun registerWith(intoModule: InjektRegistrar) {


        and therefore the extension only appears in the scope of the builder, and not everywhere in every code completion dropdown (like many functions you rarely use from other libs, some from the stdlib)

        • I don’t follow here: how this is relevant to the discussion above?

          Having an extensions only on the interface seems to be a perfect replacement for having a final member in that interface. We’ll look more into tooling support though

          • Jayson Minard says:

            it is already an extension on something else, but within the interface.

            public interface Igloo {
            public final inline fun T.freeze()

            so when you provide your own builder extension to Igloo (fun buildIgloo(init: Igloo.()->Unit):Igloo) and want to call freeze() on arbitrary object but only within the builder. So you don’t pollute every drop down in the universe you are scoping this extension.

  5. Jayson Minard says:

    I hope the only use case considered for “_” by itself is “ignore this value”, for example:

    val (a, _, c) = something()

    other cases where it propagates into any code is ugly, one of my least favourite things to see in scala is “_” running around.

    • Adel says:

      Same here, I sometimes end up having _, __, ___, ____ when I have several of those in scope
      And the compiler also gives me warnings about unused _’s

  6. M Platvoet says:

    Backing fields
    Sounds like a pretty good solution. Providing solutions for corner cases wouldn’t be right.

    Operators and infix functions
    Great to introduce an operator for this, I really like when intent is expressed. Some questions though concerning infix calls.
    – can a function marked infix still be called with a dot?
    – what will be the restriction for infix markers? is for instance a function with default params allowed to be called infix? infix fun foo(bar:Bar, x:Int=0)

    Like other I feel that const val feels rather duplicate. Furthermore const seems to narrow down the possibilities of val (only primitives). Introducing just const to me makes far more sense.
    const a = 1

    Internal visibility and mangling
    Great :)

    Other changes
    I really hope underscore isn't going to be used as a wildcard but that there is a possibility to reuse '' for this as this is more synonymous to the current implementation with generics.

    val (a, *, c) = triple()

    • can a function marked infix still be called with a dot?


      what will be the restriction for infix markers? is for instance a function with default params allowed to be called infix? infix fun foo(bar:Bar, x:Int=0)

      Likely not

      Introducing just const to me makes far more sense.

      Doesn’t seem to pay off

      • M Platvoet says:

        Since you always seem to scan current repos on usages of language features, does the use of constants for annotations indeed show up that much?

        • It’s hard to scan for this, but I’m sure it’s not much, why?

          • M Platvoet says:

            Well depending on the uses this might be such feature that can be postponed beyond 1.0.

            Because to me it seems this feature isn’t crucial at this moment and already gets some critique in the preliminary feedback. It will be much harder to change this feature after 1.0 then introducing it.

        • CountMath says:

          I just wrote a comment asking if constants existed in Kotlin. I very much look forward to constants and I use them quite a bit to abstract out values without performance lose.

  7. Chris Kent says:

    +1 for the changes to infix functions. +100 for not annotating too many standard library functions as infix. I’ve never liked the inconsistency that they introduce into the syntax and this change will definitely help?

    Will it be possible to invoke infix functions using the normal invocation syntax? I remember it used to be necessary to support the normal syntax to support nullable types. Is that still the case? Or is it possible to insist that infix functions can only be invoked using infix syntax?

  8. Peter Niederwieser says:

    To avoid this, we decided to mangle names of internal members so that they do not clash with superclass members.

    Does this mean that internal members can no longer be used from Java code? I thought that allowing fine-grained interaction between Java and Kotlin code was a design goal.

    • We are thinking about this. It is likely that we will have to sacrifice Java calls, and the workaround being straightforward (simply make it public), it seems to be OK

      • Peter Niederwieser says:

        internal seems to be losing more and more of its appeal (no longer the default, Java interop woes). Also, Java’s upcoming module system will add another layer to determine what’s truly public (i.e visible from outside a module). Perhaps time to re-align internal with Java’s package-private?

          • Peter Niederwieser says:

            Will I be able to use @JvmName to get an unmangled name?

            By the way, I’m pleasantly surprised how easy it is to define a JUnit @ClassRule in M13 – neither @JvmStatic nor @publicField is required. Does the compiler infer this from ClassRule‘s @Target({ElementType.FIELD})?

            PS: Should @publicField be @PublicField?

  9. Sergei Lebedev says:

    We use _ for slices in a NumPy-like library, for example:

    Here _ is a singleton object used for choosing between the different #get implementations.
    I must admit, the whole thing does look like a hack, but it also makes the code simpler and easier to understand (especially if you’re used to NumPy). So, since _ is going away in the next milestone, can you suggest a replacement?

  10. Pavel Sikun says:

    #On backing fields:
    Why not make them behave like a normal closures? Instead of shady and unobvious field we could use it or even let users to rename this field manually the same way as they do it in closures:

    On infix\operator things:
    Keep autoconversion of operators, just make infix keyword for defining infix functions. This will help to preserve native feel when using 3rd-party java libs(i.e. auto-something[i] instead of something.get(i) and a + b instead of ) while blocking ability to call everything infixly(-> which will make devs stick into standard code-style). Best of both worlds.

    • We believe field is more descriptive, and a body of a getter/setter is not a lambda, so it doesn’t seem logical there.

      We found that Java libraries have those names matching so rarely, that it’s not worth it

      • Ion says:

        ‘field’ is descriptive,
        but ‘it’ is used in groovy and other JVM programming languages,

        now with different names, developers need to remember
        2 things, ‘it’ for closures and ‘field’ for fields.

        And those are even not keywords.

        And IDEA doesn’t highlight them, so this is not readable at all
        for people new to kotlin.

  11. Eddie Ringle says:

    I’m good with most of these changes, but the operator/infix modifiers scare me: it seems like Kotlin is starting to gain a lot of needless verbosity that makes Java such a pain.

    I just don’t really see the point in adding more modifiers to limit syntax (as opposed to the semantics of said syntax). If people want to use the infix syntax interchangeably with dot syntax, why make it more difficult for them?

  12. Peter Niederwieser says:

    Something is wrong with the comments section of this blog. The number of responses is constantly changing forth and back (right now it’s back from “36 Responses” to “26 Responses”), and some comments are always missing. E.g. right now it only shows my initial post, but the follow-ups are gone.

    • Roman Belov says:

      Yes, it’s known problem of our blog. There are some issues with WP caching plugins. We do our best to solve this problem and brig all of our servers into sync.

  13. Cullin Poresky says:

    The operator modifier feels verbose and cumbersome. Why not keep things as is, but use getAt and setAt instead of get and set for operator overloading (like Groovy does)? It seems like for the rest, overloading an operator is almost always intentional, or at least a nice bonus.

  14. Amal Samally says:

    Operators and infix functions changes are really bad, as for me. It will ruin much of kotlin flexibility and convenience with different java libs if we always need to declare ugly extension methods. As a result, people simply will not use infix syntax almost never.

    I’m against the infix/operators function calls limitation.

    Please at least keep autoconversion of operators. In kotlin they do not cause any problems anywhere.

    • Please name the libraries you have in mind

      • Amal Samally says:

        Any custom (without use of Java Collections Framework) collection libs (get/set methods & many other that are convenient for infix syntax).

        High Performance Primitive Collections
        Guava collections
        Goldman Sachs Collections
        many many others with custom structures

        Different math & time libs (get/set methods, other operators & many other methods that are convenient for infix syntax)

        Commons Math
        many others

        • All collections you list implement collection interfaces, and their members will inherit the operator markers.

          Joda-Money: plus and minus match, “negated” doesn’t
          Joda-Time: each get will need an extension defined, you are right
          Common Maths: method names don’t match anyways

          Bottomline: this concern is rarely relevant.

          • Amal Samally says:

            All collections you list implement collection interfaces

            This is not true.

            HPPC collections doesn’t implement JCF collection interfaces. That’s the whole point of the lib.

            Guava & others doesn’t implement JCF collection interfaces for any special structures like Multimap, Table, Trie, etc. There are no suitable JCF interfaces.

          • Amal Samally says:

            Even more: org.jsoup.nodes.Attributes don’t implement Map interface, but I want to use «get» method from it with index operator. And so what I supposed to do?

            I really hate this operators & infix syntax changes, on a par with backing field syntax deprecation – it was used in dozens places within our projects and now we have to use ugly backing property syntax instead.

          • Amal Samally says:

            Any Java lib can have classes with methods convinient for operator syntax without implementing standard JCF interfaces.

            Declare extensions every time?
            No thanks, it’s even worse than to use java. I just have to stop to use operator syntax, though it is unpleasant :(

  15. Rodrigo Quesada says:

    I’m totally in favor of dropping of the $foo syntax for backing fields, sometimes it is very important being able to enforce access to a field only through its getter/setter—such as when you use some kind of dirty-field property delegate for a persistence-related model for example, and having backing-properties should definitely be enough for the cases in which it is required to have access to a field from a place other than the defined getter/setter.

    The other changes also seem perfectly reasonable to me. :)

  16. Andrew O'Malley says:

    Backing fields
    Seems intuitive. I don’t use them enough to have a strong opinion.

    Great. This allows tooling to aggressively convert functions to their operator equivalent without accidentally including non-operator functions.

    Excellent. Chaining infix syntax seems to always break down with non obvious ambiguities. Readability is also harmed by devs choosing different styles – again tooling can enforce the style when explicitly marked as infix. After years of dabbling in scala I still couldn’t settle on a style wrt infix (and braces versus parenthesis for lambdas – mercifully not an option in Kotlin).

    Not fussed. Any barrier to using annotations is welcome. :-)

    I haven’t used this to date. It looks inconsistent with how extension functions are normally defined, but it’s obscure enough that I don’t mind.

    Internal visibility and mangling
    Seems fair enough. Keeping internal is worth the fight – package level access is virtually useless in Java.

    I’m still a bit confused about the final module design. Are tests considered to be part of a module (with internal access) even though they’re compiled separately?

    Possibly related, internal visibility doesn’t seem to be enforced by the compiler, but is shown in the IDE.

    Other Changes
    All seem fine.

  17. Eugenio Marletti says:

    All changes seem fine, except for dropping protected from interfaces!
    It’s an incredibly useful feature that allows for some unique patterns. How does it work right now in regards to Java? Can it be kept, even in a limited fashion? I’d be OK with it being unusable in Java, like not really in the JVM interface but only as metadata used by Kotlin.

  18. Ilya says:

    Regarding to infix function calls, I can see a clear parallel with the synthetic extension properties. Without them one had to define extensions manually wrapping ugly java getters and setters to get nice looking properties.
    My main concern is about existing Java API: it may turn to be impossible to annotate it with some special @infix annotation and impractical to cover with extension methods just to get the infix syntax.

  19. Olivier Binda says:

    about const : sometimes I now that something is a constant but I don’t want to have to compute it, so I would like to do something like this :

    const val myConstant = someMethod()

    Is there a way, the “const” keyword could mean that there is a contract on the someMethod() computation, in that it should always give the same constant result,
    so the limitations on const (primitives, String, enums, class literals) could be somehow lifted ?

    (the contract being about making builds and errors determistically reproductible,
    constants might also get written on disk and checked (or not) between compilations, to warn users about some wrong const usage)

    The compiler would then be able to inline the val, there would be advantages outside of the annotation scope

    I mean, the compiler should be able to compute this value for me, I don’t want to compile some code and run it to just print a value in the console tat I have then to paste in my code. I would have to redo this process whenever I change some parameters, Tools are about making things easier for the developer. :)

  20. says:

    = Backing Fields =
    Kotlin would be best served having a global access pattern for backing fields. Additionally a shortcut could be used when it is not ambiguous. What about using ‘myField::field’ and the shortcut ‘::field’ when in the getter and setter. Access to the delegate function could be ‘myField::delegate’.

    = Operator and Info =
    I disagree with the operator and infix keywords. I don’t see what problem adding these keywords solve. If there is no need for them, and the language works now, then why add them? Operators are still in same namespace as methods so adding this keyword does not solve that. If you don’t like operators, don’t use them. One of the great benefits of kotlin is many of its features are by convention (compiler tricks), allowing libraries not designed for kotlin, to be used in a very kotlin way. Many collection like classes have a “get”, good I can use it with square brackets. I feel the same about infix, if using infix methods is too confusing, then the caller should use direct methods calls.

    = Const =
    Does the “const” modifier promote a class val to its companion object? If it does then I agree with adding it to the language. If not then can the annotation issues be solved with a compiler error?

    • Chris Kent says:

      The reason I dislike allowing any function to be called using the infix syntax is that it allows a mish-mash of coding styles based on the personal preference of the developer. When I was coding in Scala I ended up cursing the flexibility of the syntax in this area.

      Requiring a modifier for an infix function makes it clear what syntax should be used to invoke it and hopefully makes the calling code consistent. And consistency is a great thing for readability.

    • :: is used for reflection, but I see what you mean. This may come in some form in future versions

      Does the “const” modifier promote a class val to its companion object?


  21. Salomon BRYS says:

    === Backing fields ===
    OK, great 😉

    === infix functions ===
    I agree with Sergey, Eddie, Amal and msgile, I believe being that making functions non-infix by default will prevent most usage.
    I think it’s the programmer’s choice whther he chooses the infix form, or the dot form. For his usecase and for his code, he should have the choice.
    Why not an @Infix annotation that would allow tools to actively propose the infix syntax when using annotated methods (and forcing the method to have only one parameter) ?

    === Operators ===
    Please do not take away the automatic operator feature of kotlin!
    Here’s a use case that you might not have think of: I maintain a corporate library that is in Java but I do, in Java, propose the functions that allow kotlin code to use operators. I would now have to also maintain a kotlin version of this library, just to add the operator keyword. I do agree with Eddie, Cullin, Amal and msgile when they say that the “operator” keyword would add unnecessary verbosity and would remove a great choice from the programmer.
    I don’t believe in taking the programmer by hand to tell him how to programm is a good idea. He should have the choice and selects what works best for him.
    Why not an @Operator annotation that would allow tools to actively propose the operator syntax when using annotated methods (and forcing the method to be operator-able) ?

    === Constants ===
    Will const vals be inlined? And furthermore, will Java static final will be inlined ?
    That would be a very good news for Android developers.

    === invokeExtension() convention ===
    I do not really care, but I agree with Andrew : It really seems inconsistent with how extension functions are normally defined. Which is sad.

    === Internal visibility and mangling ===
    I don’t understand why not make kotlin’s internal like package-protected in the JVM ? What’s the argument ?
    What worries me is that kotlin is loosing a bit of its Java interoperability. Meaning that we will have modules / packages wrote either in Kotlin or in Java, but it will be difficult to have a module / package writen partly in Java, partly in Kotlin, because anything they would share would have to be public.

    === Other changes : _, __ and ___ ===
    I think we need a syntax to ignore an argument in a lambda and in a multi-assigns statement. I really hope this is what _ is for.
    Star () is also good, btw, I don’t care. I’d just like to have a way to declare a lambda like this: { event, _, _ -> /…*/ }
    Can you tell us what’s on your mind regarding those three identifiers ?

    === Other changes : protected & internal interfaces ===
    can’t you put a protected interface inside a protected wrapping class ?
    In Java, an interface defined inside a package-protected class is accessible only inside the package :

    /package-protected/ class Wrapper {


    === Other changes : Others ===
    OK, great 😉

    • Salomon BRYS says:

      The final code did not print well :

    • Will const vals be inlined? And furthermore, will Java static final will be inlined ?

      Share your use cases, please. The only one I know of is the API version, which is a minor thing, AFAIU

      I don’t understand why not make kotlin’s internal like package-protected in the JVM ? What’s the argument ?

      I don’t believe it is possible.

      can’t you put a protected interface inside a protected wrapping class ?

      We could, but it wouldn’t solve the problem of protected and internal members in interfaces.

      • < blockquote>Share your use cases, please. The only one I know of is the API version, which is a minor thing, AFAIU

        There is one more use case at least: debug-only execution. Let’s take logging as the most used example.

        is not removed from the bytecode in release builds, despite the fact that it is unreachable.
        So all the debug logging strings stay in the production bytecode, which is not nice.

        I’ve written the blog post on this topic, and the lack of inlining Java “static final” fields is the only thing that stops debug logging in Kotlin from being perfect. By “perfect” I understand “absolutely invisible in production”.

      • Salomon BRYS says:

        Yes, the use case is the API version, which is NOT a minor thing. Google specifically advises a method that crashes in Kotlin, which is a problem because :
        – A programmer that learns Android with Kotlin will have it’s app crash without good reason
        – We can’t port compatibility aware Java code to kotlin.

        As for interfaces, it’s a good start, though, why not allow protected interfaces but not protected interface members ? 😉

        • A programmer that learns Android with Kotlin will have it’s app crash without good reason

          Yes, this is unfortunate.

          We can’t port compatibility aware Java code to kotlin.

          It’s a bit of an exaggeration: I believe that defining a named constant in your portable code is only a minor inconvenience.

          As for interfaces, it’s a good start, though, why not allow protected interfaces but not protected interface members ?

          Did I say we are not allowing protected interfaces?

          • Salomon BRYS says:

            Sorry for the misunderstanding about interfaces 😉

            As for inlining constants :
            – The code compiles in Java
            – The app works when compiled with Java
            – The code is correctly converted in Kotlin by the plugin
            – The code compiles in Kotlin
            – The app crashes when compiled with kotlin.

            I belive it adds a complexity layer to the person who is learning to use Kotlin and / or Android.

            Is it complicated to add constant inlining in Kotlin ?

            • It is not hard to add it, but the consequences are complicated: Java’s const inlining costs people considerable trouble every now and then (it breaks separate compilation). So, we are considering mitigating this somehow, but haven’t settled on a solution yet.

          • Krtko says:

            Hey just to put in my two cents, I am a game developer and I rely heavily on inlined constants. It greatly reduces the bugs of inlining the values one’s self as well as not taxing performance. Sometimes I will have several hundred constants in one game, organized in dozen or so classes, and used heavily through out the app.

            Right now I am using singleton – val to simulate static final I don’t see it as ideal, but Kotlin is a pretty fantastic language otherwise. :)

Comments are closed.