https://kotlinlang.org logo
Join SlackCommunities
Powered by
# codingconventions
  • m

    Michal Klimczak

    09/07/2023, 10:11 AM
    I got no answers on the compose channel, figured that maybe here I will have more luck and it seems to fit the theme. https://kotlinlang.slack.com/archives/CJLTWPH7S/p1693389803639179
    p
    • 2
    • 2
  • e

    echo

    09/08/2023, 7:47 AM
    Which do you prefer? When you use JPA in a Web MVC Spring framework application, what do you do when defining the
    @ID
    of an entity class? And
    @Id
    property is generated by database autoincrement. In this question, pk is not-null in the database, and there is discussion within the team about what value should be set as default before Entity persisted, so we are also asking the community's opinion. In this case, I dont discuss about using constructor each time when create instance.
    Copy code
    1. nullable - var
    @Entity
    class Entity(
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      var id: Long? = null
    )
    
    2. nullable - val
    @Entity
    class Entity(
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      val id: Long? = null
    )
    
    3. non-null - var
    @Entity
    class Entity(
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      var id: Long = 0L
    )
    
    4. non-null - val
    @Entity
    class Entity(
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      val id: Long = 0L
    )
    Please share your voice and opinion free!
    1️⃣ 1
    2️⃣ 2
    3️⃣ 1
    4️⃣ 10
    l
    • 2
    • 1
  • a

    Asaf Peleg

    09/22/2023, 2:28 AM
    I'm using this class for Kafka deserialization and I'd like to wrap/extend it in some clean way so that result implements
    Deserializer<GenericRecord>
    instead of
    Any
    What approaches can I use for that?
    p
    • 2
    • 2
  • e

    elect

    10/17/2023, 4:22 PM
    I have this code snippet
    Copy code
    .forEach {
        val (k, v) = it.split(':')
        meta[k.trim()] = v.trim()
    }
    I though I could make it more concise with
    associateTo
    , but I still need two lines
    Copy code
    .associateTo(meta) {
        val (k, v) = it.split(':')
        k.trim() to v.trim()
    }
    unless I'm missing something, I'd revert to the first version
    e
    k
    +2
    • 5
    • 9
  • d

    David Kubecka

    12/01/2023, 3:00 PM
    What's your opinion on using function/method references instead of lambdas for scope or library functions? Most of the code I've seen uses lambdas, e.g.
    Copy code
    myList.map { transform(it) }
    myString.takeIf { it.isNotEmpty() }
    As an alternative, however, one could also use function/method references, e.g.
    Copy code
    myList.map(::transform)
    myString.takeIf(String::isNotEmpty)
    Which convention do you prefer and why?
    2️⃣ 3
    l
    s
    +5
    • 8
    • 24
  • c

    christophsturm

    12/12/2023, 8:18 AM
    I have this class and a reified helper method:
    Copy code
    package util
    class JsonFetcher() {
    ...
        suspend fun <T> get(url: String, cls: TypeReference<T>): T {
            return mapper.readValue(diskCacheHttpClient.get(url), cls)
        }
    }
    suspend inline fun <reified T> JsonFetcher.get(content: String): T = get(content, jacksonTypeRef<T>())
    but when I import the helper method I have to
    import util.get
    so its unclear that its the get method of JsonFetcher. is there a way to improve this?
    e
    • 2
    • 2
  • g

    Garret Yoder

    01/24/2024, 7:18 PM
    If I have a generic function, is there a better way to type-bound it with unrelated types other than checking the instance of T to each possible bound? This is unrelated types like "could be an int, string, boolean, long, etc"
    j
    s
    • 3
    • 12
  • t

    Tom Truyen

    01/29/2024, 12:34 PM
    When using interfaces and implementations in Kotlin what is considered best practice?
    interface UserRepository
    and
    class UserRepositoryImpl: UserRepository
    or
    interface IUserRepository
    and
    class UserRepository: IUserRepository
    Or are there any alternative practices?
    👀 1
    s
    k
    +3
    • 6
    • 6
  • e

    Eugen Martynov

    02/05/2024, 10:13 AM
    So no other way how to ensure new line at the end of file except .editorconfig file?
    l
    j
    +2
    • 5
    • 10
  • e

    Eugen Martynov

    02/05/2024, 10:14 AM
    Do you prefer to use .editorconfig or codeStyle folder in git to have seamless shared formatting in the team?
  • g

    Garret Yoder

    02/20/2024, 3:26 PM
    I really wish there was a way to assure the compiler that this var will not be changed outside of this scope that way you didn't have to do !! for every call. Like it's a locally scoped var, its not going to get touched by another thread. to be clear - I 100% understand why an if statement vs a ?.let causes no smart cast vs a smart cast, I just wish there was a way you could do !! for an entire scope or something similar. Sure in this specific context of ksoup you could use a for loop and a safe called let, but it's just an example and I need to refer back to the last element for some processing so I can't do a for or a map. Or maybe some sort of loop where you do a snapshot inside. I guess I could write a scope function that does that, but all that does is move the silly while chained let somewhere else haha
    s
    r
    k
    • 4
    • 6
  • h

    Hildebrandt Tobias

    03/06/2024, 12:23 PM
    Hey, a small question about variable naming. I have many
    Endpoints
    in my Multiplatform Project so that both js and jvm are always on the same page. For readability I have a singleton that just holds all the references to the actual
    Endpoints
    . Is there a more idiomatic way in general to do this or is this fine? Endpoints.kt
    Copy code
    object Endpoints {
        // Keycloak
        val keyCloakNewToken = _keyCloakNewToken
        val keyCloakRefreshToken = _keyCloakRefreshToken
        val keyCloakUsers = _keyCloakUsers
    
        // Server
        val devices = _devices
        val changeDevice = _changeDevice
    }
    KeyCloakEndpoints.kt
    Copy code
    val _keyCloakUsers = Endpoint(
        url = "/admin/realms/<realm>/users",
        method = EndpointMethod.GET,
        serializer = ArraySerializer(KeycloakUser.serializer())
    )
    
    val _keyCloakRefreshToken = Endpoint(
        url = "/realms/<realm>/protocol/openid-connect/token",
        method = <http://EndpointMethod.POST|EndpointMethod.POST>,
        serializer = AuthJwt.serializer(),
        header = mapOf(
            "Content-Type" to "application/x-www-form-urlencoded"
        ),
        requiredUrlEncodedBody = mapOf(
            "grant_type" to "refresh_token",
            "client_id" to "frontend",
            "refresh_token" to ""
        )
    )
    I read that only private Backingfields should start with an underscore, but I can't make them private here of course.
    • 1
    • 1
  • g

    Garret Yoder

    03/06/2024, 8:09 PM
    Is there a reason that neither an abstract function or it's eventual override implementation can supply default argument values?
    s
    k
    • 3
    • 5
  • h

    Hildebrandt Tobias

    03/27/2024, 10:40 AM
    Hey, currently I just give my Endpoint (think ktor and similar) a repository object. Now I want to put something in between because most calls need to do more than just save to repo, like auditing, sending MQTT, etc. What would you call that? Handler is a bit generic I feel.
    d
    r
    • 3
    • 3
  • c

    Czerwinskimarek88

    04/17/2024, 8:52 PM
    Hey, which option do you think is better, or maybe you have another idea? a) Option A
    Copy code
    class DoSomethingUseCase {
    
        fun handle(command: DoSomethingCommand) {
            TODO("not yet implemented")
        }
    }
    
    data class DoSomethingCommand(
        val someValue: String
    )
    b) Option B
    Copy code
    class DoSomethingUseCase {
    
        fun handle(command: Command) {
            TODO("not yet implemented")
        }
    
        data class Command(
            val someValue: String
        )
    }
    🅰️ 2
    c
    j
    • 3
    • 2
  • z

    Zyle Moore

    05/06/2024, 12:21 AM
    Is there a standard idiom for making a range of a single value?
    Copy code
    inline fun Char.toRange(): CharRange =
        this..this
    
    @Test
    fun `toRange creates a range with a single value`() {
        val range = 'Z'.toRange()
        assertEquals('Z', range.first)
        assertEquals('Z', range.last)
    }
    ✅ 1
    s
    k
    • 3
    • 8
  • z

    Zyle Moore

    05/09/2024, 12:32 AM
    Is there a convention for getting all indices of a value in an array? I came up with this for ByteArrays, but wanted to make sure I wasn't missing a library method by an unfamiliar name
    Copy code
    inline fun ByteArray.indicesOf(value: Byte): List<Int> =
        mapIndexed { index, byte -> index.takeIf { byte == value } }.filterNotNull()
    e
    y
    k
    • 4
    • 12
  • d

    diego-gomez-olvera

    05/13/2024, 11:48 AM
    I see that in the Google Style Guide it's recommended to use only lowercase for packages definition, is it also the case for module names, or is it fine to use camel case? I couldn't find a rule for #detekt about it, but with
    PackageNaming
    and
    InvalidPackageDeclaration
    , it seems that implicitly the convention is the same, just use lowercase
    e
    • 2
    • 4
  • j

    Jørund Amsen

    05/14/2024, 2:19 PM
    How do people handle wanting to add contextual information to an exception that is thrown? Say I have a function getUser() that can throw exceptions of various types for various (unknown) reasons. This function can be called multiple places, for example in getAdmins() and getCustomers() and I'd like to append contextual information in the callplace, to say what I was trying to do when the function failed
    Copy code
    fun getAdmins(adminId: String) {
        try {
            getUsers(adminId)
        } catch (e: Exception) {
            // "Failed fetching admin by $adminId"
        }
    }
    Now I could wrap the existing exception in a new custom exception MyUserException("Failed ...", e) However this means I cannot catch the underlying exception specifically, and in most logging tools shows my wrapper rather than the often usefull underlying Exception. I could rethrow the exception, with a log statement
    Copy code
    catch (e: Exception){
       log.error("Failed fetching admin...", e)
       throw e
    }
    However I dislike having multiple log entries from a single error, and puts the responsibility on me for "connecting the dots" of the different log statements.
    y
    j
    • 3
    • 6
  • g

    George

    06/10/2024, 4:39 PM
    How do you choose adding methods to dto/dao vs adding extension methods? My understanding is that everything should be an extension. But for some reason it feels like I am missing some good cases where it makes sense to add methods inside the dto/dao. Ps: I am not referring to complex business logic functions, these should reside elsewhere.
    c
    j
    • 3
    • 3
  • c

    Cies

    06/11/2024, 4:27 PM
    Do you prefer
    if (rank == null) return BadRequest("Rank is missing")
    or
    rank ?: return BadRequest("Rank is missing")
    ?
    k
    d
    r
    • 4
    • 3
  • t

    Thomas

    07/16/2024, 6:33 AM
    How would you choose between the following two styles, factory functions ("from" functions) and extension functions ("to" functions)?
    Copy code
    fun main() {
        val a = A(1)
        val b = B(2)
        
        println(b.toA()) //A(a=2)
        println(A.fromB(b)) //A(a=2)
    }
    
    data class B(val b: Int)
    data class A(val a: Int){
        //1. "static converter" function
        companion object{
            fun fromB(b: B): A = A(b.b)
        }
    }
    
    //2. extension function
    fun B.toA() = A(this.b)
    j
    r
    +2
    • 5
    • 7
  • e

    Ellen Spertus

    08/04/2024, 8:51 PM
    Please let me know which KDoc you prefer or if you have better suggestions. It would be easier to write if the width and height parameters were named
    width
    (instead of
    w
    ) and
    height
    (instead of
    h
    ), but those are instance variables in the superclass (
    JPanel
    ). I'm a professor creating a problem set, so there aren't team guidelines I can follow. I just want to set a good example. 1️⃣
    Copy code
    /**
         * Draws a rectangle with the specified [x] and [y] coordinates,
         * [outlineColor], and [fillColor]. The parameters [w] and [h]
         * specify the width and height.
         */
    2️⃣
    Copy code
    /**
     * Draws a rectangle with width [w] and height [h] with the specified 
     * [x] and [y] coordinates,[outlineColor], and [fillColor].
     */
    1️⃣ 1
    e
    c
    • 3
    • 22
  • e

    Eugen Martynov

    09/19/2024, 9:46 AM
    Is it correct formatting?
    Copy code
    is String
                    -> {
                    0
                }
    I would expect that closing bracket is on the level of arrow and body had indentation from arrow as well.
    s
    • 2
    • 2
  • i

    Ivan Cagle (IvanEOD)

    10/06/2024, 10:37 PM
    Copy code
    open class TestAbstract {
        
        init {
            onCreated()
        }
        
        open fun onCreated() {
            println("Applying base TestAbstract creation code on class '${this.javaClass.simpleName}'.")
        }
        
    }
    
    class Test1 : TestAbstract() {
        override fun onCreated() {
            super.onCreated()
            println("Applying Test1 specific creation code.")
        }
    }
    
    class Test2 : TestAbstract() {
        override fun onCreated() {
            super.onCreated()
            println("Applying Test2 specific creation code.")
        }
    }
    
    val test1 = Test1()
    val test2 = Test2()
    I know this is not encouraged, and the IDE shows a warning for calling
    onCreated()
    in the
    init
    block... although it seems to work on a simple class... i'm guessing on larger classes with more going on it could cause problems.... I'm curious though... if changing it to the following is just tricking the IDE to make the warning go away, or is it actually acceptable?
    Copy code
    open class TestAbstract {
        init {
            created()
        }
        private fun created() {
            onCreated()
        }
        open fun onCreated() {
            println("Applying base TestAbstract creation code on class '${this.javaClass.simpleName}'.")
        }
    }
    j
    • 2
    • 23
  • d

    David Breneisen

    10/07/2024, 5:35 PM
    This might be a useful convention: when creating a Composable that is only expected to function correctly in a certain scope such as BoxScope, we can make the Composable an extension function:
    fun BoxScope.MyComposable()
    even if the scope isn’t used, the constraint may be helpful
    i
    c
    • 3
    • 2
  • a

    AlexD

    11/13/2024, 6:57 PM
    Which do you prefer? 1️⃣
    Copy code
    if (isValidInput) {
        doSomething()
        doSomethingElse()
    } else {
        handleInputError()
    }
    2️⃣
    Copy code
    when {
        isValidInput -> {
            doSomething()
            doSomethingElse()
        }
        else -> handleInputError()
    }
    2️⃣ 2
    1️⃣ 11
    y
    p
    +7
    • 10
    • 14
  • z

    Zyle Moore

    12/25/2024, 7:33 PM
    Is there a convention for deciding string forms of multiplicity? For instance,
    0 Records
    ,
    1 Record
    ,
    2 Records
    Copy code
    val recordSummary = listOf(records.size, records.singleOrNull()?.let { "Record" } ?: "Records").joinToString(separator = " ")
    
    val recordSummary = listOf(records.size, if (records.size == 1) { "Record" } else { "Records" }).joinToString(separator = " ")
    e
    • 2
    • 2
  • g

    George Z

    12/31/2024, 5:59 PM
    Which one do you prefer? 1️⃣
    Copy code
    suspend fun <T : Any> handleApi(execute: suspend () -> T): Resource<T> {
        return try {
            val response = execute()
            Resource.Success(response)
        } catch (e: Exception) {
            Resource.Error(
                when (e) {
                    is IOException -> ErrorType.Network
                    is HttpException -> mapApiError(e.code())
                    is SerializationException -> ErrorType.Serialization
                    else -> ErrorType.Unknown
                }
            )
        }
    }
    2️⃣
    Copy code
    suspend fun <T : Any> handleApi(execute: suspend () -> T): Resource<T> {
        return try {
            val response = execute()
            Resource.Success(response)
        } catch (e: IOException) {
            Resource.Error(ErrorType.Network)
        } catch (e: HttpException) {
            Resource.Error(mapApiError(e.code()))
        } catch (e: SerializationException) {
            Resource.Error(ErrorType.Serialization)
        } catch (e: Exception) {
            Resource.Error(ErrorType.Unknown)
        }
    }
    2️⃣ 3
    1️⃣ 9
    l
    r
    • 3
    • 3
  • r

    Roeniss Moon

    02/11/2025, 5:46 AM
    Hi! I'm wondering if there's any source or reference for the Documentation comments convention:
    Copy code
    Generally, avoid using @param and @return tags
    But why? Those tags seems useful for converting comments info other formats in my view
    h
    • 2
    • 2