https://kotlinlang.org logo
Join SlackCommunities
Powered by
# language-proposals
  • a

    anlex N

    03/26/2024, 6:05 AM
    what benefits does
    emptyList<String>()
    have compared to
    listOf<String>()
    ?
    r
    j
    • 3
    • 2
  • v

    vach

    04/14/2024, 1:34 PM
    Hi everyone, i want to implement/contribute https://discuss.kotlinlang.org/t/kotlin-to-support-package-protected-visibility Would be great if someone familiar with the kotlinc could give me pointers where to start, what potential issues i need to be aware of and test for... any reading material that could help me kickstart working on the compiler would be awesome. The goal is very simple, i want to have package visibility just like in java, nothing more for now (in the topic there are couple of interesting suggestions for improving over what java did)... i undestand that proper process for this is KEEP but i want to test it out use it myself + get some idea how to work with the compiler.
    e
    g
    • 3
    • 4
  • g

    Gat Tag

    04/19/2024, 1:24 PM
    I find myself building an internal DSL for Kotlin that relies on the user creating a large number of extension properties (potentially for types which are parameterized). Over time the verbosity grows quite large and refactors more tedious. My thoughts on the language involve introducing a new block that supports specifying the extension type, declaring type parameters, and providing a scope for declaring properties and functions. All declarations inside the scope would be extensions of the specified type. I see this language construct as a syntactic sugar that would allow the following:
    Copy code
    interface MyThing<A: Any, B: MyRoot?> { }
     
    extension <A: Any, B: MyRoot?> (MyThing<A, B>){
        
        val thingA: A get() = TODO()
        
        val thingB: Optional<B & Any> get() = TODO()
        
        val otherThing: (A) -> String by TODO()
        
        fun <C: SomeType> doThing(): Pair<A, C> {
            return TODO()
        }
    }
    A reduction step would emit:
    Copy code
    interface MyThing<A: Any, B: MyRoot?> { }
        
    val <A: Any, B: MyRoot?> MyThing<A, B>.thingA: A get() = TODO()
        
    val <A: Any, B: MyRoot?> MyThing<A, B>.thingB: Optional<B & Any> get() = TODO()
    
    val <A: Any, B: MyRoot?> MyThing<A, B>.otherThing: (A) -> String by TODO()
    
    fun <A: Any, B: MyRoot?, C: SomeType> MyThing<A, B>.doThing(): Pair<A, C> {
        return TODO()
    }
    This syntax could also be used inside a class like declaration for member extension functions as well. I could also see more widely applicable usage when allowing something similar for the upcoming context receivers allowing a block for which all declarations require the specified contexts.
    ➕ 5
    l
    g
    • 3
    • 6
  • g

    groostav

    04/25/2024, 12:36 AM
    Can I have (/is there already) an annotation
    DontInferAny
    so that I can avoid a call to
    Collection.minus<T>(it: T)
    inferring
    T
    is
    Any
    ? I used to have this code
    Copy code
    data class SimpleDomainValueType(name: String);
    data class Customer(simples: List<SimpleDomainValueType>);
    
    fun businessLogic(cust: Customer){
      val specialSimples: List<SimpleDomainValueType> = doBusinessLogic()
    
      val result = specialSimples- cust.simples
    }
    Then I did a refactor
    Copy code
    data class SimpleDomainValueType(name: String);
    class SimpleDomainValueCollection {
      operator fun get(index: Int): SimpleDomainValueType = ...
      val size: Int get() = ...
    }
    data class Customer(simples: SimpleDomainValueCollection);
    And I spent 30 minutes tracking down that the line
    val result = specialSauceItems - cust.simples
    still compiles, because
    minus
    is effectively becoming
    Copy code
    val result = specialSimples.minusElement<Any>(cust.simples)
    which is definitely not what I want. I suspect its not what the overwhelming majority of people want. I would think we could tell kotlin something like:
    Copy code
    public operator fun <@DontInferAny T> Iterable<T>.minus(elements: Iterable<T>): List<T>
    to tell kotlin that
    Any
    is not an acceptable resolution for
    T
    here. --- this would blow up a lot of existing code, especially people using raw-typed lists or similar 🙃 but it makes my life easier and thats all that matters so i want it.
    j
    y
    +4
    • 7
    • 14
  • p

    PHondogo

    04/25/2024, 1:48 PM
    While developing library in DSL style some thoughts came: what if there was possibility to constraint methods with how much they can be invoked and with constraints on reference copying. It can help finding mistakes of library usage at compile time. For example, consider builder pattern:
    Copy code
    // interfaces declaration
    
    @NotReferencable
    interface SomeBuilder {
       
       @AtLeastOnce
       fun author(name: String)
    
       fun comment(text: String)
    
       @ExactlyOnce
       fun body(lambda: SomeScope.()->Unit)
    }
    
    fun build(lambda: SomeBuilder.()->Unit)   
    
    
    // usage
    
    var builder: SomeBuilder? = null
    
    build {
       
       builder = this // ERROR cause SomeBuilder is constrained with @NotReferencable 	
      	
    
       author(name = "Test name 1") // OK (if comment this line and line after than it is error at compile time, cause fun author must be called at least once)
       author(name = "Test name 2") // OK
    
       comment(text = "Comment 1") // OK (if comment this line and line after it still will be OK, cause there are no constraints for this function)
       comment(text = "Comment 2") // OK
       
       body {} // OK
       body {} // ERROR cause exactly once constraint specified, if comment both lines that it will be an error cause of the same reason 
    }
    👍 2
    👍🏻 1
    y
    m
    h
    • 4
    • 6
  • d

    Derek Peirce

    04/28/2024, 12:49 AM
    In addition to the standard
    +
    operator, should there be a way to implement a more efficient multi-plus method? Such as
    operator fun <E> Set<E>.plusAll(vararg others: Iterable<E>): Set<E>
    ? Currently,
    setA + setB + setC
    will first create an intermediate
    setAB
    set, so one must use something like:
    Copy code
    buildSet {
        addAll(setA)
        addAll(setB)
        addAll(setC)
    }
    to avoid the inefficiency, which is a fair bit more code to achieve the same result.
  • j

    jNayden

    05/13/2024, 4:42 PM
    Is there a reason the spread operator to not work for lists ? But only for arrays ?
    j
    • 2
    • 2
  • j

    joseph_ivie

    06/11/2024, 4:33 PM
    No idea what this should really be named; I'll take suggestions. For now I'm calling it "Monad Flattening". When using RxJava, I find that my team really struggles with thinking in terms of
    Observable.map {}
    and
    Observable.combine()
    , and I don't blame them. It's not particularly easy to read. Similar APIs and problems exist with Android's
    LiveData
    , Kotlin's own
    Flow
    , and several other similar libraries. I wonder if we can make operating on these types read similarly or identical to simpler code, much like suspension makes writing async code look like sync code. So here's the proposal, roughly:
    Copy code
    @MonadFlattening
    interface Observable<T> {
        fun <OUT> map(transformer: (T)->OUT): Observable<OUT>
        fun <OUT> flatMap(transformer: (T)->Observable<OUT>): Observable<OUT>
        
        // For optimization purposes, not strictly speaking necessary
        fun <B, OUT> combine(other: Observable<B>, transformer: (T, B)->OUT): Observable<OUT>
    }
    
    fun sample(x: Observable<Int>, y: Observable<Int>) {
        // using & as a postfix operator to indicate the start of flattening.  Don't think that's the right symbol, but we'll work with it for now
        val onePlusX: Observable<Int> = 1 + x&
        // reduces to
        val onePlusX: Observable<Int> = x.map { 1 + it }
        
        val xPlusY: Observable<Int> = x& + y&
        // reduces to
        val xPlusY: Observable<Int> = x.combine(y) { x1, y1 -> x1 + y1 }
        
        val xAsString: Observable<String> = x&.toString()
        // reduces to
        val xAsString: Observable<String> = x.map { it.toString() }
        
        val xSlashY: Observable<String> = "${x&} / ${y&}"
        // reduces to
        val xSlashY: Observable<String> = x.combine(y) { x1, y1 -> "$x1 / $y1" }
        
        data class Point(val x: Int, val y: Int)
        val point: Observable<Point> = Point(x&, y&)
        val angle: Observable<Double> = atan2(y&.toDouble(), x&.toDouble())
    }
    This enables a better potential syntax for UI and data:
    Copy code
    val counter = Observable.interval(1, TimeUnit.seconds)
    val view: TextView = TODO()
    view::setText bind "${counter&} seconds elapsed"
    Problem is that I think this is an incredibly large overhaul. It affects just about every expression in the language. I can see this enabling a lot of interesting ideas further down the line. I feel like there are some issues with the idea I'm not seeing yet, but this could be really useful.
    y
    m
    e
    • 4
    • 8
  • a

    Alejandro Serrano.Mena

    06/17/2024, 3:52 PM
    new KEEP about improving resolution using expected type -> https://github.com/Kotlin/KEEP/issues/379
    K 4
  • l

    louiscad

    06/25/2024, 10:58 PM
    Is that Swift 6 feature something that could be done in Kotlin, within K2? https://x.com/arkann1985/status/1805721280244486241?t=e2yRkR8qg11zw56McrNYwA&s=19
    e
    • 2
    • 1
  • d

    Daniel Pitts

    07/06/2024, 6:19 PM
    Is there a proposal to support "overloads by return type"? Something that would allow the following to compile:
    Copy code
    class A
    class B
    
    fun make():A = A()
    fun make():B = B()
    
    
    fun main() {
        val a:A = make()
        val b:B = make()
    }
    e
    • 2
    • 22
  • d

    Daniel Pitts

    07/10/2024, 6:39 PM
    Are
    Context Parameters
    available for use yet? I'm currently using
    Context Receivers
    for some things, and found a show-stopping compiler bug with them.
    🚫 2
    r
    • 2
    • 3
  • d

    dave08

    07/17/2024, 3:51 PM
    It would be nice if this would work (especially for DSLs...):
    Copy code
    val baz = "foo.bar"
    var foo: String
    var bar: String
    
    // for assigning the vars, not new vals...
    (foo, bar) = baz.split('.')
    ➕ 1
    e
    • 2
    • 3
  • h

    Hayden Jones

    08/07/2024, 11:39 AM
    Does Jetbrains have a plan for multithreading with regards to Kotlin/Native?
    s
    • 2
    • 3
  • o

    Oleg Yukhnevich

    08/12/2024, 4:05 PM
    Hey! During the migration of Dokka analysis to K2, several questions arose around KDoc links resolution. That's why there is a new KEEP (first of its kind) about KDoc! https://github.com/Kotlin/KEEP/issues/385
    K 3
  • a

    Alejandro Serrano.Mena

    09/12/2024, 10:00 AM
    New KEEP about exposing boxed inline value classes in the JVM. Feedback is more than welcome!
  • u

    utenma

    09/20/2024, 1:03 AM
    Coming from scala miss so much tuples when working on kotlin, has there been disscussions about it? Scala also added support for named tuples which are the lambdas (annonymous/structural) counterpart for data classes instead of named/nominal, so they can be used as structural data types, while still being plain tuples as tuple names are erased
    plus1 1
    a
    • 2
    • 2
  • d

    dmcg

    09/26/2024, 8:06 AM
    So, context parameters, nee receivers. I see that the compiler now says Experimental context receivers are deprecated and will be superseded by context parameters. Please don’t use context receivers. You can either pass parameters explicitly or use members with extensions. Passing parameters explicitly I understand, but what exactly is meant by use members with extensions? I would like if possible to maintain at least some of the structure that my existing context receivers gave in the interregnum during which neither context receivers nor context parameters will be supported
    a
    o
    r
    • 4
    • 5
  • c

    Cies

    10/07/2024, 3:25 PM
    I read the blog post about "how I can contribute to Kotlin's future". There's one thing that I'd really like to see changed in Kotlin: it's handling of platform types. My team has been bitten too many times by platform types. Probably everyone who needs interop with Java code/libraries has had this problem. Now I dont mind that platform types exist, but I do mind that they are "treated as nonnull while they are certainly nullable". This is the biggest cause for NPEs that we find. IMHO a copmiler flag (like "warningsAsErrors") would be a good solutions, e.g. "treatPlatformTypesAsNullable". But maybe a compiler plugin could also be useful. On top of that we obviously also want the IDEA to follow along and give the right type hints. I'm not sure where to put this idea, should i create a KEEP for it? Or does anyone know if a similar proposal exists?
    b
    r
    h
    • 4
    • 13
  • m

    Maria Sokolova

    11/07/2024, 11:46 AM
    Hi! Here is the new KEEP about introduction of Common Atomic and Atomic Array types in the Kotlin standard library. Feedback is very welcome 🙂
    ✅ 2
    👍 3
  • a

    Alejandro Serrano.Mena

    12/20/2024, 5:31 PM
    New KEEP about nested (non-capturing) type aliases. This KEEP presents a way to have type aliases which live inside another classifier. As usual, feedback is more than welcome 🙂
    K 3
    K 6
  • a

    Augusto Megener

    12/28/2024, 1:13 PM
    I had an idea for KEEP and I wanted to know if it is viable or if someone has already proposed something similar I would like to propose the creation of
    implement
    statements, they would serve as an alternative way to create extension members
    Copy code
    kt
    class Foo {
     val bar = "hi"
    }
    implement Foo {
     val baz get() = "$bar, kotlin!" // would work like val Foo .baz get() = "$bar, kotlin!" 
    }
    syntax sugar for interface implementation wrappers for existing classes, when used in classes from other libraries
    Copy code
    kt
    class ExternalClass {
     val foo= "hi"
    }
    
    interface MyInterface {
     fun getText(): String
    }
    
    implement ExternalClass : MyInterface {
     override fun getText() = foo
    }
    
    // internally creates a wrapper
    @JvmInline
    value class MyInterfaceExternalClass(val value: ExternalClass) : MyInterface {
     override fun getText() = value.foo
    }
    
    // when ExternalClass is used in contexts that require MyInterface, internally the wrapper will be used, but in practice, you can use it as if it were actually ExternalClass
    
    fun myFun(arg: MyInterface) {
     println(arg.getText())
    }
    
    val obj = ExternalClass()
    
    myFun(obj) // prints "hi"
    and for separating classes in multiple files, but uniting everything in a single class, when used in project classes
    Copy code
    // a.kt
    class Class {
     [...]
    }
    
    // b.kt
    implement Class {
     [...]
    }
    
    // c.kt
    implement Class : MyInterface {
     override fun getText() =randomValue
     [...]
    }
    in my opinion this would be viable and useful, what do you think?
    j
    • 2
    • 9
  • d

    Daniel Pitts

    01/11/2025, 9:26 PM
    Is there a status update on Context Receivers/Context Parameters in the 2.1.20-beta? Slack Conversation
    👍 1
  • r

    Roman Venediktov

    02/04/2025, 10:16 AM
    New KEEP-409 on Subtyping Reconstruction is open for review. This KEEP presents the Subtyping Reconstruction technique that introduces smart casts for generics. This feature might be known to you as GADT. Any feedback is welcome
    K 17
  • j

    Jesse Gottlieb

    02/04/2025, 8:12 PM
    Hey folks I had an idea for predicated scope functions. Wondering if anyone has proposed these before or if they are a good candidate for a KEEP. The idea is to add
    applyIf
    ,
    applyUnless
    ,
    alsoIf
    , and
    alsoUnless
    to the standard lib. I chose
    apply
    and
    also
    among the various scope functions because these functions simply return the receiver object, so the return type can still be known regardless of the predicate. As a server developer, I use
    applyIf
    on builder objects quite frequently and my company has added it to an internal shared kotlin library. I suspect many kotlin devs use some version of this already. An example would be:
    Copy code
    inline fun <T> T.applyIf(predicate: Boolean, f: T.() -> Unit) = apply {
      if (predicate) f()
    }
    
    val myPlanBuilder = MyPlan.newBuilder()
    
    myObjectBuilder.applyIf(isSunnyOutside) {
      addPlanLineItem(goGetIceCream)
    }
    h
    e
    • 3
    • 3
  • l

    Laxystem

    02/18/2025, 10:41 AM
    I've created a youtrack issue for suspend interfaces, an idea to fix Kotlin's code coloring using interfaces and functions that are compiled to have a suspending and a non-suspending variant, to avoid the ecosystem looking like Rust's, where the entire ecosystem is duplicated
  • s

    sandwwraith

    03/05/2025, 3:34 PM
    Hi! We have a new KEEP to share with you — https://github.com/Kotlin/KEEP/issues/412. It is about enhancing the functionality of the existing 'unused expression' static analysis in the Kotlin compiler. New diagnostic should be able to report complex expressions whose return values are meaningful (e.g., non-Unit) but are not used.
    😍 4
    🚀 3
    good idea 2
    K 6
  • b

    bobko

    03/21/2025, 3:24 PM
    Hello everyone! Happy to share a new KEEP-416 Collection literals. Collection literals is a syntactic construct that allows creating collection instances more concisely and effortlessly. As always, feedback is welcome!
    K 10
    🎉 6
    ❤️ 7
  • j

    Jaebaek Seo

    04/16/2025, 8:56 PM
    Hi! I am not sure this is a right place to advertise my post, but I just opened https://youtrack.jetbrains.com/issue/KT-76846 to take opinions about "data object implicitly capturing properties". If you take a look and add some comments, I would appreciate it!
  • d

    Derek Peirce

    04/27/2025, 6:02 AM
    Recently, I used the RxJava method
    Completable.doOnEvent
    , which takes a lambda `(Throwable?) -> Unit`:
    Copy code
    myCompletable.doOnEvent { doSomething() }
    However, this started throwing exceptions. As it is a Java method, Kotlin automatically regarded
    it
    as
    Throwable!
    and therefore
    Throwable
    , and as soon as the lambda was called with a null value, it did a null check and threw a NPE, even though it was verifying a value that went completely unused. As the only reason Kotlin automatically treats
    Throwable!
    as
    Throwable
    here is for convenience, could it recognize in this case that the parameter is entirely unused, and therefore not overeagerly perform a null check? The solution to avoid the exception is to specify
    { _: Throwable? -> doSomething() }
    , which I'd rather not need to specify, and I'd especially have preferred not to have to deal with the exception in the first place at all.
    k
    j
    • 3
    • 4