Conversational Concurrency

Tony Garnock-Jones

PhD Dissertation Defense
December 8th, 2017

more than one thing to do

Concurrency

vs.

Parallelism

progress on more than one at once

more than one thing to do

Concurrency

vs.

Parallelism

progress on more than one at once

Simon Marlow:

Concurrency is [...] for structuring your program as a collection of interacting agents. Parallelism, on the other hand, is just about making your programs go faster.

(in a 2008 post to the Haskell-Cafe mailing list)

more than one interacting thing

Concurrency

vs.

Parallelism

progress on more than one at once

more than one interacting thing

Concurrency

more than one interacting thing

Concurrency

is about

  • groups of components
  • working together
  • to achieve some shared goal.

more than one interacting thing

Concurrency

is about

cooperation.

Coordinate

  • arrange to take turns performing helpful tasks
  • via communication

Communicate

  • build shared understanding
  • of relevant knowledge
  • required to achieve the shared goal
    = manage conversational state

Coordinate

  • arrange to take turns performing helpful tasks
  • via communication

Communicate

  • build shared understanding
  • of relevant knowledge
  • required to achieve the shared goal
    = manage conversational state

Coordinate

  • arrange to take turns performing helpful tasks
  • via communication

Communicate

  • build shared understanding
  • of relevant knowledge
  • required to achieve the shared goal
    = manage conversational state

Coordinate

  • arrange to take turns performing helpful tasks
  • via communication

Communicate

  • build shared understanding
  • of relevant knowledge
  • required to achieve the shared goal
    = manage conversational state

Coordinate

  • arrange to take turns performing helpful tasks
  • via communication

Communicate

  • build shared understanding
  • of relevant knowledge
  • required to achieve the shared goal
    = manage conversational state

(dissertation fig. 2)

Concurrency is aboutcooperation
throughcommunication
ofconversational state

Unpredictability

  • pure, total functions
  • effects
  • coroutines
  • threads & shared memory
  • network conditions
Concurrency is aboutcooperation
throughcommunication
ofconversational state
in anunpredictable setting
Syndicate provides a new, effective, realizable linguistic mechanism for sharing state in a concurrent setting.

Syndicate provides a...

newdesign landscape
effectiveevaluation
realizableprototypes, tries
linguisticreified conversations
mechanism for sharing statedataspace model

in a concurrent setting.

Syndicate provides a...

newdesign landscape
effectiveevaluation
realizableprototypes, tries
linguisticreified conversations
mechanism for sharing statedataspace model

in a concurrent setting.

Syndicate provides a...

newdesign landscape
effectiveevaluation
realizableprototypes, tries
linguisticreified conversations
mechanism for sharing statedataspace model

in a concurrent setting.

Syndicate provides a...

newdesign landscape
effectiveevaluation
realizableprototypes, tries
linguisticreified conversations
mechanism for sharing statedataspace model

in a concurrent setting.

Syndicate provides a...

newdesign landscape
effectiveevaluation
realizableprototypes, tries
linguisticreified conversations
mechanism for sharing statedataspace model

in a concurrent setting.

Syndicate provides a...

newdesign landscape
effectiveevaluation
realizableprototypes, tries
linguisticreified conversations
mechanism for sharing statedataspace model

in a concurrent setting.

Syndicate provides a...

newdesign landscape
effectiveevaluation
realizableprototypes, tries
linguisticreified conversations
mechanism for sharing statedataspace model

in a concurrent setting.

Syndicate provides a...

newdesign landscape
effectiveevaluation
realizableprototypes, tries
linguisticreified conversations
mechanism for sharing statedataspace model

in a concurrent setting.

Syndicate provides a...

newdesign landscape
effectiveevaluation
realizableprototypes, tries
linguisticreified conversations
mechanism for sharing statedataspace model

in a concurrent setting.

Syndicate provides a...

newdesign landscape
effectiveevaluation
realizableprototypes, tries
linguisticreified conversations
mechanism for sharing statedataspace model

in a concurrent setting.

Syndicate provides a...

newdesign landscape
effectiveevaluation
realizableprototypes, tries
linguisticreified conversations
mechanism for sharing statedataspace model

in a concurrent setting.

Roadmap

  1. Dataspace model and assertion tries
  2. Reifying conversations
  3. Programming experience with Syndicate
  4. Evaluation
  5. Conclusion & future work

Roadmap

  1. Dataspace model and assertion tries
  2. Reifying conversations
  3. Programming experience with Syndicate
  4. Evaluation
  5. Conclusion & future work

Dataspace model

Dataspace model

Tuplespace model

Actions: eval, out, rd, in

 

Tuplespace model

Actions: eval, out, rd, in

 

Tuplespace model

Actions: eval, out, rd, in

 

Tuplespace model

Actions: eval, out, rd, in

(out (balance 'account1 123.0))

Tuplespace model

Actions: eval, out, rd, in

(out (balance 'account1 123.0))

Tuplespace model

Actions: eval, out, rd, in

 

Tuplespace model

Actions: eval, out, rd, in

(rd (balance 'account1 _))

Tuplespace model

Actions: eval, out, rd, in

 

Tuplespace model

Actions: eval, out, rd, in

(in 'lock)

Tuplespace model

Actions: eval, out, rd, in

(in 'lock)

Tuplespace model

Actions: eval, out, rd, in

 

Tuplespace model

Actions: eval, out, rd, in

 

Tuplespace model

Actions: eval, out, rd, in

 

Dataspace model

Dataspace model

Dataspace model

Dataspace model

Dataspace model

Dataspace model

(observe P)

Assertion of interest in P


(color 'boat 'blue)

"The color of the boat is blue"

(observe (color 'boat _))

"Interest exists in the color of the boat being anything at all"

(observe P)

Assertion of interest in P


(color 'boat 'blue)

"The color of the boat is blue"

(observe (color 'boat _))

"Interest exists in the color of the boat being anything at all"

(observe P)

Assertion of interest in P


(color 'boat 'blue)

"The color of the boat is blue"

(observe (color 'boat _))

"Interest exists in the color of the boat being anything at all"

Figure 11, chapter 4

Figure 13, chapter 4

Figure 14, chapter 4

ActorEvent transducer
 
ActionsSpawn new actor
Replace assertions
Message
 
EventsDataspace has changed
Message

Reduction rules: deliver events; gather actions; interpret actions; step contained actors

(struct dns-entry (name address))


(dns-entry "localhost" "127.0.0.1")

"The address of localhost is 127.0.0.1"

(observe (dns-entry "localhost" _))

"Interest exists in the address of localhost"

(observe (observe (dns-entry _ _)))

"Interest exists in interest in dns-entry records"

(struct dns-entry (name address))


(dns-entry "localhost" "127.0.0.1")

"The address of localhost is 127.0.0.1"

(observe (dns-entry "localhost" _))

"Interest exists in the address of localhost"

(observe (observe (dns-entry _ _)))

"Interest exists in interest in dns-entry records"

(struct dns-entry (name address))


(dns-entry "localhost" "127.0.0.1")

"The address of localhost is 127.0.0.1"

(observe (dns-entry "localhost" _))

"Interest exists in the address of localhost"

(observe (observe (dns-entry _ _)))

"Interest exists in interest in dns-entry records"

(struct dns-entry (name address))


(dns-entry "localhost" "127.0.0.1")

"The address of localhost is 127.0.0.1"

(observe (dns-entry "localhost" _))

"Interest exists in the address of localhost"

(observe (observe (dns-entry _ _)))

"Interest exists in interest in dns-entry records"

Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
  • Supports S-expression-like data and wildcards well
  • Closed under ∪, ∩, −
  • Reasonably efficient ∪, ∩, −
  • Reasonably compact
  • Gives efficient routing of assertions and messages

Properties

  • No errors and stuck-free
  • Deterministic
  • Order-preserving
  • Conversational "soundness", "completeness"
  • actions correctly interpreted
  • an event for every relevant change
  • every event is
    • truthful,
    • relevant, and
    • complete.
  • No errors and stuck-free
  • Deterministic
  • Order-preserving
  • Conversational "soundness", "completeness"
  • actions correctly interpreted
  • an event for every relevant change
  • every event is
    • truthful,
    • relevant, and
    • complete.
  • No errors and stuck-free
  • Deterministic
  • Order-preserving
  • Conversational "soundness", "completeness"
  • actions correctly interpreted
  • an event for every relevant change
  • every event is
    • truthful,
    • relevant, and
    • complete.

Roadmap

  1. Dataspace model and assertion tries
  2. Reifying conversations
  3. Programming experience with Syndicate
  4. Evaluation
  5. Conclusion & future work

Facet

  • Assertions
  • Local fields
  • Data flow → control flow
  • Control flow → data flow
  • Local data → shared data
  • Shared data → local data
  • Subfacets
(react (field [field-name expr] ...)
       endpoint-expr ...)

endpoint-expr
  = (assert expr)
  | (on (asserted pattern) expr ...)
  | (on (retracted pattern) expr ...)
  | (on (message pattern) expr ...)
  | (on-start expr ...)
  | (on-stop expr ...)
(stop-when E expr ...)
  = (on E (stop-facet (current-facet-id) expr ...))

(during pattern endpoint-expr ...)
  = (on (asserted pattern)
        (react (stop-when (retracted pattern′))
               endpoint-expr ...))
(react (field [field-name expr] ...)
       endpoint-expr ...)

endpoint-expr
  = (assert expr)
  | (on (asserted pattern) expr ...)
  | (on (retracted pattern) expr ...)
  | (on (message pattern) expr ...)
  | (on-start expr ...)
  | (on-stop expr ...)
(stop-when E expr ...)
  = (on E (stop-facet (current-facet-id) expr ...))

(during pattern endpoint-expr ...)
  = (on (asserted pattern)
        (react (stop-when (retracted pattern′))
               endpoint-expr ...))
(react (field [field-name expr] ...)
       endpoint-expr ...)

endpoint-expr
  = (assert expr)
  | (on (asserted pattern) expr ...)
  | (on (retracted pattern) expr ...)
  | (on (message pattern) expr ...)
  | (on-start expr ...)
  | (on-stop expr ...)
(stop-when E expr ...)
  = (on E (stop-facet (current-facet-id) expr ...))

(during pattern endpoint-expr ...)
  = (on (asserted pattern)
        (react (stop-when (retracted pattern′))
               endpoint-expr ...))
(react (field [field-name expr] ...)
       endpoint-expr ...)

endpoint-expr
  = (assert expr)
  | (on (asserted pattern) expr ...)
  | (on (retracted pattern) expr ...)
  | (on (message pattern) expr ...)
  | (on-start expr ...)
  | (on-stop expr ...)
(stop-when E expr ...)
  = (on E (stop-facet (current-facet-id) expr ...))

(during pattern endpoint-expr ...)
  = (on (asserted pattern)
        (react (stop-when (retracted pattern′))
               endpoint-expr ...))
(react (field [field-name expr] ...)
       endpoint-expr ...)

endpoint-expr
  = (assert expr)
  | (on (asserted pattern) expr ...)
  | (on (retracted pattern) expr ...)
  | (on (message pattern) expr ...)
  | (on-start expr ...)
  | (on-stop expr ...)
(stop-when E expr ...)
  = (on E (stop-facet (current-facet-id) expr ...))

(during pattern endpoint-expr ...)
  = (on (asserted pattern)
        (react (stop-when (retracted pattern′))
               endpoint-expr ...))
(react (field [field-name expr] ...)
       endpoint-expr ...)

endpoint-expr
  = (assert expr)
  | (on (asserted pattern) expr ...)
  | (on (retracted pattern) expr ...)
  | (on (message pattern) expr ...)
  | (on-start expr ...)
  | (on-stop expr ...)
(stop-when E expr ...)
  = (on E (stop-facet (current-facet-id) expr ...))

(during pattern endpoint-expr ...)
  = (on (asserted pattern)
        (react (stop-when (retracted pattern′))
               endpoint-expr ...))
(react (field [field-name expr] ...)
       endpoint-expr ...)

endpoint-expr
  = (assert expr)
  | (on (asserted pattern) expr ...)
  | (on (retracted pattern) expr ...)
  | (on (message pattern) expr ...)
  | (on-start expr ...)
  | (on-stop expr ...)
(stop-when E expr ...)
  = (on E (stop-facet (current-facet-id) expr ...))

(during pattern endpoint-expr ...)
  = (on (asserted pattern)
        (react (stop-when (retracted pattern′))
               endpoint-expr ...))
(react (field [field-name expr] ...)
       endpoint-expr ...)

endpoint-expr
  = (assert expr)
  | (on (asserted pattern) expr ...)
  | (on (retracted pattern) expr ...)
  | (on (message pattern) expr ...)
  | (on-start expr ...)
  | (on-stop expr ...)
(stop-when E expr ...)
  = (on E (stop-facet (current-facet-id) expr ...))

(during pattern endpoint-expr ...)
  = (on (asserted pattern)
        (react (stop-when (retracted pattern′))
               endpoint-expr ...))
(react (field [field-name expr] ...)
       endpoint-expr ...)

endpoint-expr
  = (assert expr)
  | (on (asserted pattern) expr ...)
  | (on (retracted pattern) expr ...)
  | (on (message pattern) expr ...)
  | (on-start expr ...)
  | (on-stop expr ...)
(stop-when E expr ...)
  = (on E (stop-facet (current-facet-id) expr ...))

(during pattern endpoint-expr ...)
  = (on (asserted pattern)
        (react (stop-when (retracted pattern′))
               endpoint-expr ...))
(react (field [field-name expr] ...)
       endpoint-expr ...)

endpoint-expr
  = (assert expr)
  | (on (asserted pattern) expr ...)
  | (on (retracted pattern) expr ...)
  | (on (message pattern) expr ...)
  | (on-start expr ...)
  | (on-stop expr ...)
(stop-when E expr ...)
  = (on E (stop-facet (current-facet-id) expr ...))

(during pattern endpoint-expr ...)
  = (on (asserted pattern)
        (react (stop-when (retracted pattern′))
               endpoint-expr ...))
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
(spawn (stop-when (asserted (dns-entry "localhost" $addr))
         (printf "localhost is ~a\n" addr)))
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
(spawn (on (asserted (observe (dns-entry $name _)))
           (react (stop-when (retracted (observe (dns-entry ···))))
             (assert (dns-entry "localhost" ···)))))
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
(spawn (on (asserted (observe (dns-entry $name _)))
           (define deadline (+ (current-inexact-milliseconds) 2000))
           (react (stop-when (asserted (later-than deadline)))
                  (assert (observe (dns-entry name _))))))
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
(spawn (stop-when (asserted (dns-entry "localhost" $addr))
         (printf "localhost is ~a\n" addr)))
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
(spawn (during (observe (dns-entry $name _))
         (define addr (engage-in-internet-dns-protocol-for name))
         (assert (dns-entry name addr))))
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
(spawn (on (asserted (observe (dns-entry $name _)))
           (define deadline (+ (current-inexact-milliseconds) 2000))
           (react (stop-when (asserted (later-than deadline)))
                  (assert (observe (dns-entry name _))))))
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
(spawn (stop-when (asserted (dns-entry "localhost" $addr))
         (printf "localhost is ~a\n" addr)))
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
(spawn (during (observe (dns-entry $name _))
         (define addr (engage-in-internet-dns-protocol-for name))
         (assert (dns-entry name addr))))
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
(spawn (on (asserted (observe (dns-entry $name _)))
           (define deadline (+ (current-inexact-milliseconds) 2000))
           (react (stop-when (asserted (later-than deadline)))
                  (assert (observe (dns-entry name _))))))
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
(spawn (stop-when (asserted (dns-entry "localhost" $addr))
         (printf "localhost is ~a\n" addr)))
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
(spawn (during (observe (dns-entry $name _))
         (define addr (engage-in-internet-dns-protocol-for name))
         (assert (dns-entry name addr))))
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
(spawn (on (asserted (observe (dns-entry $name _)))
           (define deadline (+ (current-inexact-milliseconds) 2000))
           (react (stop-when (asserted (later-than deadline)))
                  (assert (observe (dns-entry name _))))))
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
(spawn (stop-when (asserted (dns-entry "localhost" $addr))
         (printf "localhost is ~a\n" addr)))
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
(spawn (on (asserted (observe (dns-entry $name _)))
           (react (stop-when (retracted (observe (dns-entry ···))))
             (assert (dns-entry "localhost" ···)))))
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
(spawn (on (asserted (observe (dns-entry $name _)))
           (define deadline (+ (current-inexact-milliseconds) 2000))
           (react (stop-when (asserted (later-than deadline)))
                  (assert (observe (dns-entry name _))))))
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
(spawn (stop-when (asserted (dns-entry "localhost" $addr))
         (printf "localhost is ~a\n" addr)))
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
(spawn (during (observe (dns-entry $name _))
         (define addr (engage-in-internet-dns-protocol-for name))
         (assert (dns-entry name addr))))
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
(spawn (on (asserted (observe (dns-entry $name _)))
           (define deadline (+ (current-inexact-milliseconds) 2000))
           (react (stop-when (asserted (later-than deadline)))
                  (assert (observe (dns-entry name _))))))
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
(spawn (stop-when (asserted (dns-entry "localhost" $addr))
         (printf "localhost is ~a\n" addr)))
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
(spawn (during (observe (dns-entry $name _))
         (define addr (engage-in-internet-dns-protocol-for name))
         (assert (dns-entry name addr))))
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
(spawn (on (asserted (observe (dns-entry $name _)))
           (define deadline (+ (current-inexact-milliseconds) 2000))
           (react (stop-when (asserted (later-than deadline)))
                  (assert (observe (dns-entry name _))))))
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
(spawn (stop-when (asserted (dns-entry "localhost" $addr))
         (printf "localhost is ~a\n" addr)))
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
(spawn (during (observe (dns-entry $name _))
         (define addr (engage-in-internet-dns-protocol-for name))
         (assert (dns-entry name addr))))
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
(spawn (on (asserted (observe (dns-entry $name _)))
           (define deadline (+ (current-inexact-milliseconds) 2000))
           (react (stop-when (asserted (later-than deadline)))
                  (assert (observe (dns-entry name _))))))
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
(spawn (stop-when (asserted (dns-entry "localhost" $addr))
         (printf "localhost is ~a\n" addr)))
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
(spawn (during (observe (dns-entry $name _))
         (define addr (engage-in-internet-dns-protocol-for name))
         (assert (dns-entry name addr))))
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
(spawn (on (asserted (observe (dns-entry $name _)))
           (define deadline (+ (current-inexact-milliseconds) 2000))
           (react (stop-when (asserted (later-than deadline)))
                  (assert (observe (dns-entry name _))))))
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
(spawn (stop-when (asserted (dns-entry "localhost" $addr))
         (printf "localhost is ~a\n" addr)))
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
(spawn (during (observe (dns-entry $name _))
         (define addr (engage-in-internet-dns-protocol-for name))
         (assert (dns-entry name addr))))
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
(spawn (on (asserted (observe (dns-entry $name _)))
           (define deadline (+ (current-inexact-milliseconds) 2000))
           (react (stop-when (asserted (later-than deadline)))
                  (assert (observe (dns-entry name _))))))
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
(spawn (stop-when (asserted (dns-entry "localhost" $addr))
         (printf "localhost is ~a\n" addr)))
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
(spawn (during (observe (dns-entry $name _))
         (define addr (engage-in-internet-dns-protocol-for name))
         (assert (dns-entry name addr))))
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
(spawn (on (asserted (observe (dns-entry $name _)))
           (define deadline (+ (current-inexact-milliseconds) 2000))
           (react (stop-when (asserted (later-than deadline)))
                  (assert (observe (dns-entry name _))))))
Client
  • Asserts (observe (dns-entry "localhost" _))
  • When notified of a (dns-entry "localhost" $addr), prints addr and quits
(spawn (stop-when (asserted (dns-entry "localhost" $addr))
         (printf "localhost is ~a\n" addr)))
Server
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), looks up the addr for name and asserts (dns-entry name addr)
(spawn (during (observe (dns-entry $name _))
         (define addr (engage-in-internet-dns-protocol-for name))
         (assert (dns-entry name addr))))
Cache
  • Asserts (observe (observe (dns-entry _ _)))
  • In response to (observe (dns-entry $name _)), asserts the same, and also (observe (laterThan ···))
  • In response to (laterThan ···), removes the corresponding assertions
(spawn (on (asserted (observe (dns-entry $name _)))
           (define deadline (+ (current-inexact-milliseconds) 2000))
           (react (stop-when (asserted (later-than deadline)))
                  (assert (observe (dns-entry name _))))))

Figures 16 & 17, chapter 5

Figures 19 & 20, chapter 5

Figure 23, chapter 5

Roadmap

  1. Dataspace model and assertion tries
  2. Reifying conversations
  3. Programming experience with Syndicate
  4. Evaluation
  5. Conclusion & future work

Syndicate/js

In-browser and node.js implementation

Assertions can place DOM elements on the page

DOM events generate Syndicate/js messages

Websocket protocol connects browser to Syndicate/rkt

function todoListItemModel(initialId, initialTitle, initialCompleted) {
  spawn {
    field this.id = initialId;
    field this.title = initialTitle;
    field this.completed = initialCompleted;

    stop on message deleteTodo(this.id);

    assert todo(this.id, this.title, this.completed);

    on message setCompleted(this.id, $v) { this.completed = v; }
    on message setAllCompleted($v)       { this.completed = v; }

    on message setTitle(this.id, $v)     { this.title = v;     }

    on message clearCompletedTodos() {
      if (this.completed) :: deleteTodo(this.id);
    }
  }
}
  • IRC Server
  • TCP/IP Stack
  • Collaborative text editor server
  • Broker: embeds Syndicate/js in Syndicate/rkt
  • Web-based chat application
  • Many, many, many smaller examples

http://syndicate-lang.org/

Roadmap

  1. Dataspace model and assertion tries
  2. Reifying conversations
  3. Programming experience with Syndicate
  4. Evaluation
  5. Conclusion & future work

How should we evaluate a language design idea?

Quantitatively? Benchmark suites
Error rates
Programmer productivity
Qualitatively Simplification of programs
Asymptotic performance

How should we evaluate a language design idea?

Quantitatively? Benchmark suites
Error rates
Programmer productivity
Qualitatively Simplification of programs
Asymptotic performance

How should we evaluate a language design idea?

Quantitatively? Benchmark suites
Error rates
Programmer productivity
Qualitatively Simplification of programs
Asymptotic performance

How should we evaluate a language design idea?

Quantitatively? Benchmark suites
Error rates
Programmer productivity
Qualitatively Simplification of programs
Asymptotic performance

How should we evaluate a language design idea?

Quantitatively? Benchmark suites
Error rates
Programmer productivity
Qualitatively Simplification of programs
Asymptotic performance

How should we evaluate a language design idea?

Quantitatively? Benchmark suites
Error rates
Programmer productivity
Qualitatively Simplification of programs
Asymptotic performance

How should we evaluate a language design idea?

Quantitatively? Benchmark suites
Error rates
Programmer productivity
Qualitatively Simplification of programs
Asymptotic performance

How should we evaluate a language design idea?

Quantitatively? Benchmark suites
Error rates
Programmer productivity
Qualitatively Simplification of programs
Asymptotic performance

Patterns

Simplify by eliminating patterns.

Patterns

Programming Pattern [Felleisen 1991]

Design Pattern [Gamma et al. 1994]

Informal → Formal → Invisible

[Norvig 1996]

  1. Event Broadcast (encoding)
  2. The "Observer" Pattern [Gamma et al. 1994]
  3. State Replication Pattern

  4. The "State" Pattern [Gamma et al. 1994]

  5. The "Cancellation" Pattern [Russell et al. 2016]

State Replication

Event broadcastingObserver patternState replication
Smalltalkinformal/invisibleformalinformal
Rubyinformal/invisibleformalinformal
Javainformal/invisibleinformalinformal
Erlang/OTPinformal/invisibleinformalinformal
Syndicateinvisibleinvisibleinvisible

"State" Pattern

Javainformal
Syndicateinvisible

"Cancellation" Pattern

JavaScriptinformal
Syndicateinvisible
(struct service-a (request response))
(struct service-b (request response))

(spawn (during (service-a 'request-from-a $response)
         (on-start (printf "Response: ~v\n" response))))

(spawn (during (observe (service-a $req-a _))
         (during (service-b 'request-from-b $resp-b)
           (assert (service-a req-a (make-answer resp-b))))))

Asymptotic performance

Message routing & delivery, sec/event vs k


Unicast: Õ(1)

Broadcast: Õ(1/k + 1)

Asymptotic performance

Assertion set update cost, sec/event vs k


k-independent: Õ(1)

k-dependent: Õ(1)

Asymptotic performance

TCP echo server, sec/conn vs k


Marginal cost of additional connection: Õ(1)

Roadmap

  1. Dataspace model and assertion tries
  2. Reifying conversations
  3. Programming experience with Syndicate
  4. Evaluation
  5. Conclusion & future work

Syndicate provides a...

newdesign landscape
effectiveevaluation
realizableprototypes, tries
linguisticreified conversations
mechanism for sharing statedataspace model

in a concurrent setting.

Future Work

  • Enhancements to the formal models
    types; names; grouping & relaying; formal properties
  • System model
    performance; tool support; generic protocols; process management;
    stdio; contracts; security; persistence; polyglot
  • Distributed systems
    unpredictable latency & scheduling; message loss; subnets

Thank you!

Committee: Thank You for Signing my Dissertation! :-)

Future Work

  • Enhancements to the formal models
    types; names; grouping & relaying; formal properties
  • System model
    performance; tool support; generic protocols; process management;
    stdio; contracts; security; persistence; polyglot
  • Distributed systems
    unpredictable latency & scheduling; message loss; subnets

Thank you!

Committee: Thank You for Signing my Dissertation! :-)

Backup

New expressions:
(spawn endpoint-expr ...)
(spawn* expr ...)
(dataspace expr ...)
(react endpoint-expr ...)
(stop-facet facet-id-expr expr ...)
(current-facet-id)
(send! expr)
Field access:
(fieldname)
Field update:
(fieldname expr)
New expressions:
(spawn endpoint-expr ...)
(spawn* expr ...)
(dataspace expr ...)
(react endpoint-expr ...)
(stop-facet facet-id-expr expr ...)
(current-facet-id)
(send! expr)
Field access:
(fieldname)
Field update:
(fieldname expr)
New expressions:
(spawn endpoint-expr ...)
(spawn* expr ...)
(dataspace expr ...)
(react endpoint-expr ...)
(stop-facet facet-id-expr expr ...)
(current-facet-id)
(send! expr)
Field access:
(fieldname)
Field update:
(fieldname expr)
New expressions:
(spawn endpoint-expr ...)
(spawn* expr ...)
(dataspace expr ...)
(react endpoint-expr ...)
(stop-facet facet-id-expr expr ...)
(current-facet-id)
(send! expr)
Field access:
(fieldname)
Field update:
(fieldname expr)
New expressions:
(spawn endpoint-expr ...)
(spawn* expr ...)
(dataspace expr ...)
(react endpoint-expr ...)
(stop-facet facet-id-expr expr ...)
(current-facet-id)
(send! expr)
Field access:
(fieldname)
Field update:
(fieldname expr)
New expressions:
(spawn endpoint-expr ...)
(spawn* expr ...)
(dataspace expr ...)
(react endpoint-expr ...)
(stop-facet facet-id-expr expr ...)
(current-facet-id)
(send! expr)
Field access:
(fieldname)
Field update:
(fieldname expr)
New expressions:
(spawn endpoint-expr ...)
(spawn* expr ...)
(dataspace expr ...)
(react endpoint-expr ...)
(stop-facet facet-id-expr expr ...)
(current-facet-id)
(send! expr)
Field access:
(fieldname)
Field update:
(fieldname expr)
New expressions:
(spawn endpoint-expr ...)
(spawn* expr ...)
(dataspace expr ...)
(react endpoint-expr ...)
(stop-facet facet-id-expr expr ...)
(current-facet-id)
(send! expr)
Field access:
(fieldname)
Field update:
(fieldname expr)
New expressions:
(spawn endpoint-expr ...)
(spawn* expr ...)
(dataspace expr ...)
(react endpoint-expr ...)
(stop-facet facet-id-expr expr ...)
(current-facet-id)
(send! expr)
Field access:
(fieldname)
Field update:
(fieldname expr)
(struct set-box (new-value))
(struct box-state (value))

(spawn (field [current-value 0])
       (assert (box-state (current-value)))
       (on (message (set-box $new-value))
           (current-value new-value)))

(spawn (on (asserted (box-state $v))
           (send! (set-box (+ v 1)))))
(struct set-box (new-value))
(struct box-state (value))

(spawn (field [current-value 0])
       (assert (box-state (current-value)))
       (on (message (set-box $new-value))
           (current-value new-value)))

(spawn (on (asserted (box-state $v))
           (send! (set-box (+ v 1)))))
(struct set-box (new-value))
(struct box-state (value))

(spawn (field [current-value 0])
       (assert (box-state (current-value)))
       (on (message (set-box $new-value))
           (current-value new-value)))

(spawn (on (asserted (box-state $v))
           (send! (set-box (+ v 1)))))
(struct set-box (new-value))
(struct box-state (value))

(spawn (field [current-value 0])
       (assert (box-state (current-value)))
       (on (message (set-box $new-value))
           (current-value new-value)))

(spawn (on (asserted (box-state $v))
           (send! (set-box (+ v 1)))))
(struct set-box (new-value))
(struct box-state (value))

(spawn (field [current-value 0])
       (assert (box-state (current-value)))
       (on (message (set-box $new-value))
           (current-value new-value)))

(spawn (on (asserted (box-state $v))
           (send! (set-box (+ v 1)))))
(struct set-box (new-value))
(struct box-state (value))

(spawn (field [current-value 0])
       (assert (box-state (current-value)))
       (on (message (set-box $new-value))
           (current-value new-value)))

(spawn (on (asserted (box-state $v))
           (send! (set-box (+ v 1)))))
(struct set-box (new-value))
(struct box-state (value))

(spawn (field [current-value 0])
       (assert (box-state (current-value)))
       (on (message (set-box $new-value))
           (current-value new-value)))

(spawn (on (asserted (box-state $v))
           (send! (set-box (+ v 1)))))
(struct set-box (new-value))
(struct box-state (value))

(spawn (field [current-value 0])
       (assert (box-state (current-value)))
       (on (message (set-box $new-value))
           (current-value new-value)))

(spawn (on (asserted (box-state $v))
           (send! (set-box (+ v 1)))))
(struct set-box (new-value))
(struct box-state (value))

(spawn (field [current-value 0])
       (assert (box-state (current-value)))
       (on (message (set-box $new-value))
           (current-value new-value)))

(spawn (on (asserted (box-state $v))
           (send! (set-box (+ v 1)))))
(struct set-box (new-value))
(struct box-state (value))

(spawn (field [current-value 0])
       (assert (box-state (current-value)))
       (on (message (set-box $new-value))
           (current-value new-value)))

(spawn (on (asserted (box-state $v))
           (send! (set-box (+ v 1)))))
(struct set-box (new-value))
(struct box-state (value))

(spawn (field [current-value 0])
       (assert (box-state (current-value)))
       (on (message (set-box $new-value))
           (current-value new-value)))

(spawn (on (asserted (box-state $v))
           (send! (set-box (+ v 1)))))