Bounds for classes implementing this interface

Kotlin has powerful and useable interfaces. We can make it sealed and make some restrictions on implementors but sometimes we need more specific bounds.

For example, I have some entity Type1 and want to define subtype IterableType1 with specific features. So now I need to define an abstract class and extend it if needed. But if there is more than one such subtype? I need to have more than one abstract class and they become incompatible. So I have to define some interfaces except abstract classes. Anything can implement it:

class Type1
interface SomeThing1
interface SomeThing2`Preformatted text`
class SomeType1 : Type1, SomeThing1 // It is OK, our goal
class SomeBadThing : SomeThing1 // It is bad and anoying.

Why not allow to add bounds to interface implementors?
Example syntaxis:

class Type1
{
}

interface for Type1 IterableType1 : Iterable<...>
{
	...
}
or
interface IterableType1 for Type1 : Iterable<...>
{
	...
}
or 
interface IterableType1[Type1] : Iterable<...>
{
	...
}
or
interface IterableType1<<Type1>> : Iterable<...>
{
	...
}

And then we now some about implementor we can allow using its methods in default implementations.

It is a common feature in functional languages(Scala, Rust).

To avoid incompatibility, misunderstanding, and other problems, such entities can be called differently(for example, trait).

What kind of restrictions do you mean? Sorry, but I don’t understand your examples and how do they differ from:

interface IterableType1 : Type1, Iterable<...>

Generally speaking, interfaces were designed specifically so anyone can write any implementation. Restricting them is like using them in opposite way than they were meant to. Sealed interfaces is one exception where we want our interface to be extendable internally, but not externally.

Type1 is a class so we can’t extend it from the interface. I want to make an interface that can be implemented only by any of the children of Type1

I think this concept of restricted implementators is just a more complicated way of achieving functionality that is usually provided by mixins. But Java/Kotlin doesn’t have mixins.

Just make Type1 an interface and create Type1Impl class. Don’t require anyone to use Type1Impl class specifically, but Type1 interface instead. This is a common pattern in Java, used for decades already. We use interfaces for requirements and classes provide implementations. If we require others to use a specific class, the code becomes less flexible and harder to extend.

interface SomeInterface<Self : Type1>
{
    fun someWork()
    {
        if (this !is Self)
           throw WrongSelfTypeException("")
         ...
    }
}

Now we can make code with same meaning.

But if Type1 is class from library?

Interfaces with bounds for implementors are a kind of feature for that(Type1 in our example) class. We needn’t implement code except specific feature configuration.

If a library provided a class and requires its users to extend it then I would say it is not well designed and your problems are actually caused by this design. If it would be an interface, you would not need any specific language feature to do what you need.

Anyway, if you want subtypes of IterableType1 to extend Type1, then why not to make IterableType1 an abstract class extending Type1?

Yes! Making it an abstract class is a common solution. But if I have more than one feature? I can’t extend the class from 2 abstract classes.

Ok, I think I finally see your point. Still, I think the root cause of this design problem is that we/someone used a class where interface should be used. Unfortunately, I don’t see a good solution to this problem. Also, I’m not sure if Kotlin could add such features, because it is designed for Java interop and Java type system doesn’t support this.

I’ve sent code higher. The proposed feature can be compiled into it

For now probably your best option is to not inherit from Item1 for this purpose, but instead use composition and put it into your own type hierarchy. See this example:

// we don't control this
open class Animal(val name: String)

interface AnimalEx {
    val animal: Animal

    // optionally
    val name get() = animal.name
}

interface FlyingAnimal : AnimalEx {
    fun fly()
}

interface BarkingAnimal : AnimalEx {
    fun bark()
}

class Birdog : FlyingAnimal, BarkingAnimal {
    override val animal = Animal("birdog")
    override fun fly() { ... }
    override fun bark() { ... }
}

Of course, animals are not subtypes of Animal, however, we can very easily acquire their animal prop whenever needed.

Om… Yes, it is king of solution.

But it doesn’t make this feature useless. After coding on rust and scala, living without it becomes hard.

Type traits as you’ve seen them in other languages aren’t coming to Kotlin (at least anytime soon). They are kinda globally present never declared imports for implicit conversion. The Kotlin team would rather address the problematic use cases in another manner.

Context receivers are on the way. So you’ll be able to define a context receiver with the functionality that you are trying to add to an existing type and then you’ll explicitly bring it into scope.

Until then, use composition and wrap the original type. If you have two abstract classes, then you need two wrappers.

As you can see, I didn’t called this thread as 'Traits in kolin. I called it bounds for implementors`. The context recievers doesn’t fix to my problem.

I want to make interfaces more usuable as features for existing type. This features can be overrided, configured from implementors. It is like extending multiple abstract classes without diamond problem.