Enum value verbosity


#1

Unexpectedly Kotlin is unnecessarily verbose in enum values using. For example

enum class MySomeSpecificState{
    GONE, VISIBLE_FIRSTLY, VISIBLE_AGAIN
}

fun processing(state:MySomeSpecificState){
    when(state){
        MySomeSpecificState.VISIBLE_AGAIN -> {...}
        MySomeSpecificState.VISIBLE_FIRSTLY -> {...}
        MySomeSpecificState.GONE -> {...}
    }
}

fun determine(){
...
    processing(MySomeSpecificState.VISIBLE_AGAIN)
...
    processing(MySomeSpecificState.VISIBLE_FIRSTLY)
...
    processing(MySomeSpecificState.GONE)
}

===========

Much better would be if it will be allowed to write

fun processing(state:MySomeSpecificState){
    when(state){
        VISIBLE_AGAIN -> {...}
        VISIBLE_FIRSTLY -> {...}
        GONE -> {...}
    }
}

fun determine(){
...
    processing(VISIBLE_AGAIN)
...
    processing(VISIBLE_FIRSTLY)
...
    processing(GONE)
}

In such cases type is already known to compiler, any type mistypes will be detected.
I can’t see any reason to rewrite enum type again and again.

This feature will significantly clean code, make bussiness logic readable

Especialy in cases SomeSpecificEntityClass.SomeSpecificFieldStateEnum.SOME_VALUE


#2

You can do this. Simply import the values that you want to use unqualified:

import ....MySomeSpecificState.VISIBILE_FIRSTLY

#3

Thanks, it works!

import …MySomeSpecificState.*

works too

The only caveat it is not pure enum type matching
if I have 2 enums with the same value name, conflicts will no be resolved

import ...SomeSpecificField1.*
import ...SomeSpecificField2.*

enum class SomeSpecificField1{
    GONE, VISIBLE
}
enum class SomeSpecificField2{
    GONE, VISIBLE_FIRSTLY, VISIBLE_AGAIN
}

fun processing(field1:SomeSpecificField1,  field2:SomeSpecificField2) {
   ...
}

fun determine(){
    processing(VISIBLE, VISIBLE_FIRSTLY)  // OK
    processing(GONE, GONE)                        // UNRESOLVED
}

it can be solved with renaming GONE to GONE1 and GONE2

or

import ...SomeSpecificField2.GONE as GONE2

or

 processing(VISIBLE, VISIBLE_FIRSTLY) 
 processing(SomeSpecificField1.GONE, SomeSpecificField2.GONE) 

but it’s all a kind of cumbersome

Common state values have very well known bussiness logic spelling
and are wrotten many times in code,
otherwise special uncommon enum values much rarely

There is no benefit to write SomeSpecificField1.GONE many times
but have posibility to write VISIBLE_FIRSTLY once


#4

I think it is ambiguous if Kotlin has to guess which GONE you mean in more complex cases. For example:

SomeSpecificEntityClass(GONE.someExtensionFunctionReturningTheCorrectEnum(), GONE)

Which GONE must be used for the 1st occurrence? The compiler can only determine that by checking whether someExtensionFunctionReturningTheCorrectEnum() exists for one of the enum types. What should happen if that function is defined for both enum types? If multiple function calls, conditionals, etc. are chained, how far does the compiler need to infer the types used in the expression to determine the type of the identifier with which the expression is started?


#5

Agree, there are 100 cases when enum type is too complex to figure out

But there are 10000 code usage cases when it’s completly clear

It would be great if in simply cases enum type will be resolved

In other 1% complex cases compiler can continue ask to write it verbosely
and it will be great too


#6

I have a similar situation - I have many different Enum classes representing the state of different entities. Since the Enums are specific to the entity they are a nested class of the entity in my model.
That makes it even more verbose to write the enums, even for all those cases where there can be no ambiguity because it’s used in an assignment or when() clause, as I have to write out the full path for something like Shift.State.PUBLISHED !


#7

I seem to be forever linking to the recent future features survey though the truth is that solutions to most of the things which people consider to be ‘pain points’ in the language, are currently under consideration and ‘short notation for enum constants’ (item 3 on the list) is one of them.

I can certainly see the sense of this when an enum is the subject of a when statement / expression or if you’re initializing an enum variable (or parameter) with some value.

I don’t know whether this is likely to be implemented but, if it is, then the problem for the designers will clearly be to try to restrict it to situations where the enum type you’re referencing can be readily inferred by both the compiler and the human reader.


#8

One possibility is using an alias, such as

import MySomeSpecificState as M

fun processing(state: chap03.MySomeSpecificState){
    when(state){
        M.VISIBLE_AGAIN -> {...}
        M.VISIBLE_FIRSTLY -> {...}
        M.GONE -> {...}
    }
}

Alternatively you may use:

typealias M = MySomeSpecificState