← board

Interfaces

Priority note (2026-06-16, refined 2026-06-18)

Low priority, but the OOP-family capstone — not "never". Interfaces are largely a COM-era binary-contract mechanism (cross-binary ABI stability: Windows COM, OLE). PXX targets standalone, all-in-one-binary applications, so that primary value does not apply, and the secondary value (inheritance-free polymorphic abstraction + ARC lifetime) is covered by classes, abstract methods, and object (feature-object-reference-type). So it stays low — but it is the last gap in the OOP feature set, and deferring it forever means repeatedly bumping into it. Do it eventually, after the other OOP pieces; pull forward only if a concrete interop need appears.

Effort is MEDIUM, not the scary arc the original note implied — the expensive substrate already exists: VMT + virtual dispatch, the RTTI class registry, ARC refcounts (managed-string IncRef/DecRef), and scope-exit + exception-unwind finalisation. CORBA-style (no refcount, fat-pointer {IMT, instance}, is/as/ Supports via the RTTI walk) is ~2–4 focused days; COM-style ARC is an incremental add reusing the existing ARC + scope-cleanup machinery.

Item 5 is extracted. Class is/as/Supports (the runtime type-walk) is now its own ticket feature-class-is-as — useful independently (class downcasts, the demos) and a prerequisite this ticket reuses.

Motivation (original)

A real language gap, but not active: no current target source requires interfaces, and even a lightweight Linux-native model adds substantial dispatch, ABI, and lifetime surface. Ordered after the LFM arc (reuses its class registry / RTTI) if ever taken up.

Decisions to lock first

Mechanism (the work)

  1. Parse IFoo = interface [guid] <signatures> end;.
  2. Class implements: bind each interface method to a class method by name+sig.
  3. Per-(class,interface) Interface Method Table (IMT), distinct from VMT. Choose representation: Delphi-style hidden field + Self-adjusting thunks, or fat pointer {IMT, instance}. Document the choice.
  4. Interface-typed variable storage + class→interface assignment + call slot[k].
  5. is/as/Supports via the class registry.
  6. Operators: assign, identity =/<>, params, results.

Synergy: Self-adjusting IMT thunks suit the new inline asm or a small IR op. Out of scope: implements delegation, interface inheritance depth, method resolution clauses, COM ARC.

Acceptance

IFoo/class-implements/interface-call/is/as/Supports covered by tests; self-host fixedpoint holds.

Log

2026-07-14 — CLOSED. The last open item shipped.

The only thing keeping this in done-followup/ was deferred COM/ARC refcounting. That landed: feature-interface-refcounting is in done/, and both test/test_interface_arc.pas and test/test_interface_arc_exc.pas run green at HEAD (create=2 / freed=2, and freed=3 on the exception-unwind path). b337 then settled the ABI on top of it (an interface VALUE is ONE pointer, FPC-compatible).

Nothing remains under this slug.

Spun out — a real gap found while verifying this

class(TInterfacedObject, IFoo) where TInterfacedObject / IInterface are not declared by the user compiles silently and segfaults at runtime. There is no RTL-provided TInterfacedObject; every interface test in tree declares its own, which is exactly why nobody noticed. That is a missing diagnostic AND an RTL gap, and it is filed separately as [[bug-pascal-tinterfacedobject-missing-silent-segfault]] rather than left buried here.