Functions and Generics


#1

Hello,
I have here a little example of generic function, which I expected it should work…

fun<T: Number> f( x: T ): T = x*x
fun main(args: Array<String>) {
    println( f(20) )
    println( f(2.0) )
    println( f(3.0f) )
}

I know Generics are not templates, but I expected since Kotlin can override operators, then it should resolve that simple generic function.
What do you think?


#2

Number does not implement a times() method, so I don’t see why you would be able to multiply two x in the first place


#3

Yeah. I know that it does not implement any operator… Maybe it would be reasonable that it does?


#4

Number is an open-ended (non-sealed) class. You cannot know all the number implementation in advance, and so it is impossible to write a correct open-ended implementation of operators on arbitrary numbers. However, for your particular application you should have some knowledge on what particular number implementations you care about and you can implement your own operation for your needs, for example, writing something like this:

operator fun Number.times(y: Number): Number = when (this) { 
    is Int -> this * y.toInt()
    is Double -> this * y.toDouble()
    is Float -> this * y.toFloat()
    else -> error("unsupported")
}

It will not make your original code work (because, again, it is impossible to require that any two arbitrary numbers can be multiplied in a sensible way), but it is as close as it gets.


#5

Seeing the kotlin library, all the operator overloads of the different number classes eg. Int, Double, Long etc. may have different return types depending which 2 kinds of numbers your working with. IMO a “one for all” solution might not be the best in most cases


#6

I see. This solution I only expected to be afterwards.
My opinion is, it would be nice to avoid something like that. Instead of Generics it should be used BigDecimal than you can choose in which type you wish to operate.

My intention was more a philosophical question…