Lake

Protocols

A protocol is Lake's interface/trait: a named set of method requirements a type can implement. Protocols give polymorphism without inheritance — a type opts in to a behaviour, it does not extend a base class.

§Declaring a protocol

A protocol lists required methods. Self stands for the implementing type:

lake
Eq is proto {
  eq is { Self Self -> i64 }
}

§Implementing a protocol

Implementation is nominal and checked. A type declares it implements a protocol with Type is Proto, and must actually provide the methods:

lake
Color is enum { Red Green }

pub eq is {
  a Color b Color -> ret i64 { ret 1 }
}

Color is Eq          # asserts Color implements Eq

If the required eq machine were missing, the compiler rejects the program with an error — you cannot promise a protocol you do not provide.

§Bounds and dispatch

Protocols constrain generic parameters:

lake
same[T: Eq] is {
  a T b T -> ret i64 { ret eq(a b) }
}

Dispatch is static: there are no vtables. Protocol-bounded code is monomorphised, and the right method is chosen by argument types at compile time, so a protocol call is a direct call with no runtime indirection — consistent with Lake's “native, no runtime” philosophy.

§Inheritance between protocols

A protocol may require another with +:

lake
Ord is proto +Eq {
  cmp is { Self Self -> i64 }
}

X is Ord then obliges X to provide both cmp and (via +Eq) eq.

§Operators are protocols

The subscript operator [] is the Index protocol. A composite type opts into v[i] by declaring is Index and providing an index method — which is exactly how Vec supports v[i]:

lake
Index is proto { index is { Self i64 -> T } }
Vec is Index

§Connection to OOP

Protocols are interfaces; records and enums are the data; machines and actors are objects that communicate by messages. Together they give an object model where polymorphism comes from composition and constraints, not from a class hierarchy.

§Key ideas

  • proto declares method requirements over Self.
  • Type is Proto is a checked, nominal implementation claim.
  • [T: Proto] bounds generics; dispatch is static (monomorphised, no vtables).
  • Protocols inherit with +Parent; operators like [] desugar to protocol methods.