Swift algorithms rely heavily on generics, but being generic doesn't necessarily mean that an algorithm can accept any instance type. Often the instance types that can be accepted by an algorithm are restricted to ones that adopt or inherit a certain protocol. For example extend() requires that the instance being extended adopts the Sequence protocol (S : Sequence) and that the extension is made up of elements of the same type as contained in the sequence being extended (hence T == T).

func extend<S : Sequence where T == T>(sequence: S)

So how do we know that extend(), for example, can accept both an array and a string? Well, the Array type adopts the MutableCollection protocol, which in turn adopts the Collection protocol, which finally adopts the Sequence protocol. This means that the Array type inherits the Sequence protocol down the chain and so we can do this:

var array = ["one","two"] array.extend(["three","four"])

Likewise String adopts the Collection protocol and, as before, this in turn adopts the Sequence protocol. Again we have inheritance of the Sequence protocol and so can do this:

var string = "Hello," string.extend(" #Swift!")