# Suggestion: platform specific methods in multiplatform classes

**URL:** <https://discuss.kotlinlang.org/t/suggestion-platform-specific-methods-in-multiplatform-classes/14793>\
**Category:** Language Design\
**Created:** [October 26, 2019, 8:06am UTC](https://discuss.kotlinlang.org/t/suggestion-platform-specific-methods-in-multiplatform-classes/14793 "2019-10-26T08:06:14Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![rnikander](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/rnikander/32/6881_2.png) [@rnikander](https://discuss.kotlinlang.org/u/rnikander)\
**Post date:** [October 26, 2019, 8:06am UTC](https://discuss.kotlinlang.org/t/suggestion-platform-specific-methods-in-multiplatform-classes/14793/1 "2019-10-26T08:06:14Z")

</div>

I’ve been using Kotlin for a multiplatform project (a web app with JVM and JS). The `expect/actual` feature is very useful, but I wish I could do something like this in a shared class:

```
class Thing {
    var x = ...
    fun foo() { ... }
    expect fun bar(): Baz
}

```

In my case I only want to implement `bar()` on the JVM. I can’t use an extension method because I have a class hierarchy of `Things` and I want the virtual dispatch on `bar()`.

So, I’m wondering…

- Do others also want this feature?
- Is it already in the works.? I don’t see it anywhere.
- Is there a nice workaround that obviates the need?
- Are Kotlin users encouraged to flesh out ideas like this and submit KEEPs?

It seems there are two related but separate situations:

1. You want methods in a common class to have different implementations on different platforms. This fits with `expect/actual`.
2. You want to add methods to a common class on one particular platform. Maybe `expect/actual` is not ideal here, since the other `actual` methods would just throw an Exception.

Rob

---

<div class="post-metadata">

**Author:** ![innov8ian](https://avatars.discourse-cdn.com/v4/letter/i/ee7513/32.png) [@innov8ian](https://discuss.kotlinlang.org/u/innov8ian)\
**Post date:** [October 29, 2019, 3:21am UTC](https://discuss.kotlinlang.org/t/suggestion-platform-specific-methods-in-multiplatform-classes/14793/2 "2019-10-29T03:21:52Z")

</div>

If the class ‘Thing’ is common to both platforms, than any method of ‘thing’ must be on both platforms.  
However, you can have a method that generates an exception if called on a platform where the method is not implemented (that is…implemented beyond throwing the exception)

To answer your specific questions:  
declaring a ‘bar’ in the js module with ‘TODO()’ as the only code is about as close as i see as possible to a solution and it is possible already, as it throws a ‘not implemented’ exception if the function is called.

Perhaps this gives the workaround you need?

---

<div class="post-metadata">

**Author:** ![jstuyts](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/jstuyts/32/2141_2.png) [@jstuyts](https://discuss.kotlinlang.org/u/jstuyts)\
**Post date:** [October 29, 2019, 5:55am UTC](https://discuss.kotlinlang.org/t/suggestion-platform-specific-methods-in-multiplatform-classes/14793/3 "2019-10-29T05:55:28Z")

</div>

If a function, value or variable only needs to be available on a specific platform, do not add it to the common type definition. Simply add the member to the actual platform implementation of the common type.

See these types for an example:

- [Common type](https://github.com/squins/ooverkommelig/blob/d802ab98b87fb7efdf935638d620d3e643463557/common/src/main/kotlin/org/ooverkommelig/definition/SubGraphDefinitionOwner.kt)
- [JVM implementation type](https://github.com/squins/ooverkommelig/blob/d802ab98b87fb7efdf935638d620d3e643463557/jvm/src/main/kotlin/org/ooverkommelig/definition/SubGraphDefinitionOwner.kt), which adds function `transitiveRetrievableDefinitions(...)` to the JVM implementation

---

<div class="post-metadata">

**Author:** ![rnikander](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/rnikander/32/6881_2.png) [@rnikander](https://discuss.kotlinlang.org/u/rnikander)\
**Post date:** [October 29, 2019, 7:09am UTC](https://discuss.kotlinlang.org/t/suggestion-platform-specific-methods-in-multiplatform-classes/14793/4 "2019-10-29T07:09:12Z")

</div>

> [@innov8ian](#):
>
> declaring a ‘bar’ in the js module with ‘TODO()’ as the only code is about as close as i see as possible to a solution and it is possible already

I don’t think that’s possible. You have to `expect` the entire class, in which case I would have to duplicate code in JVM and JS. My example code, which has `Thing` in the common module and `expect` on just the `bar` method, does not compile.

---

<div class="post-metadata">

**Author:** ![rnikander](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/rnikander/32/6881_2.png) [@rnikander](https://discuss.kotlinlang.org/u/rnikander)\
**Post date:** [October 29, 2019, 8:37am UTC](https://discuss.kotlinlang.org/t/suggestion-platform-specific-methods-in-multiplatform-classes/14793/5 "2019-10-29T08:37:04Z")

</div>

> [@jstuyts](#):
>
> If a function, value or variable only needs to be available on a specific platforms, do not add it to the common type definition. Simply add the member to the actual platform implementation of the common type.

Okay, so you’re splitting the class into a base and subclass. This seems like a good workaround, but the way you said “_the_ common type definition” made it sound like this is the standard way to do platform specific declarations. There is no mention of this technique in the [Kotlin docs](https://kotlinlang.org/docs/reference/platform-specific-declarations.html) on the topic. They show a single class split into expected and actual, not two classes related by inheritance.

Splitting a class like this seems like the best workaround, if we can’t have individual expected members of common classes. The downside is that it will almost double the number of classes in my hierarchy (already about 20), so that’s a lot of boilerplate.

Another workaround is to have a method in the common class immediately call a top level expected function. But this only works if the function can be implemented without access to private class members.

I still think it would be an improvement if Kotlin allowed expected members in a common class.

---

<div class="post-metadata">

**Author:** ![jstuyts](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/jstuyts/32/2141_2.png) [@jstuyts](https://discuss.kotlinlang.org/u/jstuyts)\
**Post date:** [October 29, 2019, 8:44am UTC](https://discuss.kotlinlang.org/t/suggestion-platform-specific-methods-in-multiplatform-classes/14793/6 "2019-10-29T08:44:05Z")

</div>

> [@rnikander](#):
>
> Okay, so you’re splitting the class into a base and subclass.

No, I don’t. I am saying that the platform-specific implementation class (`actual`) of a common class (`expect`) can have platform-specific methods. There is no inheritance needed. It just so happens that the function in the example I posted overrides a function from a base type, but this is not a requirement.

Simple create a minimal project and try different techniques to see what happens.

> [@rnikander](#):
>
> I still think it would be an improvement if Kotlin allowed expected members in a common class.

I have no idea what you mean here. That is exactly what you can do with a common class.

Common types can do the following:

- Provide member implementations that are common to all platforms.
- Declare that some members need to be implemented in a platform-specific manner.

---

<div class="post-metadata">

**Author:** ![rnikander](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/rnikander/32/6881_2.png) [@rnikander](https://discuss.kotlinlang.org/u/rnikander)\
**Post date:** [October 29, 2019, 8:57am UTC](https://discuss.kotlinlang.org/t/suggestion-platform-specific-methods-in-multiplatform-classes/14793/7 "2019-10-29T08:57:05Z")

</div>

> [@jstuyts](#):
>
> I have no idea what you mean here. That is exactly what you can do with a common class.

I don’t see how to do that. Can you show me some example code with a _single class_ that has both common and platform specific members? This does not compile for me:

```
// in common module
expect class A {
    fun fooCommon() { } // error: Expected declaration most not have a body
    fun bar()
}

```

Nor the other way:

```
// in common module
class A {
   fun commonFun() { }
   expect fun bar()
}

```

The only way I see to do it is like I saw in your example before where you put the common code in one class, and then have a subclass that is `expected` and implemented differently in JVM and JS.

---

<div class="post-metadata">

**Author:** ![ilya.gorbunov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ilya.gorbunov/32/1645_2.png) [@ilya.gorbunov](https://discuss.kotlinlang.org/u/ilya.gorbunov)\
**Post date:** [October 29, 2019, 9:13am UTC](https://discuss.kotlinlang.org/t/suggestion-platform-specific-methods-in-multiplatform-classes/14793/8 "2019-10-29T09:13:35Z")

</div>

I recall there is a feature request for that: [https://youtrack.jetbrains.com/issue/KT-20427](https://youtrack.jetbrains.com/issue/KT-20427). If implemented, it would allow to provide default common implementations for `expect` declarations, including members of expect classes. Currently that is not possible.

---

<div class="post-metadata">

**Author:** ![rnikander](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/rnikander/32/6881_2.png) [@rnikander](https://discuss.kotlinlang.org/u/rnikander)\
**Post date:** [October 29, 2019, 11:27am UTC](https://discuss.kotlinlang.org/t/suggestion-platform-specific-methods-in-multiplatform-classes/14793/9 "2019-10-29T11:27:07Z")

</div>

Okay, thanks for the clarification. I’ve voted for that issue but also created a second one here: [https://youtrack.jetbrains.com/issue/KT-34668](https://youtrack.jetbrains.com/issue/KT-34668). I think it’s a bit different, but I understand if it ends up marked as a duplicate.

---

<div class="post-metadata">

**Author:** ![imanushin](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/imanushin/32/5471_2.png) [@imanushin](https://discuss.kotlinlang.org/u/imanushin)\
**Post date:** [October 29, 2019, 2:20pm UTC](https://discuss.kotlinlang.org/t/suggestion-platform-specific-methods-in-multiplatform-classes/14793/10 "2019-10-29T14:20:02Z")

</div>

Looks like you can just use different interfaces for this.

As an example:

```auto
interface AllPlatforms {
    fun commonMethodForAllPlatforms()
}

interface JVMPlatform : AllPlatforms {
    fun jvmMethod()
}

object PlatformApiHolder {
     val api : AllPlatforms
         get(): {
                    if(JVM) {
                         return object : JVMPlatform {                              
                         }
                    }
         }
}

fun someJvmMethod() {
    val jvmApi = PlatformApiHolder.api as JVMPlatform ;
}

```

Finally you can define different interfaces for each platform. Moreover, the most of validation will be in compile time.
