I do wish that the toString of maps, lists and dat...
# announcements
r
I do wish that the toString of maps, lists and data classes was compilable.
blob thinking upside down 4
a
compilable?
r
In my ideal world this would be true:
Copy code
listOf("one", "two", "three").toString() == """listOf("one", "two", "three")"""

mapOf(1 to "one", 2 to "two").toString() == """mapOf(1 to "one", 2 to "two")"""

Person(name="Joe \"Awesome\" Smith", age=32).toString() == """Person(name="Joe \"Awesome\" Smith", age=32)"""
So that I could just cut and paste the output into a source file and it would compile. Impossible now, would be a huge breaking change. Just venting a mild frustration as I yet again struggled to reproduce an issue from a log file and had to massage strings and so on to make the output compilable.
a
Impossible now
Not really, data classes output is directly compilable. And for lists and maps, you can define your own custom implementation:
Copy code
fun <T> List<T>.toCompilableString(): String =
    joinToString(", ", prefix = "listOf(", postfix = ")") { if (it is String) """"$it"""" else "$it" }
r
data classes output is directly compilable.
Not it isn’t. It doesn’t quote strings.
My own custom implementations won’t catch what other people do. Nor will it catch string concatenation / interpolation where toString is called implicitly.
Copy code
Person(name="Joe \"Awesome\" Smith", age=32).toString() == Person(name=Joe "Awesome" Smith, age=32)
- which is not compilable.
a
Why do you want to compile a String repr?
You could encode the object to ByteArray, and get it back...
r
I said above. Reproducing behaviour from logs.
a
If you store the logs, probably you can call external extensions 🙂
v
Well,
toString()
is for nice human consumption. A compilable string is usually not fulfilling this point. So I highly doubt this will ever change.
☝️ 1
r
Source code is for nice human consumption.
v
No, Source code is for nice compiler consumption and easy human creation 😄
r
Stongest disagreement I can find. Source code is read far, far more often than it is written. Understanding is the bottleneck, not speed of writing.
v
I totally agree that code is read far more often, that was not the point. That's why coding conventions exist that care for proper human readability. But the language is not defined for human readability. You can write all code of a 1000 lines human-readable class into one very long line. The compiler will be perfectly happy with that as it can properly parse it.
r
For that matter the the toString of a map with a 1,000 entries will be spat out on a single, and consequently human illegible, line.
There are two aspects of the toStrings of maps, lists and data classes that make them laborious to rebuild: 1)
:
rather than
to
between key and value in a Map entry - I really think that, apart from breaking backwards compatibility, it would be no big deal to human legibility if that changed 2) Strings are not quoted appropriately. This is actually an issue for human readability too; you cannot reliably distinguish whether a value is a number or a boolean or a string. And even if you can, sorting out the escaping to get a compilable string in a map containing loads of them is a huge pain. For me the lack of ambiguity, and the ease of reuse, if the string were printed as a compilable string literal would significantly outweigh the reduction in legibility when part of the output of a list, map or data class. (In my current role I quite often get a log of a Map<String, Any> which was parsed from json or some other format, unknowable at compile time, with fields like
id: 1234
. The json isn’t logged. I’m trying to reproduce an issue by feeding the real world input into a test. Should I make that an int or a string? With work I can find out, but it would be a lot easier if the output were unambiguous in the first place.)
v
Well, make an improvement request in youtrack. I just said I doubt it will be done. But I might as well be wrong. 🙂
r
If I were managing Kotlin I’d reject it; while you’re not meant to parse toString, the odds that no-one is are low, and so the reputational cost to Kotlin of breaking them to make me happy would seem to me prohibitively high. I was just venting; voicing frustration after a period of trying to build test input from log files using increasingly convoluted regex. If I could go back in time to pre 1.0 I’d push harder on the subject.
v
Well, asking never hurts. At least if you can live with an official denial 😄
a
That's a bit harsh reply I'd say...
v
was it? o_O
c
you can just create your own library method that produces compilable output.
v
That was already suggested and denied above 😉
t
How about using JSON in your logs? Pretty readable and usually easy to parse back into objects.
2