Elena van Engelen
10/30/2024, 1:17 PMsuspend fun createFoo(foo: Foo) {
// Create record in DB and then perform additional tasks within scoped functions
dbService.saveFoo(foo)
.also {
// Cache invalidation
cacheService.invalidateCacheForFoo(foo.id)
}
.also {
// Update search engine
searchEngineService.addFooToSearch(foo)
}
}
dave08
10/30/2024, 4:48 PMazabost
10/31/2024, 2:47 PMinterface Foo {
val xyz: String
}
class Bar : Foo {
override val xyz: String
init {
xyz = compXyz("XYZ")
}
fun compXyz(key: String) = key.reversed()
}
fun main() {
val s = Bar()
println(s.xyz)
}
I'm asking because I seem to get this warning in Android Studio (I use Kotlin 1.9.24 in the project):
Property must be initialized, be final, or be abstract. This warning will become an error in future releases.
and not sure how to interpret this issue: https://youtrack.jetbrains.com/issue/KT-57553/Implement-deprecation-for-open-val-with-backing-field-and-deferred-initialization-in-K1
i.e. whether this is going to be deprecated soon or not
I don't see any issues running it in Kotlin Playground though (tried both 1.9 and 2.0) š¤MatyÔŔ VĆtek
11/10/2024, 4:00 PMDaniel Pitts
11/10/2024, 6:17 PMkson
for now). (Example code here)
2. Type safe Json wrapper with JsonSchema generation and validation. (Example code here). This feature was heavily inspired by Exposed DAO.
I will add examples of the DSLs in š§µ too.
Please let me know any thoughts or suggestions.christophsturm
11/18/2024, 11:36 AMval TOTAL_TRIES = 3
val triedPorts = ArrayList<Int>(TOTAL_TRIES)
while (true) {
val realPort = port ?: findFreePort()
triedPorts.add(realPort)
val undertow: Undertow = buildUndertow(rootHandlers, defaultHandler, realPort, host)
try {
undertow.start()
} catch (e: RuntimeException) {
// it seems that undertow sometimes wraps the bind exception in a runtime exception
if (e.cause is BindException) {
if (port != null)
throw RestaurantException("could not start server on port $port")
if (triedPorts.size == TOTAL_TRIES)
throw RestaurantException("could not start restaurant after trying $TOTAL_TRIES times." +
" ports tried: $triedPorts")
continue
}
} catch (e: BindException) {
// if no port was specified, we retry
if (port != null)
throw RestaurantException("could not start server on port $port")
if (triedPorts.size == TOTAL_TRIES)
throw RestaurantException("could not start restaurant after trying $TOTAL_TRIES times." +
" ports tried: $triedPorts")
continue
}
all strategies that i tried just made it more confusing imo.arve
11/26/2024, 1:30 PMList<T:Any?>
or a T:Any?
, with slightly different implementations. The goal is for the caller not to have to care whether the param is a value or collection of values (SQL interpolation stuff)
Whatās a good way to allow these to have the same name?
currently I have
inline fun <reified T : Any> Statement.helperList(param: Collection<T>?, stmt: (Param<*>) -> Statement) = TODO("thing that has to know T")
inline fun <reified T : Any> Statement.helper(param: T?, stmt: (Params<*>) -> Statement) = TODO("Same thing but handled a differnt way since its not a collection"
Currently if I give them the same name, helper
will be called even if the argument is a collection, because it also matches Any
. Is there a way to constrain T so that itās āNot collectionā somehow?Ellen Spertus
12/01/2024, 3:03 AM// version 1
println(comment.body)
println()
// version 2
println("${comment.body}\n")
// version 3
println(comment.body + "\n")
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?