[Idea] implicit protocols and type oriented protocols


(Adrian Zubarev) #1

Hello Swift community, I’d like to throw a few more ideas on what features future Swift version might or should have.

I’d like to talk about implicit protocols for reference and value types first and then about type oriented protocols.
As everyone know Swift has a great differentiation between reference types (only class) and value types (struct, enum and tuples).

In one of my little projects I could build a workaround, but this wasn’t on parameter level as I'd like it to be:

So I used something like this inside the function scope to differentiate between reference or value types.

guard instance.dynamicType is AnyClass else { return }

This won’t bridge my type to an Objective-C type, but I will know that it’s a class type.

Lets sum up what we already have:

`Any = protocol<>` - The protocol to which all types implicitly conform.
`@objc AnyObject` - The protocol to which all classes implicitly conform.

That been said I’d like to introduce you some new protocols I’d wish Swift to have.

protocol ReferenceType {} or protocol AnyReference {} - The protocol to which all (Swift) classes implicitly conform.

and

protocol ValueType {} or protocol AnyValue {} - The protocol to which all (Swift) value types implicitly conform.

Also it would be good that `AnyObject` would extend from `ReferenceType / AnyReference` protocol.

This will open a few new doors for us to build more specific code. For example we could finally differentiate between value and reference types and overload functions correctly for a specific desire.

Here is an abstract example:

func mutate<T: AnyValue>(value: T, scope: @noescape (value: inout T) -> Void) -> T {
    
var mutableValue = value
scope(value: &mutableValue)
return mutableValue
}

func mutate<T: AnyReference>(value: T, scope: @noescape (value: T) -> Void) -> T {
    
scope(value: value)
return value
}

class A { var x = 0 }
struct B { var y = 1 }

let a = mutate(A()) { $0.x = 10 }
let b = mutate(B()) { $0.y = 42 }

That’s all I have on my mind about implicit protocols right now. Now I’d like to scratch the surface of type oriented protocols.

We already have the ability to create class only protocols like so:

protocol SomeName: class {}

And there is no chance to limit these protocols to value types only, so a library user might be forced to design value types for some purpose.

Does Swift need something like `protocol SomeName: struct {}` or `protocol SomeName: value {}`? What do you think?

If we already had `AnyReference` and `AnyValue` protocols we could drop the `class` keyword for protocols and use `AnyReference` instead. This will also open us the way for creating value types only protocols like so: `protocol ValueProtocol: AnyValue {}`.

Migrating wouldn’t be that hard, because we only have to replace the `class` keyword on protocols with the new `AnyReference` protocol.

Im curious about your feedback.

···

From my point of view Swift still lacks of implicit protocols for these types. Don’t get me wrong, we already have `AnyObject`, but this protocol is a bit tricky, because whenever you use it in your generic function, you "might“ bridge your type to an Objective-C type.

--
Adrian Zubarev