Did you know Kotlin has mandatory varargs? <https...
# feed
c
👍 7
👍🏽 1
K 16
s
It feels more like a hack than a proper language feature to me. I’m not comfortable introducing
@Deprecated
in new code, but the standard solution isn’t very elegant either. If I'd do it that way I would leave that annotation out. Maybe you’re right: There probably should be a mandatory varargs language feature. That said, I don’t use varargs very often. I usually prefer a proper
Set
or
List
.
t
That's actually very cool, I can see some occasion I could had used this. Thanks for sharing!
c
> That said, I don’t use varargs very often. I usually prefer a proper
Set
or
List
. That's another article that's coming soon, but yeah varargs should only ever be used as a convenience overload for the real method that takes a Set or List (because the spread operator is not very good)
➕ 1
l
I guess if you use a NonEmptyList from Arrow, you would just have errors on runtime, and only if it can used as a vararg?
c
NonEmptyList
cannot be used as a vararg. Its constructor uses the
(e: T, es: List<T>)
version that I showcase in the first half of the article.
👍 1
f
Throwing an IllegalArgumentException would just move the error from Compile-Time to Runtime.. 🤔
t
For another practical example this is how LauchedEffect is designed in compose to allow them to have varargs but still force the user to supply a key source
💡 1
👍 1
c
Yep, that's the same pattern
p
The only downside with that trick is it doesn't stop you from doing
.containsAll(elements = emptyArray())
or
.containsAll(*emptyArray())
but that's fine for some cases (like your example) - but wouldn't work for something like
NonEmptyList
c
I don't think your first line (without the spread operator) is legal, but yeah the second is allowed. I do mention in the article that you have to take care of it. In the case of
NonEmptyList
, there is no other choice than a runtime exception because it's not possible to know at compile-time that the input list is empty—that's why
NonEmptyList
exists, after all!
p
The first is legal For
NonEmptyList
that's very likely why it has the classic
T, vararg T
parameters to enforce at compile time that construction is with at least one value. The conversions from
Iterable
etc to
NonEmptyList
require explicitly handling (or will explicitly throw).
c
TIL, I didn't know you could pass varargs with an array directly, without the spread operator
p
only when using named arguments
c
Yeah. If I designed
NonEmptyList
, I probably would still use the deprecated trick + a runtime check.
Ah, that makes sense, good to know