https://kotlinlang.org logo
Title
l

lifter

08/30/2018, 3:09 PM
Is it possible to write
justAddThem1
such that it takes any numeric type?
justAddThem2
and
justAddThem3
won't compile.
fun justAddThem1(x: Int, y: Int) = x + y

fun justAddThem2(x: Number, y: Number) = x + y

fun <T : Number> justAddThem3(x: T, y: T) = x + y
a

Andreas Sinz

08/30/2018, 3:10 PM
e.g.
fun <T: Number> justAddThem(x: T, y: T, f: (T, T) -> T) = f(x, y)
c

Can Orhan

08/30/2018, 3:11 PM
Thanks @Andreas Sinz. Didn't know that was the term for it 😄
a

Andreas Sinz

08/30/2018, 3:12 PM
@Can Orhan thats how @cedric calls it 😬
c

Can Orhan

08/30/2018, 3:12 PM
Good enough for me 😄
1
c

cedric

08/30/2018, 3:13 PM
Hopefully it's not just me calling it that 🙂
l

lifter

08/30/2018, 3:18 PM
I actually know Haskell, and am familiar with the terms ad-hoc polymorphism and the other side of the coin, parametric polymorphism. Parametric polymorphism is when you're dealing with a type that could be absolutely anything under the sun. So, if I were to attempt to apply the term to Kotlin, I'd imagine something like this:
fun <T> f(x: T) { /* ... */ }
Function
f
is parametrically polymorphic. Ad-hoc polymorphism in Haskell would be when there is a typeclass constraint on the type variable. Haskell typeclasses are similar to OOP interfaces. So, in Kotlin, I'd imagine something like this:
fun <T: Comparable> f(x: T) { /* ... */ }
T
is constrained in the sense that it's no longer anything under the sun, it's anything that is comparable.
c

cedric

08/30/2018, 3:23 PM
@jason I wouldn't call type boundaries ad hoc polymorphism, they are a different concept. Ad hoc polymorphism is more concerned with adjusting types to make them conform to an interface they do not initially conform with.
l

lifter

08/30/2018, 3:25 PM
OK.
Well, I'm only familiar with how the terms apply to Haskell.
In any case, this
fun <T: Number> justAddThem(x: T, y: T, f: (T, T) -> T) = f(x, y)
really doesn't add the numbers, does it? Looks like it just takes two numbers and a function, and applies the function to the two numbers.
c

cedric

08/30/2018, 3:30 PM
Yes, I guess it's a more universal "add", in a monoidal sense. "Combine" would be another term
l

lifter

08/30/2018, 3:32 PM
I think it's just function application...?
f
could do anything.
It could, for example, just perform a side effect, perhaps:
fun f(x: Int, y: Int) { println("$x / $y") }
I guess my point is, maybe one's intent is to use
justAddThem
to "add" or "combine" in some sense, but there are no guarantees from the type system or otherwise that enforce that.
a

Andreas Sinz

08/30/2018, 3:57 PM
@lifter thats a typesafe way to do it, you could also do it the following way e.g.
fun <T: Number> justAddThem(x: T, y: T): T {
    return when {
        x is Int && y is Int -> x + y
        x is Double && y is Double -> x + y
        [...]
        else -> throw Exception()
    } as T
}
l

lifter

08/30/2018, 3:59 PM
OK, I can see that. Though personally I'm not a big fan of all the boilerplate. I wonder if it would work without the
&& y is Int
if
x
and
y
are both
T
.
a

Andreas Sinz

08/30/2018, 4:01 PM
sadly it doesn't right now
👍 1