Are type-erased Any... structs necessary for non-generic protocols? - swift

When defining a generic Swift protocol (that is, a protocol with at least one associatedtype) for a framework, it's common practice to also provide an Any... struct, e.g. SomethingType and AnySomething. For example, the standard library does this with AnySequence.
Is this necessary for a non-generic protocol? In that case, you can refer to the protocol type directly, so it seems that the protocol itself is already a type-erased version?

A protocol that does not have an associated type can easily be used as a Type in its own right. This is often done to allow diverse concrete types to be stored in collections identifying them only by a common protocol that all the concrete types implement.
Or to put it another way "type erasing" is a technique for dealing with protocols that have associated types. If your protocol does not have associated types, there is no need to employ the technique.

Related

Is there an equivalent in swift to Go's empty interface?

Is there an equivalent in Swift to pass as an argument an empty interface{} like in Go?
I am not very familiar with Go, but I think the Swift equivalent would be an argument of type Any or AnyObject. You can't do much with such an argument other than try to cast it to a more specific type.
Go's interfaces and Swift's protocols are quite different:
Golang's interfaces are "structural" (akin to C++'s "Concepts"), meaning that their identity is defined by their structure. If a go struct has the structure required by an interface, it implicitly implements that interface. That is, the struct doesn't say anywhere "I am strust S, and I implement interface I."
Swift's protocols are "nominal", meaning that their identity is defined their name. If a Swift struct fulfills all of the requirements of a protocol, it doesn't conform to that protocol, unless an explicit struct S: P { ... } declaration is made (the body of that declaration can even be empty, but it's still necessary for the conformance to exist).
The closest analogue to interface{} in Swift is Any. It's built-in protocol to which all type conform. It gets special treatment, it's defined by the compiler, and has hard-coded logic to make all other types conform to it. You won't see protocol Any {} or struct S: Any {} declared anywhere explicitly. AnyObject is similar, and also gets special treatment. But no other Swift protocols do. Their conformance need to be explicit.
If I am not mistaking Swift's equivalent would be:
protocol EmptyProtocol {
}
In swift interfaces are called protocols don't ask me :D
Are you trying to do type erasure or something? Just curious...

Swift: Protocol With associatedType

I have a question about Protocol with associated type, why I can not make the protocol a type of my instance for example:
I know I can use Type Erasure to fix the issue, but why protocol with an associated type does not like to be a type of an instance, and if you will say because the associated type is also used as a constraint, well I want to implement the properties inside the protocol not inside its extensions since protocol extensions has the power to control who can access its properties, why we still have this issue.
Thank you.
There are lots of articles and answers (like this one) out there describing why but in summary, It needs associatedtype. Variables can not have an associatedtype. So alongside with Type Erasure method (that you don't want), you can simply make it opaque with adding some keyword to the type:
var objectA: some ProtocolA = A()

Binary operator '==' cannot be applied to two 'Equatable' operands... what?

You can see in the image below that I was trying to extend the Collection protocol to include a method called removingDuplicates, which is supposed to do exactly what it says. The error that the compiler is displaying seems to directly contradict the definition of the Equatable protocol. Is this a bug or am I misunderstanding something?
Replace Element == Equatable with Element: Equatable.
The == function (all operators are actually functions in Swift) is a requirement of the Equatable protocol, which means it must be used with some concrete implementations of the protocol.
Another aspect is that Collection is a generic type, and its Element associated type will need to eventually be also filled with a concrete type, and == Equatable doesn't help here.
Actually it's not even possible to have a collection of generic Equatable values, as Equatable is a protocol with Self requirements, thus it can be directly referenced in a lot of places, e.g. [Equatable], one reason being the fact that that declaration can't satisfy the "collections are homogenous" requirement as you'd be able ot place two completely unrelated types in the array that way.
What you need to do is to transform the equality where clause to a conformance one: extension Collection where Element: Equatable. This moves the burden of providing an actual implementation on the user of the extension. And allows you to use the support brought by the Equatable type.

How should protocol/implementation pairs be adjusted for the Swift API design guidelines?

In the new Swift API design guidelines, the commonly-used Type suffix for protocols is being dropped. While this is easy to do for protocols that are stand-alone (SequenceType becomes Sequence), I'm not sure how to update my APIs in which a protocol provides the base for an implementation. Here's some examples from popular frameworks:
The Result µframework provides Result, a concrete success/fail enumeration, and ResultType, a generic base protocol for a success/fail type, to which Result conforms.
ReactiveCocoa's main types are Signal and SignalProducer, which are backed by SignalType and SignalProducerType.
In both cases, much of the implementation is in extensions of the protocols, allowing extensions to use the full power of type constraints, and allowing the implementations to be generic. This is different from the case of protocols with AnySequence-style type-erasing types: you aren't really expected to implement these protocols on your own, or unify disparate types.
I would advise using the suffix Protocol. This is consistent with how the standard library have stripped the Type suffix from protocols, as stated in SE-0006:
On high level, the changes can be summarized as follows.
Strip Type suffix from protocol names. In a few special cases this
means adding a Protocol suffix to get out of the way of type names
that are primary (though most of these we expect to be obsoleted by
Swift 3 language features).
For example, GeneratorType was renamed to IteratorProtocol.
And, for example, is also how both Result & ReactiveSwift have updated their APIs for Swift 3. ResultType was renamed to ResultProtocol (in this commit), and SignalType was renamed to SignalProtocol, and SignalProducerType was renamed to SignalProducerProtocol (in this commit).
Although it's worth noting that in a vast majority of these cases, such protocols only exist as a workaround for the lack of parameterised extensions.
For example, we cannot currently say:
struct SomeGenericThing<T> {
var value: T
}
extension <T> Array where Element == SomeGenericThing<T>, T : Comparable {
}
But introducing a protocol allows us to realise the generic placeholder(s) as associated type(s), which we can then use in constraints:
protocol SomeGenericThingProtocol {
associatedtype T
var value: T { get set }
}
struct SomeGenericThing<T> : SomeGenericThingProtocol {
var value: T
}
extension Array where Element : SomeGenericThingProtocol, Element.T : Comparable {
// ...
}
Therefore once parameterised extensions are supported, we'll be able to do away with such protocols.

Use of a Structure instead of a Class in Swift [duplicate]

This question already has answers here:
Why Choose Struct Over Class?
(17 answers)
Closed 7 years ago.
I learn Swift from some time, I know the differences between structure and class. The main difference is structure is of value type and class is of reference type but didn't understand when to use structure instead of a class. Please explain it.
For example, In case of Protocols:
First, We have just a protocol of struct type:
protocol SomeProtocol{
func doSomeStuff()
}
Second, We make protocol of class type like this:
protocol SomeProtocol: class{
func doSomeStuff()
}
So, Please explain me, when we have to use protocol of struct type or of class type.
Firstly structs are passed by value (copied), and a class is passed by reference (copied just the memory address to the object).You may want to use structs for simpler types, because you get a free init for all the properties your struct has.And with protocols, the first one you can use it on class,struct and enum, the second you say that you only use that on classes,and you may want to put class if your protocol is a delegate or a data source,because you want the property(of the type of your protocol) weak to avoid the memory cycle. IMHO use classes for multi-scene apps because you don't need to take care to update value when you edited something in an another scene.
The protocol is not "of struct type" or "of class type", that is wrong terminology.
If you write SomeProtocol: class you make sure only classes can conform to that protocol, structs cannot. If you don't include the class both classes and structs can conform.
The docs (scroll down to "Class-Only Protocols") tell you that
You can limit protocol adoption to class types (and not structures or enumerations) by adding the class keyword to a protocol’s inheritance list. The class keyword must always appear first in a protocol’s inheritance list, before any inherited protocols.
Use a class-only protocol when the behavior defined by that protocol’s requirements assumes or requires that a conforming type has reference semantics rather than value semantics. For more on reference and value semantics, see Structures and Enumerations Are Value Types and Classes Are Reference Types.