I wish to know why I cannot have an `Array<Noth...
# compiler
g
I wish to know why I cannot have an
Array<Nothing>
in kotlin. I understand that
Array
is not a real class and thus kotlins presentation of
Array
as a generic type is misleading and I'm certain the reason that
Array<Nothing>
being a
Nothing[]
and something to do with reifying the type nothing is the cause, but I cant understand why. Is there no entry in the classpool for
Nothing
?
e
Array<Nothing>?
is representable on JVM (as
[Ljava/lang/Void;
) but
Array<Nothing>
is not (there is no
[V
)
1
🤔 1
hmm, or so I thought, but testing it out, it seems Kotlin rejects that too
g
I would've thought
Unit
is more like
Void
, so
Array<Unit?>
-> jbc -> java ==
Void[]
makes sense
But I dont think
Nothing
and
Void
share much in common
e
java's
void
has two meanings, one is
Unit
-like and one is
Nothing
-like
e.g.
() -> Nothing
has a similar meaning as
Callable<@Nonnull Void>
, for example - meaning it cannot return normally definitely a different meaning than
() -> Unit
which is somewhat like
Callable<@Nullable Void>
which can return normally, only with a single value
digging into it, Kotlin treats
Class<Nothing>
like
Class<*>
a raw type. (conversely, generics in raw types become
in Nothing
when
in
parameterized and
out Any?
when
in
parameterized, https://kotlinlang.org/docs/generics.html#star-projections). so under those rules, it's understandable that
Array<Nothing>
doesn't work, as only reified array types exist
j
What are you trying to do with
Array<Nothing>
anyway? Represent a zero-length array separately from a non-zero-length array?
g
I have an immutable collection backed by an array. I want to make an
EMPTY
instance, which is a
MyCustomCollection<Nothing>
, which wants an instance to fill it's backing array.
👍 1
I could of course use the same trick as java util collections and use Array<Any> as my backing type, not the I have a plethora of gross casting to do
j
I think it's easier to unsafe cast the empty array instance to your Array<T>
e
that seems potentially problematic if there's ever anything that uses a concrete type instead of
<T>
, because
Array<Any>
cannot be cast to
Array<AnyOtherType>
basically I don't think there's a good answer with
Array
, even if you could write
Array<Nothing>
. why are you using
Array
anyway? almost always it's better to work with
List
or other collections
f
Nothing
isn't
void
nor
Void
. It's nothing. It cannot be stored, not in an array, not elsewhere. Hence, the fact that
Array<Nothing>
isn't valid makes perfect sense.
Array<Nothing?>
should work, but that's captured in KT-67675. Imho Kotlin should feature
Null
as a dedicated type for use cases like this and other where only
null
is permissible.
e
even with that, "empty array which is a subtype of all other arrays" can't exist on JVM
f
An
Array<Null>
would translate to
Void[]
and thus be representable. In this particular case it doesn't matter to the Kotlin user what the native type is, all they want is
null
.
g
@Fleshgrinder I think this argument is flawed because it also applies to
List<Nothing>
which is a helpful type and is exactly what is returned by
emptyList
As I think about it I wonder if kotlinc (and kotlin 2.0) could pull the trigger on --what I hope is a fairly small-- implementation of type-erasure arrays. If the language presents them as generic, then why not use the traditional generic facilities? Something like
val myArray: Array<Customer> =  Array<@NotReified Customer>(3) { ... }
. What
@NotReified
would do is tell the compiler to just use
Object[]
. It of course comes with all the caveats of heap pollution but those exist for any generic type. thoughts? should kotlin just sorta, not-do arrays and use
Object[]
as the backing type for any array type (--as is the employed solution for java collections)?
e
breaks java interop though, you would not be able to pass an
Array<String>
to a Java method expecting
Array<String>
if it was created as an
Array<@NotReified String>