More changes: Enum Syntax, Another Deprecation and More

Enum Syntax

Currently the syntax for enums with non-trivial constructors is kind of monstrous:

We would really like to make it nicer, e.g. something like this:

Now, there are some technicalities, namely, enums can have other members:

The problem is that A and B can be parsed as annotations on foo(). So, we had some options to consider here.

We are leaning toward putting a separator there between entries and other members:

The semicolon is only necessary when some members follow it.

Other options include requiring escaping on all annotations on members (and, possibly, modifiers too):

This would be a little inconsistent with normal classes, traits etc.

Or we could prefix enum entries with a (soft-)keyword:

This looks too verbose.

Another question here is how do we annotate enum entries themselves. Requiring escaping looks reasonable here:

Other options include

  • requiring a comma between enum literals (like in Java)
  • requiring a newline between enum literals and allowing unescaped annotations on the same line

We have not decided which way to go on this one yet.

Prohibiting break/continue in when-expressions

We are planning to implement continue in when-expressions as a jump to the next when-entry. It is not implemented yet, but we want your code to stay unchanged when we add it, so for the time being, we prohibit using continue in when without a label that points to a loop:

We also prohibit unlabeled break inside when. While it is not decided whether we want to allow it ever, it seems like a better design to keep break and continue symmetric.

NOTE: A simple interpretation of break inside when is “stop matching and jump outside” (as in switch in Java and C), but our when often returns a value, and that would be unknown if we break out of it.

Rename traits to interfaces

Well, we picked the names long time ago, and now what we call “trait” in Kotlin is not so much of a trait, and is exactly like Java’s interface nowadays, so we want to deprecate the usage of the trait keyword, and introduce interface in M12.

Feedback request: Let the flame begin :)

About Andrey Breslav

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

59 Responses to More changes: Enum Syntax, Another Deprecation and More

  1. Christian Brüggemann (@cbruegg) says:

    For enums, I’d go with the semicolon + comma solution. I feel like Kotlin is Java on steroids, so there’s no need to forcedly differentiate to it.

  2. m1shk4 says:

    is there a typo in the last code block? label is loo, but continue is called on loop

  3. +1 for using “interface” instead of “trait”, naming same things the same way within the same ecosystem.

    PS: Using U+1F44D inside the “Comment” field, lead to my previous messed up post.

  4. Java’s interface can’t have code whereas Kotlin’s trait can

    • Mohammad Shamsi says:

      Well, in Java 8 you can have code in interfaces. default implementation and also static methods.

  5. Mohammad Shamsi says:

    By changing the annotation syntax to java style (@Foo) and dropping the short form for annotations (current implementation), I think, there will be no issue regarding changes in Enum syntax. am I right?

    • Max says:

      I think the same way. Last modifications in Kotlin has been caused by unnecessary (in my opinion) desire to support short form of annotations. This desire makes the language tricky. That’s sad.

      • Jayson says:

        Annotations requiring @ only bothers me for data classes because I like to forget that it is an annotation. Otherwise I don’t see much value in having a short form of annotations. In other areas of the language there is ambiguity because of this… Bring back the @, is fine with me.

        Also, in regards to enums, a comma separator is fine and is one of the biggest mistakes I make with enums in Kotlin every time I create one. For some reason a list of things feels odd without the list separator.

        But, it is nice if we allow optional trailing commas in these type of lists without something following (last item in list). Could be a warning, but makes commenting things in/out in lists easier.

    • Mykhailo says:


  6. Ladislav Thon says:

    How come trait is not a trait? I admit my knowledge is lacking in this area, but as far as I know, Kotlin’s traits are [stateless] traits. As are Java 8 interfaces, mostly.

    • Well, “mostly” is the key here, for the sake of performance and uniformity, we will likely align semantics of our traits with Java interfaces anyways.

      • Oliver Plohmann says:

        So far traits in Kotlin were intended to support abstract variables and methods that both can also be declared as protected. Is this functionality supposed to be retained in M12 or will this be removed?

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

    The last proposal for the enum syntax looks like class initialisation in C++, which is one of the most HATED syntax features of the language, mostly for its dissimilarity to any other initialisation.

    Enums are relatively rarely used, and having ‘mostrouse’ but uniform syntax is preferable.

    • I wouldn’t say that enums are used rarely enough for this to be ignorable.

      Also, I don’t follow your point about C++. Could you clarify?

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

        Sure. The C++ feature is called ‘initializer list’, used for initializing constant values.

        See the discussion here:

        • Do you imply that it is in some way similar to this syntax?

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

            See the similarity in this way:

            C++ has a special way of assigning values with brackets, while elsewhere in the language it is done with ‘=’.

            You propose a special syntax for initialising instances (objects?) with invoking something on a enum object name, while everywhere else this name is never invoked.

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

            Yes, I think both of these syntax solutions look similar to each other. Of course there is nothing bad in it. This is inconsistency that I am worried about.

            I am saying that the abnormality of the corresponding C++ code is so that I had to google the syntax not once, but many times while learning the language.

            Maybe I am stupid, maybe you don’t want the same for Kotlin 😉

            • Well, this is a very distant analogy, I’m afraid. I assume it does not bother you that values are sometimes assigned to function parameters by enclosing expressions in parentheses (e.g. foo(x))

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

            No jokes on this point, foo(x) means passing a value, not assigning it. With this new syntax ERROR("error") is going be the only place in kotlin where something is invoked without a declaration elsewhere.

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

            But this constructor happend to change its name ‘Message’ to ‘ERROR’ somehow!

            • Well, there are other place in Kotlin where something like this happens: e.g. when you use the invoke() convention, you call something whose name differs from the function actually invoked.

              In any case, this discussion is somewhat pointless, because this syntax is exactly what Java has since version 5 and I can’t recall any complaints about it.

    • Jayson says:

      I use ENUMS heavily, many times instead of string constants so that the list of options is confined. And typically with one constructor parameter and the old syntax is horrible (as pointed out), and something short and clean is preferred.

  8. Separate enums with commas. No biggie.
    I wouldn’t use break in any way in a when expression. And even allowing a continue to a label is dangerous, since it breaks out of the expression, which I don’t like. Maybe it can only be used if the expression isn’t being assigned to anything.
    I’m okay with the traits/interface change. Although, can “default” methods in traits be marked as “final”?

  9. B7W says:

    I like trait key word. It is short and it tell me that there can be implementation.

    • Jayson says:

      I like trait as well, but as Andrey says, Java 8 Interfaces become very similar including with default methods. Would be nice if Java renamed to trait, but not likely to happen. So unify @annotation requiring @, commas between enum values (end list with ; if you have things following), and rename trait to interface (I’ll be sad, but it makes sense, trait is so much cooler sounding)

      unfortunately we’ll see checkbox language comparisons now saying “Kotlin doesn’t have traits, we do”

  10. farrukh says:

    upto M11 kotlin language was clean and simple now there are so much changes coming i am afraid you people are making language more complected
    +1 for renaming trait to interface

  11. farrukh says:

    loop@ is ugly

    what about this syntax for label loops
    for (…) @loop{

  12. Philip Lombardi says:

    A comma between Enum entries seems to be the best. I do not think the Java syntax there needs any kind of reinventing.

    I agree with renaming ‘trait’ to ‘interface’ in order to be more consistent with the larger Java ecosystem though I would also reserve the ‘trait’ keyword for later use if Kotlin ever introduces stateful traits like Scala.

  13. Enum syntax

    I like the “entry” keyword. Verbosity is your friend when it adds to legibility; the “entry” keyword typographically differenciates the entries from the rest.

    Please don’t add mandatory commas, Java got it so wrong.

    Prefixing annotations with “@” is OK for me for the same reason.

    Rename traits to interfaces

    +1, the “trait” keyword always looked obscure (Scala-ish?) to me.

  14. Juanjo says:


    First of all, THANK YOU. I truly believe Kotlin is a great language with a great power/easiness trade-off. The only lack is that… well, it is not stable yet!

    My preferences about the post alternatives would be:

    Enums: the comma separated values seems good to me, anyway, is gonna be common to have all of them in the same line. Regarding the semicolon, I though all annotations will be prefixed with ‘@’ from now on (though I’m not sure) if this were the case, will the semicolon still be needed? if that’s an alternative, I would like to keep annotations without ‘@’
    Traits: I’ve seen a lot of opinions about keeping this consistent with Java because Java interfaces now seem like traits… IMHO for me it would be better to keep the language consistent with itself better than with Java. And maybe Java people would like to change ‘interface’ by ‘trait’… but the fact is that they can’t (and at this stage Kotlin can) would this be regreted in the future? It is clear I would prefer ‘trait’ 😀
    Jumps: they maintain their semantics for loops, right? For ‘when’, having a continue seems nice to me, and break doesn’t.


  15. Graham says:

    The idea of annotations working differently depending on the presence or absence of a newline character is not a good one to me. I’d much prefer the comma and semicolon solution. Everyone already understands it, it’s simple and there are no unexpected surprises if you reformat your code.

  16. Elviss says:

    One feature that I use quite often with enums is abstract method overrides for each enum entry. Sample:

    enum class Test {
    T : Test() {
    override fun hello() = "world"


    It makes enums span multiple lines and it could make comma separators and/or semicolon feel out-of-place (and almost all other places in Kotlin where”;” is used are optional).
    One alternative idea that I think would look good is optional {} block (mandatory only if there are other members) that can isolate enum entries from other parts of enum code, like:

    enum class Test {
    entries {


  17. Vladimir Krivosheev says:

    -1 to renaming trait to interface. English is not my native language, but for me “interface” it is just a contract. Kotlin trait is an abstract class, but stateless. For example, I can have one contract (EditorService), but if implementation is complex and big, implementors can split it up to several files (ContentAssistService and so on). “trait” is more natural word.

    • Oliver Plohmann says:

      I would also prefer traits not being renamed to interfaces. What really makes a difference to Java besides true closures are extension methods and traits. Those things are to me the big points. From what I know traits originate from Self. Also Ceylon, Scala, Rust, Squeak Smalltalk and now also Groovy have them (although in Groovy they are just JDK8 interfaces with defender methods). People could think that Kotlin doesn’t have traits because there is no mentioning besides interfaces although the competition all have them.

      A big + for having annotations the same way as in Java. For the time being I use Kotlin when I have to learn new frameworks, tools and things. Knowing it would be just the same way in Java when I do the same thing at work lets me safely play with Kotlin. I believe this would hold true for others that for the time being want something more modern than Java but don’t have a chance to use Kotlin at work for the time being.

  18. Edoardo Vacchi says:

    I gave my 2 cents on annotation syntax previously on the forums

    In short, in my opinion brackets may be optional when the annotation has no arguments, and mandatory in every other case. This would be also a good occasion to change the annotation syntax, dropping parentheses; suppose:

    annotation class foo(bar: String = "baz", qux: String = "quux")

    then, to annotate a fun:

    [foo bar="baz" qux="quux"] fun myfun() = ...

    but allowing:

    foo fun myfun() = ...

    this should remove any ambiguity in enums (and anywhere else).

    As for interface v. trait. I see your point in switching back to interface. On the other hand Java 8’s default methods should be used as a means to evolve APIs (at least, this is what JDK devs say). I feel like “traits” should be thought of a first-class inheritance mechanism, rather than a fallback. But I also see that the overlap may be confusing.

  19. Anton Danshin says:

    Why do you need @ for annotations when you already have brackets: [ … ]? For enums you can require to use square annotations with these brackets.
    Plus, @ is used in return@, and this@

    I would also vote for a semicolon at the end of enum-entries declaration.

  20. Steven Gertiser says:

    I think that the word trait is more apt if traits go beyond the functionality of a standard Java interface in the future. Some examples of that would be traits with state as in Scala for mixed-in inheritance, or (even better!) a trait with a defined default implementation.

    I would hope for feature enhancement in this direction, so trait as a keyword should be reserved in any event.

  21. Scott says:

    I find the commas in Java enums to be annoying. I think they should be separated with lines. I understand the sentiment to go with what’s familiar, but why force writing something when you don’t have to?

  22. Isak says:

    I think the enum constructors are just fine as they are. Monstrous? No. Adding commas or mandatory semicolons is certainly worse. The constructors, as they are just now, are consistent with the rest of kotlin.

Comments are closed.