Curry functions - How to call 3 (or multiple) functions? - kotlin

I am trying to curry a function in kotlin such that i can call it like this
myAdditionFunction(1)(2)(3)
this call would return 6 because 1+ 2 + 3 = 6
i just need it to perform an addition over all the numbers. actually i really want it to do a builder
pattern in the future but still trying to see how curry functions work. Here is what i have so far:
fun myAdditionFunction(x: Int) { { y: Int -> x + y }
this works for two parameters. so myAdditionFunction(1)(2) will print 3.
i want it to work for 3 or multiple : here is what i have tried for 3 paramters:
fun myAdditionFunction(x: Int) {
var sum = 0
return { y: Int ->
sum = x + y
sum }
}
How do i carry the sum forward and how to make it take a third inner function ?? it wont compile.
but it will not compile

I'm not exactly sure what's going on in either of your examples, and neither compiled on my machine (Kotlin 1.3.10).
However, you can do lambda expressions, as they allow arbitrarily deep nesting. So for 2 variables, you could have
val myAdditionFunction = {x: Int -> {y: Int -> x + y}}
And for three variables, you can go a level deeper:
val myAdditionFunction = {x: Int -> {y: Int -> {z: Int -> x + y + z}}}
Just for reference, a lambda expression (aka anonymous function) is in the form:
val functionName = {argument1: type -> return_value}

I think something can't be an Int and a function simultaneously. Maybe use an extention function on Int class?
operator fun Int.invoke(x: Int) = this + x
val a = 1(2)(3)

With Lionel Briand's great idea to create an operator extension function invoke on Int, you just need another function curry as entry point
operator fun Int.invoke(x: Int) = this + x
fun curry(x: Int) = x
and you can do exactlty what you wanted:
curry(1)(2)(3)(4) // will return 10

Related

Whats the difference between these two function callings in kotlin?

The first way
fun add(a: Int, b: Int): Int {
return a + b
}
fun main() {
print(add(a = 2, b = 3))
}
The second way
fun add(a: Int, b: Int): Int {
return a + b
}
fun main() {
print(add(2, 3))
}
The end result of the two functions is the same but i was wondering if there is any internal difference between the two ways of function calling.
In the first case you're explicitly stating to which field of the add() method constructor you're assigning the value.
In this way the order in which you put the values doesn't matter, as long as each value is explicitly assigned to a parameter. For example, in this case you can also write:
print(add(b=3, a=2))
still works.
As instead, in the second way you are forced to follow the order in which the fields are written in the method implementation (the first value is implicitly assigned to a, the second to b and so on)
For this example there is no difference, because you are adding the arguments in order
add(a=2,b=3): here a is going to take 2 and b is going to take 3
add(2,3): and here a is the first argument so it's going to take the first passed argument which is 2 and the same for b
But here is the difference (a + b == b + a so I add minus function to see the difference because a - b != b - a) :
fun minus(a : Int,b:Int):Int{
return a-b;
}
fun main()
{
print(minus(a=2,b=3)) // a = 2, b = 3 -> a - b = 2 - 3 = -1
print(minus(b=2,a=3)) // a = 3, b = 2 -> a - b = 3 - 2 = 1
print(minus(2,3)) // a = 2, b = 3 -> a - b = 2 - 3 = -1
}
So if you add minus(a=2,b=3) you are saying that a is going to take 2 and b is going to take 3,
and here minus(2,3) you are saying that the first parameter (a) is going to take 2 and the second parameter (b) is going to take 3
But let's say for some reason you change the order of the parameters of your function:
fun add(b : Int,a:Int):Int{
return a+b;
}
Now if you add minus(a=2,b=3) you are saying that a is going to take 2 and b is going to take 3 so nothing changes for this case and your code will work fine.
But here minus(2,3) you are saying that the first parameter (b) is going to take 2 and the second parameter (a) is going to take 3 so you will not get the same result before changing the order of the parameters of the function. So adding parameter name when you call a function is a best practice to say that you want this value for that exact argument.
Also there's other example, let's say that you have a function that has default values:
fun test(a : Int = 10, b:Int = 5):Int {
return a+b;
}
So the you can call it like that test() without passing any argument, but let's say that you want to change only b to 15, if you write test(15), a is going to take 15 not b so here you need to specify that the 15 is for b: test(b = 15)
There is no difference, the only difference is readability by using named arguments in the first example.
The fun thing about using named arguments when calling your method is that you can also change the order or even leave out some of the values if they are default i.e:
fun add(a :Int,b: Int):Int {
return a+b;
}
Can also be written with a default value like so:
fun add(a :Int = 2,b: Int = 3, c: Int = 4):Int {
return a+b+c;
}
Now you can skip some of the values like so:
fun main() {
print(add(a = 2, c = 3))
}
// So we did 2 + 3 + 3
// prints 8
// Notice we skipped b

How to do multiple variable assignments in one line in Kotlin like C,C++?

I had to swap 2 numbers in one line expression using no other variable except x and y.
So I wrote the following .c program to swapp two numbers with the given conditions and it works like charm.
int main() {
int x =5, y =2;
x = y-x+(y=x);
printf("X=%d, y=%d", x, y);
return 0;
}
But when i try to do the same in kotlin it gives me an error that
Assignments are not expressions, and only expressions are allowed in
this context,
I can resolve this issue by introducing a third variable just like this. But I'm not allowed to have any other variable except x and y which are already given. So is there any other way I can do this in one line using any kotlin property?
Below is the kotlin program
fun main() {
var x = 5
var y = 10
x = y-x+(y=x)
println("X = $x, Y = $y")
}
While I have two suggestions below, I want to start with a recommendation against either of them, at least in this simple example.
It's usually a lot more clear to optimise code for developers to read in the following ways:
create an extra variable with a descriptive name
prefer val over var to avoid accidental mutations
and try to make the code 'linear', so the operations can be read from top-to-bottom without jumping between functions
avoid code that needs an IDE to see what the type-hints are
And I'll trust that the compiler will make make the code performant.
fun main() {
val x = 5
val y = 10
val newX = y
val newY = x
println("X = $newX, Y = $newY")
}
Local function
You could use a local function to perform the swap, as the function will still be able to access the original values.
fun main() {
var x = 5
var y = 10
fun swap(originalX: Int, originalY: Int) {
y = originalX
x = originalY
}
swap(x, y)
println("X = $x, Y = $y")
}
Scope function
This could be code-golfed into one line
use to to create a Pair<Int, Int>,
and a scope function to use the result.
fun main() {
var x = 5
var y = 10
(x to y).apply { x = second; y = first }
println("X = $x, Y = $y")
}
One line? Yes. More difficult to read? I think so.

Is there any function like ap2, ap3 in arrow-kt?

I saw scala code using cats in this post.
val a = Some(7)
val b = Some(9)
Applicative[Option].ap2(Some(add))(a,b)
And I tried migrating this code to kotlin and arrow like following.
Option.applicative()
.tupled(Some(7), Some(9))
.ap(Some(::add))
// works but dirty
fun add(tuple: Tuple2<Int, Int>): Int = tuple.a + tuple.b
// not work, compilation error
// fun add(a: Int, b: Int): Int = a + b
As you noticed, Tuple2 must be specified in the add function signature.
I searched the official document of arrow, but there is no apN function like ap2, ap3, ap4.
Is there any way to use the second function which not included Tuple2 type?
Once version 0.10 is available Arrow will have a .tupled() method on function types that handles this, so you will be able to write:
Option.applicative()
.tupled(Some(7), Some(9))
.ap(::add.tupled())
fun add(a: Int, b: Int) = a + b
for functions of up to 22 arguments.

Function definition: fun vs val

I'm curious about what is the suggested way to define member functions in Kotlin. Consider these two member functions:
class A {
fun f(x: Int) = 42
val g = fun(x: Int) = 42
}
These appear to accomplish the same thing, but I found subtle differences.
The val based definition, for instance, seems to be more flexible in some scenarios. That is, I could not work out a straight forward way to compose f with other functions, but I could with g. To toy around with these definitions, I used the funKTionale library. I found that this does not compile:
val z = g andThen A::f // f is a member function
But if f were defined as a val pointing to the same function, it would compile just fine. To figure out what was going on I asked IntelliJ to explicitly define the type of ::f and g for me, and it gives me this:
val fref: KFunction1<Int, Int> = ::f
val gref: (Int) -> Int = g
So one is of type KFunction1<Int, Int>, the other is of type (Int) -> Int. It's easy to see that both represent functions of type Int -> Int.
What is the difference between these two types, and in which cases does it matter? I noticed that for top-level functions, I can compose them fine using either definition, but in order to make the aforementioned composition compile, I had to write it like so:
val z = g andThen A::f.partially1(this)
i.e. I had to partially apply it to this first.
Since I don't have to go through this hassle when using vals for functions, is there a reason why I should ever define non-Unit member functions using fun? Is there a difference in performance or semantics that I am missing?
Kotlin is all about Java interoperability and defining a function as a val will produce a completely different result in terms of the interoperability. The following Kotlin class:
class A {
fun f(x: Int) = 42
val g = fun(x: Int) = 42
}
is effectively equivalent to:
public class A {
private final Function1<Integer, Integer> gref = new Function1<Integer, Integer>() {
#Override
public Integer invoke(final Integer integer) {
return 42;
}
};
public int f(final int value) {
return 42;
}
public Function1<Integer, Integer> getG() {
return gref;
}
}
As you can see, the main differences are:
fun f is just a usual method, while val g in fact is a higher-order function that returns another function
val g involves creation of a new class which isn't good if you are targeting Android
val g requires unnecessary boxing and unboxing
val g cannot be easily invoked from java: A().g(42) in Kotlin vs new A().getG().invoke(42) in Java
UPDATE:
Regarding the A::f syntax. The compiler will generate an extra Function2<A, Integer, Integer> class for every A::f occurrence, so the following code results in two extra classes with 7 methods each:
val first = A::f
val second = A::f
Kotlin compiler isn't smart enough at the moment to optimize such kind of things. You can vote for the issue here https://youtrack.jetbrains.com/issue/KT-9831. In case you are interested, here is how each class looks in the bytecode: https://gist.github.com/nsk-mironov/fc13f2075bfa05d8a3c3
Here's some code showing how f and g are different when it comes to usage:
fun main(args: Array<String>) {
val a = A()
exe(a.g) // OK
//exe(a.f) // does not compile
exe { a.f(it) } // OK
}
fun exe(p: (Int) -> Int) {
println(p(0))
}
Where f and g are:
fun f(x: Int) = 42
val g = fun(x: Int) = 42
You can see that g is an object that can be used like a lambda, but f cannot. To use f similarly, you have to wrap it in a lambda.

Kotlin null safety?

Let's have a function foo and a class Bar:
fun foo(key: String): String? {
// returns string or null
}
class Bar(x: String, y: String) {
// ...
}
Now, let's have the code:
val x = foo("x")
val y = foo("y")
if (x.isNotEmpty() && y.isNotEmpty())
return Bar(x, y)
The problem is that this code will not compile. Since it needs the Bar(x!!, y!!).
However when I replace the function with its content, !! are not needed.
val x = foo("x")
val y = foo("y")
if ((x != null && x.length() > 0) && (y != null && y.length() > 0))
return Bar(x, y)
Why it is not possible to resolve the null check from the function .isNotEmpty()?
This is possible in theory, but it would mean that either
1. The declaration of isNotEmpty() must convey to the compiler the fact that x is guaranteed to be non-null if the result is true
2. A change to a body of any function may cause its call sites to fail to compile.
Option 2 is definitely unacceptable. Option 1 requires a rather expressive mechanism in the type system, which we decided not to add at the moment, because it is likely to complicate things for the user.
We are planning to support something like this with inline functions, but it's still under consideration.