Automatically adopt and conform to protocol based on the nested property

Currently, there is needed a boilerplate when it comes to protocol conformance especially for generic classes that are used as a box, decorator, etc.

To better visualize the problem take a look at this example:

protocol SomeProtocol {
    func someFunction()
}

class ClassA: SomeProtocol {
    var test: String = ""
    func someFunction() {
        print("\(#function)")
    }
}

class WeakBox<T: Any> {
    private weak var _value: AnyObject?
    var value: T? {
        return _value as? T
    }

    init(value: T) {
        self._value = value as AnyObject
    }
}

let x = WeakBox(value: ClassA())

func dependency(some: SomeProtocol) {
    print(some)
}

dependency(some: x) // Argument type 'WeakBox<ClassA>' does not conform to expected type 'SomeProtocol'

WeakBox of course does not conform to SomeProtocol as the error message describes.
To fix that currently we use to do:

extension WeakBox: SomeProtocol where T: SomeProtocol {
    func someFunction() {
        value?.someFunction()
    }
}

In case when we have more WeakBox class usages in a project where protocols need to be adopted there is more and more code needed just to delegate function/variable calls to the underlying implementation.

I'm aware that as the example when e.g. the underlying property is optional how the auto conforms feature should behave or what kind of syntax we could use to handle it.

I don't have a good candidate, how this could be expressed, so I hope if the community will find this value we will find good approach. Anyway just to start it might look like this:

@autoProtocolConform
extension WeakBox: SomeProtocol where T: SomeProtocol {
    var conformer: SomeProtocol: { self._value as! SomeProtocol }
}

I wonder if it would be well received and widely used. What do you think?

This is a specific example of creating a “newtype” and protocol forwarding. It’s been talked about a few times on this list and you can find those conversations using the search feature. Those discussions may help you to fully flesh out your idea. But yes, you’ve definitely identified an area that could use some improvement.

1 Like

I recently suggested something similar in another related, more focused, pitch thread.

I think it would be better to annotate the conforming member, rather than the type (and always use conformer), since it would allow a type to conform to many protocols, but forward each protocol conformance to different children. See a motivating example further down in the mentioned thread, where Task conforms to both Collection and Comparable, by delegating to different members.

Anyways: Bikeshedding syntax aside, I think this is a problem worth discussing.

2 Likes

If we ever get the @implements attribute, then I think it’s a pretty easy win to be able to say that a property implements an entire protocol (or even several protocols).

2 Likes