SAM Style Curly-Brace Quirk


#1

So I have a Java functional interface defined like so:

public interface AlchemyAssertion<A>
{
    void check(@Optional A argument) throws FailedAssertionException;
}

If I create the Lamda like so, it works:

val assertion: AlchemyAssertion<Account> = AlchemyAssertion  {
                
}

But if I move the curly brace to the next line, it doesn’t compile:

val assertion: AlchemyAssertion<Account> = AlchemyAssertion  
{
                
}

This is bizarre. It’s almost like the compiler is forcing me to use the “same-line” style. In contrast, in Java this would work no problem.

Thoughts?


#2

This is because Kotlin doesn’t require semicolons for ending statements, so it has to “guess” where statements are ending. Your last example is interpreted like

val assertion: AlchemyAssertion<Account> = AlchemyAssertion;  
{
                
}

and thus doesn’t work. I’d recommend to always put the “{” on the same line.


#3

I’m with you. Hiding braces on the end of the line is an abomination and have no idea how anyone ever thought this was a good idea. This crops up in other cases as well, such as higher order functions that have a single parameter that is a function and the ability to drop the parentheses.

 value.apply
 {
     doSomething()
 } 

does not compile, but does if you hide the opening brace on the end of the line. I have taken to doing this instead, but then you get a warning about unnecessary parentheses:

 value.apply()
 {
     doSomething()
 } 

So unlike Jonathan, I do not recommend you make your code harder to read to work around the fact that the compiler is broken, I want to see the compiler quit advocating the less readable style.

Can you tell that I this is a hot button issue with me?

Some other links on the topic:

https://youtrack.jetbrains.com/issue/KT-15195


#4

Thanks! I couldn’t agree more.

Basically what I’m saying is that this code-style issue should not a compiler-issue.

There has to be a better way.