Annotations naming convention


#1

Standard annotation classes in Kotlin seem to be all named starting from lower case. While it looks good for keyword-like annotations ("volatile", "syhnchronized", etc), it's arguable for multi-word annotations like "platformStatic". And given that Kotlin will co-exist with the java eco-system where all annotations are named starting from upper case, this solution does not seem to be reasonable. My suggestion is to leave lower case naming only for single word annotations. Opinions?


#2

Aesthetically, I'd rather see platformStatic become just static. I don't need the code yelling "this isn't javascript" at me, in a JVM project, I know that already.

Still the wider issue remains, yes. Kotlin doesn’t have much of a style guide at the moment.


#3

A style guide would be very helpful! It was much too late that Scala got one ...

But maybe there is another way to avoid syntax proliferation: IntelliJ inspections for Kotlin. With decent defaults this would give orientation to developers. This approach would be a bit like Go with “gofmt”. All Go code looks the same thanks to this tool.


#4

All I have on the topic for now is more questions:

  • Is it OK  to write capitalized annotations without suqare brackets ("FooBar fun foo()" looks weird to me, while "[FooBar] fun foo()" is OK)?
  • Using one-word Kotlin annotations from Java is still a little weird, are we OK with it?
  • Using one-word Kotlin annotation classes as types in Kotlin is also weird:

fun printDeprecationMessage(d: deprecated) {   prinln(d.value) }

Should we maybe play some tricks along the lines of what C# has (they remove the word "Attribute" from the call site)? Maybe decapitalize annotation names? Maybe even use "-" instead of CamelCase? Example:

annotation class PlatformStatic

platform-static fun foo() {…}

fun takesAnnotation(a: PlatformStatic) {
  // …
}


Side-effect: Java annotations will also be trasformed:

import com.google.inject.BindingAnnotation

binding-annotation annotation class MyGuiceExample

Disclaimer: This is all pure fiction, I have no opinion on this topic at the moment.


#5

What I dislike about the idea of playing with names is that it will add complications into IDE support (and into a lot of different places). They are all indeed solvable but will require serious efforts and add lot of additional complexity. So I would not go this way unless we have serious arguments for doing so.


#6

> Is it OK  to write capitalized annotations without suqare brackets ("FooBar fun foo()" looks weird to me, while "[FooBar] fun foo()" is OK)?

I think it’s rather a matter of code style.


#7

I'm not sure it needs anything fancy. The one word annotations are mostly things that would be keywords in other languages anyway, so you would not import them into Java and use them there.

I experimented with renaming java annotations to lower case at import time for a while in my own codebases, but couldn’t be bothered keeping it up. It doesn’t look so bad to me if the first letter is capitalised in normal Java style.


#8

I had a quick exchange about platformStatic with Ilya a few days ago on Twitter

https://twitter.com/evacchi/status/564064537020997632

I, for one, think the decapitalization with dashes would look nice, if odd. Best part it would make it work with Java annotations (which is even better IMO). Then, even native kotlin annotations could be defined as capitalized. Worst part would be that you would define them one way, and use them in another which is not the best for consistency.

As for the platformStatic annotation in particular, I do think it looks terribly odd (and verbose). Today the idea of wrapping it inside an object sprouted into my mind, which might be a way tok make it look better.

I have shared more thoughts on the same subject in another thread https://devnet.jetbrains.com/message/5524901#5524901


#9

We briefly discussed it here and there is not much difference here between object and package. In fact, you can do it like this already:

import kotlin.platform

object X {
  platform.platformStatic
  fun fn() {}
}

Now, if we should or shouldn’t rename “platformStatic” to just “static” is still to be decided. But if yes, we can have it like this:
import kotlin.platform

object X {
  platform.static
  fun fn() {}
}


Or even

import kotlin.platform.static

object X {
  static fun fn() {}
}


      

#10

We briefly discussed it here and there is not much difference here between object and package. In fact, you can do it like this already:

``

import kotlin.platform

object X {
  platform.platformStatic
  fun fn() {}
}

That is correct. But if you use the nested class trick, then, because of how Kotlin imports (currently) work, you can force your users to always use the qualified version platform.static

Consider:

package com.example object platform {   annotation class static } ...

import com.example.platform

object X {
  platform.static // works as intended
  fun fn() {}
}

import com.example.platform.static // error: cannot import from platform


Unless, of course, you decide at some point to introduce imports “à la Scala”, where everything can be imported from any scope