Follow-up: New Class Object Syntax

In the previous post I explained the rethought design of what used to be called “class objects”: they are now more uniform with normal nested objects, have names (name may be omitted, but a default one will be used by the compiler), and we can write extensions to them.

One of the goals of that post was to gather feedback on the term we proposed, namely “default object”, and many of you rightfully stated in the comments that the term has a disadvantage: it is easily misread for “a default instance of the class”. Now we are looking for a better term and need some more feedback…

Update: thanks to everyone, with your help, we chose companion.

We are talking about a modifier in front of the word object:

Our candidates are:

  • default object
  • attached object
  • companion object
  • manifest object

We’d be very grateful if you shared your thoughts about these candidates in the comments.

Thanks!

P.S. There was a proposal of simply using a naming convention instead of a modifier. This comment explains why we decided in favour of a modifier. Also note that this convention would be used a lot more often than others, and others are subject to reconsideration under the upcoming language design review.

About Andrey Breslav

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

53 Responses to Follow-up: New Class Object Syntax

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

    How would one refer to such an object with no name specified explicitly?
    Is it KotlinClass.object or something ?

  2. Anton Belokrylov says:

    I don’t like any of the candidates.
    I propose this object.
    Or simply leave class object?

  3. Eugen says:

    I like companion object best although attached object isn’t bad either.

  4. Danijoo says:

    I really like the changes to class object. But If its up to me, let the name “class object”. Companion object would be the only suitable alternative if you ask me.

  5. Piotr Puchalski says:

    In my opinion: if we already have such problem with proper or confusing naming… it has to be a cause of it… And I think it is that the “class object”(static methods etc.) shouldn’t be declared in/mixed with the same block as methods or objects ” defined for instance”(hope U know what I mean!). And as You propose “attached” keyword, it brings me to the conclusion that those “static methods” should be attached to the class, not defined in its main body or – at least – not mixed with the rest of declarations. It would be handy in my opinion. So this is my proposition:

    class KotlinClass {
    fun normalMethod(...)
    }.object {
    fun callMeOnTheClassName() { ... }
    }

    Or something similar. And extending “class object” would look like this:
    KotlinClass.object.newMethod(…)

    I’m really curios of Your answers:)

    • Danijoo says:

      In my opinion class ClassName{ //… }.object{ //…} looks really bad.

      I like the way scala is solving that with an extra block:

      class ClassName {
      // methods
      }

      object ObjectName {
      // objects with ObjectName == ClassName are companion objects
      }

  6. Mohammad Shamsi says:

    I think, “default object” is the most suitable one.

  7. Jean-Sebastien says:

    agree with Anton Belokrylov

  8. Artem Zinnatullin says:

    default object — NOT okay, it’s like a default value of an null class reference
    attached object — better variant, looks like candidate #1
    companion object — also okay, candidate #2
    manifest object — not okay, manifests are usually works as configuration or description of something, in current case — manifest of a class is not same to attached/companion object by meaning</li

    I’d prefer “companion object”, because it’s understandable that such object is not instance of current class and it’s just a companion of a class.

    “attached object” is okay, but because usually we can attach multiple things to something: like email attachments, etc — somebody might think that he can attach multiple objects to a class using this syntax.

  9. Jayson says:

    either ‘static’ or ‘root’ makes sense to me, although they are all static objects.

    ‘default’ does not, I was confused in 0.1-SNAPSHOT when I hit that because it sounded like something altogether different. I like the name matching the class, but then as you said before in the comment that the compiler doesn’t know when you have a typo or a new name. So a modifier makes it clearer what is being tried.

    So if I had to pick for now, “root” or “dot” because it is a “.” when it comes down to it.

  10. Michael Z. says:

    If I were to choose freely, I’d choose ‘delegate object’ even though the term might be overloaded. At least to me it makes the most sense.

    From the given options I prefer ‘companion’, that however might be out of habit.

    • Cypressious says:

      IMHO “static” is the correct choice. Because that’s what it resembles the most: Static methods and constants.

  11. Jake Russo says:

    What about meta object or internal object or shared object or innate object?

      • “meta object” conveys the wrong meaning of being a meta-description of this class
      • “internal” already means a different thing: visibility internal to the module, and does not convey much of
      • “shared” is too vague, and I wouldn’t say that we are talking about a shared object here
      • “innate” is interesting
  12. Mohammad Salehe says:

    I would choose “attached object”. “default object” and “manifest object” are not suitable IMO.

  13. Olivier Binda says:

    This migt be a very stupid idea (in itself and considering what you want to achieve).

    Would it be possible and make sense to use an empty name ? say have

    class A {
    object {// the old class object}
    object another {// another object}
    }

    val c = A // The old class object
    val d = A.another // the other object

    After all, one of the point of having a class/companion/default object is to just be able to call it by using the class name, right ? (yet it might be a poor choice and make things more difficult for you)

    I think whatever name you choose should be short (class was short) and not be ambiguous (sugar ? 😀 ).

    • We need class objects to be named, at least to write extensions to them

      • Anton Belokrylov says:

        I support Olivier Binda’s idea (aside mine ideas :-). You were going to give unnamed objects name “Keyword”, so it will be A.Object.

        I’m against any new keywords (i don’t want to backtick every “default”, “companion”, “manifest”, or whatever in existing code), and even if they are more clear than “class object” or “default object”, they are still not flawless enough and are just small improvements to readability and moving confusion from one aspect to another.

        • Ed Pavlov says:

          I agree with Anton. Why do you need any additional keywords for default “class object”? Here is my choice :)


          class A {
          object {// the old class object}
          object another {// another object}
          }

          var def = A.object
          var oth = A.another

  14. Rusi Filipov says:

    How about ‘static object’ or just ‘static’ without anything else? At least it would suggest the purpose/semantics of the concept in a traditional way. It should not suggest the implementation mechanism behind it (as ‘attached object’ suggests).

  15. Alex B says:

    I think companion is the most clear probably followed by attached. Default is fine too but I think it would always be a gotcha for new developers since the term default is already used to mean so many things in computing. Manifest is pretty confusing.

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

    Let me point out one little readability confusion: if we want default object andMYClass.default to be read naturally, then from the english grammar point of view default must be an adjective and a noun by its semantic. Here are all variants, suggested so far:

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

      To sum up, this measurement lefts us with: ‘default’, ‘companion’, ‘manifest’, ‘root’ and ‘internal’

    • Jake Russo says:

      I disagree that this should be a noun. Here’s from the previous post arguing for default:

      Now, one of these objects may be declared with the default modifier, which means that its members can be accessed directly through class name[.]
      […]
      Accessing members of Obj1 requires qualification: KotlinClass.Obj1.foo(), for members of Obj2 the object name is optional: KotlinClass.foo().

      This makes it seem like it’s really more of an adjective. A special type of object that can be within a class.

      Also, ‘companion’ is really not very illustrative of what is actually going on here. All objects declared within the class are “companions” of that class so-to-speak. The keyword needed should portray that is a special type of object who’s members can be accessed directly off of the parent class.

      I do really like my suggestion of ‘innate’ as this english word feels close to ‘default’ while also not evoking any sense of “default instance of class”.

      Two other ideas came to me while writing this reply: “main” or “inner”

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

        Well, of course it is an adjective, and all this words already are.
        The challenge here is to find a term which is both noun and adjective, since we have two different situations for it.

  17. Mykhailo says:

    +1 for “companion object”.

  18. Eric Grobler says:

    Terms like default, attached, manifest, static etc are all in use in various languages and thus the meaning is language dependent and often conflicting.
    The only way to avoid people assuming the wrong meaning is to use a complete new/unique term like “door object” or even something silly like “raft object”.
    Then you have the luxury to define and refer to “door, raft or whatever” without people having neuron noise from other language implementations.

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

      As far as I see, ‘companion object’ used in Scala with exactly this meaning.

  19. Piotr Puchalski says:

    If there should be one word for this(not separate block/part for those methods) I’m also for “companion object” – somehow makes sense.

  20. Dmitry Romanov says:

    default object – very misleading. Looks very like it is something about initialization or something.

    attached object – agree on opinion, that if one object is attached, it looks like another one could be attached too

    companion object – looks good. I don’t know why the object is “companion” though. But at least the companion word doesn’t have drawbacks that other have.

    manifest object – for me the manifest is very .NET related and thus misleading.

    meta, shared, this, static, python – nonono, please? Too vague, too many meanings in many languages.

    root object – “root” feels like there should be a tree growing from it.

    innate – Short, sounds good. Could it be, it is not so bad that it is an adjective?

    Going through synonyms of “main” gave me:

    prime. So declaration: prime object {… – looks easy to understand. ClassName.prime looks understandable too.

  21. Andreas Sinz says:

    I’d prefer “companion object”.

    +1 for the separation of the class and the default object.

  22. kocka says:

    default object the others aren’t any good

  23. TesX says:

    Why don’t call it ‘object’?
    Foo.object seems good enough…

    So it would be
    class Foo {
    object {}
    }

    The name thus, is optional…

    bar object {}

    Foo.bar

  24. I think companion is probably the best candidate (although it is a bit too long a word, for my taste; oh, well, we grew accustomed to override after all), because it is the naming Scala already adopts.

    I don’t really like the innate object, but it suggests to me intrinsic (which sounds nice, but that has quite a different meaning in other programming languages)

    Also, let me throw in the bunch: “helper”, “side”, and “builtin”

  25. Artyom Gapchenko says:

    Offtopic: is there any info about the release date? I mean, I searched through Internet trying to find out the current state of project and found nothing. I wish to know if it’s stable enough to start rewriting some of our Android code in it.

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

    I just thought that
    SomeClass.object
    is the most suitable of all, so may be leave the syntax as it is:

    • Daniel Rothmaler says:

      I still would prefer a solution that doesn’t involve a keyword at all (because of the potential name clash, is decried in a comment, in the last post and also because it mixed up a keyword based approach [“default”] with a name base convention [“Default” as default name]). So the post from Даниил could be the key to one…

      We could simply use a nameless object, that could still be accessed and extended.

      Of cause the compiler would probably still use a generated name (like “$$Default$$”) and some kind of marker (like an attribute) internally. But the user doesn’t have to care about it.

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

        A good thing about using a keyword is syntax highlighting – you can set your IDE to emphasize the ‘whatever object’ declaration, so it is not lost among others:

        • Daniel Rothmaler says:

          Well the existence of a keyword is not my major concern.
          It is the mixture of an annotation/keyword and an implicit name (that I still have to know, to access the object).

          This leads to an asymmetric and non intuitive usage (declaration by annotation+keyword, but access by magic name).
          That is why I liked your suggestion, to use the “object” keyword, at the access side, because it takes the magic name out of the equation.

          But this would still leave a little discrepancy, between the declaration (special annotation + general keyword) and the usage site (only the general keyword).

          And because the annotation is not a real keyword, we can not use it at the access site (as there could be another object with the same name).

          This (and the fact that it seams to be a real problem, to find the “right” attribute name), leads me to the conclusion that it would be the easiest an cleanest way, to drop the annotation completely. What is left than, is just “object” at both sites; simple, symmetric and without naming issues.

  27. vekaz says:

    comrade object, obviously.

    If not that, then companion.

  28. Oleg Makarov says:

    Companion is great, but it’s a bit long.
    I like “innate”.

  29. Daniel Rothmaler says:

    OK, so here are my 2 cents regarding your name suggestions…

    default object
    I think I like this one most, as it describes the intention of the object best: “This one is the default object, if no other one is specified.”

    attached object
    This one is also OK, but if i would be a reader, that does not (yet) know kotlin, I would ask myself: “What is the object attached to, an why should I care?”

    companion object
    I like this one, because it is a well known term (to Scala developers). But as a complete newbee I would ask myself the same question as above.
    Also the term has another major drawback… As far as I understand the word companion, it describes two (or more) people/thngs, working together side by side and this is the perfect description, for the way Scala defines companion objects:

    But in kotlin, the companion object would be defined inside the companion class, and this feels really weird to me…

    manifest object
    This one is a no-go in my opinion! “manifest” only describes a small part of what the object would be good for. E.g. if you have a default object, that defines only helper methods and is completely stateless, “manifest” would be a total mismatch.

    • your comment made me think: how about companion object, but non-nested? as in:

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

      There are advantages in clarity of having a nested ‘class object’ declaration.
      1) According to the plan one accesses the object through the class, not the other way around:

      2) If I am not mistaken ‘class object’ can access private and protected members, so it is logical to put it in the same visual scope.

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

    Not sure if anybody should care, but in Apple Swift ‘class’ keyword is used for the same purpose:

    Swift has class methods and properties, but it is not the point. Personally I like the Kotlin-Scala approach with objects more, because it corresponds to the real situation with an object, stored in memory with the class information.

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

    Not sure if anybody should care, but in Apple Swift ‘class’ keyword is used for the same purpose:

    Swift has class methods and properties, but it is not the point. Personally I like the Kotlin-Scala approach with objects more, because it corresponds to the real situation with an object, stored in memory with the class information.

Comments are closed.