Interfaces
Goal: understand structural satisfaction (no
implements), vtable dispatch, and the small interfaces that stitch the stdlib together.
Structural satisfaction
Section titled “Structural satisfaction”An interface is a decl with signatures (chapter 03). Implementing the methods already satisfies it: there
is no implements declaration:
decl Writeable { fn write(data: []byte) -> error}
decl Log { ... }fn (l: *Log) write(data: []byte) -> error { ... } // Log now satisfies Writeable, without saying anythingVtable dispatch
Section titled “Vtable dispatch”An interface value carries a pair (a pointer to the data, a pointer to the concrete type’s vtable). The vtable is built by the compiler per type, not per instance: the struct never carries function pointers inline. It is the cost of the pair at the point of use, zero overhead per object:
fn log_to(w: Writeable, msg: string) -> error { // 'w' is an interface value (vtable) return w.write(msg.bytes)}When the result depends on the concrete type (map[A,B](xs: C[A]) -> C[B]), then it is a monomorphized
generic, not a vtable (chapter 10). The rule: an action that does not return the receiver’s type can use
a vtable; a transformation that returns it needs monomorphization.
The small interfaces of the stdlib
Section titled “The small interfaces of the stdlib”Makoto adopts “small composable interfaces”: few, of one or two methods, that everything reuses:
Readable(io):fn read(buf: mut []byte) -> Result[usize, error],Ok(0)= EOF.Writeable(io):fn write(data: []byte) -> error.Display(fmt):fn to_string() -> string; it is what the{{ }}interpolation uses.Iterator[T](io):fn next() -> Optional[T]; it is whatloop x in itconsumes.Serializable(encoding): becomes bytes and back; auto-derived byreflect(chapter 09/10).
Because they are small, they compose: any Readable can be buffered, copied (io.copy), scanned
line by line; any Display can be interpolated; any Iterator can be map/filter/
collect. You implement one method and gain the ecosystem.
sc := io.scanner(io.stdin())loop linha in sc.lines() { process(linha) } // stdin is Readable → scanner → Iterator[string]What is NOT an interface (on purpose)
Section titled “What is NOT an interface (on purpose)”Hash/Ord/Clone/Drop/From do not exist as interfaces. Hashability and order are
derived (by reflect) or functions (fn(T,T) -> Order); copy is @copy-free default and
@promote; cleanup is defer. The comparison/copy axis does not become a family of traits.