https://kotlinlang.org logo
Docs
Join the conversationJoin Slack
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by Linen
language-proposals
  • g

    gabrielfv

    08/11/2020, 10:23 PM
    I have modelled a scenario where I have a
    Controller<S>
    and a
    View<S>
    and I want this to work as a cyclic dependence where the controller depends on the view indirectly. For that I was thinking on defining a
    Provider
    that takes a concrete controller and creates an instance of view with that injected. Currently it looks like this:
    fun interface ViewProvider<C : Controller<S>, S : State> {
        fun get(controller: C): View<S>
    }
    It feels redundant that I have to locally specify
    S
    , since
    Controller<S>
    already does that job. For example:
    class AController : Controller<A>
    class Provider : ViewProvider<AController, A>
    S
    here can only be
    A
    , since
    Controller<S>
    is invariant in
    S
    , and here
    S
    is
    A
    . Specifying
    A
    looks somewhat redundant. Could the type parameter here be inferred so the client code becomes less redundant?
    ➕ 1
    d
    1 reply · 2 participants
  • n

    Nir

    08/19/2020, 4:48 PM
    I'm curious, if there has ever been a proposal for, or interest in, "named" destructuring Kotlin has your typical destructuring that's also seen in a number of other languages. it's positionally based:
    data class foo(val i: Int, val s: String)
    val (s, i) = foo(5, "hello")  // Reverse order you might expect, s is an int, i is a string
    One could imagine doing it by name of the field instead. Imagine we use =, to piggy back off of the analogy between positional and named arguments
    val (=s, =i) = foo(5, "hello")  // okay, now it matches by name instead, so we create a variable s that's a string, i that's an int
    It would require that there was a property with the name of the variable. if not, compiler error. behind the scenes it just gets translated to:
    val unusable = foo(5, "hello")
    val s = unusable.s
    val i = unusable.i
    Advantages would be that it would allow destructuring "safely", without worrying about getting the order right. It's a relatively minor/simple thing to implement, easy to understand at first glance, and has a similar benefit for correctness as named arguments over positional arguments.
    👍 2
    e
    e
    +2
    32 replies · 5 participants
  • f

    Fleshgrinder

    08/20/2020, 5:07 AM
    Do we already have a proposal for the spaceship operator?
    <=>
    would be nice together with a corresponding
    Ordering
    Enum.
    when (a <=> b) {
        Ordering.Less -> {}
        Ordering.Equal -> {}
        Ordering.Greater -> {}
    }
    g
    d
    +1
    20 replies · 4 participants
  • e

    edrd

    08/20/2020, 3:20 PM
    Proposal: externally-defined companion objects. Allow defining companion objects externally, similar to what Scala does (https://docs.scala-lang.org/overviews/scala-book/companion-objects.html). Same motivation from my previous (https://kotlinlang.slack.com/archives/C0B9K7EP2/p1597588637286600) proposal: • Allowing to add extension functions for Java types (solves most-voted YouTrack issue: https://youtrack.jetbrains.com/issue/KT-11968). • Improving consistency with the way non-companion extension functions work, as they don't require special declarations on the class being extended. Proposed syntax:
    package com.fasterxml.jackson.module.kotlin
    
    import com.fasterxml.jackson.databind.ObjectMapper
    
    companion object ObjectMapper.Kotlin {
        fun forKotlin(): ObjectMapper = ...
    }
    
    // Would then also work
    fun ObjectMapper.Kotlin.withAlphabeticallySortedProperties(): ObjectMapper = ...
    
    // Usage from another file
    import com.fasterxml.jackson.module.kotlin.ObjectMapper.Kotlin
    
    fun main() = ObjectMapper.forKotlin()
    This eliminates the need to add empty
    companion object
    declarations in classes solely for the purpose of allowing extension functions and allows defining extensions for Java types. The difference between internally and externally defined companion objects would be the ability to access private and protected members. For more information on use cases and problems of the current alternatives, see my previous proposal (linked above).
    g
    e
    44 replies · 3 participants
  • n

    Nir

    08/31/2020, 1:37 PM
    is there any consideration towards allowing break/continue inside lambdas, that are in
    inline
    functions with loops? Since
    return
    is allowed inside lambdas in that situation, it seems surprising that break/continue do not work. It also limits the language's ability slightly to "extend" the built in loops.
    👍 2
    e
    2 replies · 2 participants
  • j

    janvladimirmostert

    09/02/2020, 8:28 PM
    Proposal: allowing default values for infix functions making it possible to use infix notation almost like a "postfix" notation Use case, when building a DSL that requires "chaining words", like in SQL, the last "word" requires garbage input in order to compile
    class postgresql(function: postgresql.() -> Unit) {
    		
            ....
            
            infix fun postgresql.DESC(value: Unit): postgresql {
    			return this
    		}
    	}
    
    	fun main() {
    		postgresql {
    			SELECT (
    				ListingTable::section, ListingTable::id,
    				ListingImageTable::name, ListingImageTable::listingId
    			) FROM (
    				ListingTable::class
    			) LEFT JOIN (
    				ListingImageTable::class
    			) ON (
    				ListingTable::id == ListingImageTable::id
    			) WHERE (
    				true
    			) ORDER BY(ListingTable::modified) DESC Unit
    		}
    e
    r
    +2
    22 replies · 5 participants
  • n

    Nir

    09/06/2020, 2:47 AM
    Are there any proposals to improve ergonomics for updating nested members of immutable data classes? I've seen lens libraries can help a bit but they only go so far given the tools the language currently provides
    r
    3 replies · 2 participants
  • n

    natpryce

    09/10/2020, 12:22 PM
    Not sure what the best channel for this is, but it’s a compiler issue, so language-proposals seems the closest fit… In Java 11, the functions
    List.of(…)
    and
    List.copyOf(…)
    create immutable lists. The Kotlin equivalents,
    listOf(…)
    and
    anIterable.toList()
    actually create mutable lists but return the List interface that doesn’t allow mutation. In Kotlin, that’s not a problem — lists are processed by being transformed with map/flatMap/filter/etc. and so nothing holds on to a reference to mutable lists and aliasing errors do not occur. However… when you pass the Kotlin List across the Java interop boundary, Java sees it as a mutable java.util.List and, because the Kotlin list is actually mutable, Java can mutate a list through an interface that the Kotlin type system considers to be unmodifiable. Worse, the Kotlin code is now more error prone than the Java code, because the Java code would fail immediately if you tried to mutate the immutable list, but the Kotlin code allows that list to be mutated. Suggestions: • when the kotlin compiler is targeting JVM version 11 and above, translate Kotlin’s listOf and toList to the JDK List.of and List.copyOf functions. • on 1.8 and below, wrap Kolin Lists with Collections.unmodifiableList (or some equivalent in the Kotlin runtime) when being passed across the interop boundary.
    👍 3
    j
    i
    +3
    13 replies · 6 participants
  • e

    Eduardo Guerra

    09/11/2020, 1:47 PM
    Hello, everybody! I just arrived at this channel so it's possible that someone has already asked this question before. But, I was wondering if anyone else would like to have n-uples in return statements in kotlin(swift style) like this:
    func returnMultipleValues() -> (String, Int, Double) {
        return ("Swift Tuple", 12, 3.14)
    }
    PS. I know how to use lists hahaha, I just think that it would be a lot easier this way
    ➖ 1
    ➕ 14
    r
    h
    +4
    29 replies · 7 participants
  • n

    Nir

    09/16/2020, 7:08 PM
    Somewhat related to above, but has there ever been discussion of variadic generics in Kotlin? Even if it were done, say, only for inline functions, the same way that
    reified
    is. I think that would be super useful. That could allow simple tuples, and non-neutered implementations of things like zip, for example.
    h
    4 replies · 2 participants
  • e

    eduardog3000

    09/17/2020, 6:32 PM
    Proposal: class as a use-site annotation target for top level functions. Example syntax and very basic potential use case, using Spring Boot:
    @class:Controller
    @GetMapping("/test")
    fun singleFunController() = "viewname"
    At the moment all top level functions in a file compile to the same class, so any with a class annotation would have to compile to its own class, presumably with a name based on the function name,
    SingleFunControllerKt
    or something. Probably a little limited in use, but it would be neat.
    👍 1
    f
    1 reply · 2 participants
  • b

    blackstardlb

    09/21/2020, 1:43 PM
    Proposal: keyword to expose a val/var as an interface or a parent class. Having to write private backing properties requires a lot of boilerplate especially if you have many properties to expose.
    class Test1 {
        private val _subject: Subject<String> = BehaviorSubject.createDefault("Test")
        val subject: Observable<String> = _subject
        fun onEvent(event: String) = _subject.onNext(event)
    }
    
    class Test2 {
        val subject: Observable<String> = BehaviorSubject.createDefault("Test")
        fun onEvent(event: String) = (subject as BehaviorSubject<String>).onNext(event)
    }
    
    class Proposal {
        exposed:Observable<String> val subject: BehaviorSubject<String> = BehaviorSubject.createDefault("Test")
        protected exposed:Observable<String> val subject2: BehaviorSubject<String> = BehaviorSubject.createDefault("Test")
        fun onEvent(event: String) = subject.onNext(event)
    }
    
    fun main() {
        // should all be of type Observable<String>
        val test = Test().subject
        val test2 = Test2().subject
        val proposal = Proposal().subject
    }
    Test1 shows the private backing property method. Test2 shows using the val as the interface / parent class and casting everywhere with as. Proposal show an example syntax of how this could be made less verbose and more readable.
    j
    n
    3 replies · 3 participants
  • s

    Sebastian Brunner

    09/23/2020, 6:46 PM
    I don't know if this has been discussed before but I couldn't find it anywhere so... I'd really like to make comparisons and assignments a bit more idiomatic with the following changes: Comparisons: Similar to Python, numeric comparisons should be more mathematical. Like
    if (1 <= x <= 10) // do something
    This would greatly improve readability and would reduce bugs since it's easier to understand that x is within the boundaries of 1 and 10. Way better than the current equivalent:
    if (1 <= x && x <= 10)
    . The "&& x" is just boilerplate code here... Assignments: For assignments I'd like to have the possibility of assigning an assignment to another variable. E.g.
    myObject.apply { inputFee = outputFee = 1.0 }
    In this case both inputFee and outputFee would be set to 1.0 (or more like inputFee would be set to outputFee). This is useful for mapping code so it makes most sense for properties. I could also imagine like saving a property to a variable before it is modified in someway. Maybe like this:
    val before = myObject.counter = someArg
    myObject.count() // modifies counter
    val difference = myObject.counter - before
    What do you guys think?
    g
    a
    +2
    43 replies · 5 participants
  • f

    Fleshgrinder

    09/26/2020, 11:58 AM
    The ability to change mutability (or reassignability) without coming up with a new name like in Rust would be great. fun f() { var x = 0 val x = x }
    ➕ 14
    m
    e
    +2
    27 replies · 5 participants
  • n

    natpryce

    10/02/2020, 8:32 PM
    I wish that if you declared the primary constructor of a data class private, its copy method would be private too.
    ➕ 11
    n
    1 reply · 2 participants
  • n

    natpryce

    10/02/2020, 8:32 PM
    Probably too late now though…
    g
    h
    +1
    4 replies · 4 participants
  • s

    Slackbot

    10/03/2020, 3:28 PM
    This message was deleted.
    g
    a
    3 replies · 3 participants
  • d

    Daniele Segato

    10/06/2020, 5:07 PM
    This is more thinking out loud than a language proposal... Default arguments are great. But let's compare them with a builder pattern for a second:
    Something.Builder()
       .apply {
         foo("mandatory argument*)
         val barArg = grabBarArg()
         if (barArg != null) {
            bar(barArg)
         } else {
            // do nothing, leave the default
         }
       }
       .build()
    With the default parameters we don't have the option of leaving the default like that;
    Something (
        foo = "mandatory argument",
        bar = grabBarArg() ?: _
    )
    I think it would be helpful to have a way of explicitly saying "use default" like passing a
    Nothing
    ? Or in some other similar way? When I'm this situation if i have control on the class i create a secondary constructor, but it could be helpful, i think, to have a way to provide the default from the caller. It might also improve kotlin / java interoperability.
    ➕ 10
    e
    f
    +1
    21 replies · 4 participants
  • h

    holgerbrandl

    10/10/2020, 10:20 AM
    Why isn't the
    Number
    interface extending
    Comparable
    ? Being a number always superimposes an ordering imho.
    l
    f
    +2
    8 replies · 5 participants
  • r

    raulraja

    10/13/2020, 10:01 PM
    In yesterday’s presentation by @elizarov regarding the potential future features of Kotlin @with was mentioned. We were exploring changing arrow meta @Given to this proposal but we quickly encountered as so have others the limitation with generic type args as in @with<ComparableA> or similar where A is in the function it decorates as a generic arg. We found this issue where this is being discussed https://youtrack.jetbrains.com/issue/KT-42435 by @etolstoy as well. Has there been any thoughts as to how to deal with these cases or does anyone have any ideas as to how we can enable these additional receiver types that are generic over annotations that need to be concrete on their type? Also interested in thoughts about how to support multiple type args since `@with(Rec1, Rec2…). Thanks for any ideas 🙏 .
    @with
    👍 2
    e
    e
    3 replies · 3 participants
  • a

    aarjav

    10/14/2020, 2:56 PM
    Are there any proposals for a way to avoid having to specify params to be passed to parent classes constructor? for example if we have
    abstract class Foo(val id: String, val f1: String, val f2: String)
    class Bar(id: String, f1: String, f2: String, val other: String): Foo(id, f1, f2)
    I want to avoid having to specify the same props (
    id
    ,
    f1
    ,
    f2
    ), and better yet would like to reuse the documentation across all the subclasses
    n
    b
    6 replies · 3 participants
  • m

    Marc Knaup

    10/16/2020, 9:52 PM
    I just thought that it would be nice if we could get access to the eventual exception in the
    finally
    block. I often log timing, exceptions and cancelations for a block of code. With the current approach I’d have to duplicate logging code in
    catch
    clause(s) and at the end of the try block in the success case. I’d also have to use
    .also { … }
    in the try block to not change the return value. It would be much easier if I could something like
    val start = TimeSource.Monotonic.markNow()
    val x = try {
       lotsOfLogic()
    }
    finally { e -> // Throwable?
        // complicated logging with or without exception
    }
    Without:
    val start = TimeSource.Monotonic.markNow()
    val x = try {
       lotsOfLogic().also {
         // complicated logging without exception
       }
    }
    // multiple catch clauses would duplicate logging
    catch(e: Throwable) {
        // complicated logging with exception
        throw e // rethrow needed
    }
    ➕ 3
    l
    i
    12 replies · 3 participants
  • a

    aleksey.tomin

    10/22/2020, 5:57 AM
    I’m working with multiplatform and I’ve found the problem with logging. What do you thing about this proposal? -------------- A developer of a multiplatform project has to use some external library or write its own implementation (with slf4j/println/NSLog as an actual implementation). For example, ktor library uses slf4j for JVM target and println for others target. It’s better to use a common library. Example (the best but not good enough): https://github.com/MicroUtils/kotlin-logging/
    👍 2
    ❓ 3
    g
    2 replies · 2 participants
  • e

    elect

    10/22/2020, 11:04 AM
    This is happening to me multiple times.. I find
    when
    and the possibility to declare some
    val
    quite limiting:
    val platform = when(val os = DefaultNativePlatform.getCurrentOperatingSystem()) {
        os.isWindows -> 0
        
    }
    if I declare something like that,
    when
    expect exclusively matches against
    os
    Type I'd like something more broad
    m
    5 replies · 2 participants
  • m

    Marc Knaup

    10/25/2020, 12:55 PM
    I say let’s get rid of the idea of multiple receivers 😄 https://youtrack.jetbrains.com/issue/KT-42435#focus=Comments-27-4466122.0-0
    👀 2
    r
    l
    +1
    63 replies · 4 participants
  • n

    Nir

    10/26/2020, 1:49 PM
    With respect to Result, I know a concern is that it erases the type of the error. Has there been consideration to making Result an interface, and having a derived class:
    interface Result<out T> : Serializable
    inline class Outcome<out T, out E: Throwable> : Result<T>
    If you do something like this, then you can use
    Outcome
    as local error handling wherever you want to keep the type. And, if you need to collect errors from multiple sources, you just let Outcome up-convert to a Result. Things like
    runCatching
    could construct an
    Outcome<T, Throwable>
    (i.e. the most general case of Outcome) which could then be allowed to up-convert to Result instantly (leaving their API identical to now)
    m
    g
    +5
    194 replies · 8 participants
  • n

    natario1

    10/27/2020, 12:14 PM
    Wouldn't it be nice if we could destructure into function parameters?
    fun getMarkerLocation(): Pair<Double, Double> { ... }
    
    fun addMarker(name: String, lat: Double, lng: Double, color: Int) { ... }
    
    addMarker(
        name = "marker",
        color = Color.RED,
        (lat, lng) = getMarkerLocation()
    )
    I wonder if this has ever been discussed.
    ➕ 7
    n
    g
    17 replies · 3 participants
  • a

    Animesh Sahu

    10/31/2020, 2:55 PM
    I wish if there could be a substitute for
    @inheritDoc
    . Something even more extensible and familiar, more like:
    /**
     * @copyFrom SuperClassOrInterfaceManualSelection.someFunctionName
     * // extended docs with other info
     */
    • It could be used by IDE to jump into correct definition. • It could be beneficial to follow strict code styles where a KDoc is required on public/internal/protected functions. • It can and also give the user a clue from where the doc is being inherited from, such as if a class has multiple Interface inheritence (and no superclass) with same function defined with different KDoc one can assure the overridden KDoc follows the particular interface. • Same goes (on rare cases) if one wants to inherit KDoc from the interface instead of super class (if class both extend a class and implement interface(s)). Edit: Another idea came in my mind extending the above feature-request/proposal, if there can be pythonic style line selector in
    @copyFrom
    :
    @copyFrom Interface.method[1:5]  // copy/inherit line 1 to 5 (exclusive or maybe inclusive)
    @copyFrom Interface.method[2:]   // copy/inherit line 2 to the last line
    @copyFrom Interface.method[:6]   // copy/inherit from first line to line 6
    
    // Below are not important part of this proposal, but maybe easier to select from bottom if the KDoc of Interface.method was long enough
    @copyFrom Interface.method[:-2]   // copy/inherit from first line to second last line
    Apologies for any grammatical errors and/or improper formatting.
    💜 4
    z
    2 replies · 2 participants
  • e

    elect

    11/27/2020, 11:23 AM
    I'd like to overload the spread
    *
    operator, so that this:
    val s = "pos (%8.2f,%8.2f), uv (%.6f,%.6f)\n".format(v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col)
    may become
    val s = "pos (%8.2f,%8.2f), uv (%.6f,%.6f)\n".format(*v.pos, *v.uv)
    z
    r
    5 replies · 3 participants
  • m

    Marc Knaup

    11/28/2020, 11:24 PM
    It would be great for DSL if I can state for a function that at least one of the optional parameters must be specified, i.e. the function is otherwise either useless or an invocation invalid.
    interface SomeType
    
    @RequiresAtLeastOneOptionalArgument
    fun SomeType.with(key: String? = null, ref: Ref<*>? = null, block: () -> Unit): Unit = TODO()
    
    fun foo(some: SomeType) {
    	some.with {
    		// useless with
    	}
    	some.with(key = "key") {
    		// good
    	}
    }
    Another example:
    @RequiresAtLeastOneOptionalArgument
    fun makeBorder(width: BorderWidth? = null, style: BorderStyle? = null, color: Color? = null): Border =
    	if (width != null || style != null || color != null) Border(width, style, color)
    	else error("At least one property must be specified.")
    makeBorder()
    is then statically known to be invalid. It won’t catch
    makeBorder(null)
    but that’s another issue.
    e
    l
    3 replies · 3 participants
Powered by Linen
Title
m

Marc Knaup

11/28/2020, 11:24 PM
It would be great for DSL if I can state for a function that at least one of the optional parameters must be specified, i.e. the function is otherwise either useless or an invocation invalid.
interface SomeType

@RequiresAtLeastOneOptionalArgument
fun SomeType.with(key: String? = null, ref: Ref<*>? = null, block: () -> Unit): Unit = TODO()

fun foo(some: SomeType) {
	some.with {
		// useless with
	}
	some.with(key = "key") {
		// good
	}
}
Another example:
@RequiresAtLeastOneOptionalArgument
fun makeBorder(width: BorderWidth? = null, style: BorderStyle? = null, color: Color? = null): Border =
	if (width != null || style != null || color != null) Border(width, style, color)
	else error("At least one property must be specified.")
makeBorder()
is then statically known to be invalid. It won’t catch
makeBorder(null)
but that’s another issue.
e

ephemient

11/28/2020, 11:44 PM
dunno if there's a better way, but with O(n) overloads you can force any one parameter to be given a non-null value
private fun makeBorderImpl(width: BorderWidth?, style: BorderStyle?, color: Color?): Border = ...

fun makeBorder(width: BorderWidth, style: BorderStyle? = null, color: Color? = null) =
    makeBorderImpl(width = width, style = style, color = color)
fun makeBorder(style: BorderStyle, color: Color? = null) =
    makeBorderImpl(width = null, style = style, color = color)
fun makeBorder(color: Color) =
    makeBorderImpl(width = null, style = null, color = color)
m

Marc Knaup

11/28/2020, 11:50 PM
Yeah that’s an option. But I have plenty of functions, so it’s not just
n
overloads but
n * m
(times amount of functions). That’s a looot. (You also wouldn’t be able to call that with three nullable variables in your example)
l

louiscad

11/29/2020, 9:26 AM
You can make a no argument overload that is deprecated with error level, with a clear message.
👍 6
View count: 1