# Generics & Enums

**URL:** <https://discuss.kotlinlang.org/t/generics-enums/3538>\
**Category:** Language Design\
**Created:** [June 28, 2017, 10:47am UTC](https://discuss.kotlinlang.org/t/generics-enums/3538 "2017-06-28T10:47:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![wetnose](https://avatars.discourse-cdn.com/v4/letter/w/919ad9/32.png) [@wetnose](https://discuss.kotlinlang.org/u/wetnose)\
**Post date:** [June 28, 2017, 10:47am UTC](https://discuss.kotlinlang.org/t/generics-enums/3538/1 "2017-06-28T10:47:53Z")

</div>

I tried to port the following Java code to Kotlin and I didn’t succeed

(class names are changed)

```
interface Action<E extends Enum<? extends Action<E>>> {
   ...
}

enum Actions implements Action<Actions> {
    ...
}

<E extends Enum<? extends Action<E>>> void iterate(Class<E> actions) {
    ...
}

...
iterate(Actions.class);
...

```

Could someone help me to port such code to Kotlin?

---

<div class="post-metadata">

**Author:** ![elizarov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/elizarov/32/2164_2.png) [@elizarov](https://discuss.kotlinlang.org/u/elizarov)\
**Post date:** [June 28, 2017, 11:05am UTC](https://discuss.kotlinlang.org/t/generics-enums/3538/2 "2017-06-28T11:05:09Z")

</div>

A simple `interface Action<E : Enum<E>>` will do the trick for your case with `fun <E : Enum<out Action<E>>> iterate(actions: Class<E>)`

---

<div class="post-metadata">

**Author:** ![wetnose](https://avatars.discourse-cdn.com/v4/letter/w/919ad9/32.png) [@wetnose](https://discuss.kotlinlang.org/u/wetnose)\
**Post date:** [June 28, 2017, 11:30am UTC](https://discuss.kotlinlang.org/t/generics-enums/3538/3 "2017-06-28T11:30:04Z")

</div>

The thing is that `<E extends Enum<? extends Action<E>>>` enters an additional claim to the enum: it must implemet `Action` interface.

Look at the example

```
class Processor<E extends Enum<? extends Action<E>>> {
    public Processor(Class<E> actions) {
    }
}

```

Can I port it keeping the key constraint of type parameter?

---

<div class="post-metadata">

**Author:** ![elizarov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/elizarov/32/2164_2.png) [@elizarov](https://discuss.kotlinlang.org/u/elizarov)\
**Post date:** [June 28, 2017, 2:45pm UTC](https://discuss.kotlinlang.org/t/generics-enums/3538/4 "2017-06-28T14:45:20Z")

</div>

How would you use this additional claim? Can you also add a piece of code, please, that fails to compile with a simpler `Processor<E extends Enum<E>>`? I’m trying to understand what is the exact constraint on `E` that you are trying to satisfy.

---

<div class="post-metadata">

**Author:** ![wetnose](https://avatars.discourse-cdn.com/v4/letter/w/919ad9/32.png) [@wetnose](https://discuss.kotlinlang.org/u/wetnose)\
**Post date:** [June 28, 2017, 3:30pm UTC](https://discuss.kotlinlang.org/t/generics-enums/3538/5 "2017-06-28T15:30:04Z")

</div>

OK. Look at the following code (simplified case)

Declare the action descriptor

```
class Action<E extends Enum<? extends Action.Const<E>>> {

    final E constant;
    final Object extra;

    Action(E constant, Object extra) {
        this.constant = constant;
        this.extra = extra;
    }

    E getConstant() {
        return constant;
    }

    Object getExtra() {
        return extra;
    }

    interface Const<E extends Enum<? extends Action.Const<E>>> {
        Action<E> action();
    }
}

```

Then declare a class that operates on an action set

```
class API<E extends Enum<? extends Action.Const<E>>> {

    API(E actionSet) {
       ...
    }

    Action<E> actionOf(Object extra) {
       ...
    }
}

```

Declare some action sets

```
enum ActionSet1 implements Action.Const<ActionSet1> {

    func1("extra1"),
    func2("extra2"),

    ;

    final Action<ActionSet1> action;

    ActionSet1(Object extra) {
        this.action = new Action<>(this, extra);
    }

    @Override
    public Action<ActionSet1> action() {
        return action;
    }
}

enum ActionSet2 ...
enum ActionSet3 ...

```

And use them

```
val api = API(ActionSet1::class.java)
val action = api.actionOf(...)

val rep = when(action.getConstant()) {
    ...
}

```

But you cannot do this in Kotlin

```
class Processor<E : Enum<out Action.Const<E>>> (val api: API<E>)

```

---

<div class="post-metadata">

**Author:** ![elizarov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/elizarov/32/2164_2.png) [@elizarov](https://discuss.kotlinlang.org/u/elizarov)\
**Post date:** [June 29, 2017, 7:51am UTC](https://discuss.kotlinlang.org/t/generics-enums/3538/6 "2017-06-29T07:51:16Z")

</div>

Thanks for details. However, it does not explain why you have to have these baroque type constraints in Java. Your Java code is type-safe and compiles properly with simpler type constraints in declarations:

```auto
class Action<E extends Enum<E>> {
    ...
   interface Const<E extends Enum<E>> {
        Action<E> action();
   }
}

class API<E extends Enum<E>> { ... }

```

(Note, that in your Java code `API` constructor takes parameter that is named `actionSet` but has the type `E` - an instance of a particular instance set, while in the subsequent code you try to pass a class of actions there. I’ve left it as is).

The above type constrains translate to Kotlin without problems (I’ve made it more idiomatic by converting `Action.Const.action()` to property):

```auto
class Action<E : Enum<E>>(val constant: E, val extra: Any) {
   interface Const<E : Enum<E>> {
        val action: Action<E>
    }
}

class API<E : Enum<E>>(actionSet: E) {
    fun actionOf(extra: Any): Action<E> {
        //...
    }
}

enum class ActionSet1 private constructor(extra: Any) : Action.Const<ActionSet1> {
    func1("extra1"),
    func2("extra2");

    override val action: Action<ActionSet1> = Action(this, extra)
}

```

and you can nicely use them from Kotlin:

```auto
    val api = API(ActionSet1.func1) // you can also replace API constructor will a version that takes class or set of values
    val action = api.actionOf(...)

    val rep = when (action.constant) {
       //...
    }

```

---

<div class="post-metadata">

**Author:** ![wetnose](https://avatars.discourse-cdn.com/v4/letter/w/919ad9/32.png) [@wetnose](https://discuss.kotlinlang.org/u/wetnose)\
**Post date:** [June 29, 2017, 11:32am UTC](https://discuss.kotlinlang.org/t/generics-enums/3538/7 "2017-06-29T11:32:49Z")

</div>

Yes, this works. And I see several other WORKAROUNDS, but not solutions. Kotlin looks like a more stronger language than Java (null checks, mutable/unmutable collections and so on). But here you suggest that I should drop an existing check in Java code that obstruct porting it to Kotlin. The problem is that in your example you can pass an enumeration to the constructor of `API` calss even if that enumetation doesn’t implement the `Action.Const` interface. This error will be detected in runtime which makes debugging more expensive.

But what if we cannot port `Action/API` classes because they are part of a legacy library? Such Java classes are not fully supported by Kotlin. That is the problem!

---

<div class="post-metadata">

**Author:** ![elizarov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/elizarov/32/2164_2.png) [@elizarov](https://discuss.kotlinlang.org/u/elizarov)\
**Post date:** [June 29, 2017, 12:06pm UTC](https://discuss.kotlinlang.org/t/generics-enums/3538/8 "2017-06-29T12:06:08Z")

</div>

Kotlin is a pragmatic language. It does not have features just because other languages have them, but because there are compelling use-cases for those features. That is why I’ve asked for examples. The fact that this code is possible to write in Java is not compelling enough to substantiate its inclusion into Kotlin. Use-cases are needed. Kotlin had purposely removed a few Java features because they are either rarely used or hard to understand and use.

By the way, you can further constrain generic type `E` in Kotlin code in the way you’d like it to be constrained using `where` clause in the following way:

```auto
class API<E>(actionSet: E) where E : Enum<E>, E: Action.Const<E>

```

This would lead to a type signature that is easier to reason about than a nested constraint in your original Java code, while providing similar guarantees. You could have expressed this constrain in Java, too:

```auto
class API<E extends Enum<E> & Action.Const<E>>

```

---

<div class="post-metadata">

**Author:** ![wetnose](https://avatars.discourse-cdn.com/v4/letter/w/919ad9/32.png) [@wetnose](https://discuss.kotlinlang.org/u/wetnose)\
**Post date:** [June 29, 2017, 1:50pm UTC](https://discuss.kotlinlang.org/t/generics-enums/3538/9 "2017-06-29T13:50:46Z")

</div>

Thanks a lot!
