Function expression body formatting
yole opened this issue ยท 9 comments
If the function has an expression body that doesn't fit in the same line as the declaration, put the =
sign on the first line. Indent the expression body by 4 spaces.
fun f(x: String) =
x.length
If the expression body does not fit on one line, prefer using a block body instead.
If the body of a function is an if
, when
, try
or object
expression, the expression is not additionally indented; the closing brace of the expression is on the same indentation level as where the function closing curly brace would be.
fun f(x: String) = when(x) {
"foo" -> ...
else -> ...
}
However, if the function header is long and can't be fit on the same line as function declaration (because the declaration is too long, the condition is complex, or the object expression needs a complex set of super-types), then the expression is on a new line and the closing brace of the expression is on the same indentation level as the head of the expression:
fun f(x: String, y: String) =
when(x.equals(y, ignoreCase = true)) {
"foo" -> ...
else -> ...
}
I think it's worth to put the =
sign on the first line
- There are already a lot of declaration with breaks after
=
(~ 500) in our project - Such break rule fits better in case of multiline expression:
fun foo(args: Array<String>) =
args.getOrNull(0)?.let { println(it) }
?: Unit // expression starts at the same indentation level
I'm in favor of putting the =
sign on the new line.
I changed my mind. I'm in favor of putting the =
sign on the same line and the expression on a new line.
Well, to be honest, we have approximately 400 functions with =
on the new line
One argument in favor of putting =
on the previous line is the consistency with val
:
val VeryLongString =
"StringValue"
vs
val VeryLongString
= "StringValue"
I think the former looks clearly better.
I think that =
before function expression body is similar to {
in block body.
Your eye usually skip it when you read it. It doesn't really deserve spotlight.
To me,
val veryLongAndMeaningfulName
= "value"
reads like "I already know it is going to be an initializer, because it is something indented after val
".
I find it very hard to read when the start of a conditional expression is on the first line after a long function declaration:
fun f(firstParameter: String, secondParameter: List<String>) = when(x) {
"foo" -> ...
else -> ...
}
A solution for this is to use return when(x)
in a block body
If the body of a function is an if
, when
or object
expression, and it can't be fit on the same line as function declaration (because the declaration is too long, the condition is complex, or the object expression needs a complex set of super-types), then the expression is on a new line and the closing brace of the expression is on the same indentation level as the head of the expression:
fun f(x: String, y: String) =
when(x.equals(y, ignoreCase = true)) {
"foo" -> ...
else -> ...
}
When reading a function declaration with expression body I usually read the method signature and at some point I skip (fast forward) to the =
sign which delimits the method start. This works just the same with a =
sign ending the first line. After skipping to the sign it is clear to me that the actual method body begins on the new line, with the typical method body indentation.
Also, if a method has a block body, the opening curly brace is at the end of the line. The method body starts at the new line with the same method body indentation. Thus having the =
sign at the end of the first line also has the advantage that the begin if a method body its indentation is the same for both styles.
Hence I vote for the =
sign at the end of the line.
I went through my project and replaced usages of
fun foo()
= expression.call()
with
fun foo() =
expression.call()
I find this style to be better, too.
As I see it, there's consensus this style is better, right? In that case we should create an issue for the formatter to automatically place the =
sign.