Hallo. I was wondering if Kotlin has any kind of "...
# multiplatform
s
Hallo. I was wondering if Kotlin has any kind of "strict common mode" that checks that code can be used regardless of target? (i.e. that I'm not relying on features which aren't available on particular platforms). I'm asking because I'm writing some libraries, and I don't want to unwittingly make it incompatible with consumers of any platform.
x
well,
commonMain
is already strict - and you wouldn’t be able to call platform-specific api from
commonMain
🤔
e
that's not necessarily true, it depends on which targets you have enabled
☝️ 8
💯 1
j
Not possible right now, as indeed you need to specify targets and then you can use which common code is written for those targets. There is this issue: https://youtrack.jetbrains.com/issue/KT-52666/Kotlin-Multiplatform-libraries-without-pla[…]fic-code-a.k.a.-Pure-Kotlin-libraries-Universal-libraries
e
yeah that's related too (although it goes even further)
👍 1
j
It's also a relatively impossible goal since you cannot predict the behavior and capability of future targets. The "common" in "commonMain" means common to the specified targets.
👍 2
p
Sadly to say, there is one more thing you should concern is that in JS target it is not allowed to mix property name with function without parameters name in one scope. So code below will not compile for js target:
Copy code
class Test{
  val x: Int
  fun x() {}
}
j
Right, so if this would've been a thing and then JS support was added it would break already, as Jake mentioned. Even the simplest example might be incompatible with future support.
m
I do not quite understand the discussion here. Obviously we have to distinguish between the two incompatible definitions of “common” for the “commonMain” source set vs. the standard library API definition. But why shouldn’t it be possible to provide some tool (which could also be the compiler with a related flag) which ensures that a given Kotlin source file only depends on features flagged as “common” in the API docs?
j
Because it's not guaranteed that definition of common is stable. If I ship a library that has only jvm + native source sets I may have a blocking API that's available in my common source set. But if in a new version I add JS or WASM then that blocking API only becomes common to the jvm+native source sets and the API that is common to jvm+native+JS could be something entirely different–or not even exist.
m
Your arguments are only referring to the “commonMain” source set definition of “common”. I only want to check my code against the well defined and published API and nothing else. This API definition is completely independent of your current mixture of platforms and I hope that this API stays at least backward compatible with a new compiler or platform version. If this would not be the case then this API definition would not make any sense at all.
j
That well defined and published API is a function of the current mixture of platforms supported by the stdlib. New targets could change that API surface.
m
Is there any official statement of how this has to be interpreted or is this just your understanding? But even if your understanding is right it would still be helpful to have some tool to check my code against the published API of a given Kotlin version. I hope they will never add new platforms independently from the compiler version.
p
I was developing my multiplatform application. And at first I was targeting Jvm and Android. I was checking carefully that all stdlib api I'm using is common. But when I add js target, got compilation errors for such cases:
Copy code
class Test{ // name conflict for js target
  val x: Int
  fun x() {} 
}
So in addition to stdlib common dependency one should consider that even language rules are platform dependent. So even you are prepared for common, nobody can be sure that new target will not break language rules.
m
Or this is simply a bug in the JS compiler implementation.
j
No the backend limitations often bubble up into the language compilation. If you use a function name with spaces in it, for example, and add a JS target your app will now fail to compile.
m
Obviously I am not used to such kind of vagueness in language and API design. This is not the kind of multiplatform programming which I envision.
s
Interesting discussion, thanks. I guess the flexibility to add new targets quickly is worth it at the moment; although I wonder if we would ever reach a point where the list of recognised targets stabilises to allow for a kind of stable universal Kotlin.
e
you can check that your code works on all currently available targets by simply building for all currently available targets
the capabilities of future targets are unknown
(okay, so "simple" is a little bit of a lie, depending on what your dependencies are. but if you rebuild those too, you can check)
👍 1
s
yeah, that was my mistake first time round - i assumed common would have some kind of inbuilt lint / restriction that would stop me adding platform specific code, I should have just added all intended targets from the outset.
m
A "stable" language is a dead one
s
Hi. nice to meet another Stanton in here 🙂
😄 1
m
😄
e
there's a trade-off between providing the same capabilities on all targets and integrating smoothly with each host environment