Inverted "repeat" function in Kotlin - kotlin

There is a Kotlin Standard Library repeat() function that allows for executing a given function specified number of times and retrieving the index of a current repetition. For example:
repeat(3) {
println(it)
}
Is there a function that will do the same in reverse order? In a way, the indices descend?

No, there's no version of the stdlib repeat() function that counts down.
That's probably because it's so easy to use other structures such as forEach().  (And if you care enough about the passed value to want a particular ordering, then that would probably be a good idea as it'd make it explicit.)
But if you really don't want to use that directly, it's dead easy to write your own:
inline fun repeatReverse(times: Int, action: (Int) -> Unit)
= (times downTo 1).forEach(action)

Related

Using inline function kotlin

I know there was documented in main kotlin page, but there is no clear explanation about when to use it, why this function need a receiver as a function. What would be the correct way to create a correct definition of inline function.
This is inline function
inline fun String?.toDateString(rawDateFormat: String = MMMM_DD_YYYY, outputDate: String = MM_DD_YYYY, block: (date: String) -> String): String {
return try {
var sdf = SimpleDateFormat(rawDateFormat, Locale.US)
val date = sdf.parse(this.orEmpty())
sdf = SimpleDateFormat(outputDate, Locale.US)
block(sdf.format(date ?: Date()).orEmpty())
} catch (ex: Exception) {
block("")
}
}
The same way we also can do
inline fun String?.toDateString(rawDateFormat: String = MMMM_DD_YYYY, outputDate: String = MM_DD_YYYY): String {
return try {
var sdf = SimpleDateFormat(rawDateFormat, Locale.US)
val date = sdf.parse(this.orEmpty())
sdf = SimpleDateFormat(outputDate, Locale.US)
sdf.format(date ?: Date()).orEmpty()
} catch (ex: Exception) {
""
}
}
If anyone could have a detail explanation about this?
Edit:
I understand that the inline function will insert the code whenever it called by the compiler. But this come to my attention, when I want to use inline function without functional parameter receiver type the warning show as this in which should have a better explain. I also want to understand why this is such recommendation.
There are few things here.
First, you ask about using a function with a receiver.  In both cases here, the receiver is the String? part of String?.toDateString().  It means that you can call the function as if it were a method of String, e.g. "2021-01-15 12:00:00".toDateString(…).
The original String? is accessible as this within the function; you can see it in the sdf.parse(this.orEmpty()) call.  (It's not always as obvious as this; you could simply call sdf.parse(orEmpty()), where the this. is implied.)
Then you ask about inline functions.  All you have to do is to mark the function as inline, and the compiler will automatically insert its code wherever it's called, instead of defining a function in the usual way.  But you don't need to worry about how it's implemented; there are just a few visible effects in the code.  In particular, if a function is inline and accepts a function parameter, then its lambda can do a few things (such as calling return) that it couldn't otherwise do.
Which leads us to what I think is your real question: about the block function parameter.  Your first example has this parameter, with the type (date: String) -> String — i.e. a function taking a single String parameter and returning another String.  (The technical term for this is that toDateString() is a higher-order function.)
The toDateString() function calls this block function before returning, applying it to the date string it has formatted before returning it to the caller.
As to why it does this, it's hard to tell.  That's why we put documentation comments before functions: to explain anything that's not obvious from the code!  Ideally, there would be a comment explaining why you're required to supply a block lamdba (or function reference), when it's not vital to what the function does.
There are times when blocks passed this way are very useful.  For example, the joinToString() function accepts an optional transform parameter, which it applies to each item before joining it to the list.  If it didn't, the effect would be a lot more awkward to obtain.  (You'd probably have to apply a map() to the collection before calling joinToString(), which would be less efficient.)
But this isn't one of those times.  As your second example shows, toDateString() would work perfectly well without the block parameter — and then if you needed to pass the result through another function, you could just call it on toDateString()'s result.
Perhaps if you included a link to the ‘main kotlin page’ where you saw this, it might give some more context?
The edited question also asks about the IDE warning.  This is shown when it thinks inlining a function won't give a significant improvement.
When no lambdas are involved, the only potential benefit from inlining a function is performance, and that's a trade-off.  It might avoid the overhead of a function call wherever it's called — but the Java runtime will often inline small functions anyway, all on its own.  And having the compiler do the inlining comes at the cost of duplicating the function's code everywhere it's called; the increased code size is less likely to fit into memory caches, and less likely to be optimised by the Java runtime — so that can end up reducing the performance overall.  Because this isn't always obvious, the IDE gives a warning.
It's different when lambdas are involved, though.  In that case, inlining affects functionality: for example, it allows non-local returns and reified type parameters.  So in that case there are good reasons for using inline regardless of any performance implications, and the IDE doesn't give the warning.
(In fact, if a function calls a lambda it's passed, inlining can have a more significant performance benefit: not only does the function itself get inlined, but the lambda itself usually does as well, removing two levels of function call — and the lambda is often called repeatedly, so there can be a real saving.)

Kotlin expression fun vs normal fun - differences

Let's assume that I have two functions which do the same stuff.
First one:
fun doSomething() = someObject.getSomeData()
Second one:
fun doSomething(): SomeData {
return someObject.getSomeData()
}
Are there any technical differences between expression functions and standard function in Kotlin excluding the way how they look?
Is compiled output the same?
Are there any advantages using one instead another?
As #Sơn Phan says, they both compile to exactly the same bytecode.
So the differences are simply about conciseness.  The expression form omits the braces and return; it also lets you omit the return type (using type inference as needed).  As the question illustrates, the expression form can be shorter — and when all else is equal, shorter tends to be easier to read and understand.
So whether the expression form is appropriate is usually a matter of style rather than correctness.  For example, this function could be on one line:
fun String.toPositiveIntegers() = split(",").mapNotNull{ it.toIntOrNull() }.filter{ it >= 0 }
But it's a bit long, and probably better to split it.  You could keep the expression form:
fun String.toPositiveIntegers()
= split(",")
.mapNotNull{ it.toIntOrNull() }
.filter{ it >= 0 }
Or use a traditional function form:
fun String.toPositiveIntegers(): List<Int> {
return split(",")
.mapNotNull{ it.toIntOrNull() }
.filter{ it >= 0 }
}
(I tend to prefer the former, but there are arguments both ways.)
Similarly, I rather like using it when the body is a simple lambda, e.g.:
fun createMyObject() = MyObject.apply {
someConfig(someField)
someOtherConfig()
}
…but I expect some folk wouldn't.
One gotcha when using the expression form is the type inference.  Generally speaking, in Kotlin it's good to let the compiler figure out the type when it can; but for function return values, that's not always such a good idea.  For example:
fun myFun(): String = someProperty.someFunction()
will give a compilation error if the someFunction() is ever changed to return something other than a String — even a nullable String?.  However:
fun myFun() = someProperty.someFunction()
…would NOT give a compilation error; it would silently change the function's return type.  That can mask bugs, or make them harder to find.  (It's not a very common problem, but I've hit it myself.)  So you might consider specifying the return type, even though you don't need to, whenever there's a risk of it changing.
One particular case of this is when calling a Java function which doesn't have an annotation specifying its nullability.  Kotlin will treat the result as a ‘platform type’ (which means it can't tell whether it's nullable); returning such a platform type is rarely a good idea, and IntelliJ has a warning suggesting that you specify the return type explicitly.
1. Compiled output
Yes the compiled output will be completely the same
2. Advantage
You usually use expression function when the body of a function is only one line of expression to make it a oneliner function. Its advantage mainly about making the code more concise. Imagine instead of all the brackets and return, you only need a = to make things done.

Purpose of repeat function

Using kotlin I can repeat an action in at least two ways:
val times = 5
// First option
for (i in 0 until times) {
print("Action $i")
}
// Second option
repeat(times) {
print("Action $it")
}
I'd like to know the purpose of repeat.
Should the traditional for loop be replaced with repeat function if possible?
Or are there special cases for this function?
Are there any advantages in repeat function?
EDIT
I've made some research about this question. As long as kotlin is open source project, I could download the sources and check git history.
I found that
1) repeat function is a replace for times function extension.
public inline fun Int.times(body : () -> Unit)
2) KT-7074. times function has become deprecated. But why?
It's just a matter of convenience (shortens the code). There are even more ways for example using an IntRange and forEach
(0..4).forEach {
println(it)
}
0 1 2 3 4
They all serve the same purpose, so the choice is yours.
You don't need to worry about performance either, since repeat and forEach are inline functions, which means the lambda code is copied over to the call site at compile time.
Next lines are all just my opinion:
there are no special cases when you should or shouldn't use repeat
function.
it has more concise syntax.
In places where you don't need to manipulate the loop counter or need to repeat only some simple action I would use that function.
It's all up to you to decide when and how to use it.
From Standard.kt:
/**
* Executes the given function [action] specified number of [times].
*
* A zero-based index of current iteration is passed as a parameter to [action].
*
* #sample samples.misc.ControlFlow.repeat
*/
#kotlin.internal.InlineOnly
public inline fun repeat(times: Int, action: (Int) -> Unit) {
contract { callsInPlace(action) }
for (index in 0 until times) {
action(index)
}
}
As you can see repeat(times) is actually for (index in 0 until times).
There is also a zero-based loop counter and it is: it.
Should the traditional for loop be replaced with repeat function if
possible?
I can't find any reason for that
Or are there special cases for this function?
None I can think of.
Are there any advantages in repeat function?
None I can think of, or maybe(?) just 1:
for educational purposes, I suppose it's easier to teach
that repeat(n) { } performs n iterations of the block of statements inside the curly brackets.

How to make and use an arraylist of functions

How can i make an arraylist of functions, and call each function easily? I have already tried making an ArrayList<Function<Unit>>, but when i tried to do this:
functionList.forEach { it }
and this:
for(i in 0 until functionList.size) functionList[i]
When i tried doing this: it() and this: functionList[i](), but it wouldn't even compile in intellij. How can i do this in kotlin? Also, does the "Unit" in ArrayList<Function<Unit>> mean return value or parameters?
Just like this:
val funs:List<() -> Unit> = listOf({}, { println("fun")})
funs.forEach { it() }
The compiler can successfully infer the type of funs here which is List<() -> Unit>. Note that () -> Unit is a function type in Kotlin which represents a function that does not take any argument and returns Unit.
I think there are two problems with the use of the Function interface here.
The first problem is that it doesn't mean what you might think. As I understand it, it's a very general interface, implemented by all functions, however many parameters they take (or none). So it doesn't have any invoke() method. That's what the compiler is complaining about.
Function has several sub-interfaces, one for each 'arity' (i.e. one for each number of parameters): Function0 for functions that take no parameters, Function1 for functions taking one parameter, and so on. These have the appropriate invoke() methods. So you could probably fix this by replacing Function by Function0.
But that leads me on to the second problem, which is that the Function interfaces aren't supposed to be used this way. I think they're mainly for Java compatibility and/or for internal use by the compiler.
It's usually much better to use the Kotlin syntax for function types: (P1, P2...) -> R. This is much easier to read, and avoids these sorts of problems.
So the real answer is probably to replace Function<Unit> by () -> Unit.
Also, in case it's not clear, Kotlin doesn't have a void type. Instead, it has a type called Unit, which has exactly one value. This might seem strange, but makes better sense in the type system, as it lets the compiler distinguish functions that return without an explicit value, from those which don't return. (The latter might always throw an exception or exit the process. They can be defined to return Nothing -- a type with no values at all.)

Why use Arrow's Options instead of Kotlin nullable

I was having a look at the Arrow library found here. Why would ever want to use an Option type instead of Kotlin's built in nullables?
I have been using the Option data type provided by Arrow for over a year, and there at the beginning, we did the exact same question to ourselves. The answer follows.
Option vs Nullable
If you compare just the option data type with nullables in Kotlin, they are almost even. Same semantics (there is some value or not), almost same syntax (with Option you use map, with nullables you use safe call operator).
But when using Options, you enable the possibility to take benefits from the arrow ecosystem!
Arrow ecosystem (functional ecosystem)
When using Options, you are using the Monad Pattern. When using the monad pattern with libraries like arrow, scala cats, scalaz, you can take benefits from several functional concepts. Just 3 examples of benefits (there is a lot more than that):
1. Access to other Monads
Option is not the only one! For instance, Either is a lot useful to express and avoid to throw Exceptions. Try, Validated and IO are examples of other common monads that help us to do (in a better way) things we do on typical projects.
2. Conversion between monads + abstractions
You can easily convert one monad to another. You have a Try but want to return (and express) an Either? Just convert to it. You have an Either but doesn't care about the error? Just convert to Option.
val foo = Try { 2 / 0 }
val bar = foo.toEither()
val baz = bar.toOption()
This abstraction also helps you to create functions that doesn't care about the container (monad) itself, just about the content. For example, you can create an extension method Sum(anyContainerWithBigDecimalInside, anotherContainerWithBigDecimal) that works with ANY MONAD (to be more precise: "to any instance of applicative") this way:
fun <F> Applicative<F>.sum(vararg kinds: Kind<F, BigDecimal>): Kind<F, BigDecimal> {
return kinds.reduce { kindA, kindB ->
map(kindA, kindB) { (a, b) -> a.add(b) }
}
}
A little complex to understand, but very helpful and easy to use.
3. Monad comprehensions
Going from nullables to monads is not just about changing safe call operators to map calls. Take a look at the "binding" feature that arrow provides as the implementation of the pattern "Monad Comprehensions":
fun calculateRocketBoost(rocketStatus: RocketStatus): Option<Double> {
return binding {
val (gravity) = rocketStatus.gravity
val (currentSpeed) = rocketStatus.currentSpeed
val (fuel) = rocketStatus.fuel
val (science) = calculateRocketScienceStuff(rocketStatus)
val fuelConsumptionRate = Math.pow(gravity, fuel)
val universeStuff = Math.log(fuelConsumptionRate * science)
universeStuff * currentSpeed
}
}
All the functions used and also the properties from rocketStatus parameter in the above example are Options. Inside the binding block, the flatMap call is abstracted for us. The code is a lot easier to read (and write) and you don't need to check if the values are present, if some of them is not, the computation will stop and the result will be an Option with None!
Now try to imagine this code with null verifications instead. Not just safe call operators but also probably if null then return code paths. A lot harder isn't it?
Also, the above example uses Option but the true power about monad comprehensions as an abstraction is when you use it with monads like IO in which you can abstract asynchronous code execution in the exact same "clean, sequential and imperative" way as above :O
Conclusion
I strongly recommend you to start using monads like Option, Either, etc as soon as you see the concept fits the semantics you need, even if you are not sure if you will take the other big benefits from the functional ecosystem or if you don't know them very well yet. Soon you'll be using it without noticing the learning-curve. In my company, we use it in almost all Kotlin projects, even in the object-oriented ones (which are the majority).
Disclaimer: If you really want to have a detailed talk about why Arrow is useful, then please head over to https://soundcloud.com/user-38099918/arrow-functional-library and listen to one of the people who work on it. (5:35min)
The people who create and use that library simple want to use Kotlin differently than the people who created it and use "the Option datatype similar to how Scala, Haskell and other FP languages handle optional values".
This is just another way of defining return types of values that you do not know the output of.
Let me show you three versions:
nullability in Kotlin
val someString: String? = if (condition) "String" else null
object with another value
val someString: String = if (condition) "String" else ""
the Arrow version
val someString: Option<String> = if (condition) Some("String") else None
A major part of Kotlin logic can be to never use nullable types like String?, but you will need to use it when interopting with Java. When doing that you need to use safe calls like string?.split("a") or the not-null assertion string!!.split("a").
I think it is perfectly valid to use safe calls when using Java libraries, but the Arrow guys seem to think different and want to use their logic all the time.
The benefit of using the Arrow logic is "empowering users to define pure FP apps and libraries built atop higher order abstractions. Use the below list to learn more about Λrrow's main features".
One thing other answers haven't mentioned: you can have Option<Option<SomeType>> where you can't have SomeType??. Or Option<SomeType?>, for that matter. This is quite useful for compositionality. E.g. consider Kotlin's Map.get:
abstract operator fun get(key: K): V?
Returns the value corresponding to the given key, or null if such a key is not present in the map.
But what if V is a nullable type? Then when get returns null it can be because the map stored a null value for the given key or because there was no value; you can't tell! If it returned Option<V>, there wouldn't be a problem.