Parsing strings to arbitrary enums in Kotlin Multiplatform - kotlin

I was wondering whether it's possible to implement a function such as the following in Kotlin Multiplatform:
inline fun <reified T : Enum<T>> parseToEnum(value: String): T {
// ?
}
Basically, a function that takes the type of an Enum and a string and then returns the enum value of enum T that matches the passed string (value).
I know that it is possible in Java (and therefore in Kotlin/JVM) but I fear that there might not be a way to do this in common multiplatform code, because there's very little reflection data retained at runtime.
If there's a way to do this (or something similar in functionality), please let me know.
Using Kotlin 1.5.20 (or generally the newest version, I can update if necessary)

Found the answer myself, and it's fairly simple: There's a multiplatform stdlib function with exactly this signature:
enumValueOf().

Related

Is the jvm method name of function with inline classes stable?

I declared an inline class
#JvmInline
value class Creator<T>(val type: KClass<T>);
, and declared an interface
interface Itf {
fun <T> creator(type: KClass<T>): Creator<T>;
}
I want to implement this interface by generating the bytecode by asm(https://asm.ow2.io/ 1).
I found java method decompiled from bytecode is
public KClass<T> creator-9k1ZQyY();
The java method name is “creator-9k1ZQyY”. the suffix “-9k1ZQyY” is added by kotlin compiler and I know why kotlin compiler did it.
This suffix is very important for bytecode generator.
My question:
If the interface and inline class are stable, can kotlin compiler guarantee that suffix is stable too? Does that suffix have nothing to do with the version of kotlin-compiler?
The docs seem to suggest the mangling is stable:
functions using inline classes are mangled by adding some stable hashcode to the function name
As noted in the same doc, the mangling scheme has changed once with the version 1.4.30 of the Kotlin compiler, but I would consider it quite stable nonetheless. They even provided a flag to use the old scheme to generate binary compatible code, so I'm assuming it's not only unlikely to change again, but even if it does, it will surely be done with some way to keep compatibility.

Why do we need an explicit function interface modifier in Kotlin?

consider a SAM defined in Java
public interface Transform {
public String apply(String str);
}
This interface supports lambda to type conversion in Kotlin automatically
fun run(transform: Transform) {
println(transform.apply("world"))
}
run { x -> "Hello $x!!" } // runs fine without any issues
But now consider a Kotlin interface
interface Transform2 {
fun apply(str: String): String
}
Now the only way to invoke the run function would be by creating an anonymous instance of Transform2
run(object : Transform2 {
override fun transform(str: String): String = "hello $str!!"
})
but if we make the Transform2 interface a functional interface then the below is possible
run { str -> "hello $str!!" }
Why the Kotlin compiler cannot automatically type cast lambdas to matching interfaces (just as it does with Java interfaces) without needing to explicitly mark the said interfaces as a functional interface.
I've found some kind of a rationale in a comment in KT-7770:
... treating all the applicable interfaces as SAM might be too
unexpected/implicit: one having a SAM-applicable interface may not
assume that it will be used for SAM-conversions. Thus, adding another
method to the interface becomes more painful since it might require
changing syntax on the call sites (e.g. transforming callable
reference to object literal).
Because of it, current vision is adding some kind of modifier for
interfaces that when being applied:
Adds a check that the interface is a valid SAM
Allows SAM-conversions on call sites for it
Something like this:
fun interface MyRunnable {
fun run()
}
Basically, he is saying that if the SAM conversion were done implicitly by default, and I add some new methods to the interface, the SAM conversions would no longer be performed, and every place that used the conversion needs to be changed. The word "fun" is there to tell the compiler to check that the interface indeed has only one abstract method, and also to tell the call site that this is indeed a SAM interface, and they can expect the author to not suddenly add new abstract methods to the interface, suddenly breaking their code.
The thread goes on to discuss why can't the same argument can't be applied to Java, and the reason essentially boils down to "Java is not Kotlin".
This is speculation, but I strongly suspect one reason is to avoid encouraging the use of functional interfaces over Kotlin's more natural approach.
Functional interfaces are Java's solution to the problem of adding lambdas to the Java language in a way that involved the least change and risk, and the greatest compatibility with what had been best practice in the nearly 20 years that Java had existed without them: the use of anonymous classes implementing named interfaces. It needs umpteen different named interfaces such as Supplier, BiFunction, DoublePredicate… each with their own method and parameter names, each incompatible with all the others — and with all the other interfaces people have developed over the years. (For example, Java has a whole host of interfaces that are effectively one-parameter functions — Function, UnaryOperator, Consumer, Predicate, ActionListener, AWTEventListener… — but are all unrelated and incompatible.) And all this is to make up for the fact that Java doesn't have first-class functions.
Kotlin has first-class functions, which are a much more general, more elegant, and more powerful approach. (For example, you can write a lambda (or function, or function literal) taking a single parameter, and use it anywhere that you need a function taking a single parameter, without worrying about its exact interface. You don't have to choose between similar-looking interfaces, or write your own if there isn't one. And there are none of the hidden gotchas that occur when Java can't infer the correct interface type.) All the standard library uses function types, as does most other Kotlin code people write. And because they're so widely-used, they're widely supported: as part of the Kotlin ecosystem, everyone benefits.
So Kotlin supports functional interfaces mainly for compatibility with Java. Compared to first-class functions, they're basically a hack. A very ingenious and elegant hack, and arguably a necessary one given how important backward compatibility is to the Java platform — but a hack nonetheless. And so I suspect that JetBrains want to encourage people to use function types in preference to them where possible.
In Kotlin, you have to explicitly request features which improve Java compatibility but can lead to worse Kotlin code (such as #JvmStatic for static methods, or casting to java.lang.Object in order to call wait()/notify()). So it fits into the same pattern that you also have to explicitly request a functional interface (by using fun interface).
(See also my previous answer on the subject.)

what is the benefit of extension fun in kotlin?Is it good to leak a fun to other classes?

Is it a good idea to cut my code anywhere around the project in other classes using extension functions?
I mean what is the point?For what exactly a class fun can leak to other classes?
Friends, I'm new to Kotlin and I appreciate if anyone can provide a real example of using extension fun in kotlin.
class Car{
//any code you imagine
}
class Garage{
//any code
fun Car.boost(){
//boost implementation
}
}
As stated in Kotlin Coding Conventions, extension functions are a good practice:
Use extension functions liberally. Every time you have a function that
works primarily on an object, consider making it an extension function
accepting that object as a receiver.
There are a few reasons for that:
Extension functions keep your class small and easy to reason about
Extension functions force you to have good API, since they cannot access any private members of your class
Extension functions have zero cost on performance, since they're simply rewritten by Kotlin compiler into static methods, with method receiver (the class you're extending) as its first argument

How to inline function map on Flux or Mono object in Kotlin and Project Reactor

I'm trying to develop a demo app using Kotlin and Project Reactor and I want to inline some functions like map on objects like Flux or Mono.
I did like this:
private inline fun Flux<Account>.map(noinline transformer: (Account) -> AccountDTO): Flux<AccountDTO> {
return this.map(transformer)
}
but it's not ok because I'm receiving the following warning from IDEA:
Expected performance impact of inlining 'private open inline fun Flux<Account>.map(noinline transformer: (Account) -> AccountDTO): Flux<AccountDTO> defined in com.freesoft.reactiveaccountservice.api.controller.AccountController' is insignificant. Inlining works best for functions with parameters of functional types.
Does anyone have any idea how I can implement this inline functions or if it matters to implement it?
Tx!
So far as you are just calling the non-inlined map defined in Java, there won't be a benefit. You could in principle look at the Java definition, and translate it to Kotlin, and make that your inlined map's defintion, but (without checking) I'd expect it just to be something like return new MapFlux(...) which probably won't benefit either because the lambda needs to be stored in a field.
So you'd need to reimplement a considerable portion of the library in Kotlin.
Usually, you want to inline lambda functions which are passed into higher-order functions because it reduces the runtime overhead. No anonymous classes and function reference objects will be created during runtime when you inline the lambdas. In your case, inlining doesn't boost performance because it's a regular function. You can read full explanation with examples here

What is the #InlineOnly annotation?

I often see the #InlineOnly annotation when browsing Kotlin's stdlib. As far as I recall the annotation only happens to be on inline functions. What is the purpose of this annotation? Isn't it obvious that inline functions are always inlined? It's documentation isn't really helpful
Specifies that this function should not be called directly without inlining
Is it possible for inline functions to be called not inline?
To quote an answer found here:
InlineOnly means that the Java method corresponding to this Kotlin
function is marked private so that Java code can not access it (which
is the only way to call an inline function without actually inlining
it).
This annotation is internal only because
This annotation was added in the last moment before release, so we hadn't time to validate the design and decided to keep it internal for a while. There are good chances we make it public later.