I don't understand why does the compiler think i a...
# announcements
p
I don't understand why does the compiler think i am trying to pass a second lambda to
run
Copy code
run {
  // some code
}

{ /*my unrelated block here*/ } shouldNotThrow AnyException
j
lint warning: “LonelyLambda. Your lambda is lonely. Bring it closer.”
p
@Shawn
val x = { my code }
is valid
s
🙂 It is not java. A statement that starts with a
{
and ends with a
}
is an expression that results in a lambda. This lambda is not run and just sits there. It is lonely 🙂
p
so
{ my code }
is valid too
m
Because
{ }
is not a block. It's a lambda.
👆 1
You could do
run { ... }
s
like I said, doesn’t do what it does in Java
like sure you can have a bare lambda without assigning it to anything
p
this compiles perfectly fine Shawn:
Copy code
if (true) {
  // nothing
}

{ myMock.method(arg) } shouldNotThrow AnyException
not sure why are we talking about Java here, this is valid Kotlin code
s
1. does
myMock.method()
even run 2. the compiler knows not to treat a bare lambda as an argument to an `if`…
s
It is valid, but it doesn’t do anything. In java, similar syntax will run the code in that block. In Kotlin, it won’t run that code.
s
valid != useful
p
yes it will run the code
because
shouldNotThrow
has
this.invoke()
in it
s
Ah… I didn’t know that was code.
p
it is an infix function
s
You didn’t say it was… it looked like some comment or something 🙂
👆 1
p
my complaint is that the compiler should not treat it as a second lambda when it knows the previous code can't accept another lambda
i think there should be room in the grammar to handle this correctly
s
What is the signature of
shouldNotThrow
?
p
Copy code
infix fun <T : Throwable> (() -> Any?).shouldNotThrow(expectedException: KClass<T>)
s
I think you find an issue. I can imagine that putting the lambda of your
shouldNotThrow
on the same line as the closing bracket of the `run`’s lambda generates a compiler error, but you put it on a new line. This should not give a compiler issue, I think.
p
Exactly! Makes no sense to me.
s
I would file an issue and see what JetBrains has to say 🙂
p
a workaround:
Copy code
run {
 // some code
}

val call = { myMock.method(arg) }
call shouldNotThrow AnyException
d
a workaround would also be putting semicolon at the end run block
👆 2
now I see why kotlin still allows you to have semicolons 😛
🚛 1
p
nice! that is concise!
still annoying though 😄
d
tho I don't see any issue with your workaround, I wouldn't event call it a workaround, I just do it most of time
p
if i have a lot of calls to verify, i prefer one line per each
☝️ 1
l
perhaps you can invert this call?
In #kotlintest we do
shouldThrow { call() }
Or
shouldNotThrow { }