Extension function on a generic type - kotlin

I am new in Kotlin and I am trying to understand type alias and functions.
I have the following example:
interface EmptyInterface
typealias GenericCase<T> = T.(EmptyInterface) -> T
val myFunctionVariable: GenericCase<String> = {
_ -> "Hello world!"
}
So far what I understand is that I extend what ever T is defined with a function that accepts as argument an EmptyInterface and returns a T.
So the myFunctionVariable is a function that should be called passing an EmptyInterface
But the following code does not compile
class a: EmptyInterface
println("${myFunctionVariable(a())}")
I need to pass a String as the first parameter:
class a: EmptyInterface
println("${myFunctionVariable("",a())}")
Why is the string needed as the first parameter? T.(EmptyInterface) -> T which in this case is String.(EmptyInterface) -> String has only 1 parameter.
Could someone please explain this?

The T. in the type T.(EmptyInterface) -> T means that this function is an extension function on T. So the regular way to call this function is to acquire a T instance, and call it on that instance, as if it was a member function. In the case of your example, where you chose T to be a String, you have to call the function on a String instance:
"foo".myFunctionVariable(a())
The syntax you've used is an alternative way to call this extension, passing in the receiver as if it was the first parameter of the function (which, at the bytecode level, it actually is):
myFunctionVariable("foo", a())
If you wish to use your function with this syntax, however, it's better to declare it to take two parameters, as this invocation of an extension function can be quite unexpected.
(There's some more info about how you can go back and forth between a function that's an extension on a type and one that takes it as a first parameter in this answer.

In the type T.(EmptyInterface) -> T, the first T is the receiver: an instance that the function is called upon, and which becomes this within the function definition.  (Similar to an extension function.)
Effectively, the receiver becomes a hidden first parameter to the function; as you discovered, if you try to call the function directly, you'll need to give it explicitly.
The language spec for it is here; some other answers may also help.

Related

How to shadow member function with a custom Kotlin extension function? (like Kotlin stdlib does)

I am reading Kotlin in Action 2nd edition.
Chapter 3 says:
If the class has a member function with the same signature as an extension function, the member function always takes precedence
At the same the book demonstrates the CharSequence.split Kotlin's stdlib extension function (which API is less confusing than an API of Java's String#split).
The thing I do not understand is how this split extension functions takes precedence on the following call:
"12.345-6.A".split(".") // <-- Kotlin's extension function gets invoked here even though there is a member function on String class in Java with matching signature
The book also leaves the following comment on this case:
Kotlin hides the confusing method and provides as replacements several overloaded extensions named split that have different arguments
How does Kotlin hide a member function? Can I also shadow some member function which I do not like with my custom extension function? Or it is a trick which is only available to Kotlin language developers?
Actually Kotlin has a separate implementation of CharSequence and String.
These kotlin String/Charsequence does not have its split function. Kotlin team has made all those string implementation functions separately with help of extension functions.Your string will be referring to kotlin String instead of Java String.
If you need to create java String, you need to refer String with package like below.
var str : java.lang.String = java.lang.String("a b c")
str.split("")
Here it will always call Java split function.
Even if you create split function for java.lang.String , it will call only member function as you have read.
member function always takes precedence

How to schedule repeating task in kotlin?

I want to call some api in the background every X minutes and then process the json file I get
I've lokked into this documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.concurrent/java.util.-timer/schedule.html
I'm new to kotlin (I used java before) and I have no idea how to use those functions, any examples of usage would be helpful.
Right now I have something like this:
Timer("NameOfMyTimer", true).schedule(refreshImages(knownPosts, knownFiles, httpClient), TimeUnit.MINUTES.toMillis(5))
And the result is:
None of the following functions can be called with the arguments supplied:
public open fun schedule(p0: TimerTask!, p1: Date!): Unit defined in java.util.Timer
public open fun schedule(p0: TimerTask!, p1: Long): Unit defined in java.util.Timer
What did I wrong? How should I call those functions?
I thought that I'm supposed to pass my function "refreshImages" to the timer with list of arguments it should be called with...?
I think I just don't get the "function is object" philosophy right.
You're trying to call
.schedule(refreshImages(knownPosts, knownFiles, httpClient), TimeUnit.MINUTES.toMillis(5))
So you're passing as first argument the result of refreshImages(knownPosts, knownFiles, httpClient), and as second argument a number of milliseconds.
And as you can see from the compilation error, the Timer class has two schedule() methods, but both expect a TimerTask as argument. And your refreshImages method doesn't return a TimerTask, so that doesn't compile.
If you want to use one of these two Timer methods, you need to create an instance of TimerTask, and pass that as argument.
My guess is that you would like to pass a function that will be executed after some delay. That's not what you're doing right now. What you're doing is that you execute refreshImages() immediately, and pass its returned value to schedule().
Passing a function is not possible with the native Timer schedule method: it doesn't expect a function, but a TimerTask. But as the Kotlin documentation you linked to shows, it's possible by calling one of the extension functions of the Kotlin standard library.
The signature of the schedule extension function is
inline fun Timer.schedule(
delay: Long,
crossinline action: TimerTask.() -> Unit
): TimerTask
So, as you can see, its first argument is a delay, and its second argument is a function with TimerTaskas receiver. So you can call this extension function using a delay as first argument, and a lambda as second argment:
timer.schedule(TimeUnit.MINUTES.toMillis(5)) {
refreshImages(knownPosts, knownFiles, httpClient)
}

Could someone, please, explain me the implementation of the following "Kotlin Literal high order function"?

I am a newbie in Kotlin, I just started to learn it,
I get the following code example about literal/high order function:
fun myHigherOrderFun(functionArg: (Int)->String) = functionArg(5)
println ( myHigherOrderFun { "The Number is $it" })
prints "The Number is 5"
Which I have difficulty to understand: the function myHigherOrderFun get a lambda function as parameter but i can't understand, where is the (Int) input parameter? I see is passed in functionArg(5)... but i can't realize how is possible that?
Thanks in advance.
To start from the beginning, in Kotlin functions are first-class types, just like numbers and Strings and stuff.  So a function can take another function as a parameter, and/or return a function as its result.  A function which does this is called a ‘higher-order function’.
And that's what you have in your example!  The line:
fun myHigherOrderFun(functionArg: (Int)->String) = functionArg(5)
defines myHigherOrderFun() as a function which takes one parameter, which is itself a function taking a single Int parameter and returning a String.  (myHigherOrderFun() doesn't specify an explicit return type, so it's inferred to be a String too.)
The next line is probably where things are less clear:
println(myHigherOrderFun{ "The Number is $it" })
The first non-obvious thing is that it's calling myHigherOrderFun() with a parameter.  Because that parameter is a lambda, Kotlin lets you omit the usual (…), and use only the braces.
The other non-obvious thing is the lambda itself: { "The Number is $it" }. This is a literal function taking one parameter (of unspecified type).
Normally, you'd have to specify any parameters explicitly, e.g.: { a: Char, b: Int -> /* … */ }.  But if there's exactly one parameter, and you aren't specifying its type, then you can skip that and just refer to the parameter as it.  That's what's happening here.
(If the lambda didn't reference it, then it would be a function taking no parameters at all.)
And because the lambda is being passed to something expecting a function taking an Int parameter, Kotlin knows that it must be an Int, which is why we can get away without specifying that.
So, Kotlin passes that lambda to the myHigherOrderFun(), which executes the lambda, passing 5 as it.  That interpolates it into a string, which it returns as the argument to println().
Many lambdas take a single parameter, so it gets used quite a lot in Kotlin; it's more concise (and usually more readable) than the alternative.  See the docs for more info.

How do I read / interpret this Kotlin code effectively?

I know how to read/interpret Java code and I can write it. However being new to kotlin I find code like below hard to read. Perhaps I am missing key concepts in the language.
But, how would you go about interpreting this code? Where do you propose one to start reading it in order to understand this piece of code quickly and efficiently? Left to right? Right to left? Break down parameters first? Look at return values?
inline fun <T : Any, R> ifNotNull(input: T?, callback: (T) -> R): R? {
return input?.let(callback)
}
So, like Java this is a generic function. It has two type parameters T which is of type 'Any' ('Any' is like 'Object' in Java) and R. The input parameter is a nullable T, as denoted by the question mark. Nullable types mean that the value can be null. The other function parameter is a function that takes in a T (non nullable type) and returns R. The return type of the function is a nullable R. The body of the function says that if input is not null, call and pass that to the callback and return that value. If input is null, then null is what gets returned.
Let's dissect the function definition piece by piece:
inline: Indicates that the code of the function will be copied directly to the call site, rather than being called like a normal function.
fun: We're defining a function.
<T : Any, R>: The function takes two generic type parameters, T and R. The T type is restricted to the Any type (which is Kotlin's Object-type). That might seem redundant, but what it actually says is that T cannot be a nullable type (Any?).
ifNotNull: The name of the function.
input: T?: The first parameter of type T?. We can put the ? on the T type here because we restricted it to non-nullable types in the type declaration.
callback: (T) -> R: The second parameter is of type (T) -> R, which is a function type. It's the type of a function that takes a T as input and returns an R.
: R?: The function returns a value of type R or null.
return input?.let(callback): The function body. The let function takes a function parameter, calls it with its receiver (input), and then returns the result of the function. The ? after input says that let will be called only if input is not null. If input is null, then the expression will return null.
The function is equivalent to this Java method (except for the inlining and nullable types):
public <T, R> R ifNotNull(final T input, final Function<T, R> callback) {
if (input == null) {
return null;
}
return callback.apply(input);
}
Matt's answer explains everything well in one go; I'll try to look at how you might go about reading such code.
Skipping over the first word for now, the most important thing is the second word: fun.  So the whole thing is defining a function.  That tells you what to expect from the rest.
The braces tell you that it's a block function, not a one-liner, so the basic structure you're expecting is: fun name(params): returnType { code }.  The rest is filling in the blanks!  (This fits the general pattern of Kotlin declarations, where the type comes second, after a colon.  The Java equivalent would of course be more like returnType name(params) { code }.)
As with Java, the stuff in angle brackets is giving generic parameters, so we can skip that for now and go straight to the next most important bit, which is the name of the function being defined: ifNotNull.
Armed with those, we can read the rest.  inline is a simple modifier, telling you that the function will be inlined by the compiler.  (That enables a few things and restricts a few others, but I wouldn't worry about that now.)
The <T : Any, R> gives the generic parameter types that the function uses.  The first is T, which must be Any or a subtype; the second is R, which is unrestricted.
(Any is like Java's Object, but can't be null; the topmost type is the related Any?, which also allows null.  So except for the nullability, that's equivalent to the Java <T extends Object, R>.)
Going on, we have the function parameters in parentheses.  Again, there are two: the first is called input, and it's of type T?, which means it accepts any value of type T, and also accepts null.  The second parameter is called callback, and has a more complicated type, (T) -> R: it's a function which takes a T as its parameter, and returns an R.  (Java doesn't have function types as such, so that probably looks strangest.  Java's nearest equivalent is Function<R, T>.)
After the parentheses comes the return type of this function itself, R?, which means it can return either an R or null.
Finally, in braces is the actual code of the function.  That has one line, which returns the value of an expression.  (Its effect is to check whether the value of input is null: if so, it returns the null directly.  Otherwise, it calls the callback function given in the parameter, passing input as its parameter, and returns its result.)
Although that's a short declaration, it's quite abstract and packs a lot in, so it's no wonder you're finding it hard going!  (The format is similar to a Java method declaration — but Kotlin's quite expressive, so equivalent code tends to be quite a bit shorter than Java.  And the generics make it more complex.)  If you're just starting to learn Kotlin, I'd suggest something a bit easier :-)
(The good news is that, as in Java, you don't often need to read the stdlib code.  Although Kotlin's doc comments are rarely up to the exemplary level of Java's, they're still usually enough.)

Explanation on Function literal with receiver in Kotlin

I was following this link https://kotlin.link/articles/DSL-builder-in-Kotlin.html to understand the builder implementation in Kotlin. I didn't understand the methods inside Builder class. Method name() receives Extension Function as an argument which receives nothing and returns String. And the caller calls name { "ABC" }. If the caller is passing String to name method, how does it translate to an Extension method which returns String ?
I tried following Kotlin documentation for Function literals with receivers but all had samples which returns Unit or refers to DSL Builders. Tried googling it as well to understand but no luck in grasping the concept.
The call to name { "ABC" } is a combination of two Kotlin conventions.
There is a convention that if the last parameter to a function is a function you can omit the parenthesis. Also since there are no parameters to the lambda, "ABC" is what is returned by it.
So the caller is actually passing a lambda in the form name ({() -> "ABC"}), rather than a String.
Looking at the example in the link, it doesn't look like the receiver is necessary for name(), which is why it could be misleading.