```"FooBarBaz".lowercase().capitalize()``` When I ...
# getting-started
j
Copy code
"FooBarBaz".lowercase().capitalize()
When I use this I ofc get the known capitalize() being deprecated. And it offers me to be replaced with:
Copy code
replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() })
My question is, why doesnt capitalize doing this under the hood instead and stop deprecating it? Feels wrong adding my own capitalize extension for this, which would interfere with this one. I know I have capitalize(Locale) but I would like to avoid that variant because of Kotlin multiplatform reasons.
v
Probably because it would change behavior and thus be a breaking change
j
The true reason behind this, is that the old capitalize using "wrong" Locale? Or like what can happen in reality?
I guess not nice having capitalize2() or such, until removed the deprecated variant ๐Ÿ˜„
v
"wrong" depends on definition, but yes I'd say. Usually Kotlin uses UTF-8 by default for things, but there it uses the System default locale.
s
j
Copy code
// in all targets
String.capitalize()   -> String.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it }
String.decapitalize() -> String.replaceFirstChar { it.lowercase() }

// in JVM
String.capitalize()         -> String.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it }
String.capitalize(locale)   -> String.replaceFirstChar { if (it.isLowerCase()) it.titlecase(locale) else it }
String.decapitalize()       -> String.replaceFirstChar { it.lowercase(Locale.getDefault()) }
String.decapitalize(locale) -> String.replaceFirstChar { it.lowercase(locale) }
Hmm yeah this make my head spin ๐Ÿ˜„ So for non jVM variants you want to use without Locale even for titlecase? Not entirely sure now when to use what. When do I want to use this,
Copy code
String.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it }
and when should I use:
capitalize(Locale.Root) or capitalize(Locale.getDefault())
?
From my end I got more confused with the new APIs compared to the other ones. But is it possible for me, like in my case with Kotlin multiplatform to have the correct behaviour automatic aligned correct for all targets I have? Or how do I know when I should use which Locale?
s
You should use the Locale that corresponds to the language the text you're working with is written in ๐Ÿ˜‰
๐Ÿ˜œ 1
j
And that I cannot get automatic? ๐Ÿ˜„
Isnt the language more based on the encoding table its used? I can write Turkish in String but without Turkish chars as of example.
s
The point is that different languages have different rules for how case conversions work. So you can get different results for the exact same text. If you tell Kotlin that your text is Turkish, and then ask it to capitalize it, you'll get a different result from if you told it the language was English.
Depending on what your app is doing, there are different ways to figure out the locale you should be using. On a mobile app, the system default locale will be the one the user selected in their device settings, but on a web server, you would need to use content negotiation as you're serving different pages to different users.
j
Right, but isnt that more presentation level of a String so to say? I mean if the String is written in english I would like it to be converted in English and not something else. But I guess would need AI or something to detect language in the String and not using the Locale user having. Most often I need to have conversions in my code being same language as the programming language which is english, being Locale agnostic so to say. In those cases I guess I should be using
String.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it }
?
In my case I am taking EnumClass.A.name.capitalize where I want to convert enum name to something else, for a new identifier ๐Ÿ˜›
Not to be used in presentation logic.
s
Sure, if you use the new (non-deprecated) Kotlin methods it will use the "invariant" locale, which should be fine for what you're describing ๐Ÿ‘
j
As of example when doing "title".capitalize() I do not want if the user has Turkish to do something odd, I want it always to be Title ๐Ÿ˜„
๐Ÿ‘ 1
But I guess I would create a new extension called like invariantCapitalize or whatever ๐Ÿ˜›
And for the other cases, I keep using capitalize(Locale.getDefault or Locale.ROOT)
Like it wasnt complex as it was with date, time, numbers, also need to considering String conversion ๐Ÿ˜„
I wish there was a kotlinx.formatting library ๐Ÿ˜„
s
Kotlin isn't the problemโ€”reality is ๐Ÿ˜„.
๐Ÿ˜„ 1
๐Ÿ’ฏ 1
Honestly it's amazing how good a job the Unicode project has done at imposing some sort of structure on the insanity that is human communication
j
Yeah I totally agree ๐Ÿ˜„ I just wished there was more things solved from JVM/Java world in the past, no one at Oracle adressed or ignored for very long time, which now inherited by Kotlin. Simple things as BigDecimal formatting or input from user convert to Locale keyboard input, or formatting timezone based Instant to human readable ISO formats. Its always about Locale ๐Ÿ˜„ I just wished kotlinx and Kotlin provide more awesome stuff like kotlinx-datetime not provide agnostic formatting of time and dates in upcoming 0.6.0 release. I would like to have everything enforce in ISO formats everywhere, and not accept anything else. But also in JVM world how to copy Locales in Android has been, very special over time as well, to have Threeten or Jodatime cover up, or using desugaring to have polyfills. Sorry off topic maybe ๐Ÿ˜„
k
Honestly it's amazing how good a job the Unicode project has done at imposing some sort of structure on the insanity that is human communication
It bugs me that today's ultra-modern computing carries a lot of baggage from the past, from even before computers existed. Unicode is one example of this. There are many ways to indicate a new line: LF, CR, CR+LF, NEL (U+0085), LS (U+2028) and probably a few others I haven't thought of. Qwerty keyboards are another example, with key positions optimized for mechanical typewriters. I wish we could just start afresh, but I know that's unfortunately unrealistic.