Skip to content

Protocols and Conformances ​

Implementation status: protocol declarations / conformance / witness tables / default implementations / associated types / existential types any P Implemented; Self constraints / protocol composition / protocol extension where / HKT witness Partially implemented; class-only protocol Not implemented


Protocol Declarations ​

protocol-decl ::= access? attrs? 'protocol' identifier generic-params?
                 (':' type (',' type)*)? where-clause? '{' protocol-member* '}'

protocol-member ::= protocol-method
                 |  protocol-property
                 |  protocol-init
                 |  protocol-associatedtype
                 |  protocol-method-with-default
swift
protocol Equatable {
    func ==(lhs: Self, rhs: Self) -> Bool
}

protocol Sequence {
    associatedtype Element
    func makeIterator() -> Iterator
}

protocol Iterator {
    func next() -> Element?
}
ElementDescription
func name(params) -> RRequired method
var name: T { get }Required get-only property
var name: T { get set }Required get + set
static func nameRequired type method
init(params)Required initializer
associatedtype XAssociated type
typealias X = YAssociated type default (Partially implemented)
Default implementationA method body may be provided inside the protocol

Conformance ​

conformance ::= type ':' protocol (',' protocol)*
             |  extension type ':' protocol where-clause? '{' … '}'
swift
class MyClass: Equatable, CustomStringConvertible {
    func ==(lhs: MyClass, rhs: MyClass) -> Bool { … }
    func description() -> String { … }
}

extension Array: CustomStringConvertible { … }

A class declaration's : Protocol list triggers witness table generation (partial path). Conformance is declared at a single point within a module (to avoid cross-file conflicts).

Diagnostics: S006 (Iterator missing next), S010 (does not conform), S012 (associated type)

Built-in Protocols ​

ProtocolDescriptionImplicit conformance
Equatable==Built-in value types
HashableHashingBuilt-in value types
ComparableOrdered comparisonNumeric types GA
CustomStringConvertible.description()Built-in value types
CustomDebugStringConvertibleDebug descriptionBuilt-in value types
Encoder / DecoderFormat-agnostic codec sinkProtocol surface pinned (ADR-230; container API → S7-02)
Encodable / Decodable / CodableSerializationProtocol surface pinned (Codable: Encodable, Decodable); @Codable / JSON.encode are the default back end
Iteratornext()Declaration checking
Sequence / CollectionIterationPartially implemented
SendableCross-isolation safetyExplicit annotation
ErrorError typeUser-defined

Defined in crates/syx-stdlib/src/protocols.rs.

Protocol Default Implementations ​

swift
protocol Greetable {
    func greet() -> String
    func greet() -> String { return "Hello" }   // Default
}

class User: Greetable {
    // Inherits the default → "Hello"
}

class Loud: Greetable {
    func greet() -> String { return "HI!" }    // Override
}

Default implementations are declared through an extension or a method body inside the protocol (Phase 50+).

Dynamic Dispatch ​

FormDispatch mechanism
class + protocolWitness call (CallWitness)
opaque someConcrete at compile time (no virtual dispatch)
any P existentialRuntime witness table
swift
protocol Named { func name() -> String }

class A: Named { func name() -> String { return "A" } }
class B: Named { func name() -> String { return "B" } }

func greet(_ n: Named) { print("hi \(n.name())") }
greet(A())                                    // "hi A"
greet(B())                                    // "hi B"

Protocols as Types ​

protocol-type ::= 'any' protocol
              |  'some' protocol
FormMeaning
some POpaque result (concrete at compile time)
any PExistential type (runtime witness)
swift
func make() -> some Equatable { 42 }          // Int at compile time
let p: any CustomStringConvertible = obj      // Runtime witness

See Language Guide: Opaque Types.

Associated Types ​

swift
protocol Container {
    associatedtype Item
    func add(_ item: Item)
    func get(at: Int) -> Item
}

class IntStack: Container {
    typealias Item = Int
    var items: Array<Int> = []
    func add(_ item: Int) { items.append(item) }
    func get(at i: Int) -> Int { return items[i] }
}

Automatic inference: when the add / get signatures uniquely determine Item, typealias Item = … may be omitted.

Protocol Extension Constraints ​

protocol-extension ::= 'extension' type ':' protocol where-clause? '{' … '}'
                    |  'extension' type where-clause? '{' … '}'
swift
extension Collection where Element: Equatable {
    func unique() -> [Element] { … }
}

Status: protocol extension constraints are Partially implemented; multi-constraint where clauses since Phase 42+.

Protocol Composition ​

swift
protocol A { func a() }
protocol B { func b() }

func use<T: A & B>(_ x: T) {
    x.a()
    x.b()
}

Status: & composition constraints are Partially implemented (basic T: A & B works); use where T: A, T: B for the full form.

Self Constraints ​

swift
protocol Equatable {
    func ==(lhs: Self, rhs: Self) -> Bool
}

Self refers to the concrete type implementing the protocol. Status: Partially implemented (basic witness dispatch works).

@unchecked Sendable ​

swift
@unchecked Sendable
class MyLegacy {
    var internal: Int = 0
}

Suppresses Sendable checking; external synchronization is required to guarantee thread safety.

Encoder / Decoder / Codable Protocols (ADR-230 / M2-S7-01) ​

swift
public protocol Encoder { }
public protocol Decoder { }
public protocol Encodable { }
public protocol Decodable { }
public protocol Codable: Encodable, Decodable { }

The protocol layer provides an extensible encoding abstraction; the default back end is still dynamic JSON.encode / synthesis by the @Codable macro (not JSONEncoder GA).

swift
@Codable
data class User(name: String, age: Int)

@Codable
enum Status {
    case ok
    case err
}

Status: the protocol surface was pinned by ADR-230; JSONEncoder/JSONDecoder + codingPath pinned by ADR-231 / M2-S7-02; JSONStream NDJSON session + chunk feed pinned by ADR-232 / M2-S7-03 (codingPath=line[N].…; S7 closed out). @Codable L1 GA; L2 associated-value enums partial GA. Not a CodingKeys DSL / metatype T.Type / real File S3-03 streaming / IANA.

Use with Extensions ​

swift
extension MyType: CustomStringConvertible {
    func description() -> String { return "MyType" }
}

A protocol conformance may be declared at the original type declaration or in a separate extension. SYX allows cross-module extensions (Phase 60+).

Synthesized Conformance ​

The @Equatable / @Hashable / @Codable macros synthesize witnesses automatically on data class and associated-value enums:

swift
@Equatable
@Hashable
@Codable
data class Point(x: Int, y: Int)

See Attributes and Language Guide: Macros.

Witness Table Implementation ​

class + protocol → witness table (runtime dispatch):

  • A class holds witness_table: *const WitnessTable
  • The CallWitness instruction goes through the witness table
  • Multiple protocols: one table per protocol
swift
class Multi: A, B, C {
    func a() { … }
    func b() { … }
    func c() { … }
}

Internally the class stores three tables: witness_a / witness_b / witness_c.

Differences from Swift ​

SwiftSYX
Protocol declarationImplemented
Default implementationImplemented (inside protocol + extension)
Associated typesImplemented
Self constraintsPartially implemented
class-only protocolNot implemented (use a class constraint)
protocol extension wherePartially implemented
protocol composition &Partially implemented
Existential any PImplemented (witness table)
Opaque result some PImplemented
retroactive conformanceAllowed across modules (unlike Swift)
_const protocolsNot implemented

Complete Example ​

swift
protocol Shape {
    func area() -> Double
    func describe() -> String
}

class Circle: Shape {
    var r: Double
    init(r: Double) { self.r = r }
    func area() -> Double { return 3.14159 * r * r }
    func describe() -> String { return "circle r=\(r)" }
}

class Square: Shape {
    var s: Double
    init(s: Double) { self.s = s }
    func area() -> Double { return s * s }
    func describe() -> String { return "square s=\(s)" }
}

func total(_ shapes: Array<Shape>) -> Double {
    var sum = 0.0
    for s in shapes { sum = sum + s.area() }
    return sum
}

func main() {
    let shapes: Array<Shape> = [Circle(r: 2.0), Square(s: 3.0)]
    for s in shapes { print(s.describe()) }
    print("total=\(total(shapes))")
}

Diagnostics: S006 / S010 / S012 / S015 / S016 / P001

Usage examples → Language Guide: Protocols

See also → Types · Declarations · Generic Parameters · Attributes

SYX · Apache-2.0