Kotlin Future Features Survey Results

With all the exciting recent events, we had to postpone the publication of the Future Features Survey results. Sorry about that. Better late than never, this blog post summarizes what we learned from the survey.

To recap, the Future Features Survey ran in April and got about 850 replies. We would like to thank everyone who took part in the survey!

Survey results

The raw (anonymized) data for the survey are available here.

The questions asked were:

  • The most expected feature 1, The most expected feature 2, The most expected feature 3
  • Nominate one feature that you would like to be banned (optional)

You can see the list of proposed features here.

We received a total of 852 responses (a few of them blank). Most people used up all three slots for positive feature nomination, and some 300+ people skipped the negative nomination.

Here’s the summary chart of all results (sorted by nominations in favour of a feature):

So, the favorites here are: “Collection literals”, “SAM conversions for Kotlin interfaces” and “Truly immutable data”.

“Private members accessible from tests” seems to be the most controversial feature: 108 people for and 120 against, which is understandable since designing for testability is widely recognized as a good practice.

I’m a bit puzzled over the “Overloadable operators | and &” controversy: 46 for and 50 against, while I see zero harm in this feature. Please share your motivation in the comments to this post.

Here’s the chart of negative nominations:

We shouldn’t have put “Optional commas” and “Optional trailing commas” under the same feature (my mistake, sorry), as it’s actually two features, so the results there are difficult to interpret.

Another mistake (and on my part as well): we forgot to include “Ternary conditional operator” in the survey, and realized that too late in the game. Sorry, folks, we understand that there’s substantial demand for this feature, and will look into it.

Curiously enough, the results of the survey that was conducted at the Kotlin 1.1 Launch Event turned out quite differently:

I suspect that the results may have been affected by the fact that people saw previous votes and got biased, but it’s hard to be sure. Other factors may also be relevant, e.g. the audience at the meetups may be a bit different from the online survey audience.

Conclusion

There are clear leaders:

  • Collection literals
  • SAM conversions for Kotlin interfaces
  • Truly immutable data

The rest of the features got significantly fewer nominations. Truly immutable data is very desirable indeed, but really tough too, so no promises there. The other two seem tractable in the foreseeable future, and multi-catch looks like a good thing to look into as well. Anyway, we will take the results into account while planning our work.

Disclaimer: as announced previously, we are not committing here to implementing any of these features in a particular time frame, or at all. We do care a lot about what our users need, but can’t promise anything upfront. For one thing, there’s significant design work required before we even know if these features can be fit pragmatically (and elegantly) into the language.

About Andrey Breslav

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

59 Responses to Kotlin Future Features Survey Results

  1. Jake Wharton says:

    Ah, yes: collection literals. Spitting in the face of a language design principle to save a whole 5 characters. For the next survey please include “synchronized as a keyword” and “async/await keywords” so that we can continue to regress things into the language when a library function is already doing Just Fine™.

    Please executive decision this to the bottom of the “NO” pile.

    • Zach says:

      +1, I would really rather the language NOT have to know about the datastructures in the standard library. It’s improper separation of concerns…

      • AD says:

        Maybe collection literals can be implemented in a way that does not require the language to know (too much) about data structures, just by using some (not too) smart inference mechanisms.

        For instance, when the compiler reads :

        val l: List = [ 1, 2, 3 ]

        it knows that where the collection literal appears, a List is expected. It will therefore replace the literal [1, 2, 3] by a call to some factory method from List.Companion (having a reserved name such as “of()”, the same way reserved names are used for overloading operators).

        Thus such literals could automatically be used for any type having a factory method with required name and signature.

        • Alexander Kosenkov says:

          Wow, that’s a nice approach and it is totally in line with the spirit of Kotlin like a in b b.contains(a).

          The only problem is that it must be List or List<~> in Java 8 sense. It is a less of a problem if the value gets passed to a function with explicit argument type:

          calculateVector( [1, 2, 3] )
          or
          calculateMatrix( [1, 2; 3, 4] )

    • Michael McLellan says:

      Would you mind explaining your reasoning?

      Collection literals are one of my favorite parts of Clojure, and I always miss them when dealing with any sort of nested data.

    • Oğuz Can Ayverdi says:

      I feel that the current implementation is the one spitting in the face of a design principle. Where else in the language do you use a function (that is not a constructor) to initialise an object? It confused me when I was learning the language, and still feels weird.

    • João Vitor Verona Biazibetti says:

      Totally agree.

    • Yeah, and it’s a pretty big dangerous move for a sugar.

    • I understand the concerns here, and we have no decision about this feature yet. The biggest problem we are having here wrt collection literals is array constants in annotations (currently really ugly compared to Java), and this is a big use case, because of numerous Java frameworks relying on annotations. So, this issue requires some further consideration.

      On a side note, I wouldn’t dismiss the seemingly small advantage of [1, 2, 3] over listOf(1, 2, 3) too quickly. Not saying I’ve finished evaluating it yet, but it seems that it may not be all that straightforward when it comes to data science use cases, for example.

    • I’ve added my thoughts on the possible implementation:
      https://medium.com/@kosiakk/experiments-with-kotlin-array-literals-7f4e75d24ebf

      For vectors, it all boils down to making this implicit in operator call val x = this [1, 2, 3], nothing more. The rest is a library.

  2. Christian says:

    I’m a bit shocked that the ugly and redundant ternary operator could be included in Kotlin! What is the motivation? What are the benefits over a simple and readable if/else?

    Same is true for static members. Objects and companion objects are much cleaner conceptually. I hope you as the language stuarts can resist to include features that are redundant. That is one point I really like about Scala: there is one powerful solution for one problem. There is if as an expression and no ternary operator; there are object and not static members; there are functions and no operators; there is pattern matching and no other construct to exceptions; and so on. Don’t get me wrong: I don’t want Kotlin to become Scala, but I’d like Kotlin to maintain some minimalism.

    To the question regarding “|” and “&” operators: I’ve no strong opinion but the misuse of operator like methods in Scala is one thing I really dislike.

    • Alex Berry says:

      I’d agree with you about the ternary operator if Kotlin didn’t already have the Elvis operator. I think it’s a little weird for a language to have the Elvis operator and not the ternary operator since the Elvis operator is just a short cut for a common ternary operator pattern. If you are going to have one should probably have the other since the ternary operator can be useful sometimes.

    • alexander says:

      I love the ternary operator. Coming from C++/OpenGL using conditional move(cmov) is (was) faster then braching if else spaghetti code.

      And i know it not just me, that understand the beauty of math notation.

      Personaly: If i read if else with all the longfunctiondeclarationforlegibility, i get totaly unfocused and lost.

  3. Mario says:

    Please don’t convert Kotlin in another Scala.

  4. Alan Fox says:

    Regarding the “Overloadable operators | and &” feature, I remember dismissing this out of hand because it wasn’t clear to me how this would affect the present ‘or’ and ‘and’ infix functions when it came to bitwise operations. If the latter were simply going to be replaced by the former, then this could lead to a mess as the precedence would presumably be different.

    Although one can argue that the traditional bitwise operators should have been used in the first place, I for one am happy with the present situation and think we should now live with it.

    Although a lot of people miss the ternary operator, it seems to me that it would be difficult to introduce it into Kotlin now because the presence of the ‘?’ might make people think that it’s something to do with nullability. The if/else expression has the advantage of clarity even if it is a bit verbose. One could perhaps include an: iff(condition, result1, result2) generic function in the standard library which would be slightly less verbose but still clear for simple cases.

    It also seems to me that there is little point in introducing collection literals unless it is clear from the literal itself what its type is – otherwise you have to specify the type and no typing is saved. Given that we have generic arrays, primtive arrays, lists, sets and maps – and mutable/immutable versions of the last three – then, unless you’re going to introduce some elaborate system using different types of brackets and/or prefixes or suffixes, it’s difficult to see how this is going to be feasible. You could perhaps introduce literals for immutable lists or maps and not for the others – though no doubt this wouldn’t satisfy everybody.

    Having said all this I wish there was an easier way to declare multi-dimensional collections as the present system involves a lot of repetition.

  5. Pascal Le Merrer says:

    I did not answer to the survey, as it was mostly oriented towards feature addition.
    And my wish is not for new features to be added.

    On the contrary, I’m afraid you wil continue to add many new features. I would prefer the language to remain simple, with an easy learning curve.

    Just add essential features, and forget the rest, to avoid making Kotlin a bloated language and keeping it as nice as it is today.

  6. kabram says:

    As other folks have commented, there is no need to introduce syntax when the existing construct just works. List Comprehensions are the best example of an absolutely non-intuitive construct pretending to be easier than filter and map functions. Comprehensions may appeal to those coming from a python background but familiarity of obtuse syntax among some is no reason to inflict everyone with it. And when you have multiple comprehensions being combined, the result is an absolute mess. Please, drop the idea of comprehensions.

    list.filter { … }.map () is simple enough.

    • soywiz says:

      +1 too. https://haxe.org/manual/lf-array-comprehension.html
      (0 until 10).map { ... } has better readability for me. Do not require additional syntax. I think comprehensions are better suited for languages without statically typed systems without extension methods or with more verbose lambdas. I don’t see the point in Kotlin.
      What you can do instead is to try to optimize generated code to avoid garbage as much as possible (optimize inlined code further if there are any sane opportunities there).

  7. Hannes Dorfmann says:

    So developers would like to save writing few characters with collection literals but at the same time they dont want to introduce static but rather want to write companion objects all the time. I don’t get it…

    • It’s like cooking, people want to throw in everything that gave them a good feeling before. But then, later, you taste that soup, and notices that some ingredientes did well only in rice with meat and not in the chicken soup you made.

      But the first moment, is thinking in throwing every nice thing in there. And just later you learn that’s not really a good approach to cooking.

      Developer are the inexperienced chef trying to cook a language. And I am one myself.

    • Bernd says:

      You are not forced to write companion objects. There are top level declarations for static elements:

      [code]
      private val ABC_123 = mapOf(
      “a” to 1,
      “b” to 2,
      “c” to 3)

      private fun square(x: Int) = x * x

      class Foo(private val bar: Int = 5) {
      fun printAbc123() = println(ABC_123)
      fun squaredBar() = square(bar)
      }
      [/code]

  8. Nick says:

    Jake Wharton – What design principle are you talking about? In general the Kotlin community have spoken and they WANT collection literals which is the top voted language feature. Definitely no surprise that the community is urgently after collection literals for quite some time. Remember that many major programming languages have collection literals. Python for example have them and the feature doesn’t make Python hard to learn (still the easiest language to learn).

    From the survey results here are the top 5 most request language features:

    Collection literals
    SAM conversions
    Immutable data
    List and array slices
    Inline/Value classes

    Somewhat surprised that value classes aren’t higher up the chain (very important for Kotlin Native). Good to see that SAM conversions are considered very important by the Kotlin community. Nice to see immutability in the top part of the list.

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

      He is talking about keeping the language elegant and compact, which is important.

      The survey was answered by less than 900 developers, which is a small fraction of all kotlin developers (Slack has about 8000 members, many more could be considered as a part of Kotlin community). So “the Kotlin community have spoken” is a bit exaggerated.

      It was noted that new kotliners who come from “many major programming languages” really want collection literals, but the more they use kotlin, the less they miss them.

      More over, some consider collection literals not only unnecessary, but also harmful. Adding in-build collection literals make some collections “better” than others with no apparent reason, which leads to poor design choices when developers use “the default collection type” instead of the optimal for their situation.

      Also, as was noted by Alan Fox, collection literals are among the least straightforward features to implement. The fact that over languages has implemented them before does not help, since many of them do not have the problems Kotlin has.

      Overall, please do not wrongly consider collection literals easy to implement, or unharmful, or universally desirable for that matter.

      • Paul de Vrieze says:

        I agree that I don’t see the point and like the fact that Kotlin uses the library to the extend it does. Beyond the point about some collections being more equal than others, an additional problem is that the introduction of collection literals introduces a use of symbols that may be better used for other purposes.

      • Agree, it’s a really dangerous feature, and as people pointed out, once done, will be almost impossible to remove or change if things don’t really work as expected.

        I really love it in Python, but I don’t know if I really want it in Kotlin. In Swift, the implementation behind their Literal support got rewritten more than once. And god-only knows if they won’t rewrite it again, making a lot of implementations needing for refactors. Having a lot of trouble and refactors because of a syntactic-sugar is something I really don’t want in my agenda.

    • Bernd says:

      The principle is called domain-driven design:
      https://en.wikipedia.org/wiki/Domain-driven_design

  9. neworldLT says:

    Bitwise operators like |, &, <<, >>, ~, ^ are heavily used in hardware programming. If you want to promote kotlin-native for IoT, please consider having them or highlight infix functions. Right now is hard to read tons of code like this:

    val color = 0xFF000000 or value or ((state and 0xFF) shl 16)

    • Nick says:

      Those bitwise operators are widely used for embedded development by C/C++ developers. So if Kotlin is to enter that area then it will need those operators. Downright confusing the “and” and “or” are designated bitwise operators instead of being used for logical comparisons, as a replacement for the && and || operators.

      Unfortunately in order to sort out the mess backward compatibility will need to be broken to remove the && and || operators, and replace them with “and” and “or” :( .

  10. Julian says:

    I’d like to second all the comments about keeping the language simple.

  11. Włodas says:

    Using invokedynamic for lambdas is only a part of what should be done to adjust to Java 8 features. To acchive greater compatibility and lesser bytecode default methods and optional parameters using static interface methods should be implemented to eliminate DefaultImpls classes.

    As for the rest:
    – SAM conversions – big plus
    – static members – Companion objects are not the best choice in every case. Sometimes we only want some constants in class and there is no need to generate additional classes for that.
    – collection literals and slices would be rather an API replacements, not a very big change for me
    – Scala-like string formatting would be very nice
    – when subject – big plus; similar case as with try-with-resources from Java 7 which will also be fixed in Java 9
    – package-private visibility – I thought about it a little and mostly this is only needed to avoid synthetic methods and for tests, but even so could be added for some cases
    – private members access is a bad idea. I think that tests and classes themselves should be changed instead of using hacking to access data.

  12. soywiz says:

    About trailing commas:

    I usually do small additions/moves/removes from lists, or arguments for functions or classes which I do in some cases faster than using a refactor. For long parameters I usually split it in several lines. The last line without a trailing comma, makes me lose a lot of time adding or removing or switching those commas to fit the syntax. Having a tailing comma would make it simpler, easier and homogeneous for editing it. If people don’t like general trailing commas, at least allow them then it is the last character of the line (for multiline statements)

    listOf(1, 2, 3, 4, ) // invalid (though I’m not agains allowing this too. I don’t think it is too common to have problems related to this)
    listOf(
    1, 2, 3,
    4, // valid
    )

  13. Pingback: Отчет о BKUG #4 – Belarus Kotlin User Group

  14. Zack says:

    No ternary operator, no collection literals, no collection comprehensions, no static. Features should be added to the language when there is currently no acceptable way to achieve what’s enabled, not when they add new syntax to do something the language can already handle quite well.

    val thing = if (true) 1 else 2
    listOf(1, 2, 3)
    collection.filter { }.etc.etc
    companion object { const val THING = 1 }

    I guess one could argue the solutions above aren’t acceptable but it seems to me the added confusion new syntax to achieve these same results with maybe a couple fewer characters is definitely not worth it.

    There are some big things Kotlin doesn’t have. Namely value data and immutable data. Granted it might make sense to see what direction the jvm is going with project Valhalla before implementing custom values but the point is the same, but with Kotlin being multi-target there eventually need to be some compiler / runtime magic to make certain data act as a value type or reference type depending on the target.

    Anyway I trust the Kotlin developer overlords to take all this stuff into account far better than I could and keep us safe through this perilous period of exponential growth in language adoption and community size. I think we all just love Kotlin and really really want it to age well so we can rely on it for decades to come. Or at least I do :)

  15. Christian says:

    I suspect that Kotlin got many new users now missing some familiar features from other programming languages. The best example is the ternary operator. It is redundant, since if/else can be used in the same way. But some developers are used to and no want it to have in Kotlin too, although it would add nothing.

    I suggest to be pretty conservativ in adding new features. Adding them is easy – removing them impossible.

    • Agree. Mostly takes a Major to remove it, and that takes a life to happen, if happens, but still will make maybe an even more dramatic moment to remove than not adding it in the first place.

  16. Denver Coneybeare says:

    Dang I missed the survey! Although it wasn’t part of the slides, I would have voted for a feature like Swift’s “Implicitly Unwrapped Optionals”. This is handy in frameworks like Android where properties get initialized after the constructor (e.g. in onCreate() or onCreateView()) and you want to null them out later on (e.g. in onDestroy() or onDestroyView()). The lateinit keyword is great for the first half but then there is no way to null it out later on. So you have to either leave it as nullable (e.g. ImageView?) and then use ?. or !!. when using the variable or just skip nulling it out, which could potentially lead to memory leaks in Android.

    A syntax like

    var imageView: ImageView! = null

    could basically disable all null checks and all code that accesses the variable would assume that it’s non-null (even though it is nullable). Then you could just access methods and properties on the variable with the dot operator.

  17. Lance Miller says:

    I echo the “Please don’t convert Kotlin in another Scala” comment.

    As for “Overloadable operators controversy”… they get abused way to easily. I’ve seen it in scala code, to the point of it looking like the code has been run through an obfuscator. Overloadable operators make code harder to grok at a quick pass, and sometimes nearly impossible to read without a detailed investigation. And that makes it counter to Kotlin’s goal of making code easily readable. As Dmitry and Svetlana say in their book on page 11:

    “It’s common knowledge that developers spend more time reading existing code than writing new code.” . . . “At the same time, Kotlin doesn’t try to collapse the source code to the smallest number of characters possible. For example, even though Kotlin supports operator overloading, users can’t define their own operators. Therefore, library developers can’t replace the method names with cryptic punctuation sequences. Words are typically easier to read than punctuation and easier to find documentation on.”

    Overall, I would ask that Kotlin say focused on readability & self documenting constructs and not on features designed to save a few key strokes when typing (optional commas? seriously?!?) or some “cool for the sake of being cool” feature.

  18. Alex says:

    New features should be considered in the context of a decade or more. If you think those features make sense in the way they’re implemented even 20 years down the line, they’re great candidates. Otherwise, it’s easy to be trapped with poor designs and concepts added for convenience but without considering their complexity footprint/debugging/maintainability etc. It can be a real problem to have features which don’t stand the test of time and cannot be easily removed due to the need for backwards compatibility. Java suffers from this issue a bit, as do most mature languages.

    • Alex says:

      I should also add that many new features added without enough deliberation can lead to inconsistencies in the language and a lack of elegance. I’m not against new features but I’m very cautious about them.

  19. This comment section, for me, worths way more than this survey. Whole opinions with some explanation behind each one motivations.

    For me, looks like the following.

    Good:
    SAM conversions => Nice sugar.
    when subject => I really need it! I alway think in situations this would make my code cleaner.
    Immutable data => Looks really useful and a trend.
    Unsigned arithmetic => With Native this will be really necessary for a clean interop.
    Inline/Value classes => I believe it can help performance/cg sensitive things like animations, also useful for Native.
    Format strings => Nice addition to the API, making it even more consistent.
    invokedynamic => Yes (but maybe with an opt-out flag in the compiler for Java8 users that don’t want it?)

    Maybe, probably with changes:
    Trailing commas (only) => And only on Constructors or Varargs. Otherwise makes code worse to read and reason about.
    Annotations for Static Analysis => Maybe as-is, but maybe like you did with Coroutine, that developers can extend upon some base implementation. And actually all of that annotations extend from this base Analysis.
    package-private visibility => Indeed useful, but not as the default, must be a new keyword.
    Slices for lists and arrays => Only if implemented as an Operator and anyone can implement it. Still up to debate.
    Vararg data classes => I like, and better yet, if you could use like this: https://pastebin.com/dnyBH0vT and I would like to do this one: https://pastebin.com/eqjCCADL but I don’t really know if it’s a good idea.
    Multi-catch => Yes? Is it really needed? Wouldn’t be nicer to have a new kid in the block called, for example, catchwhen, that can pattern-match on Throwables and has When-like syntax? Or just don’t?

    NOOOO, GOD NO:
    Ternary operator => Useless. We already can write this as such: val a = if (condition) “aaa” else “bbbb”
    Collection Comprehensions => At least, not as the Python one, they are a bit hard to grasp and get used to it’s syntax, easy to forget the syntax, don’t have a good “visual flow” compared to chainable lambdas. This goes against Kotlin style in my opinion. If it really goes ahead, do so just as some kind of DSL in the StdLib, and not a Language syntax.

    But as others said before, “I suggest to be pretty conservative in adding new features. Adding them is easy – removing them impossible.” and “it is a good thing that Kotlin doesn’t have some of these features”.

    Thank you for your time and the good work you are doing.

  20. Ben says:

    I’d like to second all the comments about keeping the language simple!! Please think twice.

  21. David W says:

    I am a bit surprised by the lack of discussion over one of the most controversionally answered features, “Accessing privates from unit tests”.

    My first reaction was, “No”, but upon further reflection, it become more of a “NO NO NO”. I wholeheartedly believe that any pros that this feature has will be overwhelmed by developers see it as Kotlin endorsing lazy, bad unit test design, where private methods are tested in isolation, probably after setting the class’s state using private field variables.

    The ‘correct’ way of doing this is to only use public methods in the class to organically set up and test your class; in doing so, you test that your unit (aka class) is working as a whole. Additionally, you test only your public api, rather than coupling your unit tests to implementation details that may be refactored without changing the class’s behavior.

    Definitely don’t want to see that feature in Kotlin.

  22. Being a lover of Python, you’d think I would want literals and comprehension. I do, but I’m afraid of how they could disrupt future features. There may be a time that the syntax for those makes it so you can’t use the syntax you want for something more important. Plus, both of the equivalents at this time are fairly concise and have more control. If you added a literal, what kind of list would it be? When there’s a literal syntax, people tend to forget that there’s any other kind of list. And for comprehensions, the methods can be called on a list, sequence, or an iterator, so which one would the comprehension use (I assume Sequence, but if I’m wrong, that just helps my case that it’s not obvious).
    As much as I love the features, I think it’s amazing how concise Kotlin is WITHOUT them.

  23. Pingback: Die Zukunft von Kotlin: Diese Features wünscht sich die Community - JAXenter

  24. Jesper says:

    Static members in classes: This is absolutely not necessary and there is already a better mechanism: companion objects.

    I guess that most of the people asking for this are Java programmers who have not yet understood companion objects.

    I would like to have value types, but unfortunately the JVM does not (yet) support custom value types very well (that’s also why Scala’s value types are crippled, they have to map to one of the underlying primitive types).

  25. Pingback: Programming Ideas With Jake

  26. Naetmul says:

    These guys are trying to make Kotlin a second Python. Holly molly. I don’t like Python’s syntax.

Leave a Reply

Your email address will not be published. Required fields are marked *