Kotlin Future Features Survey Results

Posted on by Andrey Breslav

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.

Comments below can no longer be edited.

75 Responses to Kotlin Future Features Survey Results

  1. skin27 says:

    February 6, 2013

    the downTo function is practical, but why does the .. operator not first check if left is greater of smaller than the right and call a upTo() or downTo() after that. If someone first tries the .. operator he will be surprised that ” for (i in 4..1) print(i) ” prints nothing. Or will he be guided by the IDE to use the downTo function?

    • Evgeny Gerashchenko says:

      February 7, 2013

      Because if we do so, it will be the big source of bugs: when you expect your program to not iterate at all, it will iterate in reversed direction. There are different syntax for direct and reversed iteration, you always know what you mean and what you expect.

      Let me show you simple example. Consider that “..” automatically iterates backwards, when first end is greater than second.

      fun f(a: List) {
          for (i in 0..a.size() - 1) {
              println(a[i])
          }
      }

      This function works perfectly for non-empty lists. But what if the list is empty? a.size() == 0. First, code will try to access element number 0. If we somehow escape IndexOutOfBoundsException, it will try to access element number −1 on next iteration. That’s not what you want to expect.

      IDE inspection for loops which never iterate is a good idea, I have added a request to issue tracker: KT-3333.

      • Stephen Colebourne says:

        February 7, 2013

        Perhaps you should allow 4..1 if both ends of the range are literals.

        • Evgeny Gerashchenko says:

          February 7, 2013

          That would be even more error-prone: 4..1 would mean absolutely different from 2+2..1

          • AssD says:

            February 8, 2013

            Haskell’s doing fine with it. You might get some edge cases, but it shouldn’t be a rocket science to cover them.

          • skin27 says:

            February 8, 2013

            Thnx, for your explanation. I can now imagine that are several cases where this can lead to errors.

            In the array example though I would expect an error, so I would know I am iterating an empty list. Now there is no clear way to find this out.

            On the subject of array. I personally find it always a bit confusing that array indexes start from 0, instead of 1 (so that maxIndex is size – 1, instead of maxIndex equals arraysize). Maybe there could be IDE inspection on this one too (common mistake to forget the -1)?

      • Daniel Siegmann says:

        February 9, 2013

        If I write 4..1 my expectation is it will iterate from 4 down to 1. In fact I ran into this when learning Groovy: I found a case where I needed this reverse iteration, and tried that approach hoping it would work. It did.

        If 4..1 doesn’t provide reverse iteration, it should be throwing IllegalArgumentException or something similar. I would certainly not expect it to do nothing – to me that is a silent failure.

        The code example you provide is obviously buggy. You need to check whether the list is empty – as a Java developer, that would be immediately obvious to me. A better solution is to allow an exclusive boundary, as Groovy does; e.g. 0..<a.size().

        Of course, in Kotlin I would expect to write something like a.each { ... }

  2. Romeo Frenksen says:

    February 7, 2013

    Hi,

    you stated, that

    for (i in 4..1) print(i) // prints nothing

    won’t print anything, but the following should be used instead:

    for (i in 4 downTo 1) print(i) // prints "4321"

    To me, it’d be more intuitive, if the first option would be possible, too. Furthermore, the second variant just adds complexity to the language as you have to memorize an additional word. Could you please explain the pro/cons for the current implementation?

    Thanks.

    • Evgeny Gerashchenko says:

      February 7, 2013

      Please read my answer to previous comment.

  3. Marc-Olivier Fleury says:

    April 1, 2013

    Why not use upTo instead of just .. for progressions? Although more verbose, this version makes it clear that the first bound has to be lower.

    Additionally, I find it a bit awkward to use the same construct for both progression and range. It seems to be a a cool feafture when first looking at it, but the different remarks posted here are probably an indicator that something is wrong.

    An example of an awkward case: using a progression with real numers requires a step, but not with integers. However, ranges will never require steps, even for real numbers.

    Bound ordering is also not a problem when defining ranges, but is suddenly a problem when using progressions.

    These are a few reasons why I would limit the use of .. for ranges, and require upTo or downTo for progressions.

  4. Anton says:

    May 29, 2013

    In 95% of cases we will have an iteration over indexed collection:
    for ( i in 0..nodes.length()-1 ) { val node = nodes.get(i); ... }
    Some languages permit an exclusion construction like:
    for ( i in 0..<nodes.length() ) { val node = nodes.get(i); ... }
    which is especially useful in the iteration as above.

  5. Jake Wharton says:

    June 13, 2017

    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:

      June 14, 2017

      +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:

        June 16, 2017

        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:

          June 21, 2017

          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:

      June 14, 2017

      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:

      June 14, 2017

      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.

      • Bernd says:

        June 14, 2017

        In several DSLs, e.g.: https://github.com/Kotlin/anko

      • Jacob A Zimmerman says:

        June 17, 2017

        Plus ranges are created from the . . operator or infix functions. Plus Pair can be made with an infix function.
        Outside of Kotlin, Hamcrest matchers do it. I do it all the time.

    • João Vitor Verona Biazibetti says:

      June 14, 2017

      Totally agree.

    • Lovis says:

      June 15, 2017

      Exactly!

    • Vithorio Polten says:

      June 16, 2017

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

    • Andrey Breslav says:

      June 16, 2017

      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.

    • Alexander Kosenkov says:

      June 21, 2017

      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.

    • Mike Holler says:

      June 23, 2017

      I hear your pain. I have really grown to enjoy the lack of collection literals in Kotlin. At first, I thought the omission was strange, but now I appreciate that it forces me to think about the collection implementation I want to use. And really, why shouldn’t it be a function? It really is just saving a couple of characters.

      All in all I’ve really liked Kotlin’s functional approach to things (in the sense that we have a very limited number of keywords and language features compared to other languages). Synchronized as a function is just fine.

      I would say that I don’t quite feel the same way about async/await as you. If it’s a function in the stdlib, we can always use other, better things if we want, but beginners can start off with good programming practices. I see this as similar to the Android architecture components announced at I/O this year. It’s good to see async/await encouraged by the language, but we always have other options if we want to use them. That being said, I’d like to see the effort focused elsewhere, but I’m not upset about their inclusion.

      • RogerV says:

        June 29, 2017

        Can’t do real coroutine style async/await with library calls – well, at least libraries written in the usual manner.

        The generator function should return an iterator and the consumer then processes on the iterator. When done in coroutine manner, the generator and iterator consumer will execute on the same thread context. That means when the generator calls yield(), it transfer execution directly back into the iterator consumer; when the iterator consumer calls next(), it will transfer execution directly back into the generator function (typically implemented as a lambda).

        So the generator and the iterator consumer ping pong back and forth, the generator returning a new result when it calls yield() and the iterator consumer obtaining that new result when it calls next().

        This can be done in Java now by letting the generator run on a background thread separate from the thread that the consuming the iterator. Generated values are passed via the blocking queue or the unbounded non-blocking linked list queue.

        Coroutine eliminates need for a queue, any thread context switching, or any blocking, because a generated value is passed directly to the consumer as it iterates.

        To implement this for Java (or Kotlin or Scala today), one can use JavaAssist to generate a bytecode class implementing yield() and next() methods. The implementations of these two methods would be coded in Java bytecode assembly language – in order to implement the ability of the special manipulation of the calling stack frames. Very simple code, very efficient, and 100% Java bytecode.

        A helper runner class would implement a run(), then(), and handleException() methods. Call run(), passing it the generator lambda. The generator signature accepts another lambda that is the yield operation. The generator invokes this to pass a value to the consumer.

        The then() method accepts a lambda that is called when the generator is done (or is terminated).

        The handleException() accepts a lambda that that will be invoked to handle any exception that occurs in the generator.

        The run() method returns a Java-style iterator (which can then be easily wrapped in a Java 8 stream).

        The consuming code initiates the generator to start by beginning to execute on the iterator.

        Then the consuming code and the generator beautifully execute on the same thread context.

  6. Christian says:

    June 13, 2017

    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:

      June 15, 2017

      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.

      • Marek says:

        June 15, 2017

        +1

      • Christian says:

        June 15, 2017

        The ternary operator is not more useful than if/else, it just save a few charaters at the cost of readability and purity of the language.

    • alexander says:

      June 18, 2017

      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.

  7. Mario says:

    June 14, 2017

    Please don’t convert Kotlin in another Scala.

    • Pascal says:

      June 14, 2017

      +1

  8. Alan Fox says:

    June 14, 2017

    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.

  9. Pascal Le Merrer says:

    June 14, 2017

    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.

  10. kabram says:

    June 14, 2017

    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:

      June 14, 2017

      +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).

  11. Hannes Dorfmann says:

    June 14, 2017

    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…

    • Vithorio Polten says:

      June 16, 2017

      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:

      June 16, 2017

      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]

  12. Nick says:

    June 14, 2017

    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:

      June 15, 2017

      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:

        June 16, 2017

        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.

      • Vithorio Polten says:

        June 16, 2017

        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:

      June 16, 2017

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

  13. neworldLT says:

    June 14, 2017

    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)

    • soywiz says:

      June 14, 2017

      +1

    • Nick says:

      June 15, 2017

      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” 🙁 .

  14. Julian says:

    June 14, 2017

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

  15. Włodas says:

    June 14, 2017

    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.

  16. soywiz says:

    June 14, 2017

    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
    )

  17. Отчет о BKUG #4 – Belarus Kotlin User Group says:

    June 14, 2017

    […] митапа стали доступны результаты голосования: https://blog.jetbrains.com/kotlin/2017/06/kotlin-future-features-survey-results/. Пожалуй аналитику результатов оставим вам, как нам […]

  18. Zack says:

    June 14, 2017

    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 🙂

    • Zack says:

      June 14, 2017

      Sorry for the typos, I just work up…

      • Zack says:

        June 14, 2017

        God dammit…

    • Lovis says:

      June 15, 2017

      This!
      If we add static, we could as well add “normal” fields next to properties.
      The point is, it is a good thing that Kotlin doesn’t have some of these features.
      If someone now drops the killer “performance” argument – this is something the compiler should take care of, and not the programmer.

      • Christian says:

        June 15, 2017

        You’re right: the compiler should get smarter and not the language gets more ways to express the same things.

      • Vithorio Polten says:

        June 16, 2017

        Agree.

  19. Christian says:

    June 15, 2017

    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.

    • Vithorio Polten says:

      June 16, 2017

      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.

  20. Denver Coneybeare says:

    June 15, 2017

    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.

  21. Lance Miller says:

    June 15, 2017

    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.

  22. Alex says:

    June 16, 2017

    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:

      June 16, 2017

      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.

  23. Vithorio Polten says:

    June 16, 2017

    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.

  24. Ben says:

    June 16, 2017

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

  25. David W says:

    June 17, 2017

    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.

  26. Jacob A Zimmerman says:

    June 17, 2017

    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.

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

    June 20, 2017

    […] Details zu den Feature-Vorschlägen und den Umfrageergebnissen finden sich auf dem Kotlin-Blog. […]

  28. Jesper says:

    June 20, 2017

    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).

  29. Programming Ideas With Jake says:

    June 23, 2017

    […] the survey results for Kotlin’s future features are in. Let’s talk about […]

  30. Naetmul says:

    June 23, 2017

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

  31. 刘庆文 says:

    June 26, 2017

    Why Kotlin is not supported with Chinese?

    • frystalizer says:

      June 29, 2017

      Why should it support for Chinese? How the parser gonna read your code?

      • 刘庆文 says:

        July 4, 2017

        Sorry, but that is not what I meant, I say this because I couldn’t see my comment while I posted here in Chinese. Not for Kotlin…

Subscribe

Subscribe for updates