ursus
03/21/2025, 3:38 PMPair
and Triple
but even with the only 2 cases, the to
syntax sugar works only for pairs, which is ughh?Seri
03/21/2025, 3:46 PMto
ursus
03/21/2025, 3:46 PMSeri
03/21/2025, 3:47 PMursus
03/21/2025, 3:47 PMSeri
03/21/2025, 3:48 PMPair
into Triple
and more complicated data structures, you should instead look into using a data class
insteadursus
03/21/2025, 3:48 PM(a, b, c)
syntax, that scales to abitrary num of paramsHuib Donkers
03/21/2025, 4:24 PMval tuple = listOf(2, "tuple", 2, "furious")
val (a, b, c, d) = tuple
If you care about types (or want to use things like copy()
), I think data classes are the way to go:
data class Tuple4<out A, out B, out C, out D>(val first: A, val second: B, val third: C, val fourth: D)
val a = Tuple4(2, "tuple", 2, "furious")
val (a1, a2, a3, a4) = a
println("${a1 + a3} ${a2 + a4}") // "4 tuplefurious"
See this SO answer for an example of creating some general purpose tuples with infix notation.
I believe I read some discussion/reasoning behind the decision for kotlin to stop at 3 (Triple
) but I can't find it. I thought the general gist was that already for 2 and 3 it was preferred to use dedicated data classes (over Pair
and Triple
) to communicate intent/meaning better. E.g. Kotlin has Map.Entry
and IndexedValue
where maybe a Pair
would also have sufficed.Joffrey
03/21/2025, 5:05 PMfirst
and second
and never know what it means. With data classes you can put semantics in the names of the properties, which is far superior. And it is extremely cheap to declare and use a data classursus
03/21/2025, 5:06 PMJoffrey
03/21/2025, 5:08 PMursus
03/21/2025, 5:08 PMursus
03/21/2025, 5:08 PMJoffrey
03/21/2025, 5:09 PMursus
03/21/2025, 5:09 PMursus
03/21/2025, 5:09 PMval (title, subtitle) = when (whatever) {
FOO -> ("foo", "foofoo")
BAR -> ("bar", "barbar")
}
this is absolutely good code and tuples make it betterJoffrey
03/21/2025, 5:10 PMFOO
and BAR
?ursus
03/21/2025, 5:10 PMval (title, subtitle) = when (whatever) {
FOO -> TitleAndSubtitle("foo", "foofoo")
BAR -> TitleAndSubtitle("bar", "barbar")
}
data class TitleAndSubtitle(val title: String, val subtitle: String)
this is too noisySeri
03/21/2025, 5:12 PM(title, subtitle, author, description)
?
At this point, your signature becomes <String, String, String, String>
and requires the context from a different space to make any sense. Was it author, then description? Or description then author?ursus
03/21/2025, 5:13 PMursus
03/21/2025, 5:13 PMJoffrey
03/21/2025, 5:13 PMwhen
at allSeri
03/21/2025, 5:14 PMAny
, its going to be hell figuring out where in the when()
block you've got your types wrongursus
03/21/2025, 5:14 PMursus
03/21/2025, 5:15 PMursus
03/21/2025, 5:15 PMursus
03/21/2025, 5:16 PMSeri
03/21/2025, 5:16 PMSeri
03/21/2025, 5:16 PMursus
03/21/2025, 5:17 PMJoffrey
03/21/2025, 5:18 PMwhy would you encode UI detail on a enumIt depends on the enum, but in this specific case it looks like it should be there, because
title
and subtitle
seems conceptually properties of your enum values, so why not declare them with the enum values? It would be easier to reason with a case that's a bit more real, though, I grant you.
If the enum is rather unrelated to the tuple, then I'd argue it's even better to have a proper data class with a name that tells what the tuple represents. Then you would obviously not call this data class TitleAndSubtitle
, but the name of the thing that has a title
and a subtitle
ursus
03/21/2025, 5:18 PMval title: String
val subtitle: String
when (whatever) {
FOO -> {
title = "foo"
subtitle = "foofoo"
}
BAR -> {
title = "bar"
subtitle = "barbar"
}
}
this is like my 99% usecaseJoffrey
03/21/2025, 5:19 PMursus
03/21/2025, 5:20 PMursus
03/21/2025, 5:20 PMJoffrey
03/21/2025, 5:23 PMbut I just wanna tie 2 stuff together, I dont want to think of proper typesTo me this piece of code is as annoying as tuples. Proper types are much easier Extensions could definitely help with readability too, if you can't touch your enum, but most likely the enum has semantics that you could use here.
ursus
03/21/2025, 5:23 PMJoffrey
03/21/2025, 5:24 PMursus
03/21/2025, 5:31 PMSeri
03/21/2025, 5:31 PMSeri
03/21/2025, 5:32 PMJoffrey
03/21/2025, 5:33 PMursus
03/21/2025, 6:25 PMShawn
03/21/2025, 7:02 PMwhen
or grouped together in a Book
enum (or set of object
declarations or something similar)ursus
03/21/2025, 7:04 PMursus
03/21/2025, 7:05 PMJoffrey
03/21/2025, 7:07 PMBook
enum with some entries representing the books, you definitely don't want the title
, subtitle
, or description
to be declared in a when
somewhere else even if this is the only usage of it. The title definition belongs with the book instance definition because it's information about the book itself.Joffrey
03/21/2025, 7:09 PMFOO
and BAR
or notJoffrey
03/21/2025, 7:10 PMfun TheEnum.toMyOtherThing(): MyOtherThing = when (this) { ... }
mapping the instances (or a static map somewhere even), to convey the mapping to the reader and not mix it with some other business logicviluon
03/23/2025, 9:19 PMviluon
03/23/2025, 9:22 PMcomponentN
methods. This severely limits the use cases for tuples in Kotlin, since you can only pattern-match one level deep and in very limited ways (although pattern guards are hopefully coming). The fact that tuples are costly by default on the JVM probably doesn't help.