Skip to content

Concepts and construction

Joshua Reynolds edited this page Oct 7, 2026 · 1 revision

Concepts and construction

Use a concept-like declaration to group the operations you promise. Choose the word that communicates the role in your design: concept, component, class or interface. All use the same .expec member syntax. The selected output decides how that role maps to its format.

Describe a component

main.expec

type SystemConfig {
  gameRoot: Text
}
interface Storage {
  public save
  capability save(snapshot: Text) returns Nothing
}
component StoreGame {
  depends on SystemConfig, Storage
  construction(config: SystemConfig, storage: Storage)
  public startup, save
  capability startup() returns Nothing
  capability save(snapshot: Text) returns Nothing
}

depends on records a reference to an existing concept or type. It does not declare that type, install a package, or create a field. Types declared in the same available scope need no import. A type in another file must be made available explicitly.

construction(...) describes construction inputs. It does not implicitly make config or storage parameters of every capability, declare storage fields, or provide an implementation. There can be one construction declaration per owner. construction() explicitly asks for no inputs; omitting construction leaves it unspecified.

Public capabilities

A capability is public only when listed in public. List existing capability names separated by commas. Their spelling must match the declarations, including quoted names. A public list is a contract, not a collection of suggested operations.

Do not assume all declared capabilities are public. Another component's typed receiver and authored interaction can use its public contract, while owner-scoped examples can specify internal behavior.

Local declarations

local declares a concept-like or type declaration inside an owner. Use it for private specification details. A public signature must not expose a local type, including through an alias or generic argument.

main.expec

concept StoreGame {
  local type SessionState {
    title: Text
  }
  capability remember(state: SessionState) returns Nothing
  public stop
  capability stop() returns Nothing
}

Here remember is not public, so it can use SessionState. Listing remember as public would expose that private type.

Extend a concept

extend adds members to an existing concept-like declaration when the source is composed. It does not replace an existing capability or turn a record into a class.

main.expec

concept StoreGame {
  public startup
  capability startup() returns Nothing
}
extend StoreGame {
  public stop
  capability stop() returns Nothing
}

When you check or build the selected source files, extensions are composed with their existing declarations. Extensions keep their own source locations and lexical dependencies. Duplicate members are errors.

Relationships

Dependencies, construction inputs, fields, parameters and results establish typed connections. Those connections do not imply ownership or lifetime. Use Interactions to author a sequence of messages; no separate owns, relates or relationship declaration is required.

Related: Capabilities and contracts · Dependencies and files · Types

Clone this wiki locally