https://kotlinlang.org logo
Join SlackCommunities
Powered by
# language-evolution
  • g

    Gat Tag

    11/18/2024, 6:05 PM
    I might've misunderstood or misread, but I thought context receivers were getting dropped in 2.1.* . Is that still the case? Or is it now 2.3? (I see an issue targeting 2.3 for the feature's removal) And if so, does that mean we still won't see an experimental version of context parameters until after receivers removal?
    😓 1
    a
    d
    • 3
    • 2
  • a

    Alejandro Serrano.Mena

    11/20/2024, 11:11 AM
    New KEEP in the repo, about improvements for use-site targets at annotations: change the defaulting rule, and add a new
    all
    meta-target The discussion takes place in https://github.com/Kotlin/KEEP/issues/402, any feedback is more than welcome 🙂
  • y

    Youssef Shoaib [MOD]

    12/06/2024, 7:24 PM
    Were there any further discussion on decorators for Kotlin? My understanding is that contexts were prioritized since they were deemed a pre-requisite for it.
    plus1 1
    m
    • 2
    • 3
  • d

    Daniel Pitts

    12/14/2024, 2:44 AM
    Are Context Parameters going to solve the "I want to create an extension that requires multiple receivers?" Example in 🧵
    y
    • 2
    • 5
  • e

    Edgar Avuzi

    12/24/2024, 2:49 AM
    This Scala solution of adventofcode.com/2024/day/4 makes me want to have
    for comprehension
    in Kotlin
    e
    c
    • 3
    • 12
  • f

    Fudge

    01/02/2025, 10:16 AM
    Is there a discussion/KEEP for Kotlin const parameters / const methods? i.e. promising a method does not mutate parameters/the object?
    j
    m
    • 3
    • 3
  • e

    eygraber

    01/02/2025, 7:15 PM
    Are there any plans to provide a Kotlin approach to Vector/SIMD once Valhalla Panama is released/finalized/stabilized?
    e
    m
    • 3
    • 12
  • j

    JP Sugarbroad

    01/02/2025, 9:29 PM
    Currently
    const
    is limited to strings & numbers, but Java 11+ supports dynamic constants. Any thoughts on whether it's worth adding them?
    e
    • 2
    • 11
  • d

    Daniel Pitts

    01/11/2025, 1:08 AM
    Is there a status update on Context Receivers/Context Parameters in the 2.1.20-beta?
    K 5
    a
    • 2
    • 1
  • e

    Edoardo Luppi

    01/16/2025, 10:08 PM
    What's the status for https://youtrack.jetbrains.com/issue/KT-11968? Is there any hope we'll see a preview in 2025?
    m
    • 2
    • 2
  • e

    Exerosis

    01/23/2025, 8:54 AM
    Has anyone considered the idea of using the context rewrite as an excuse to enable kotlin as an algebraic effects language. it's ig a bit too late in the sense that it has invisible throws and suspend is a keyword but you could just make the use of those warnings.
    y
    • 2
    • 9
  • c

    CLOVIS

    02/03/2025, 7:03 PM
    I'm building a library that has a very large DSL. Operators in this DSL are usually binary and their operands must respect some type criteria. For example:
    Copy code
    interface Value<T>
    
    infix fun <T> Value<T>.eq(other: Value<T>): Value<Boolean>
    So far, this is quite simple and well-solved by Kotlin. However, there are types which can be seen as
    Value<T>
    which don't implement the interface, because I don't own them. In this particular case, there are 4: • instances of the interface
    Value<T>
    , for example as returned by other operators • instances of
    T
    (the regular Kotlin type) • instances of
    KProperty1<*, T>
    • instances of
    Field<T>
    (another type, describing what it is is not relevant to this discussion) Solution 1. Overloads Therefore, to typesafely accept all of these values, I would have to declare all operators 8 times (since they accept two operands which can each have 4 different types). Since there are more than 30–40 operators, that would result in a lot of declared extension functions, which is probably not great for compilation performance.
    Copy code
    someValue eq true
    Solution 2. Conversion method An alternative solution that is currently possible is to have the user call a conversion method to convert non-
    Value<T>
    types. For example, it could be called
    of
    .
    Copy code
    someValue eq of(true)
    This is, by far, the simplest solution at the moment. However, it implies a burden on the user, and calling
    of
    everywhere can make usage quite verbose:
    Copy code
    of(User::score) set cond { of(User::role) eq of(User::candidate) }
        .then { of(1) }
        .else { of(User::score) add of(1) }
    I think you'll agree that this is quite a bit harder to read than
    Copy code
    User::score set cond { User::role eq User::candidate }
        .then { 1 }
        .else { User::score add 1 }
    Because it burdens the user, I don't think this solution is what library authors should use at the moment. However, it can be a part of a larger solution. For example, having these conversion functions makes the overload solution trivial to implement, as all overloads just delegate to the main one. Proposed solution 3. Proper union types Based on the way the problem is described, the operand types could be declared as
    Copy code
    union Operand<T> = Value<T> | T | KProperty1<*, T> | Field<T>
    There already exists a lot of discussion on union types, so I won't detail this solution further. Proposed solution 4. Fake union types This idea is similar to union types for callers, but it doesn't require union types to exist at runtime. The idea is to coalesce all cases into a single regular type through a conversion function, and Kotlin compiler just has to call the provided conversion functions. In this example, the canonical type is
    Value<T>
    , so we could imagine a new operator that converts from other type.
    Copy code
    interface Value<T> {
        // …
    
        operator fun from(other: T) = …
        operator fun from(other: KProperty1<*, T>) = …
        operator fun from(other: Field<T>) = …
    }
    In a way, this is very similar to C++'s implicit conversion methods, but declared in reverse: instead of a type describing what it can be converted into, a type described what it can be converted from. I believe this is much safer and less surprising, but it may still be much too surprising. This could also be very badly abused if the conversion methods aren't pure (in an FP sense). Proposed solution 5. Typeclasses I know that other languages have used typeclasses to solve this issue. To be honest, I'm not fully familiar with how they work, other than "typeclasses are interfaces that you can implement remotely". Since typeclasses have been proposed to Kotlin in the past without success, I assume situations similar as this were already discussed and this message won't bring them back on the table. Also, I have heard multiple people mention context parameters could help emulate them, so maybe there is an additional context parameter solution here? But I'm not seeing it. That's about all the options I thought of. Are there other existing ways to solve this use-case? If not, are there other potential solutions being discussed? I'm curious how this could move forward.
    y
    r
    a
    • 4
    • 15
  • y

    Youssef Shoaib [MOD]

    02/05/2025, 5:38 PM
    Is there a proposal yet to incorporate shapes and materials into Kotlin? I know it was mentioned in the last KotlinConf. I keep daydreaming about it whenever I get a
    Comparable<*>
    as an inferred type.
    a
    • 2
    • 1
  • f

    Fudge

    02/14/2025, 10:19 AM
    Hey why is Jetbrains allowed to have inline constructors but I'm not? 😄
    a
    • 2
    • 2
  • y

    Youssef Shoaib [MOD]

    03/14/2025, 2:33 AM
    Something like Scala's Capture Checking would be really interesting for resource management in Kotlin (Especially for DSLs with receivers that are meant to not escape e.g.
    SelectBuilder
    ,
    Raise
    ). Scala's presentation of it is quite technical, so I wonder if it could be simplified to be more developer-friendly. I'm also writing an effects library where that would come in handy to prevent effects escaping their scope.
    j
    • 2
    • 2
  • y

    Youssef Shoaib [MOD]

    03/16/2025, 12:23 AM
    I recall there being some proposal or presentation or something about "extending" builder inference to work more generally for cases like:
    Copy code
    var x = null
    x = 5
    So that x gets inferred as
    Int?
    . I think this was meant to work like builder inference by having a postponed type variable for the type of x, so that the type variable can be inferred as such.I believe this is very similar to OCaml's weak polymorphic types. Anyone remember where that idea was presented/proposed?
    s
    • 2
    • 4
  • y

    Youssef Shoaib [MOD]

    03/19/2025, 10:33 AM
    The context parameters KEEP (which btw, in hindsight, is good naming since it's in-line with other languages, and it highlights that they really do act like parameters) explicitly doesn't support delegates with contexts right now. Has there been any thought about them anyway? I really disliked the semantics in CR because the contexts on
    getValue
    and
    setValue
    were practically useless (since they're the same ones you can capture in
    provideDelegate
    ). Is there a world where `getValue`'s contexts correspond to `get`'s contexts, and analogously for
    set
    ?
  • a

    alexhelder

    03/21/2025, 12:09 AM
    Kotlin has class and property delegation. I wonder if it makes sense to also have function delegation. For example, imagine a Facade that for some functions, simply delegates it’s exposed public function to something else:
    Copy code
    class Facade(
       private val delegate:Delegate
    ) {
        fun aaa(a,b,c,d) by delegate::bbb
    }
    
    class Delegate {
       fun bbb(a,b,c,d) { ... }
    }
    If the number of arguments or functions increases, doing it manually like
    fun aaa(a,b,c,d,e,f) = delegate.bbb(a,b,c,d,e,f)
    becomes tedious. This seems useful if a class needs to delegate to another class, only a subset of some interface, or does not want to implement the whole interface via class delegation.
    ➕ 4
    c
    p
    • 3
    • 3
  • c

    CLOVIS

    03/21/2025, 8:24 PM
    Has there been any talks about moving KEEP discussions from GitHub Issues to GitHub Discussions? Threading would help a lot with reading through KEEPs with a long history, and would make it easier to link people to already-addressed points.
    ➕ 12
  • d

    Daniel Pitts

    03/30/2025, 3:35 AM
    I remember asking a few years ago about variadic generics. There is KT-31427 - Support variadic generics, but it doesn't look like much has been done with it, and I can't find a keep. What kind of threshold in interest or use-cases would change that?
  • a

    ansman

    04/01/2025, 4:13 PM
    Maybe not the best channel for this but it seems that Kotlin 2.1.20 changed something wrt to context receivers compared to 2.1.10. We have some lambdas that accept two context receivers, and one extension receiver. It looks like this:
    Copy code
    title: context(Component.Slot<Text>, Component.Slot<Icon>) RowScope.() -> Unit
    
    fun Component.Slot<Text>.Text(...) {}
    In Kotlin 2.1.10 this worked fine:
    Copy code
    title = {
      Title()
    }
    But in 2.1.20 this is an error with:
    Copy code
    cannot be called in this context with an implicit receiver. Use an explicit receiver if necessary.
    The issue is that you don't seem to be able to actually add a context receiver as there doesn't seem to be a way to access the context receiver.
    c
    a
    +2
    • 5
    • 30
  • r

    Raymond

    04/04/2025, 12:31 AM
    Hi everyone! 👋 I'm wondering if there's any ongoing proposal or discussion around introducing a
    readonly
    -like keyword for class properties in Kotlin. For example, something like this:
    Copy code
    class ComponentDTO(
        val primaryText: String,
        val secondaryText: String? = null,
        readonly val category: Category = Category.Informative,
        readonly val drop: Drop = Drop.Down
    )
    Which would internally be equivalent to:
    Copy code
    class ComponentDTO(
        val primaryText: String,
        val secondaryText: String? = null,
    ) {
        val category: Category = Category.Informative
        val drop: Drop = Drop.Down
    }
    I think this could be particularly useful, especially if it can be implemented without breaking binary compatibility when removing the
    readonly
    keyword. Would love to hear your thoughts or if there's something similar already being considered!
    c
    a
    j
    • 4
    • 17
  • s

    Stephan Schröder

    04/04/2025, 1:27 PM
    tailrec
    is probably one of least used Kotlin features, and this is me wondering if it couldn't be improved with some additional syntactic sugar (not that it'd improve its usage much). TLDR: can we make the accumulator parameter invisible from the outside!? So let's start with a
    factorial
    -function using tail recursion:
    Copy code
    tailrec fun factorial(n: Int, f:Long): Long {
        if(n<2) return f
        return factorial(n-1, n*f)
    }
    my problem is the second parameter, the accumulator. For
    factorial
    is only valid parameter for it is
    1
    . But I don't want to hardcode
    1
    at every invocation and/or even give a programmer a chance to provide the wrong value. So let's use an optional parameter:
    Copy code
    tailrec fun factorial(n: Int, f:Long = 1): Long {
        if(n<2) return f
        return factorial(n-1, n*f)
    }
    at least now I don't have to provide the initial value anymore, i can write
    val x = factorial(6)
    , but unfortuanately I can still provide a wrong parameter. An IDE will still suggest, that I provide one. So if I want to avoid that, I have to wrap my tailrec-fun inside a normal function.
    Copy code
    fun factorial(n: Int): Long {
        tailrec fun _factorial(n: Int, f:Long): Long {
            if(n<2) return f
            return _factorial(n-1, n*f)
        }
        return _factorial(n, 1)
    }
    now the using
    factorial
    is completely safe, but there is boilerplatecode involved and invocation overhead. So how about Kotlin gains a new keyword (let's call it)
    acc
    (for accumulator) where you have to provide an initialisation value and you can't set the parameter from outside the function itself!
    Copy code
    tailrec fun factorial(n: Int, acc f:Long = 1): Long {
        if(n<2) return f
        return factorial(n-1, n*f)
    }
    now we're back to boilercode-free code that can only be invoked savely from the outside with one parameter. Alternative to naming it
    acc
    : a new keyword maybe to much to ask for, so how about using
    private
    . A private parameter (of a non-private function) has to have a default value which can only be supplied from within a private invocation context, so recursion would work 🤷‍♂️
    Copy code
    tailrec fun factorial(n: Int, private f:Long = 1): Long {
        if(n<2) return f
        return factorial(n-1, n*f)
    }
    question 1: if
    private
    parameters are allowed, what about
    internal
    parameters? question 2: Independently which name is used for the keyword, a remaining question is if this keyword should only be usabe within tailrec functions 🤔 (My initial thoughts are that I'd prefer
    acc
    over
    private
    if it's only allowed in tailrec fuctions)
    s
    y
    • 3
    • 4
  • k

    Klitos Kyriacou

    04/08/2025, 4:27 PM
    We have the operators
    <
    ,
    <=
    >=
    and
    >
    which all call
    compareTo
    but they all check for inequalities. Would there be any interest in a special operator,
    <==>
    , with the semantics that
    a <==> b
    is equivalent to
    a.compareTo(b) == 0
    ? Let's call it the "extended spaceship operator" since the normal spaceship operator
    <=>
    is already well-known in other languages and has different semantics (it returns an integer). The use case is when comparing
    BigDecimals
    for value equality (where
    a == b
    is not what is wanted because it includes scale).
    s
    • 2
    • 1
  • a

    ansman

    04/21/2025, 11:59 PM
    With context parameters, how would one access a parameter if there are multiple parameters of the same type in a lambda?
    Copy code
    fun foo(content: context(String, String) () -> Unit) {
        content("", "")
    }
    
    fun test() {
        foo {
            // Does not work: Multiple potential context arguments for 'String' in scope.
            implicit<String>()
        }
    }
    y
    a
    • 3
    • 9
  • d

    Daniel Pitts

    04/27/2025, 6:50 PM
    Is there any discussion around "import on demand" from objects? Constants.kt:
    Copy code
    package foo.bar
    
    data object Constants {
        val first = 1
        val second = 2
    }
    Main.kt
    Copy code
    import foo.bar.Constants.*
    
    fun main() {
       println("$first is first. $second is second.")
    }
    y
    • 2
    • 2
  • k

    Kelvin Chung

    04/29/2025, 7:31 PM
    Question: are there any plans to make it so that you can have something that is abstract but can have a subclass with value class semantics? Something like an "integers mod n" class, for example.
    e
    c
    • 3
    • 2
  • a

    Arjan van Wieringen

    05/07/2025, 5:28 PM
    Is it a valid statement to say that with context parameters you can actually recreate the suspend keyword? I mean, the suspend keyword provides a Continuation, but with context parameters you can provide a Continuation context.
    j
    d
    • 3
    • 3
  • j

    JP Sugarbroad

    05/07/2025, 6:14 PM
    TIL about Swift
    async let
    and I really want it: https://blog.yoshuawuyts.com/automatic-interleaving-of-high-level-concurrent-operations/
    s
    r
    +2
    • 5
    • 18
  • p

    phldavies

    05/12/2025, 10:26 AM
    With
    context-parameters
    (2.2.0-Beta2) is it expected to be ambiguous in the call to
    helloContext
    when nested inside two applicable scopes? I would have expected it to resolve the same way as the receiver case (that is, with the closest applicable candidate taking priority, given you can disambiguate to the outer scope explicitly with a
    with(this@outer)
    or
    context(this@outer)
    ) (snippet in thread - slack went weird and thought it was a binary)
    Untitled
    • 1
    • 1