Hi all, just want to ask do you guys still follow ...
# getting-started
h
Hi all, just want to ask do you guys still follow polymorphism(using interfaces) do define behaviours of a object when we can just use extension function? Thanks in advance
g
Yeah, I do! First thought that appeared in my head is a bit exotic use case, but still here it is. In mathematics you have different kinds of numbers (several kinds of integers like
Int
,
Long
, and
BigInteger
, several kinds of real numbers like
Double
and
BIgDecimal
, rational numbers, etc.), and for each of them you could have different implementation of operations (standard ones, using different algorithms, using GPU or whatever, etc.). So for each type of numbers
N
you could have several implementations of operations. To abstract them, you have to create an interface like
MathOperations<N>
(in KMath such interfaces are called
Ring
,
Algebra
,
Field
, and so on). The abstractions are needed when you implement an algorithms that just uses such operations. For example, I had an algorithm that was abstracted like this and formerly used `Double`s, but didn't work as intended, because
0.0 != -0.0
. Then I switched to rational numbers (that used `Long`s under the hood) by just using another (context) parameter for the algorithm. It does not work well, because `Long`s overflowed. So I wrote rational numbers on `BigInteger`s and without editing my algorithm (!) applied new numbers to it. And now it works fine! Another thought is about collections. Obviously, you have to define interfaces to abstract several implementations of lists, to abstract several implementations of something iterable, and so on, so that you can write more common (implementation-agnostic) algorithms. I agree that while you don't have two different implementations of the same "idea" then it's useless to abstract this "idea" as an interface. Extension functions are enough. But the moment you have two of them, you have the use case for introduction of some interface to be able to switch between them.
a
They are wildly different in usage. I do not understand your question. Care to give examples?
y
My rule of thumb is to almost never use abstract classes (even tho rarely they are the right tool for the job) and define interfaces almost-always really. Interfaces are useful because they're a minimal specification of what a system can do, and they compose really nicely. You'll notice that, among nearly every language in every paradigm, interfaces exist in one way or another. It makes sense because an interface is basically just a Strategy pattern, or simply a bunch of functions passed around. I also go
sealed
by default unless I have a reason not to, but that might not be that terribly useful for apps.
👍 2
w
I'd recommend this great read by the previous language designer of Kotlin. https://elizarov.medium.com/extension-oriented-design-13f4f27deaee
h
Thanks guys
r
I think it's important to keep in the mind that, as the official documentation says, that extension functions do not modify the underlying class. (https://kotlinlang.org/docs/extensions.html#extensions-are-resolved-statically) This has implications both for performance, but also, as extension functions are not the same as a subclass, the
protected
fields or methods that could otherwise be accessed, cannot be accessed. The use case for extension functions I believe is to conveniently be able to "add" methods to a class that one otherwise could not modify, but it does not replace polymorphism nor are they intended to at all I think.