Just bringing this to light once more :crossed_fin...
# javascript
a
Just bringing this to light once more 🤞🏾 Another pain points of dealing with kotlin/js is the kotlin collections and these are reasons Clarification: By collections, I mean the following implementations or abstractions • The
Collection
and
MutableCollection
interfaces • The
List
and
MutableList
interfaces • The
Set
and
MutableSet
interfaces • The
Map
and
MutableMap
interfaces 1. The collections are not marked with
@JsExport
making their consumption from JS/TS extremely difficult 2. There is no easy way to convert an instance of either of these collections to their native collection counterpart data structures (
List
->
Array
,
Set
,
Map
) We are currently wrapping these Collections to make them easy to use, but it feels inconvenient to have yet another wrapping of these basic building blocks of almost any library/application. We have expect/actuals in place so that we only do the wrapping in JS targets but that does require different builders to construct the said collections. This is very confusing especially for people joining the team We tried using
Array
in favor of
List
but they don't play well as properties for data classes. I know the team is currently focused on the compiler right now, but I would like to shed light one more time on how little things like these are also a crucial part of a language (at least its standard library).
☝️ 1
e
Kotlin
List
/ JS
Array
interop: how? custom
List
implementations, e.g.
Copy code
object AlmostInfiniteList : AbstractList<String>() {
    override val size get() = Int.MAX_VALUE
    override fun get(index: Int) = index.toString()
}
can't be JS `Array`s
`Set`: ditto, but also JS
Set
is ES6 and Kotlin doesn't target ES6 yet
`Map`: ditto, plus JS`Object` only allows for string keys, while JS
Map
is ES6 and isn't commonly used
given the impedance mismatches between the languages, I don't think there's any design that can seamlessly bridge them
a
No, List is not an Array, I was talking about a smooth way to convert from a List to an Array in JS. And it should be the same converting a from a Kotlin Set to JS Set and Kotlin Map to JS Map
We have a way that works (at least for Lists), but it introduces extra wrapping. and if we can achieve this, so can the stdlib
e
suppose JS calls
registerOnce(sameInstanceOfArray)
twice, where the function is implemented in Kotlin, and Kotlin is transparently wrapping that to
List
, do you expect to receive the same instance twice? ditto the other way around. I don't see how that can work in general
t
FYI
JsMap
and
JsSet
already declared in wrappers
a
You seem to be highly informed than I am @ephemient, then how do you suggest this problem to be approached? Just leave it the way it is? Or is there a much better alternative?? To me, easy conversions to the nearest native counterparts is a good tradeoff, but again that is just my underinformed opinion
@turansky thanks for the link to the wrapped js declarations. While these are helpful in consuming Js code from kotlin, they don't help much in consuming kotlin code from JS. Especially if you have too many classes in common main that have these collections as properties to be consumed from. The said instance will have kotlin's list, set or map. Which are almost impossible to consume from JS
t
Which are almost impossible to consume from JS
It looks like expected behaviour from my side
For communication between modules we use JSO, arrays, byte arrays (JS structures)
👍🏻 1
a
Sorry if I’m reviving a dead thread here, but it really would be slick if there was some kind of compiler plugin that could automatically convert between
Map
<>
JsMap
and
Set
<>
JsSet
for things that are annotated with
@JsExport
Almost similar to the KMP-NativeCoroutines project that generates helpers for `suspend fun`s for iOS
t
From my side it looks like magic plugin, which will convert any
X
to any
Y
, because
Map
and
JsMap
have common name, but different behaviour. Just for start:
Map
- interface
JsMap
- class
Map
can have different implementations.
JsMap
also can have multiple child types.
Map
contract - use
equal
for key comparing
JsMap
contract - use
===
for key comparing You can create
class SuperMap: JsMap, Map
and replace all
mapOf()
and
emptyMap()
calls but it will help only in situation, when
Map
used as output type. How to find all possible “input cases”? Is it possible?
a
There is no easy way to use kotlin.collection Map/List/Set from JS. Imagine having to write expect/actuals for basic classes just because one of their properties is a collection type. Sure, we do have JSMap and JSSet but they can't be used in commonMain as they are JS only data structures. This thread was meant to invoke the kotlin team to find a way to Make these kotlin.collection consumable from JS (something that is very possible to do, but currently not being done)
@JsExport
was meant to help solve this, but it fails miserably coz those collection interfaces are not even exported from the stdlib themselves
t
Make these kotlin.collection consumable from JS (something that is very possible to do, but currently not being done)
From my side it doesn’t look like “very possible”. It’s definitely problem, for which I don’t see simple common solution.
Map
,
List
,
Set
,
Comparable
,
Sequence
,
Comparator
,
Iterator
,
Iterable
have no native analogs, which have
String
,
Array
,
Boolean
.
a
So, for it to be usable, it doesn't need to be converted into a native analog
t
So, for it to be usable, it doesn’t need to be converted into a native analog
For me it’s open question
a
Allow me to answer it in the following way. On the stdlib, List's JS implementation can easily be marked with
@JsExport
and given a
.toArray()
method which makes it easy to break from the Kotlin world to the JS world. (We currently have a wrapper that does this)
Set
and
Map
can share the same fate. All marked with
@JsExport
and be given a
.toJsSet
and a
.toJsMap
method respectively