https://kotlinlang.org logo
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
  • b

    breandan

    02/06/2019, 3:51 PM
    What is the difference between Self types and F-bounded quantification? Does a first-class self type allow you to do something recursive type bounds cannot support? https://discuss.kotlinlang.org/t/self-types/371
    r
    • 2
    • 4
  • e

    Egor Trutenko

    02/07/2019, 1:04 AM
    Sometimes we need to preserve generic types in runtime, for example if we want to be able to distinguish between
    Container<String>
    and
    Container<Int>
    . A one particular solution (although not really flexible) would to subtype
    Container<T>
    with statically typed
    StringContainer : Container<String>
    and
    IntContainer : Container<Int>
    . The problem is, as aforementioned, it's not really flexible and we have to do it by hand. What if we could somehow tell compiler that we want to generate such subclasses with statically saved type parameter for every class that uses original, generic class? E.g.
    open class Container<sticky T> {
      ...
    }
    ...
    val sc = Container<String>()
    if (sc is Container<Int>) { // unreachable }
    Under the hood would turn into
    val sc = StringContainer()
    if (sc is Container) { ... }
    Theoretically, it is possible to track down all the types which generic type is parameterized with in compile-time; To avoid some problems with subclassing this functionality could be restricted for non-final classes. Also there could be problems with multiple type parameters. So, thoughts? Would this be useful, what more problems can this bring, is there ways to enhance it?
    r
    e
    • 3
    • 6
  • j

    jossiwolf

    02/07/2019, 11:53 AM
    Not sure if this is exactly language design, but is there a specific reason why
    @JvmOverloads
    doesn't work in interfaces with default arguments? 🙂
    g
    • 2
    • 2
  • d

    DALDEI

    02/08/2019, 8:25 PM
    C++ style generics -- new type creation C++(particularly 11+) template implement a meta-programming style which is well beyond java generics. With kotlin reified generics it may become feasible to implement some of the core concepts. Specifically the following: templates classes become new core types .e.g T<Int> and T<String> are compiled to different types with no relation. full compile-time resolution of generics to concrete types -- no need for workarounds to JVM Type Erasure as the types are fully resolved. Compile time overloading for templates type methods. e.g foo<Int>() and foo<String> are compiled into individual functions that can have different bodies. Compile time code generation/exclusion based on templates types. e.g. since types and methods compile to completely unrelated implementation you can provide completely different implementations for class and methods based on type alone. I realize the scope is large and deviates from Java compatibilty -- I am wondering if this style of generics was considered and if so what the results of the discussions. The cases for this are an extension to reified types -- If generics (or some similar language feature not replacing current generics) compiles templated types into distinct types, and related methods and classes as well are distinct -- then one can overload and specialize based on type. Classic example: (pseudo syntax in kotlin) // general case fun <T> sum( a: T , b: T) : T = a + b // specialized case fun sum<Cars>( a: Car, b: Car) = a.painted(b) fun sum<Double>(a: Double , b: Double) = _highlyoptimizedForDoubles( a , b ) Type specific singletons: class A<T> { companion object { val typeSpecific : T = T() // default init } } val A<Int>.Companion::typeSpecific : Int = 3 val A<String>.Companion::typeSpecific : String = "Three" fun <T> print( stuff: A<T> ) = println( stuff::typeSpecific ) Another valuable use case -- generic code that does not produce compile errors unless provided incompatible use. e.g. fun <A> shift( a : A ) = a shl 1 // only valid for integer types shift(1) // compiles no error shift("hello") --> Compile time error "shl undefined for String" val shifty = ::shift<String> --> compile time error My proposal is that this style of generics could be implemented as fully reified at compile time -- to non-generics. This would allow co-existence (while not great compatibility) with Java, and likely make implementation much easier. Conventions could be created as per the naming of the derived types such that it is predictable -- e.g. class A<T> , class A<Int>{} -> "A__java_lang_Integer"
    r
    c
    +4
    • 7
    • 18
  • k

    kevinmost

    02/14/2019, 7:39 PM
    Curious if anyone thinks it'd be a good idea to have a
    @JvmBuilder
    compiler plugin in the stdlib + Kotlin IntelliJ plugin that would generate synthetic members to make builders on `data class`es for use in Java. Using `data class`es with many properties is currently pretty clunky in Java. For example:
    @JvmBuilder
    data class Foo(val bar: String, val baz: Int = 0, val qux: String? = null)
    should generate
    Foo.builder()
    that returns an object like:
    public final class FooBuilder {
      public static FooBuilder builder() {
        return new FooBuilder().baz(0).qux(null);
      }
      
      // fields...
    
      public FooBuilder bar(String bar) { ... }
      public FooBuilder baz(int baz) { ... }
      public FooBuilder qux(@Nullable String qux) { ... }
      public Foo build() {
        // assert that properties with no default value were set
      }
    }
    x
    j
    e
    • 4
    • 38
  • r

    rrader

    02/15/2019, 1:45 PM
    data class Data(val a: Int)
    Why
    Data::a
    does not return
    KProperty<Data, Int>
    by return
    KProperty<Int>
    ? In first case we can write a function that receives only `Data`'s properties, something like
    func process(prop: KProperty<Data, Int>)
    i
    • 2
    • 6
  • j

    janvladimirmostert

    02/19/2019, 5:45 AM
    Named arguments are really useful and makes code much easier to read, especially when you have to call functions that have many parameters. Unfortunately, named arguments aren't allowed when doing calls to Java for example. Since Java is also statically typed, is it not possible to make named arguments work with Java functions as well? Or would this be an issue when interopting with JavaScript? Proposal: allow calling Java functions from Kotlin using Named Arguments
    g
    d
    s
    • 4
    • 10
  • l

    louiscad

    02/21/2019, 10:44 AM
    Hi, my proposal is to allow braces-less `try`/`catch`/`finally` as done for `if`/`else`. Here's an example of how it could look like:
    try registerAppInstance(info = AppInstanceInfo(
        someToken = someValue
    )) catch (e: HttpException) ui.showError(
        when (val code = e.code()) {
            503 -> ServiceUnavailableTryLater
            ...
            else -> ...
        }
    )
    👍 1
    d
    g
    • 3
    • 11
  • r

    Ruckus

    02/23/2019, 5:27 AM
    Proposal: Conditional assignment This is part of my quest to get
    ?
    on more and more operators
    If a property is not null, it would be nice to have a conditional assignment operator that would assign a nullable value only if it is not null. For example:
    map[KEY]?.let { value = it }
    would become
    value ?= map[KEY]
    Edit As @Dico pointed out,
    value ?= map[KEY]
    can be a bit confusing, as it seems to imply
    value
    is the nullable item instead of
    =
    . It may make more sense to use
    value =? map[KEY]
    , but I'm on the fence.
    d
    j
    +4
    • 7
    • 48
  • g

    groostav

    03/13/2019, 8:07 PM
    just found this in a pull request:
    val something = when(business) {
      //...
      someCase -> {
        POKOType.forName(name) ?: Log.warning("angry"); POKOType()
      }
    If i had some kind of
    @Pure
    ref-transparent enforcement I could at least get this code tagged as suspicious, if not generate a compiler failure out right. whats the most aggressive thing I can do in my build system to catch this?
    i
    n
    e
    • 4
    • 4
  • g

    galex

    03/14/2019, 3:50 PM
    Constructors for Objects 🙏
    ➖ 11
    d
    k
    +3
    • 6
    • 16
  • x

    xenoterracide

    03/15/2019, 4:10 PM
    lateinit on primitives
    d
    c
    +3
    • 6
    • 13
  • j

    Jay

    03/16/2019, 12:22 PM
    When creating classes that implement interfaces for use as delegates - it would be great to be able to mark them as incomplete and have compile-time error if the class using it as a delegate didn’t override any unimplemented methods. Is there a way to do that at the moment?
    k
    d
    t
    • 4
    • 17
  • k

    karelpeeters

    03/20/2019, 1:19 PM
    Since there's only ever one instance of an object the default identity equals and hashcode are fine, right?
    ➕ 7
    r
    d
    +2
    • 5
    • 9
  • x

    xenoterracide

    03/20/2019, 5:47 PM
    does kotlin have it’s own version of IntStream.iterate ?
    f
    i
    +3
    • 6
    • 9
  • l

    littlelightcz

    03/22/2019, 5:57 PM
    The next major version of Kotlin could automatically treat the "!!" operator either as warning or compile error, unless the particular line of code is annotated by
    @IWantNPEToBeThrownHere
    🙂. Or perhaps the compiler could have a flag to turn this behaviour on.
    :yes: 1
    ❤️ 2
    🇳🇴 7
    d
    j
    +4
    • 7
    • 15
  • g

    GreyhairRedbear

    03/23/2019, 12:54 PM
    Would it be possible to have an option to pass the enclosing class as a weak reference to lambdas? Pretty much like swift does with
    [weak self]
    r
    g
    • 3
    • 6
  • g

    GreyhairRedbear

    03/23/2019, 12:58 PM
    Further, any news regarding the package-protected visibility (https://discuss.kotlinlang.org/t/kotlin-to-support-package-protected-visibility/1544/55 and https://youtrack.jetbrains.net/issue/KT-29227)?
    r
    k
    g
    • 4
    • 7
  • o

    orangy

    03/23/2019, 2:00 PM
    So basically make a file like an object? 🙂
    r
    d
    b
    • 4
    • 4
  • e

    efemoney

    03/28/2019, 5:16 PM
    Are there any plans to support Inline classes as annotation properties where the inline class wraps an allowed annotation property type. I have a personal use case with custom scripts backed by kotlin’s #scripting feature where at compile time I want strong type safety for the file:annotation arguments.
    d
    d
    • 3
    • 4
  • p

    pablisco

    03/31/2019, 9:00 PM
    I was wondering if we could have sealed interfaces. A potential use case could be having the model for an application (let's say, type of posts on a social media platform). They can be represented as a set of sealed interfaces bit then have two different implementations depending whether they come from local cache, remote server or even dummies for testing... What do you peepz think?
    b
    • 2
    • 5
  • n

    natpryce

    03/31/2019, 11:26 PM
    You could have a sealed hierarchy of abstract classes
    p
    • 2
    • 13
  • t

    tschuchort

    04/01/2019, 4:53 PM
    I'm pretty sure this isn't possible
    p
    • 2
    • 1
  • j

    Jorge Castillo

    04/07/2019, 11:49 AM
    We can work on a keep for that if it has enough acceptation. Also for passing custom error messages into RestrictSuspension annotation.
    👍 3
    g
    r
    • 3
    • 3
  • a

    aerb

    04/12/2019, 1:58 PM
    FWIW below compiles.
    fun build(builder: (Context) -> View): View { TODO() }
    
    val a = build(::View)
    k
    • 2
    • 6
  • z

    zokipirlo

    04/17/2019, 8:22 AM
    Any new informations regarding that? https://discuss.kotlinlang.org/t/sealed-class-inheritance-and-constructors/2283
    r
    • 2
    • 1
  • r

    raulraja

    04/17/2019, 9:23 AM
    KEEP-87 is ready to be submitted for consideration. A working prototype is in place with facilities to install as an IDEA plugin. The proposal has been reworded to simplify the examples and remove references to functional programming. The syntax has been reduced to existing Kotlin idioms and we are open to different approaches. In essence it brings the ability to group extensions functions as they are today in Kotlin under an interface that is parametric. The compiler then automatically resolves proofs the extensions are supported by a given type and activate the extension syntax and functions of the interface in whatever scope these extensions are required. This is essentially compile time verified dependency injection. The PR with the propossal is ready here https://github.com/Kotlin/KEEP/pull/87 and there is a fork in the Arrow org where the prototype has been developed by members of the 47 OS team and the help of some people involved with the Kotlin compiler which were kind enough to help us navigate its complexity. Please let us know if there is a better way to submit this or any additional things we need to do on our side so this is considered. This seems a welcomed feature by the community given the active participation in the KEEP and the many people involved with the prototype and proposal. I would like to state we are very much interested in the feature for both FP and OOP and not so much in the specific encoding so we are looking forward and are open to iterate on grammar, syntax or idioms all around. We are looking forward to the compiler teams opinions and other members of the community. If you got here thanks for reading this far and let us know if you'd like to get involved to make this happen in Kotlin.
    👏 25
    🔝 15
    :kotlin: 40
    🔥 11
    :arrow: 4
    l
    • 2
    • 5
  • f

    fo2rist

    04/23/2019, 4:24 PM
    Is that a right place/time to upvote multi-catch block proposal for Kotlin? https://youtrack.jetbrains.com/issue/KT-7128
    g
    • 2
    • 1
  • g

    ghedeon

    05/08/2019, 11:31 PM
    We would like to start a discussion around enchanced ranges/slices and hopefully end up with a KEEP. Roughly the same set of questions is being regularly asked by people that come from a different language background: 1. Support for half-open range 2. Support for partial range (from, to, through) 3. Array/List slices. Possibly backed by before-mentioned ranges syntax. (all of this seem to be possible to implement without breaking changes in Kotlin) Currently, we propose to focus on the first one, in particular: adding
    <
    operator for
    until
    function. Gradually, having half-open and partial ranges, the slices syntax should follow. Given: Already implemented "closed range" in Kotlin. Since Kotlin range is closed by default, by likeness, Groovy and Swift might be considered as an inspiration: Closed range: Swift:
    0...5
    Groovy:
    0..5
    Half-open range: Swift:
    0..<5
    ,
    ...<5
    // compare to
    val a = until 5 ???
    Groovy:
    0..<5
    Slice: Swift:
    arr[1...5], arr[1..<5]
    Groovy:
    arr[1..5]
    ====================================== Why it's important, why not
    until
    , why partial range?
    Personally, I believe that the closer we can get to the formal requirement (in this case — mathematical interval) the better. Thus, you don't execute the code but the requirement itself (it is only because of imperfection of our reality we're forced to write code around formal requirements 😉). That's why
    +
    is better than
    plus()
    . The former is essential and the latter is induced workaround. Also imho, with KISS in mind, there is no need to reinvent slices syntax (I've seen
    :
    proposal) when it's already covered by good range system. But it's a different discussion and I might be missing a bigger picture. Does
    (1..<5)
    look reasonable to you?
    cc: @Dico, @Mike, @karelpeeters, @Hullaballoonatic
    👍 13
    t
    d
    +7
    • 10
    • 33
  • m

    Marc Knaup

    05/10/2019, 1:47 PM
    Java Enums are Comparable by default? 😵 If Kotlin should ever introduce their own
    enum
    type (instead of
    enum class
    ) then please don't do that 🙏
    m
    r
    +5
    • 8
    • 98
Powered by Linen
Title
m

Marc Knaup

05/10/2019, 1:47 PM
Java Enums are Comparable by default? 😵 If Kotlin should ever introduce their own
enum
type (instead of
enum class
) then please don't do that 🙏
m

marstran

05/10/2019, 1:49 PM
Like https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-enum/index.html ?
m

Marc Knaup

05/10/2019, 1:54 PM
That's the Java enum.
Or an
enum class
to be more specific.
m

marstran

05/10/2019, 1:55 PM
That class is a common class. It just maps to Java enum on the JVM.
m

Marc Knaup

05/10/2019, 1:56 PM
still it's a class
I still hope that because there's
enum class
there could be a non-class
enum
in the future 😄
m

marstran

05/10/2019, 1:57 PM
What difference does that make?
m

Marc Knaup

05/10/2019, 1:58 PM
To be a primitive instead of an object 🤔 And non-Comparable by default. Maybe even without having an ordinal by default. And maybe optionally open.
m

marstran

05/10/2019, 2:02 PM
I don't get what that would solve that today's enums doesn't solve. Also, how do you represent a primitive enum in memory without an ordinal? A string value?
m

Marc Knaup

05/10/2019, 2:10 PM
I could also solve everything in Java so why use Kotlin 🤷‍♂️ The thing is that Java's enum do too much and that can be improved. Currently • it's a reference type instead of a value type. • it has
ordinal
,
name
,
valueOf
,
Comparable
(and maybe others) defined by default which is not desirable. • it has a recursively generic abstract superclass. A String would be a reference type again, including related overhead. In memory it could be an primitive int, a memory address or whatever - I don't care nor need to know as a developer. Similar to inline classes and properly implemented in the JVM with project Valhalla.
related: https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
r

r4zzz4k

05/10/2019, 2:22 PM
I have no idea whether
Comparable
is expected on these or not, but regarding primitives and enums you can check this: https://youtrack.jetbrains.com/issue/KT-23823
r

Ruckus

05/10/2019, 2:31 PM
Why is it not desirable? What's wrong with enums being comparable?
➕ 1
I find it quite useful, for example in a logger
fun log(level: Level, message: String) {
    if (level > threshold) ...
}
➕ 1
The whole point of an enum is to enumerate some values, which implies an intrinsic order.
m

Marc Knaup

05/10/2019, 2:55 PM
No it doesn't. It could also be a set of options to choose from. It makes absolutely no sense to bring them in any order. Enumerating doesn't imply order. Just because comparable names sense in some cases it doesn't make sense to make Enums comparable by default.
Just like with Collection and List. For a Collection order of elements may or may not be relevant. List implies an order of its elements.
r

Ruckus

05/10/2019, 3:15 PM
Yes, it does. It's literally the definition of enumerate:
to ascertain the number of; to specify one after another
An enumeration is a complete, ordered listing of all the items in a collection.
m

Marc Knaup

05/10/2019, 3:26 PM
enumerate as in Java or as in the English language?
r

Ruckus

05/10/2019, 3:28 PM
As in both the English language and the vast majority of programming languages.
m

Marc Knaup

05/10/2019, 3:31 PM
Okay, but that still doesn't make elements comparable. Just because in
listOf(2, 1)
1 comes after 2 its not automatically greater than 2.
It's just about the order while enumerating them.
r

Ruckus

05/10/2019, 3:36 PM
But that is fundamental to the definition of the enum
m

Marc Knaup

05/10/2019, 3:36 PM
No, where does it say that?
r

Ruckus

05/10/2019, 3:37 PM
...in the definition
I don't mean to argue, I'm just having a hard time seeing where you're coming from, and I'm guessing you are having an equally hard time with me 🙂
m

Marc Knaup

05/10/2019, 3:43 PM
All im saying is that it doesn't make sense for many enum values to be Comparable and apart from Enum implementing it I can't find a definition which states that its supposed to be so nor why. North > South Earth > Mars it just doesn't make any sense (and that's just about Comparable - name is even more annoying)
j

jeremy

05/10/2019, 3:47 PM
https://en.wikipedia.org/wiki/Enumerated_type
Only in some languages does an enum define some inherent ordering. Often it’s used as a discriminated union.
m

Marc Knaup

05/10/2019, 3:50 PM
The latter is how I understood them, with exceptions. Assigning enums and integers and having an order came from the C world, didn't it?
r

Ruckus

05/10/2019, 3:50 PM
@Marc Knaup Agreed, so why define those as enums? It would make more sense to use an algebraic data type (i.e.
sealed class
). If it doesn't make sense to say South comes after North, it doesn't make sense to enumerate it.
m

Marc Knaup

05/10/2019, 3:52 PM
That adds even more overhead in terms of code, classes and initialization. They're not value types. Also doesn't work as constants in annotations.
Btw, the examples north/south or planets are actually from Java's documentation about enums 😅 They don't have good alternatives though.
r

Ruckus

05/10/2019, 3:54 PM
Enums aren't value types either, so I don't think it actually adds more overhead (at least not appreciably). The "constants in annotations" argument is orthogonal.
Yeah, that's a failing of Java though. Kotlin fixed that issue with proper algebraic types.
m

Marc Knaup

05/10/2019, 3:56 PM
The reason that
enum class
in Kotlin works the way it does is that it needed Java compatibility. I just suggest rethinking it as Kotlin becomes more and more its own language.
r

Ruckus

05/10/2019, 4:00 PM
I think that's an incorrect assumption. Kotlin's
Any
doesn't implement the same API as Java's
object
. I would counter that
enum class
in Kotlin works the way it does because it makes sense. That's why most every language with enums does that, even if they never talk to Java or C or whatever.
m

Marc Knaup

05/10/2019, 4:03 PM
Before inline classes there was no way to interface value types with reference types in Java hence enum needed to remain a reference type, didn't it? It also allows for complex values having method overrides. And the name & ordinal properties you also can't remove, nor the comparable interface, if you want to stay compatible.
And I'd look at modern languages rather than any language when comparing. Things change :) Swift for example doesn't have them comparable nor exposes underlying integer values.
r

Ruckus

05/10/2019, 4:05 PM
Sure, but Rust does. That's why you need to look at many languages, so see the bigger trend.
m

Marc Knaup

05/10/2019, 4:07 PM
Yeah. So the discussion should be what makes sense, not what others do or did in the past. Which brings me back to my initial messages on what should be improved :)
r

Ruckus

05/10/2019, 4:11 PM
Right. That's what I'm saying. To me the current way makes sense. I see your proposal as an impairment, not an improvement, so I'm just trying to see your reasoning why you think it is an improvement so I can see if I need to rethink my assumptions.
By the way, value type and comparable aren't mutually exclusive. `Int`s are Comparable in Kotlin. That's just a matter of compiler magic, not language definition per say.
m

Marc Knaup

05/10/2019, 4:14 PM
Why is it an impairment to remove for example a default comparable? You can still add it in cases where it makes sense. Probably for the majority of enums it doesn't make sense and not having it will make api and intent clearer.
I'm impaired by not being able to name a property
name
because it refers to Java/Kotlin identifier (the enum case) instead of the name of the thing the enum case actually describes
r

Ruckus

05/10/2019, 4:15 PM
You could say the same thing about Strings or any other type.
m

Marc Knaup

05/10/2019, 4:16 PM
No not really 🤔
r

Ruckus

05/10/2019, 4:16 PM
Again, not being able to use
name
is completely orthoganal to the comparability discussion.
m

Marc Knaup

05/10/2019, 4:16 PM
There is one single string class describing one type of data. There is an infinite amount of enum types each with different meanings
I'm not discussing compatibility though
r

Ruckus

05/10/2019, 4:17 PM
Okay, you could say the same thing about
CharSequence
Never mind, I don't think
CharSequence
is comparable
I said comparability, not compatability. The question was about why they are comparable.
m

Marc Knaup

05/10/2019, 4:19 PM
Oh, misread
r

Ruckus

05/10/2019, 4:19 PM
It's all good, I do that a lot myself 🙂
m

Marc Knaup

05/10/2019, 4:20 PM
Yeah, add autocompletion and it gets even better to have confusion than that 😅
😆 1
r

Ruckus

05/10/2019, 4:20 PM
I can kind of see where you're coming from, I'm just not convinced, but obviously I'm not the one that makes the decision. I just wanted to give my input. Thanks for the discussion and the insights
m

Marc Knaup

05/10/2019, 4:22 PM
Yeah I think you're coming from the technical side while I'm coming from the "business logic" side or whatever that would be called. What is trying to be represented and where there is confusion or limitation for whatever reason
Thank you too :)
Except value types. That's quite low level 😂
l

louiscad

05/10/2019, 4:42 PM
(Skipped the end of the thread) Enumarate implies an order per the definition in English, French, etc, and Swift is wrong to not allow accessing that order for something called an
enum
. That said, what you are looking for is
sealed class
of `object`s, with explicit inlining where the ordinal used for the underlying constant primitive is explicitly specified but private to the declaration, so it can be used for public APIs without unexpected breakages. We could also imagine a
set class
that would be like a one level
sealed class
with stateless objects only, where either order would matter, or explicit ordinal would be specified, so the compiler flattens it to primitive values for the produced binary. It could also work with something like R8 or proguard with a Kotlin specific logic to inline down to primitive all fully stateless
object
based `sealed class`es. Are you targetting Android?
m

Marc Knaup

05/10/2019, 4:44 PM
Ideally Android should work just fine for any language feature 🤔 But yes, due to multiplatform it should work everywhere.
Whether an enumeration type implies order or not is not clear. That was part of the thread you've skipped 😛
d

Dico

05/10/2019, 9:18 PM
I think there is no good motivation to do this, and I think it would have a negative impact on the language as a whole because of it. If you don't want any of the features of
enum class
, each of which have their use cases, you should consider using another way of declaring it.
l

louiscad

05/11/2019, 7:59 PM
I didn't skip most of the dispute around order or not in enums. To me, it's cleat that enumeration implies order, always, and anything that doesn't have this capability should be named otherwise.
d

Dico

05/11/2019, 8:14 PM
I don't fully agree with that, as enumerations can have an undefined order, for example with legacy java enumerations of sets. But I wouldn't suggest removing it because it has good use cases.
m

Marc Knaup

05/12/2019, 11:27 AM
We are mixing up two different things here. - iteration order of an enumeration (just like a List) - natural order of the elements (i.e. Comparable, like Int) It's fine that enums have a well-defined iteration order. But that doesn't imply that the elements need to be Comparable as it doesn't make sense for many of them. Sure it can be a good use case, but in that case you can always add Comparable on your own.
d

Dico

05/12/2019, 11:40 AM
Or you dont have to add it because it's already there, saving time
m

Marc Knaup

05/12/2019, 11:42 AM
Yeah, let's confuse API users by telling them that things can be compared which actually can't. Including autocompletion for that and the compiler won't even warn that it doesn't make sense to compare the two values you have.
But it's a little easier for other enum cases :)
d

Dico

05/12/2019, 11:43 AM
Well, it's not about whether they can be compared, but whether there is a use case for it, which depends on what you're using enums for
m

Marc Knaup

05/12/2019, 11:44 AM
Exactly! Only the person who defines the enum knows what it's supposed to express. Kotlin can't know that.
d

Dico

05/12/2019, 11:45 AM
Right. And the way it is currently is fine. Ability to compare enum values is sometimes a nice to have and sometimes unnecessary. It's lunacy to suggest changing it or adding a new kind of enum because of it.
m

Marc Knaup

05/12/2019, 11:46 AM
That's not what I said.
d

Dico

05/12/2019, 11:46 AM
Oh sorry, it's what I interpreted
l

louiscad

05/12/2019, 11:46 AM
I don't understand why not just use
sealed class
. There's even an IDE intention to do the conversion in no time.
m

Marc Knaup

05/12/2019, 11:46 AM
I said that if there will be a new enum, then it should be rethought.
l

louiscad

05/12/2019, 11:48 AM
There will probably be no new enum that doesn't enumerate, because it's against the English definition IMHO, and it'd confuse people with other enums.
m

Marc Knaup

05/12/2019, 11:48 AM
It can enumerate, even in defined order! Just because a List's elements can be enumerated doesn't mean it's elements are Comparable. Again, two different things.
l

louiscad

05/12/2019, 11:50 AM
Not completely separate, because if you can enumerate, you can give it a number (aka. ordinal), which you can then compare, so removing the comparability of enums just makes it harder and less safe to compare two entries. Also, remember that `enum class`es can't extend other classes, so there's no possible confusion about what is being compared.
m

Marc Knaup

05/12/2019, 11:52 AM
You could make the same argument for Lists... Because all elements can be enumerated there, they all should have a number and they all should be Comparable.
l

louiscad

05/12/2019, 11:52 AM
No, I can't for lists because their content can be anything and can itself be comparable.
m

Marc Knaup

05/12/2019, 11:54 AM
Enum values can have a natural way to compare them too...
l

louiscad

05/12/2019, 11:55 AM
To be clear. An enum doesn't encapsulate anything. It IS, by itself, THE enumeration. A list, is a list OF things that themselves can have any comparability criterions. You can have a list of
String
, but not an enum of
String
, this doesn't make sense and is impossible. The name of the enum entry though, is a
String
, and you can also retrieve it.
m

Marc Knaup

05/12/2019, 11:55 AM
And just because Lists can hold anything it doesn't change your definition if enumeration where elements have the position in the enumeration as natural order for Comparable. You make enumeration different for enum values and List.
❓ 1
l

louiscad

05/12/2019, 11:55 AM
They always have, that natural way is the entries declaration order.
m

Marc Knaup

05/12/2019, 11:56 AM
"They always have" is not a good argument for anything.
The we'd not have a lot of nice things today.
l

louiscad

05/12/2019, 11:58 AM
It's not an argument, its a fact, like if you don't want natural comparability, don't use
enum class
.
Maybe that's unfortunate for your use case, but this is set in stone in Kotlin and Java APIs, and I already said why I don't think comparability should be removed from enum if those compatibility and familiraity concerns could be dropped.
m

Marc Knaup

05/12/2019, 12:00 PM
wow, I can only repeat: I don't want to change today's enum.
l

louiscad

05/12/2019, 12:01 PM
So let's not call it enum, because it brings confusion, even for us.
m

Marc Knaup

05/12/2019, 12:01 PM
This is about a potential scenario where something new is introduced to iterate on the old Java enum and its introduced anyway.
I don't mind if it's called differently. Swift does well with enum and developers can express intent much more clearly with them, without the ambiguity which Java has introduced.
l

louiscad

05/12/2019, 12:05 PM
For your use case where you don't want comparability, do you need to iterate on the set elements? If so, do you need a predictable order too? Do you need to persist these values and read them back from a newer version of your program? Do you need to transfer them to another system that could have an updated, or older version with a different set of values?
m

Marc Knaup

05/12/2019, 12:11 PM
I suggest to look at Swift. There are brilliant developers specifying the language and they've though thought all of it while deeply involving the community for feedback. By default only minimal functionality is given. Enums are just a set of possible values. They can be Comparable (manually defined order), they can be enumerable (via interface which would be implemented automatically). I've also linked above the recent and lengthy debate about forward and backward compatibility of enums including add/remove/rename and exhaustiveness. In the end what makes or doesn't make sense always depends on the use case - what the developer want to express - and in Swift developer is very free to make it just right for their specific cases.
d

Dico

05/12/2019, 1:45 PM
I simply disagree that it should be changed or is worth changing
l

louiscad

05/12/2019, 2:10 PM
Community feedback and being brilliant doesn't always imply simple or consistent solutions. I just read Swift enum documentation, and here's my thoughts: 1. They start by defining their own definition of enumeration, basically pulling it to become a set/group of value, without anything regarding the enumeration apart from the
allCases
property defined later on. 2. To have something like `sealed class`es, they use the keyword
indirect
to have an enum case be another enum, which reads harder than it should be IMHO. 3. Their "enums" are really just a set/group of values that enables genuinely cool syntax in `switch`es and the related compiler checks, and you can make them use any primitive value, be it a
Character
, a
Float
, etc. Consequently, I think we're good in Kotlin with `sealed class`es, Java's and Kotlin enums are more accurate to the English definition of enumeration with their comparability, ordinals and names, and are also simpler although less full featured than Swift's fake enums. I'm not against something like in Swift as kind of a middle ground between `sealed class`es and `enum class`es, but I don't want them to be referred as enumerations. `set class`es is one of the naming I have in mind. If you think such a thing should be introduced in Kotlin because you have or can find use cases for it that current options don't satisfy well, then starting to work on a KEEP would be sound thing to do.
g

gildor

05/14/2019, 7:09 AM
kind of a middle ground between `sealed class`es and
enum class
oh, please, no need to add new entities to the language, some people already confused what to choose enum or sealed class
➕ 1
View count: 3