Explicit toString in string template


#1

No, I am not talking about performance. I am talking about code sanity.

Currently, anything, even null, Unit and Nothing (although the latter would trigger a “dead code” error), can be fitted into a string template. I think this is an error-prone behaviour.

When I use a variable in Kotlin, I already assume that the IDE/compiler would do type and null safety checks for me. While I am aware that this doesn’t include interpolation in string templates, I often accidentally use the absence of errors in a string template to assume that an expression is used correctly.

From what I have experienced (although I am not a very experienced Java/Kotlin developer), I don’t think the implicit toString call is useful. There are a few problems:

  1. While developers are advised to always override toString, toString does not always give the results you want. toString is supposed to provide as much debugging data as possible, but this is not what a developer usually wants to do when typing a string template. In short, this behaviour is only useful for debugging. Indeed, in a properly i18nized project, string templates are almost never used for anything but debugging, but not every project is (or needs to be) i18nized.
  2. On the other hand, this implicit toString behaviour provides the motivation for developers to implement toString just to “have more concise string templates”, e.g. as shortcuts to the name/id property, etc. While this is not a good practice anyway, it is tempting for new developers to do this (especially when they aren’t experienced with good testing or debugging techniques)
  3. If only Strings (or more tolerantly, CharSequences) are allowed, issues like Suggestion: Linting for String interpolation can be prevented as early as possible.

In this topic, I am proposing a new syntax for string literals that only accepts Strings/CharSequences. This can be something like changing the quotes to ''xxx'', or by introducing a new way of interpolating strings (but backward compatibility is a bit hard to solve). Or to make things simpler, apply a compiler flag that displays warnings when interpolating a nullable or non-CharSequence value in a string template.


#2

Correct. String templates aren’t really useful for outputting String to the user. Even if you’re not developing with localization in mind (you probably should, as people may want that sooner or later), there is stuff like handling plural forms and gender suffixes which are also not handled properly by simple String templates. So you really should move your Strings to external resources and use a proper library to build them.


#3

Not every single project is an i18nized project. Even if it is, not everything it uses needs i18n. Filenames don’t. Generating HTML code doesn’t. Today I am working on a project that generates some code, and obviously it doesn’t need. If you think it’s not needed, open the biggest project you have in hand, navigate to the String class and look at the operator fun plus(String) function. Search its usages – you will find so many non-i18nable usages of string, and they need concatenation.

After all, i18n or not has nothing to do with the null safety or type safety of string templates. Let’s not get carried away.