https://kotlinlang.org logo
#getting-started
Title
# getting-started
d

David Kubecka

02/27/2023, 4:27 PM
How to get a handle on the binary operator functions like
==
,
>
, etc.? For "normal" functions I would use
::
but not sure how to do that for these operators. I want to convert user input (as string) to the operator function and then call this function on the provided values.
l

Landry Norris

02/27/2023, 4:29 PM
All operators have a function name, so you can use that.
1::plus
works if you specify which plus. It does require that the operator is defined for the type.
r

Riccardo Lippolis

02/27/2023, 4:29 PM
==
->
equals
>
->
compareTo
l

Landry Norris

02/27/2023, 4:29 PM
See here for list of names
💡 1
r

Riccardo Lippolis

02/27/2023, 4:30 PM
(tip: if you're using IntelliJ, you can use the
go to implementation
feature to look this up via your IDE)
1
d

David Kubecka

02/27/2023, 4:34 PM
I already tried
::equals
but that gives me only a single parameter function.
l

Luke Armitage

02/27/2023, 4:36 PM
::equals
is a single argument function - it compares the receiver to the argument. 😄
r

Riccardo Lippolis

02/27/2023, 4:37 PM
Copy code
val instanceEquals: KFunction1<Any?, Boolean> = "My string"::equals

val stringEquals: KFunction2<String, Any?, Boolean> = String::equals
👍 2
l

Landry Norris

02/27/2023, 4:37 PM
T.equals(Any)
is the general signature for the equals method, where in this case T means a type.
d

David Kubecka

02/27/2023, 4:46 PM
So to obtain a boolean function for comparison I probably can't use simple reflection
::
, right? Instead, I would have to do something like
{ x: T, y: T -> x.compareTo(y) > 0 }
l

Landry Norris

02/27/2023, 4:46 PM
You can use x::compareTo to get the method.
d

David Kubecka

02/27/2023, 4:47 PM
yeah, but that doesn't return boolean
l

Landry Norris

02/27/2023, 4:48 PM
I see. You’d have to define one or use the lambda you provided.
You could define
T.compareToAsBoolean(y: T) -> Boolean
, but with better #naming
d

David Kubecka

02/27/2023, 5:05 PM
Hmm, but thanks to this intended usage of comparison the end result is quite verbose, e.g.
Copy code
val valueCompareTo = it.value.toBigDecimal()::compareTo
            return when (it.operator) {
                FilterOperator.EQUAL -> { money: MoneyDto -> valueCompareTo(money.amount) == 0 }
                FilterOperator.GREATER_THAN -> { money: MoneyDto -> valueCompareTo(money.amount) > 0 }
                FilterOperator.GREATER_THAN_OR_EQUAL -> { money: MoneyDto -> valueCompareTo(money.amount) >= 0 }
                FilterOperator.LESS_THAN -> { money: MoneyDto -> valueCompareTo(money.amount) < 0 }
                FilterOperator.LESS_THAN_OR_EQUAL -> { money: MoneyDto -> valueCompareTo(money.amount) <= 0 }
                else -> error("operator ${it.operator} not supported here")
            }
Ideally, I would like to return only the operator from the when expression and inject that into the money lambda (defined at single place only), but since there's no such thing as a comparison function that returns boolean I have to repeat that code. Or... ?
r

Riccardo Lippolis

02/27/2023, 5:09 PM
a function like
isGreaterThan
needs to be defined somewhere, in that case. You can choose to put it in the
when
expression, in the
MoneyDto
(if you have control over it), or define it as an extension function, for example
2
d

David Kubecka

02/27/2023, 5:18 PM
I see. My original thoughts perhaps were that this function surely must already be defined somewhere because
Copy code
fun <T> isGreaterThan(a: T, b: T) = a.compareTo(b) > 0
seems to be quite generic 🙂
Oh, this apparently can't be defined in a generic way 😞
l

Landry Norris

02/27/2023, 5:22 PM
What do you mean?
Copy code
fun <T: Comparable<T>> isGreaterThan(a: T, b: T) = a.compareTo(b) > 0
You didn’t specify that T has to be comparable.
👍 1
d

David Kubecka

02/27/2023, 5:25 PM
Anyway, isn't it reasonable to expect these functions to be in the stdlib?
l

Landry Norris

02/27/2023, 5:27 PM
I’d say no. The stdlib is included with all projects, so adding something should be an important change. The current Int behavior is consistent with the Java Comparable that exists, and provides more information (can tell you how much bigger or smaller if implemented that way).
The size of the stdlib is currently a major blocker for K/N on embedded systems. The stdlib alone creates a binary too big for most embedded systems.
d

David Kubecka

02/27/2023, 5:30 PM
I don't expect the current operators to be replaced. Just that those generic binary functions are added exactly for cases like mine.
I hear the binary size argument, although I'm not sure how those six small functions compare with the quite rich collections class (which of course I'm happy to use in my BE projects)
l

Landry Norris

02/27/2023, 5:35 PM
You can create a proposal for it to be added, but do keep in mind that you may only need 6 methods, but someone else may have another few methods that make sense for them, and someone else has another few methods they want.
I’d imagine somewhere there’s a third party library that brings in these useful helpers (kind of like arrow with functional methods). This keeps the stdlib small, while allowing methods to be added easily.
d

David Kubecka

02/27/2023, 5:41 PM
Anyway, I'm still struggling even to use these binary functions 😞 My hope was something like this:
Copy code
val filteredValue = it.value.toBigDecimal()
val cmp = filteredValue::isEqualTo
Apparently, that's not how it's supposed to be...
l

Landry Norris

02/27/2023, 5:42 PM
If you want to use
foo::isEqualTo
, you have to make sure the signature is
T.isEqualTo(other: T) -> Boolean
. If it’s like your greater than method above, you defined
isEqualTo(x: T, y: T) -> Boolean
, which is different.
d

David Kubecka

02/27/2023, 5:42 PM
I see now, of course...
l

Landry Norris

02/27/2023, 5:43 PM
Without the receiver, it’s just
::isEqualTo
d

David Kubecka

02/27/2023, 5:44 PM
I originally wanted to use just
::isEqualTo
and assign it to val but that's not possible without specifying the
T
. Will consider the other option (extension functions)
I guess there's no shorthand syntax for partial function application in Kotlin.
l

Landry Norris

02/27/2023, 5:47 PM
I’m sure if you specified a type for the val, it could get it.
d

David Kubecka

02/27/2023, 5:49 PM
Sure ^, I meant if there's a nice (without writing the full lambda) way how to get from two arg
isEqualTo
to single arg
isEqualTo
(with fixed first arg).
7 Views