Questiion about the principle of Unit Kotlin - kotlin

I am new to Kotlin and I have question as I dont fully understand the principle of Unit:
onChecked:(Boolean) -> Unit
Does it pass the certain data as parameter to other function ( as a Unit)?

(Boolean) -> Unit is a function type. Before the arrow are the parameters, in this case a Boolean and after the arrow is the return type. Unit simply means that it doesn't return anything.
See also this documentation

Unit is method signature which actually return nothing like to java void.
for example:
Kotlin
fun onChecked(isCheck: Boolean): Unit {
//TODO
}
Java
public void onChecked(boolean isCheck) {
//TODO
}
Both are similar

Related

Are Kotlin scope function blocks effectively inline?

I'm writing a Kotlin inline class to make Decimal4J more convenient without instantiating any objects. I'm worried that scope functions might create lambda objects, thereby making the whole thing pointless.
Consider the function compareTo in the following example.
/* imports and whatnot */
#JvmInline
value class Quantity(val basis: Long) {
companion object {
val scale: Int = 12
val metrics: ScaleMetrics = Scales.getScaleMetrics(scale)
val arithmetic: DecimalArithmetic = metrics.defaultArithmetic
}
operator fun compareTo(alt: Number): Int {
with(arithmetic) {
val normal = when (alt) {
is Double -> fromDouble(alt)
is Float -> fromFloat(alt)
is Long -> fromLong(alt)
is BigDecimal -> fromBigDecimal(alt)
is BigInteger -> fromBigInteger(alt)
else -> fromLong(alt.toLong())
}
return compare(basis, normal)
}
}
}
Does the with(arithmetic) scope create a lambda in the heap? The docs on kotlinlang.org consistently refer to the scoped code as a lambda expression. Is there any way to use scope functions without creating objects?
All of the built-in scoping functions, including with, are marked inline, which means the implementation gets planted directly in the code that's calling it. Once that happens, the lambda call can be optimized away.
To be more concrete, here's the implementation of with (with the Kotlin contracts stuff removed, since that's not relevant here)
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
Extension methods are, and always have been, syntax sugar resolved at compile time, so this is effectively
public inline fun <T, R> with(receiver: T, block: (T) -> R): R {
return block(receiver) // (with `this` renamed by the compiler)
}
So when we call
operator fun compareTo(alt: Number): Int {
with (arithmetic) {
println("Hi :)")
println(foobar()) // Assuming foobar is a method on arithmetic
}
}
The inline will transform this into
operator fun compareTo(alt: Number): Int {
({
println("Hi :)")
println(it.foobar()) // Assuming foobar is a method on arithmetic
})(arithmetic)
}
And any optimizer worth its salt can see that this is a function that's immediately evaluated, so we should go ahead and do that now. What we end up with is
operator fun compareTo(alt: Number): Int {
println("Hi :)")
println(arithmetic.foobar()) // Assuming foobar is a method on arithmetic
}
which is what you would have written to begin with.
So, tl;dr, the compiler is smart enough to figure it out. You don't have to worry about it. It's one of the perks of working in a high-level language.
By the way, this isn't just abstract. I just compiled the above code on my own machine and then decompiled the JVM bytecode to see what it really did. It was quite a bit noisier (since the JVM, by necessity, has a lot of noise), but there was no lambda object allocated, and the function was just one straight shot that calls println twice.
In case you're interested, Kotlin takes this example function
fun compareTo(alt: Number): Unit {
return with(arithmetic) {
println("Hi :)")
println(foobar())
}
}
to this Java, after being decompiled,
public static final void compareTo-impl(long arg0, #NotNull Number alt) {
Intrinsics.checkNotNullParameter((Object)alt, (String)"alt");
long l = arithmetic;
boolean bl = false;
boolean bl2 = false;
long $this$compareTo_impl_u24lambda_u2d0 = l;
boolean bl3 = false;
String string = "Hi :)";
boolean bl4 = false;
System.out.println((Object)string);
int n = so_quant.foobar-impl($this$compareTo_impl_u24lambda_u2d0);
bl4 = false;
System.out.println(n);
}
Quite a bit noisier, but the idea is exactly the same. And all of those pointless local variables will be taken care of by a good JIT engine.
Just some additional info to help clear up the terminology that led to your confusion.
The word “lambda” is defined as a syntax for writing a function. The word does not describe a function itself, so the word lambda has nothing to do with whether a function object is being allocated or not.
In Kotlin, there are multiple different syntaxes you can choose from to define or refer to a function. Lambda is only one of these.
// lambda assigned to variable
val x: (String) -> Unit = {
println(it)
}
// anonymous function assigned to variable
val y: (String) -> Unit = fun(input: String) {
println(input)
}
// reference to existing named function assigned to variable
val z: (String) -> Unit = ::println
// lambda passed to higher order function
“Hello World”.let { println(it) }
// anonymous function passed to higher order function
“Hello World”.let(fun(input: Any) { println(input) })
// reference to existing named function passed to higher order function
“Hello World”.let(::println)
// existing functional reference passed to higher order function
“Hello World”.let(x)
There is actually no such thing as a lambda object that can be passed around. The object is a function that could have been defined using any of the above syntaxes. Once a functional reference exists, the syntax that was used to create it is irrelevant.
With inline higher order functions, as the standard library scope functions are, the compiler optimizes away the creation of the functional object altogether. Of the four higher order calls in my example above, the first three will compile to the same thing. The last is a bit different because the function x already exists so it will be x itself that is invoked in the inlined code. Its contents don’t get hoisted out and called directly in the inlined code.
The advantage of using lambda syntax for higher order inline function calls is that it enables you to use keywords for the outer scope (non-local returns), such as return, continue, or break.

Kotlin: generic cast function parameter

Taking my first steps in Kotlin, I'm struggling to find the correct signature for a function that receives an instance of a known class along with the desired output class and then looks in a map of converter lambdas whether the conversion can be done.
Here's an example for Long:
private fun <T> castLong(value: Long, clazz: Class<out T>): T {
// map lookup removed for simplicity
return when (clazz) {
String::class.java -> { value.toString() }
else -> { throw IllegalArgumentException("Unsupported Cast") }
}
}
Where T is the class of the desired return value - let's say String. One should be able to call castLong(aLongValue, String::class.java) and receive an instance of String.
But the compiler says:
Type mismatch: inferred type is String but T was expected
This seems like it should be possible as it is quite straightforward so far but even playing around with reified and other constructs didn't yield any better results.
It happens because it can't smart cast String to T, you have to manually cast it.
Furthermore, since you said you are taking your first steps in Kotlin, I leave here two other "advices" not strictly related to your question:
you can get the class of T making it reified
the brackets of a case using when aren't necessary if the case is one line
private inline fun <reified T> castLong(value: Long): T {
// map lookup removed for simplicity
return when (T::class.java) {
String::class.java -> value.toString()
else -> throw IllegalArgumentException("Unsupported Cast")
} as T
}

Possible to keep `Unit` as the return type of a Kotlin function when called from Java?

I have a kotlin function inside a sealed class.
fun invoke(callback: Callback): Unit
Java sees the method signature as a function that returns void.
Is it possible to instruct the Kotlin compiler to keep Unit as the return type for Java? (not void)
Use case
My use case is a jvm interop issue from Java where I need to implement (Result) -> Unit.
// inside a java method (currently)
abstractClass.invoke(callback)
return Unit.INSTANCE
// what I'd prefer instead
return abstractClass.invoke(callback) // invoke returns Unit, but it's in Kotlin, so it maps to void in Java. So this doesn't work
For your edge case, you'd still have to deal with Java methods returning void. So just solve it once:
fun <T> fromConsumer(consumer: Consumer<T>): (T) -> Unit = { consumer.consume(it) }
and then instead of implementing (Result) -> Unit directly, implement/create a Consumer<Result> and pass it to this function. It could be written in Java as well, just would be more complicated.
It would certainly be possible to do this in Java:
public kotlin.Unit test() { return null; }
But in Kotlin your best option seems to be to go with a function object:
val invoke: (Callback) -> Unit = {}
// from Java:
return abstractClass.getInvoke(callback)
I may have misunderstood your question.
First, in Kotlin,
fun invoke(callback: Callback): Unit
is equivalent to
fun invoke(callback: Callback)
In Java, if you override a function like that, you do not need to return anything.
Is it possible to instruct the Kotlin compiler to keep Unit as the return type for Java? (not void)
No, because Unit is meaningless. The only valid value of Unit is Unit itself.

Coding convention for empty functions that need to be overridden in Kotlin

Accourding to the very short Coding Conventions there is no answer for the opimal way of writing down empty functions in Kotlin.
Example:
ani.setAnimationListener(object: Animation.AnimationListener {
override fun onAnimationRepeat(animation: Animation?) = Unit
override fun onAnimationStart(animation: Animation?) {}
override fun onAnimationEnd(animation: Animation?) =
activity.runOnUiThread { loadLists() }
})
Here only one of the 3 necessary Methods of AnimationListener (Android) is used.
Which type of empty Method should be used?
Single Expression (fun name() = Unit) or the traditional way used in Java (fun name() {})?
I personally like the = Unit-Way more because that seems to be meant the way of shorting functions down to one line. But {} is shorter yet older and probably more ugly.
And is there any better/shorter way for doing this code?
You've added link to Coding Conventions where seems like actually there is an answer to your question
Unit
If a function returns Unit, the return type should be omitted:
fun foo() { // ": Unit" is omitted here
}
So I believe
fun foo() {}
or
fun foo() {
}
should be the answer

How to check generic type in Kotlin?

I have class:
class Generic<T : SuperType>() { ... }
And this code is't correct, but cast s to type T:
fun typeCheck(s: SuperType) {
when(s) {
is T -> // Do something
}
}
If use: s as T - this cast will show warning (unsafe cast).
How check that s is T type?
If you need to check if something is of generic type T you need to to have an instance of Class<T> to check against. This is a common technique in Java however in Kotlin we can make use of an inlined factory method that gets us the class object.
class Generic<T : Any>(val klass: Class<T>) {
companion object {
inline operator fun <reified T : Any>invoke() = Generic(T::class.java)
}
fun checkType(t: Any) {
when {
klass.isAssignableFrom(t.javaClass) -> println("Correct type")
else -> println("Wrong type")
}
}
}
fun main(vararg args: String) {
Generic<String>().checkType("foo")
Generic<String>().checkType(1)
}
Generic types are not reified on the JVM at runtime, so there's no way to do this in Kotlin. The warning is correct because the compiler can't possibly generate any instruction that will fail when the cast is done, so the cast is unchecked, meaning that the program may or may not break at some point later instead.
A related feature which might be of use is reified type parameters in inline functions. Classes can't have reified type parameters though, so if you elaborate a bit more on your use case, I can try helping you achieve what you seem to need.
I know that I'm kinda late to this thread, but I just want to recap on the answer provided by Alexander Udalov.
It is, indeed, impossible to determine the type of a generic parameter in Kotlin unless you're using inline functions and declaring the generic type as reified.
Not sure if I'll be able to answer this question entirely and accurately, but I feel like my contribution might still be valuable for someone who is attempting to do just that. So let's say you have a few data classes, and you want to check which type you're dealing with.
You could use a function like that:
inline fun <reified T> checkType() = when (T::class) {
TypeA::class -> println("TypeA")
else -> println("Type not recognized")
}
however, functions that call it must also be inline, so you might have to write something like
inline fun <reified T> someOtherFunction(data: T) {
checkType<T>
}
however, if you cannot allow for an inline function (let's say in an interface!), you can kinda 'cheat' the system by saying, for example
class AmazingTypes {
inline fun <reified T> checkType(genericParameter: T) = when (T::class) {
TypeA::class -> println("TypeA")
else -> println("Type not recognized")
}
}
fun myAwesomeMethod(someParameter: Any) {
val amazingClass = AmazingClass()
amazingClass.checkType(someParameter)
}
This is also example.
inline fun <reified T: ApiResponse> parseJson(body: String): T {
// handle OkResponse only
val klass = T::class.java
if (klass.isAssignableFrom(OkResponse::class.java)) {
return T::class.java.newInstance()
}
// handle others
return gson.from(body, T::class.java)
}