Call for Feedback: Upcoming Changes in Kotlin

Andrey Breslav

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:

var foo: Foo = ...
    get() { beforeRead(); return $foo }
    set(v) { beforeWrite($foo, v); $foo = v }

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:

var foo: Foo = ...
    get() { beforeRead(); return field }
    set(v) { beforeWrite(field, v); field = v }

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

private var _foo = ...
public var foo: Foo
    get() = ...
    set(v) { ... }

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 a.plus(b) 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 list.map {...}
  • 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:

list map {...}.toSet() // Error: toSet() is not applicable to a lambda

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.

Constants

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:

const val SCREEN_WIDTH = 2048

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:

class Foo {
    operator fun String.invoke() { ... }
}

fun test(foo: Foo) {
    "".foo()
}

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

class Foo {
    operator fun invokeExtension(s: String) { ... }
}

fun test(foo: Foo) {
    "".foo()
}

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

class Foo

operator fun Foo.invokeExtension(s: String) { ... }

Internal visibility and mangling

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

// module X

open class Base {
    internal fun foo() {...}
}

// module Y

class Derived : Base() {
    fun foo() {...}
}

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 ===

Feedback

Your opinions and use cases are most welcome!

Comments below can no longer be edited.

91 Responses to Call for Feedback: Upcoming Changes in Kotlin

  1. Rostislav says:

    September 18, 2015

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

    • Jayson Minard says:

      September 18, 2015

      I feel the same, adding a modifier makes it wordy and redundant. A keyword is more clear. Do we need “const” to be available elsewhere? Is that why it is modifier instead? And why?

      • Andrey Breslav says:

        September 18, 2015

        Compile-time constants are not important enough to introduce a new kind of declarations (which would be huge implementation-wise).

    • Artem Zinnatullin says:

      September 18, 2015

      +1, val looks redundant

    • Rostislav says:

      September 18, 2015

      Another small request is syntax highlighting for consts and java’s static finals.

      • Andrey Breslav says:

        September 18, 2015

        Requests are most welcome in the issue tracker

    • CountMath says:

      September 19, 2015

      +1 for implementing constants! 🙂 Although they could probably reduce const val to const.

    • HE Guangyu says:

      September 26, 2015

      +1

  2. Sergey Igushkin says:

    September 18, 2015

    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.

    • Andrey Breslav says:

      September 18, 2015

      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:

        September 18, 2015

        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()))
        and
        list.add(large(expression), with(nested(calls())))

        • Sergey Igushkin says:

          September 18, 2015

          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:

        September 18, 2015

        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.

        • Andrey Breslav says:

          September 19, 2015

          We believe capturing this API design intent in the code is better

  3. Jayson Minard says:

    September 18, 2015

    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: https://youtrack.jetbrains.com/issue/KT-8695

    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.

    • Andrey Breslav says:

      September 18, 2015

      Will look into it, but I’m not sure there’s a good solution

      • Jayson Minard says:

        September 18, 2015

        Not easy, but worth finding. Maybe we need more use cases in the issue to have cases that it helps, vs. those it hurts, if optional, or mandatory, etc.

  4. Jayson Minard says:

    September 18, 2015

    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:
    https://github.com/kohesive/injekt/blob/master/api/src/main/kotlin/uy/kohesive/injekt/api/Registry.kt
    https://github.com/kohesive/injekt/blob/master/api/src/main/kotlin/uy/kohesive/injekt/api/Factory.kt

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

    • Andrey Breslav says:

      September 18, 2015

      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:

        September 18, 2015

        That works.

        • Jayson Minard says:

          September 18, 2015

          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:

            September 18, 2015

            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:

        September 18, 2015

        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) {
        intoModule.registerInjectables()
        }

        fun InjektRegistrar.registerInjectables()
        

        }

        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)

        • Andrey Breslav says:

          September 18, 2015

          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:

            September 18, 2015

            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:

    September 18, 2015

    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:

      September 28, 2015

      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:

    September 18, 2015

    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)

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

    Foo<
    >
    val (a, *, c) = triple()

    • Andrey Breslav says:

      September 18, 2015

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

      Yes

      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:

        September 18, 2015

        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?

        • Andrey Breslav says:

          September 18, 2015

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

          • M Platvoet says:

            September 18, 2015

            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:

          September 19, 2015

          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.

          • M Platvoet says:

            September 19, 2015

            Why do you need a compile time constant for that? Seems like an ordinary package level public val is sufficient for that case.

  7. Chris Kent says:

    September 18, 2015

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

    • Andrey Breslav says:

      September 18, 2015

      It will be possible to use infix functions in the standard syntax, but the tooling will be hinting towards using them as infix

    • Andrey Breslav says:

      September 18, 2015

      Will it be possible to invoke infix functions using the normal invocation syntax?

      Yes, and the tooling will be advising you to use infix in this case

  8. Peter Niederwieser says:

    September 18, 2015

    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.

    • Andrey Breslav says:

      September 18, 2015

      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:

        September 18, 2015

        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?

        • Andrey Breslav says:

          September 18, 2015

          I don’t think so 🙂

          • Peter Niederwieser says:

            September 18, 2015

            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?

            • Andrey Breslav says:

              September 18, 2015

              @JvmName will work on internals, yes

              Yes, we try to apply to property, if it’s impossible, we try field.

              @publicFiled seems to be a bad idea, will go away

  9. Sergei Lebedev says:

    September 18, 2015

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

    val m = Matrix(2, 4)
    m[_, 0]  // returns the first column of the matrix
    m[_, 0]  = 1.0  // initializes the first column
    

    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?

    • Andrey Breslav says:

      September 18, 2015

      Neat hack, indeed 🙂

      Well, I’d use a one-letter name e.g. I or S for “slice”. Another (admittedly crazy) option is to use an empty sting

    • Vladimir Reshetnikov says:

      September 18, 2015

      It’s a neat syntax, and this is unfortunate that it’s going to be reserved. You will still be able to use the underscore as as identifier if you enclose it into backticks though. Maybe it does not look so bad:

      m[
      _, 0]

  10. Pavel Sikun says:

    September 18, 2015

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

    var foo: Foo = ...
        get() { value -> beforeRead(); return value } // specified name
        set(v) { beforeWrite($foo, v); it = v } //default name
    

    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 a.plus(b) ) while blocking ability to call everything infixly(-> which will make devs stick into standard code-style). Best of both worlds.

    • Andrey Breslav says:

      September 18, 2015

      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:

        September 18, 2015

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

        • Andrey Breslav says:

          September 18, 2015

          IDEA does highlight it, and field will be highlighted as well. Different things having different names is good, trust me 🙂

        • Dale King says:

          September 19, 2015

          +1 for just using it instead of field for consistency

  11. Eddie Ringle says:

    September 18, 2015

    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?

    • Andrey Breslav says:

      September 18, 2015

      These modifiers don’t really add to verbosity. DSLs are good and powerful, but their definitions are only a tiny fraction of the code.

      • Eddie Ringle says:

        September 18, 2015

        No, actually. Adding unnecessary modifiers is the definition of verbosity.

        • Andrey Breslav says:

          September 19, 2015

          What I meant to say is that declarations of operators are very rare compared to their uses, so the verbosity argument is not an important one.

  12. Peter Niederwieser says:

    September 18, 2015

    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:

      September 19, 2015

      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:

    September 18, 2015

    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.

    • Andrey Breslav says:

      September 18, 2015

      Operators are rarely defined. I don’t think modifiers change anything about the overall verbosity of the program. But they add to readability.

  14. Amal Samally says:

    September 18, 2015

    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.

    • Andrey Breslav says:

      September 18, 2015

      Please name the libraries you have in mind

      • Amal Samally says:

        September 18, 2015

        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)

        Joda-Time
        Joda-Money
        Commons Math
        many others

        • Andrey Breslav says:

          September 19, 2015

          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:

            September 19, 2015

            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:

            October 4, 2015

            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:

            October 4, 2015

            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:

    September 19, 2015

    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:

    September 20, 2015

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

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

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

    Constants
    Not fussed. Any barrier to using annotations is welcome. 🙂

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

    September 21, 2015

    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.

    • Andrey Breslav says:

      September 21, 2015

      Making it work so that it’s really protected, not public, at runtime is something we have no good ideas how to implement

      • Eugenio Marletti says:

        September 21, 2015

        Honestly it would be fine even making it public in Java and protected in Kotlin.

        • Andrey Breslav says:

          September 21, 2015

          We don’t believe it’s a good idea.

  18. Ilya says:

    September 21, 2015

    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.

    • Andrey Breslav says:

      September 21, 2015

      I don’t think the parallel is fair: there are very many getters and setters and only a few infix functions.

  19. Olivier Binda says:

    September 23, 2015

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

    • Andrey Breslav says:

      September 23, 2015

      This is a possibility for future versions.

  20. msgile@gmail.com says:

    September 25, 2015

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

      September 25, 2015

      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.

    • Andrey Breslav says:

      September 25, 2015

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

      No.

  21. Salomon BRYS says:

    September 25, 2015

    === 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 {

    interface Interface {
        /*...*/
    }
    

    }

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

    • Salomon BRYS says:

      September 25, 2015

      The final code did not print well :

      /*package-protected*/ class Wrapper {
      
      interface Interface {
          /*...*/
      }
      
      }
      
    • Andrey Breslav says:

      September 27, 2015

      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.

      • Anton Rutkevich says:

        September 28, 2015

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

        if (BuildConfig.DEBUG) Log.d(TAG, "Some message")

        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:

        September 28, 2015

        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 ? 😉

        • Andrey Breslav says:

          September 28, 2015

          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:

            September 28, 2015

            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 ?

            • Andrey Breslav says:

              September 28, 2015

              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:

            October 2, 2015

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

            • Andrey Breslav says:

              October 6, 2015

              Thanks. We are looking into the issue of constant inlining