Allow typealias to specify the Protocols AssociatedType types

Hi everyone!

I have been several days trying to make some refactoring in my code and after many attempts I think that swift is just incapable of achieving what I want to do, here is my scenario:

The scenario

Imagine you have a framework for basic filtering. This filter looks something like this:

protocol Filtrable
{
    associatedtype FiltrableItem
    associatedtype NewFiltrable : FiltrableDelegate where NewFiltrable.FiltrableItem == FiltrableItem
    func isItemValid(transaction: FiltrableItem) -> Bool
    func filterByNegatingFilter() -> NewFiltrable
}

The framework should include some default auxiliary filters such as "NotFilter", "AndFilter" etc.
Now here is the problem, there is not a current way in Swift to explicitly specify the types of my filters, so I cannot do things like creating an array of Filtrables.

The current workaround

The only possible workaround that I found so far is to create a base class that defines the protocol associated types and create a stub implementation, then I would make each filter inherit from that class. That way I can now create arrays of that base class, but there is a fundamental problem here: I lost the compiler check for conformance of the protocol

As the base type has to implement the protocol, now the child classes don't have to. This can lead to really easy to make mistakes and a lot of testing infra is required just to validate that does not happen. (not to mention that it makes code less maintainable)

My proposing solutions

  1. Allow defining types that specify the protocol associated types

This would be the simplest as now I could do something like:

typealias MyAppSpecificFilter = Filtrable where FiltrableItem = MyAppSpecificType, NewFiltrable = MyAppSpecificFilter

The compiler should be happy because it knows exactly the type its dealing with and now I can have true polymorphism and compiler checks across the apps that use my framework

  1. Allow required to be used in functions

In this scenario I could add "required" to any function in my class and then all subclasses must implement that function too.

The differences between initialization and this scenario would be that methods would not necessarily need to call the super class implementation. This solution would also give kind of the abstract class experience.

Another consideration in this scenario would be that a subclass could use override inside of required and then its subclasses would not be mandated to override the implementation.

The ask

I am asking for feedback regarding this proposals, or if I am missing anything that would make this impossible. I would also love to hear if you have found a better solution than mine to solve this problem.

Thanks for taking the time of reading this!

The feature you’re looking for has been called “generalized existentials” and “enhanced existentials” in prior threads. If you search the forums you’ll find quite a bit of discussion about this feature. Improving the UI of generics is a good place to start.

1 Like