Gouri Panda
12/01/2024, 11:23 PMGeorge Z
12/03/2024, 7:49 PMisLoading
state?
@Test
fun `loadMovies updates uiState.isLoading`() = runTest {
coEvery { repository.getMovies(MovieCategory.DEFAULT) } coAnswers {
delay(600)
Resource.Success(emptyList())
}
assertFalse(viewModel.uiState.value.isLoading)
viewModel.loadMovies(MovieCategory.DEFAULT)
advanceTimeBy(200)
assertTrue(viewModel.uiState.value.isLoading)
advanceUntilIdle()
assertFalse(viewModel.uiState.value.isLoading)
coVerify { repository.getMovies(MovieCategory.DEFAULT) }
}
groostav
12/10/2024, 9:32 AMclass MyCustomException(val trace: List<StackTraceElement>): Exception(){
init {
stackTrace = trace.toTypedArray()
}
override fun fillInStackTrace() = this //interrupt call to dump back-trace into stack-trace
}
?Paulo Cereda
12/13/2024, 10:24 PMsleepsort
in Kotlin. 😁 The best I could come up with is as follows (playground link):
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
suspend fun main() {
println(sleepsort(listOf(63, 32, 62, 14, 5)))
}
suspend fun sleepsort(list: List<Int>): List<Int> = coroutineScope {
buildList {
list.map { number ->
async {
delay(number.toLong())
add(number)
}
}.awaitAll()
}
}
Do you have any suggestions and/or improvements to make it better (or even worse)? Thank you so much, and season's greetings to everyone! 🎄Daniel Pitts
12/17/2024, 5:39 PMimport com.stochastictinkr.json.*
fun main() {
val obj = jsonObject {
"name"("John Doe")
"age"(25)
"address" {
"number"(123)
"street"("Main Street")
"city"("Anytown")
"state"("AS")
"zip"(12345)
}
"phoneNumbers"[{
add("555-1234")
add("555-5678")
}]
"favoriteColor"(null)
"averageScore"(85.5)
}
println(JsonWriter.Pretty.writeToString(obj))
}
Resulting JSON:
{
"name": "John Doe",
"age": 25,
"address": {
"number": 123,
"street": "Main Street",
"city": "Anytown",
"state": "AS",
"zip": 12345
},
"phoneNumbers": [
"555-1234",
"555-5678"
],
"favoriteColor": null,
"averageScore": 85.5
}
Edgar Avuzi
12/22/2024, 7:45 AM.let
are redundant here (because there is no null
to handle using ?.let
). Still this disadvantage does not outweight. IMOAhmed
01/17/2025, 10:04 AMarve
01/21/2025, 1:26 PMinterface Alphabet {
fun a(): String
fun b(): String
// and many more
fun z(): String
}
I thought I had a really bright idea, since the following is valid syntax:
class A : Alphabet by TODO("NOPE") {
override fun a() = "a"
}
I was hoping the delegation would act as with actual objects, routing calls to the override if they were present, and throwing NotImplementedError otherwise. Unfortunately, the TODO()
is evaluated on instantiation of A() and not during method call 😞
// Hoping for
A().a() == "a" // true
A().b() // NotImplementedError
// but got
A() // NotImplementedError
Does anyone have an elegant way to partially implement an interface and default to NotImplementedError for the rest, without explicitly doing so for every single method?Mark
01/22/2025, 3:25 AMStateFlow
from another StateFlow
without requiring a CoroutineScope
(so no new coroutine):
private class MappedStateFlow<T, R>(
private val original: StateFlow<T>,
private val transform: (T) -> R
) : StateFlow<R> {
override val replayCache: List<R>
get() = original.replayCache.map(transform)
override val value: R
get() = transform(original.value)
override suspend fun collect(collector: FlowCollector<R>): Nothing {
original.collect { collector.emit(transform(it)) }
}
}
fun <T, R> StateFlow<T>.mapState(transform: (T) -> R): StateFlow<R> {
return MappedStateFlow(this, transform)
}
Eugen Martynov
02/10/2025, 8:11 AMcustomKeyListener?.onCustomKeyPressed()
something like
customKeyListener::onCustomKeyPressed
Richard
03/05/2025, 7:27 AMenum class ToggleValue {
YES,
NO,
UNKNOWN
}
val ToggleValue.asBoolean: Boolean? // this one
get() = when (this) {
ToggleValue.YES -> true
ToggleValue.NO -> false
ToggleValue.UNKNOWN -> null
}
val Boolean?.asToggleValue: ToggleValue
get() = when (this) {
true -> ToggleValue.YES
false -> ToggleValue.NO
null -> ToggleValue.UNKNOWN
}
Edgar Avuzi
03/07/2025, 1:47 AMMark
03/08/2025, 2:20 PMDensity
as the receiver, but isn’t the API usage cleaner when doing this?
fun TextUnit.scale(scale: Float, density: Density): TextUnit {
if (this.isUnspecified) return this
return with(density) {
(scale * this@scale.toPx()).toSp()
}
}
Ben Madore
03/11/2025, 1:31 AMval artifactName: Property<String> = project.objects.property(String::class.java)
that is consumed by maven-publish to set the name of the artifact (jar) to be published.
a couple of times, due to copy paste errors, folks have complained about failure to publish to artifactory when in fact they’ve just used the same artifactName
in multiple modules of a project.
Does this approach make sense for identifying this case and proactively failing the build and alerting the user? Am i missing something much simpler?
// Add a plugin to detect duplicate artifact names
plugins.withId("maven-publish") {
// Create a simple task that will run on every project to check for duplicate artifact names
val checkDuplicateArtifactNames =
tasks.register("checkDuplicateArtifactNames") {
group = "verification"
description = "Checks for duplicate artifact names across all projects"
doLast {
// Map to store artifact names and their corresponding projects
val artifactMap = mutableMapOf<String, MutableList<String>>()
// Collect all artifact names from all projects
rootProject.allprojects.forEach { proj ->
val projExtension = proj.extensions.findByType(GDConventionsExtension::class.java)
if (projExtension != null && projExtension.artifactName.isPresent) {
val artifactName = projExtension.artifactName.get()
if (!artifactMap.containsKey(artifactName)) {
artifactMap[artifactName] = mutableListOf()
}
artifactMap[artifactName]?.add(proj.path)
}
}
// Find duplicates (artifact names used by more than one project)
val duplicates = artifactMap.filter { it.value.size > 1 }
// If duplicates are found, throw an error with details
if (duplicates.isNotEmpty()) {
val errorMessage = StringBuilder("\nDuplicate artifact names detected:\n")
duplicates.forEach { (artifactName, projects) ->
errorMessage.append("\n Artifact name '$artifactName' is used by multiple projects:\n")
projects.forEach { projectPath ->
errorMessage.append(" - $projectPath\n")
}
}
errorMessage.append("\nPlease ensure each module has a unique artifactName in its fooConventions block.\n")
errorMessage.append("For example:\n")
errorMessage.append("gdConventions {\n")
errorMessage.append(" artifactName.set(\"unique-name\")\n")
errorMessage.append("}\n")
throw GradleException(errorMessage.toString())
}
}
}
// Make sure the check runs as part of the build
tasks.named("build").configure {
dependsOn(checkDuplicateArtifactNames)
}
}
czuckie
03/19/2025, 9:21 AMprivate fun String.asDomainSpecificObject(): DomainSpecificObject = ...
I would prefer a function to handle such things that explicitly took a string.
I thought the overwhelming view/opinion was that extension functions and properties were right when they extended the abstraction of the class that was being given an extension.
Beyond initial confusion and my own opinion, is there any reason to avoid such use of extension functions/properties, or should I embrace it?Vivek Modi
04/04/2025, 9:21 PMEmre
04/07/2025, 4:00 PMAlex Kuznetsov
04/11/2025, 5:51 PMLanguage
annotation on a String literal for syntax highlighting and such, for example
@Language("SQL")
val sql = "SELECT weight, name FROM boxes"
But I'm reviewing code where parameters are annotated with it:
`fun doSomething(@Language("JSON") payload: String) { ...
why would we want to do that? what does it buy us?Sam Dukes
04/16/2025, 8:52 AMVivek Modi
05/01/2025, 8:35 PMJetpack Compose
screen that fetches contact data using a ContactViewModel
. The ViewModel uses StateFlow
, performs API calls through a ContactsApi
, and includes email validation logic using a UseCase. It all works, but I want to refactor this to align more with Kotlin best practices, Jetpack architecture guidelines, and better separation of concerns.czuckie
05/02/2025, 12:28 PMAlex Kuznetsov
05/06/2025, 12:44 PMrunCatching
catches a Throwable
not an Exception
? Even official documentation states that
• The Error
subclass represents serious fundamental problems that an application might not be able to recover from by itself. These are problems that you generally would not attempt to handle, such as OutOfMemoryError
or StackOverflowError
.
https://kotlinlang.org/docs/exceptions.html#exception-hierarchy
Personally we use a slightly modified version of runCatching
that only catches an Exception
. What am I missing?dany giguere
05/25/2025, 3:17 PMdany giguere
06/03/2025, 9:56 PMarve
06/06/2025, 10:17 AMinterface IExample {
fun <T> something(cls: KClass<T>)
}
inline fun <reified T> ITest.something() = something(T::class)
val t: IExample = Example()
// caller has to manually know about, and import extension function before they can do
t.something<String>()
zt
06/07/2025, 5:54 PMval graph = FilterGraph {
// split input into 2 (default) outputs
filter("split") {
// get first output and assign to variable
val tmp = output {
filter("crop") {
option("out_w", "iw")
option("out_h", "ih/2")
option("x", 0)
option("y", 0)
}
// flip vertically
filter("vflip")
}
// get the second output
output {
// overlay tmp on top of this output
filter("overlay", tmp)
}
}
}
czuckie
06/16/2025, 12:54 PMturbine
for their coroutine testing?Zyle Moore
06/26/2025, 6:17 AMuseEffect(setTopLevel, props.pluginElementMarkers) {
val last = props.pluginElementMarkers.lastOrNull()
if (last == null) {
return@useEffect
}
val sequence = props.pluginElementMarkers.asSequence()
val topLevelList = mutableListOf<PluginElementMarker>()
var nextMarker = sequence.take(1).single()
while (nextMarker != last) {
val skip = nextMarker.skip
val size = when (nextMarker) {
is GroupElementMarker -> nextMarker.elementSize
is RecordElementMarker -> nextMarker.elementSize
is SubRecordElementMarker -> nextMarker.elementSize.toUInt()
}.toLong()
topLevelList += nextMarker
nextMarker = sequence
.dropWhile { marker -> marker.skip < skip + size }
.take(1)
.singleOrNull() ?: last
}
console.log("actually done")
setTopLevel(topLevelList)
}
Paulo Cereda
06/27/2025, 3:42 PM.properties
file correctly loads entries as UTF-8 — once the reader
is using the correct charset, Properties
works as expected. Consider this excerpt:
val expected = mapOf(
"italian" to "anatra",
"russian" to "утка",
"chinese" to "鸭子",
"japanese" to "アヒル",
"korean" to "오리",
"arabic" to "بطه",
"hindi" to "बत्तख",
...
)
I was wondering if I should hardcode these strings into the Kotlin file, specially that I have RTL ones in there. Is this okay or there is a better way? Any suggestions are welcome! Thanks!arve
06/30/2025, 7:52 AMimport kotlinx.serialization.StringFormat
import kotlinx.serialization.json.Json
private val format: StringFormat = Json { encodeDefaults = true }
object MyFormat : StringFormat by format
When I try to inline format
the expression insists on referring to the class Json
instead of the factory function Json
Any tips to avoid the intermediate format
variable?