Applying the style guide

To configure the IntelliJ formatter according to this style guide, please install Kotlin plugin version
1.2.20 or newer, go to Settings | Editor | Code Style | Kotlin, click on "Set from…" link in the upper
right corner, and select "Predefined style / Kotlin style guide" from the menu.

To verify that your code is formatted according to the style guide, go to the inspection settings and enable
the "Kotlin | Style issues | File is not formatted according to project settings" inspection. Additional
inspections that verify other issues described in the style guide (such as naming conventions) are enabled by default.

Source code organization

Directory structure

In mixed-language projects, Kotlin source files should reside in the same source root as the Java source files,
and follow the same directory structure (each file should be stored in the directory corresponding to each package
statement).

In pure Kotlin projects, the recommended directory structure is to follow the package structure with
the common root package omitted (e.g. if all the code in the project is in the "org.example.kotlin" package and its
subpackages, files with the "org.example.kotlin" package should be placed directly under the source root, and
files in "org.example.kotlin.foo.bar" should be in the "foo/bar" subdirectory of the source root).

Source file names

If a Kotlin file contains a single class (potentially with related top-level declarations), its name should be the same
as the name of the class, with the .kt extension appended. If a file contains multiple classes, or only top-level declarations,
choose a name describing what the file contains, and name the file accordingly. Use camel humps with an uppercase first letter
(e.g. ProcessDeclarations.kt).

The name of the file should describe what the code in the file does. Therefore, you should avoid using meaningless
words such as "Util" in file names.

Source file organization

Placing multiple declarations (classes, top-level functions or properties) in the same Kotlin source file is encouraged
as long as these declarations are closely related to each other semantically and the file size remains reasonable
(not exceeding a few hundred lines).

In particular, when defining extension functions for a class which are relevant for all clients of this class,
put them in the same file where the class itself is defined. When defining extension functions that make sense
only for a specific client, put them next to the code of that client. Do not create files just to hold
"all extensions of Foo".

Class layout

Generally, the contents of a class is sorted in the following order:

Property declarations and initializer blocks

Secondary constructors

Method declarations

Companion object

Do not sort the method declarations alphabetically or by visibility, and do not separate regular methods
from extension methods. Instead, put related stuff together, so that someone reading the class from top to bottom would
be able to follow the logic of what's happening. Choose an order (either higher-level stuff first, or vice versa)
and stick to it.

Put nested classes next to the code that uses those classes. If the classes are intended to be used externally and aren't
referenced inside the class, put them in the end, after the companion object.

Interface implementation layout

When implementing an interface, keep the implementing members in the same order as members of the interface (if necessary,
interspersed with additional private methods used for the implementation)

Overload layout

Always put overloads next to each other in a class.

Naming rules

Kotlin follows the Java naming conventions. In particular:

Names of packages are always lower case and do not use underscores (org.example.myproject). Using multi-word
names is generally discouraged, but if you do need to use multiple words, you can either simply concatenate them together
or use camel humps (org.example.myProject).

Names of classes and objects start with an upper case letter and use camel humps:

Names for test methods

In tests (and only in tests), it's acceptable to use method names with spaces enclosed in backticks.
(Note that such method names are currently not supported by the Android runtime.) Underscores in method names are
also allowed in test code.

Names for backing properties

If a class has two properties which are conceptually the same but one is part of a public API and another is an implementation
detail, use an underscore as the prefix for the name of the private property:

Choosing good names

The name of a class is usually a noun or a noun phrase explaining what the class is: List, PersonReader.

The name of a method is usually a verb or a verb phrase saying what the method does: close, readPersons.
The name should also suggest if the method is mutating the object or returning a new one. For instance sort is
sorting a collection in place, while sorted is returning a sorted copy of the collection.

The names should make it clear what the purpose of the entity is, so it's best to avoid using meaningless words
(Manager, Wrapper etc.) in names.

When using an acronym as part of a declaration name, capitalize it if it consists of two letters (IOStream);
capitalize only the first letter if it is longer (XmlFormatter, HttpInputStream).

Formatting

In most cases, Kotlin follows the Java coding conventions.

Use 4 spaces for indentation. Do not use tabs.

For curly braces, put the opening brace in the end of the line where the construct begins, and the closing brace
on a separate line aligned horizontally with the opening construct.

if (elements != null) {
for (element in elements) {
// ...
}
}

(Note: In Kotlin, semicolons are optional, and therefore line breaks are significant. The language design assumes
Java-style braces, and you may encounter surprising behavior if you try to use a different formatting style.)

Class header formatting

Classes with a few primary constructor parameters can be written in a single line:

class Person(id: Int, name: String)

Classes with longer headers should be formatted so that each primary constructor parameter is in a separate line with indentation.
Also, the closing parenthesis should be on a new line. If we use inheritance, then the superclass constructor call or list of implemented interfaces
should be located on the same line as the parenthesis:

To clearly separate the class header and body when the class header is long, either put a blank line
following the class header (as in the example above), or put the opening curly brace on a separate line:

Annotation formatting

Annotations are typically placed on separate lines, before the declaration to which they are attached, and with the same indentation:

@Target(AnnotationTarget.PROPERTY)
annotation class JsonExclude

Annotations without arguments may be placed on the same line:

@JsonExclude @JvmField
var x: String

A single annotation without arguments may be placed on the same line as the corresponding declaration:

@Test fun foo() { ... }

File annotations

File annotations are placed after the file comment (if any), before the package statement, and are separated from package with a blank line (to emphasize the fact that they target the file and not the package).

Formatting control flow statements

If the condition of an if or when statement is multiline, always use curly braces around the body of the statement.
Indent each subsequent line of the condition by 4 spaces relative to statement begin.
Put the closing parentheses of the condition together with the opening curly brace on a separate line:

The first call in the chain usually should have a line break before it, but it's OK to omit it if the code makes more sense that way.

Lambda formatting

In lambda expressions, spaces should be used around the curly braces, as well as around the arrow which separates the parameters
from the body. If a call takes a single lambda, it should be passed outside of parentheses whenever possible.

list.filter { it > 10 }

If assigning a label for a lambda, do not put a space between the label and the opening curly brace:

fun foo() {
ints.forEach lit@{
// ...
}
}

When declaring parameter names in a multiline lambda, put the names on the first line, followed by the arrow and the newline:

Documentation comments

For longer documentation comments, place the opening /** on a separate line and begin each subsequent line
with an asterisk:

/**
* This is a documentation comment
* on multiple lines.
*/

Short comments can be placed on a single line:

/** This is a short documentation comment. */

Generally, avoid using @param and @return tags. Instead, incorporate the description of parameters and return values
directly into the documentation comment, and add links to parameters wherever they are mentioned. Use @param and
@return only when a lengthy description is required which doesn't fit into the flow of the main text.

Avoiding redundant constructs

In general, if a certain syntactic construction in Kotlin is optional and highlighted by the IDE
as redundant, you should omit it in your code. Do not leave unnecessary syntactic elements in code
just "for clarity".

Unit

If a function returns Unit, the return type should be omitted:

fun foo() { // ": Unit" is omitted here
}

Semicolons

Omit semicolons whenever possible.

String templates

Don't use curly braces when inserting a simple variable into a string template. Use curly braces only for longer expressions.

println("$name has ${children.size} children")

Idiomatic use of language features

Immutability

Prefer using immutable data to mutable. Always declare local variables and properties as val rather than var if
they are not modified after initialization.

Always use immutable collection interfaces (Collection, List, Set, Map) to declare collections which are not
mutated. When using factory functions to create collection instances, always use functions that return immutable
collection types when possible:

Lambda parameters

In lambdas which are short and not nested, it's recommended to use the it convention instead of declaring the parameter
explicitly. In nested lambdas with parameters, parameters should be always declared explicitly.

Returns in a lambda

Avoid using multiple labeled returns in a lambda. Consider restructuring the lambda so that it will have a single exit point.
If that's not possible or not clear enough, consider converting the lambda into an anonymous function.

Do not use a labeled return for the last statement in a lambda.

Named arguments

Use the named argument syntax when a method takes multiple parameters of the same primitive type, or for parameters of Boolean type,
unless the meaning of all parameters is absolutely clear from context.

if versus when

Using nullable Boolean values in conditions

If you need to use a nullable Boolean in a conditional statement, use if (value == true) or if (value == false) checks.

Using loops

Prefer using higher-order functions (filter, map etc.) to loops. Exception: forEach (prefer using a regular for loop instead,
unless the receiver of forEach is nullable or forEach is used as part of a longer call chain).

When making a choice between a complex expression using multiple higher-order functions and a loop, understand the cost
of the operations being performed in each case and keep performance considerations in mind.

Functions vs Properties

In some cases functions with no arguments might be interchangeable with read-only properties.
Although the semantics are similar, there are some stylistic conventions on when to prefer one to another.

Prefer a property over a function when the underlying algorithm:

does not throw

is cheap to calculate (or caсhed on the first run)

returns the same result over invocations if the object state hasn't changed

Using extension functions

Use extension functions liberally. Every time you have a function that works primarily on an object, consider making it
an extension function accepting that object as a receiver. To minimize API pollution, restrict the visibility of
extension functions as much as it makes sense. As necessary, use local extension functions, member extension functions,
or top-level extension functions with private visibility.

Using infix functions

Declare a function as infix only when it works on two objects which play a similar role. Good examples: and, to, zip.
Bad example: add.

Don't declare a method as infix if it mutates the receiver object.

Factory functions

If you declare a factory function for a class, avoid giving it the same name as the class itself. Prefer using a distinct name
making it clear why the behavior of the factory function is special. Only if there is really no special semantics,
you can use the same name as the class.

If you have an object with multiple overloaded constructors that don't call different superclass constructors and
can't be reduced to a single constructor with default argument values, prefer to replace the overloaded constructors with
factory functions.

Platform types

A public function/method returning an expression of a platform type must declare its Kotlin type explicitly:

fun apiCall(): String = MyJavaApi.getProperty("name")

Any property (package-level or class-level) initialised with an expression of a platform type must declare its Kotlin type explicitly:

class Person {
val name: String = MyJavaApi.getProperty("name")
}

A local value initialised with an expression of a platform type may or may not have a type declaration:

fun main() {
val name = MyJavaApi.getProperty("name")
println(name)
}

Using scope functions apply/with/run/also/let

Kotlin provides a variety of functions to execute a block of code in the context of a given object: let, run, with, apply, and also.
For the guidance on choosing the right scope function for your case, refer to Scope Functions.

Coding conventions for libraries

When writing libraries, it's recommended to follow an additional set of rules to ensure API stability: