Differences between type-inheritance clause & protocol composition syntax?

Four years ago, Swift 4 introduced protocol compositions to Swift via SE-0156, with a review in early 2017, which finally added a long-awaited Obj. C feature via the new single-ampersand syntax for type declarations:

protocol A{}
protocol B{}
class C: A & B {}

However, for reasons that weren't immediately apparent from scanning the old review thread, we also kept what our current documentation describes as a "type inheritance list", which uses a comma separator as opposed to an ampersand:

class D: A, B {} 
class E {}
class F: E, A, B {} 

You can even combine them:

class E {}
class F: E, A, B {}
class G: E & A, B {} // ew
class H: E, A & B {} // yuck
class I: A & B & E {} // if it's all ampersands, the class doesn't have to be first
class J: A & B, E {} // won't compile bc there's a comma and the class isn't first

From what I can tell, these are the differences between the comma and ampersand syntax:

  • if a comma is present, and a class is in the list of types, then the compiler requires that the the class appear first in the list
  • the comma-separated variety can only appear in a type inheritance clause, but not in the type of a variable, typealias, tuple param, or function param

This begs the question of, why would you ever choose comma over ampersand for a type inheritance clause? Is it a purely stylistic thing or is there some functional difference that I'm missing?

Thank you for any insights!


Whlie it’s not a technical difference, if you use type aliases, then you might need to use both, sort of.

protocol P { … }
protocol A { …. }
protocol B { …. }
typealias MyCombo = P & A

struct S1: P { … }
struct S2: MyCombo, B { … }
struct S3: MyCombo { … }
Terms of Service

Privacy Policy

Cookie Policy