Skip to main content

do

A call to another protocol. do P runs P and comes back; do tail P runs P and never comes back.

component Radar;
component CommandPost;

message struct TrackReport {
    track_id: uint32;
}

message struct Ack {
    track_id: uint32;
}

local protocol Report in Radar {
    send any TrackReport to CommandPost;
    recv _: Ack from CommandPost;
}

local protocol Sweep in Radar {
    do Report;
    send any TrackReport to CommandPost;
}

Targets​

A do in a local protocol names a local protocol on the same component. A do in a global protocol names a global protocol.

  • Execution continues with the statement after a plain do.
  • A protocol may be the target of several do statements, which is how a sequence written once is reused.
  • Only do tail may recurse, directly or through another protocol. A plain do that leads back to itself would have to return to a caller that is still waiting.

tail​

do tail P hands control over for good, so it may appear only where nothing follows it:

  • the last statement of a protocol body, or
  • the last statement of a choice, branch, or listen arm whose own block is in tail position.

That admits the shape a protocol is usually written in — a request and its answer, where one arm repeats and the other stops. It rules out a statement after the do tail, and it rules out a do tail inside a loop body, since a loop repeats on its own rather than by tail call.

component Radar;
component CommandPost;

message struct TrackReport {
    track_id: uint32;
}

message struct Ack {
    track_id: uint32;
}

message struct Reject {
    track_id: uint32;
}

local protocol Sweep in Radar {
    send any TrackReport to CommandPost;
    listen
    | recv _: Ack from CommandPost =>
        do tail Sweep;
    | recv _: Reject from CommandPost =>
    end
}

Sweep reports, and repeats itself as long as the report is acknowledged. The do tail is the last statement of an arm, and the listen is the last statement of the body.

Errors​

Calling a protocol that runs on another component​

A local do continues the caller's own behavior, so the target has to be a protocol of the same component.

component Radar;
component CommandPost;

message struct TrackReport {
    track_id: uint32;
}

local protocol Collect in CommandPost {
    recv _: TrackReport from Radar;
}

local protocol Sweep in Radar {
    send any TrackReport to CommandPost;
    do Collect;   // error: do-component-mismatch
}

A do tail with something after it​

component Radar;
component CommandPost;

message struct TrackReport {
    track_id: uint32;
}

local protocol Sweep in Radar {
    do tail Sweep;                         // error: do-tail-position
    send any TrackReport to CommandPost;
}
  • local protocol — the protocols a local do may name.
  • global protocol — the ones a global do may name.
  • loop, break — repetition written as a block instead of a tail call.
  • listen — the arms a do tail usually sits at the end of.