Pseudocode styling, to make it less painful on mobile browsers

This commit is contained in:
Tony Garnock-Jones 2022-03-03 17:26:43 +01:00
parent 8610673851
commit a9f673e4ae
2 changed files with 22 additions and 10 deletions

View File

@ -121,7 +121,7 @@ representing spreadsheet cells. Each cell entity publishes public aspects of its
interested peers: namely, its current value. It also responds to messages instructing it to interested peers: namely, its current value. It also responds to messages instructing it to
update its formula. In pseudocode: update its formula. In pseudocode:
    ` 1:`**define entity** Cell(*formula*): <span class="pseudocode">    ` 1:`**define entity** Cell(*formula*):
    ` 2:`    *subscribers* ← ∅     ` 2:`    *subscribers* ← ∅
    ` 3:`    **on** assertion from a peer of interest in our value,     ` 3:`    **on** assertion from a peer of interest in our value,
    ` 4:`        add *peer*, the entity reference carried in the assertion of interest, to *subscribers*     ` 4:`        add *peer*, the entity reference carried in the assertion of interest, to *subscribers*
@ -136,6 +136,7 @@ update its formula. In pseudocode:
    `13:`    **continuously**, whenever *value* or *subscribers* changes,     `13:`    **continuously**, whenever *value* or *subscribers* changes,
    `14:`        **assert** the contents of *value* to every peer in *subscribers*,     `14:`        **assert** the contents of *value* to every peer in *subscribers*,
    `15:`        **retract**ing previously-asserted values     `15:`        **retract**ing previously-asserted values
</span>
Much of the subscription-management behaviour of Cell is generic: lines 26 managing the Much of the subscription-management behaviour of Cell is generic: lines 26 managing the
*subscribers* set and lines 1314 iterating over it will be common to any entity wishing to *subscribers* set and lines 1314 iterating over it will be common to any entity wishing to
@ -149,18 +150,20 @@ Hayes modem command strings) paired with *continuations* represented as entity r
responses the modem sends in reply to a command string are delivered to the continuation entity responses the modem sends in reply to a command string are delivered to the continuation entity
as a SAM message. as a SAM message.
    ` 1:`**define entity** Server(): <span class="pseudocode">    ` 1:`**define entity** Server():
    ` 2:`    **on** assertion Request(*commandString*, *replyEntity*)     ` 2:`    **on** assertion Request(*commandString*, *replyEntity*)
    ` 3:`        output *commandString* via modem serial port     ` 3:`        output *commandString* via modem serial port
    ` 4:`        collect response(s) from modem serial port     ` 4:`        collect response(s) from modem serial port
    ` 5:`        **send** response(s) as a message to *replyEntity*     ` 5:`        **send** response(s) as a message to *replyEntity*
</span>
    ` 6:`**define entity** Client(*serverRef*):
<span class="pseudocode">    ` 6:`**define entity** Client(*serverRef*):
    ` 7:`    **define entity** *k*:     ` 7:`    **define entity** *k*:
    ` 8:`        **on** message containing responses,     ` 8:`        **on** message containing responses,
    ` 9:`            **retract** the Request assertion     ` 9:`            **retract** the Request assertion
    `10:`            (and continue with other tasks)     `10:`            (and continue with other tasks)
    `11:`    **assert** Request(`"AT+CMGS=..."`, *k*) to *serverRef*     `11:`    **assert** Request(`"AT+CMGS=..."`, *k*) to *serverRef*
</span>
This is almost a standard continuation-passing style encoding of remote procedure This is almost a standard continuation-passing style encoding of remote procedure
call.[^rpc-sam-discussion] However, there is one important difference: the request is sent to call.[^rpc-sam-discussion] However, there is one important difference: the request is sent to
@ -193,7 +196,7 @@ the factoring-out of dataspaces.
A special kind of syndicated actor entity, a *dataspace*, routes and replicates published data A special kind of syndicated actor entity, a *dataspace*, routes and replicates published data
according to actors' interests. according to actors' interests.
    ` 1:`**define entity** Dataspace(): <span class="pseudocode">    ` 1:`**define entity** Dataspace():
    ` 2:`    *allAssertions* ← ∅     ` 2:`    *allAssertions* ← ∅
    ` 3:`    *allSubscribers* ← ∅     ` 3:`    *allSubscribers* ← ∅
    ` 4:`    **on** assertion of semi-structured datum *a*,     ` 4:`    **on** assertion of semi-structured datum *a*,
@ -211,6 +214,7 @@ according to actors' interests.
    `16:`        if *a* matches Observe(*pattern*, *subscriberRef*),     `16:`        if *a* matches Observe(*pattern*, *subscriberRef*),
    `17:`            remove (*pattern*, *subscriberRef*) from *allSubscribers*     `17:`            remove (*pattern*, *subscriberRef*) from *allSubscribers*
    `18:`            retract all assertions previously sent to *subscriberRef*     `18:`            retract all assertions previously sent to *subscriberRef*
</span>
Assertions sent to a dataspace are routed by pattern-matching. Subscriptions—tuples associating Assertions sent to a dataspace are routed by pattern-matching. Subscriptions—tuples associating
a pattern with a subscriber entity—are placed in the dataspace as assertions like any other. a pattern with a subscriber entity—are placed in the dataspace as assertions like any other.
@ -297,7 +301,7 @@ modem examples from above.
### Spreadsheet cell with a dataspace ### Spreadsheet cell with a dataspace
    ` 1:`**define entity** Cell(*dataspaceRef*, *name*, *formula*): <span class="pseudocode">    ` 1:`**define entity** Cell(*dataspaceRef*, *name*, *formula*):
    ` 2:`    **continuously**, whenever *value* changes,     ` 2:`    **continuously**, whenever *value* changes,
    ` 3:`        **assert** CellValue(*name*, *value*) to *dataspaceRef*     ` 3:`        **assert** CellValue(*name*, *value*) to *dataspaceRef*
    ` 4:`    **continuously**, whenever *formula* changes,     ` 4:`    **continuously**, whenever *formula* changes,
@ -308,6 +312,7 @@ modem examples from above.
    ` 9:`            **assert** Observe(⌜CellValue(*n*, *?nValue*)⌝, *k*) to *dataspaceRef*     ` 9:`            **assert** Observe(⌜CellValue(*n*, *?nValue*)⌝, *k*) to *dataspaceRef*
    `10:`    **on** message conveying a new formula,     `10:`    **on** message conveying a new formula,
    `11:`        *formula* ← *newFormula*     `11:`        *formula* ← *newFormula*
</span>
The cell is able to outsource all subscription management to the *dataspaceRef* it is given. The cell is able to outsource all subscription management to the *dataspaceRef* it is given.
Its behaviour function is looking much closer to an abstract prose specification of a Its behaviour function is looking much closer to an abstract prose specification of a
@ -319,20 +324,22 @@ There are many ways to implement RPC using dataspaces,[^rpc-sam-discussion] each
characteristics. This implementation uses anonymous service instances, implicit service names, characteristics. This implementation uses anonymous service instances, implicit service names,
asserted requests, and message-based responses: asserted requests, and message-based responses:
    ` 1:`**define entity** Server(*dataspaceRef*): <span class="pseudocode">    ` 1:`**define entity** Server(*dataspaceRef*):
    ` 2:`    **define entity** *serviceRef*:     ` 2:`    **define entity** *serviceRef*:
    ` 3:`        **on** assertion of *commandString* and *replyEntity*     ` 3:`        **on** assertion of *commandString* and *replyEntity*
    ` 4:`            output *commandString* via modem serial port     ` 4:`            output *commandString* via modem serial port
    ` 5:`            collect response(s) from modem serial port     ` 5:`            collect response(s) from modem serial port
    ` 6:`            **send** response(s) as a message to *replyEntity*     ` 6:`            **send** response(s) as a message to *replyEntity*
    ` 7:`    **assert** Observe(⌜Request(*?commandString*, *?replyEntity*)⌝, *serviceRef*) to *dataspaceRef*     ` 7:`    **assert** Observe(⌜Request(*?commandString*, *?replyEntity*)⌝, *serviceRef*) to *dataspaceRef*
</span>
    ` 8:`**define entity** Client(*dataspaceRef*):
<span class="pseudocode">    ` 8:`**define entity** Client(*dataspaceRef*):
    ` 9:`    **define entity** *k*:     ` 9:`    **define entity** *k*:
    `10:`        **on** message containing responses,     `10:`        **on** message containing responses,
    `11:`            **retract** the Request assertion     `11:`            **retract** the Request assertion
    `12:`            (and continue with other tasks)     `12:`            (and continue with other tasks)
    `13:`    **assert** Request(`"AT+CMGS=..."`, *k*) to *dataspaceRef*     `13:`    **assert** Request(`"AT+CMGS=..."`, *k*) to *dataspaceRef*
</span>
If the service crashes before replying, the client's request remains outstanding, and a service If the service crashes before replying, the client's request remains outstanding, and a service
supervisor [[Armstrong 2003][], section 4.3.2] can reset the modem and start a fresh service supervisor [[Armstrong 2003][], section 4.3.2] can reset the modem and start a fresh service

View File

@ -6,3 +6,8 @@ div.ditaa {
svg text { svg text {
font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace !important; font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace !important;
} }
span.pseudocode {
white-space: nowrap;
overflow: auto;
}