@UseExperimental(ExperimentalContracts::class)
inline fun runLambda(block: () -> Unit) {
contract {
callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
}
}
fun getNothing(): Nothing {
runLambda { throw UnsupportedOperationException("Functions cant return Nothing!") }
}
fun main() {
val nothing: Nothing = getNothing()
print("Hello ")
print(nothing as String)
}
a) UnsupportedOperationException
b) NullPointerException
c) Hello TypeCastException
d) Hello NullPointerException
e) Will not compile
Correct answer is b, We trick the compiler using the AT_LEAST_ONCE contract (it means that lambda must be called at least once, but we don’t do this). Due to this getNothing() function returns null with no expection. Than compiler looks at the main function and thinks: "Hmm... getNothing() returns Nothing, but its impossible without throwing an exception. In this case I will remove all instructions after getNothing() invocation, because they are redundand, and write "throw null' instead of "return"
@UseExperimental(ExperimentalContracts::class)
inline fun runLambda(block: () -> Unit) {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
}
fun hello(): String {
var hello: String
runLambda { hello = "Hello " }
return hello
}
fun world(): String {
var world: String
runLambda { world = "world!" }
return world
}
fun main() {
val result = hello().plus(world())
println(result)
}
a) Hello world!
b) Will not compile
c) NullPointerException
d) nullnull
e) Not of the above
Correct answer is d. We trick compiler again, but now we used contracts to return uninitialized (null) String variable from NotNull function. But why we didnt get NullPointerException by invoking plus() function on null string? Because plus() compiles into StringBuilder like this:
StringBuilder builder = new StringBuilder();
builder.append(hello());
builder.append(world());
String result = builder.toString();
a) UnsupportedOperationException b) NullPointerException c) Hello TypeCastException d) Hello NullPointerException e) Will not compile
Correct answer is b, We trick the compiler using the AT_LEAST_ONCE contract (it means that lambda must be called at least once, but we don’t do this). Due to this getNothing() function returns null with no expection. Than compiler looks at the main function and thinks: "Hmm... getNothing() returns Nothing, but its impossible without throwing an exception. In this case I will remove all instructions after getNothing() invocation, because they are redundand, and write "throw null' instead of "return"
a) Hello world! b) Will not compile c) NullPointerException d) nullnull e) Not of the above
Correct answer is d. We trick compiler again, but now we used contracts to return uninitialized (null) String variable from NotNull function. But why we didnt get NullPointerException by invoking plus() function on null string? Because plus() compiles into StringBuilder like this:
Thats why we got "nullnull"