PhD Dissertation Defense
December 8th, 2017
more than one thing to do
vs.
progress on more than one at once
more than one thing to do
vs.
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.
more than one interacting thing
vs.
progress on more than one at once
more than one interacting thing
more than one interacting thing
is about
more than one interacting thing
is about
(dissertation fig. 2)
Concurrency is about | cooperation |
through | communication |
of | conversational state |
Concurrency is about | cooperation |
through | communication |
of | conversational state |
in an | unpredictable setting |
new | → | design landscape |
effective | → | evaluation |
realizable | → | prototypes, tries |
linguistic | → | reified conversations |
mechanism for sharing state | → | dataspace model |
in a concurrent setting.
new | → | design landscape |
effective | → | evaluation |
realizable | → | prototypes, tries |
linguistic | → | reified conversations |
mechanism for sharing state | → | dataspace model |
in a concurrent setting.
new | → | design landscape |
effective | → | evaluation |
realizable | → | prototypes, tries |
linguistic | → | reified conversations |
mechanism for sharing state | → | dataspace model |
in a concurrent setting.
new | → | design landscape |
effective | → | evaluation |
realizable | → | prototypes, tries |
linguistic | → | reified conversations |
mechanism for sharing state | → | dataspace model |
in a concurrent setting.
new | → | design landscape |
effective | → | evaluation |
realizable | → | prototypes, tries |
linguistic | → | reified conversations |
mechanism for sharing state | → | dataspace model |
in a concurrent setting.
new | → | design landscape |
effective | → | evaluation |
realizable | → | prototypes, tries |
linguistic | → | reified conversations |
mechanism for sharing state | → | dataspace model |
in a concurrent setting.
new | → | design landscape |
effective | → | evaluation |
realizable | → | prototypes, tries |
linguistic | → | reified conversations |
mechanism for sharing state | → | dataspace model |
in a concurrent setting.
new | → | design landscape |
effective | → | evaluation |
realizable | → | prototypes, tries |
linguistic | → | reified conversations |
mechanism for sharing state | → | dataspace model |
in a concurrent setting.
new | → | design landscape |
effective | → | evaluation |
realizable | → | prototypes, tries |
linguistic | → | reified conversations |
mechanism for sharing state | → | dataspace model |
in a concurrent setting.
new | → | design landscape |
effective | → | evaluation |
realizable | → | prototypes, tries |
linguistic | → | reified conversations |
mechanism for sharing state | → | dataspace model |
in a concurrent setting.
new | → | design landscape |
effective | → | evaluation |
realizable | → | prototypes, tries |
linguistic | → | reified conversations |
mechanism for sharing state | → | dataspace model |
in a concurrent setting.
Actions: eval, out, rd, in
Actions: eval, out, rd, in
Actions: eval, out, rd, in
Actions: eval, out, rd, in
(out (balance 'account1 123.0))
Actions: eval, out, rd, in
(out (balance 'account1 123.0))
Actions: eval, out, rd, in
Actions: eval, out, rd, in
(rd (balance 'account1 _))
Actions: eval, out, rd, in
Actions: eval, out, rd, in
(in 'lock)
Actions: eval, out, rd, in
(in 'lock)
Actions: eval, out, rd, in
Actions: eval, out, rd, in
Actions: eval, out, rd, in
(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"
Actor | Event transducer |
---|---|
Actions | Spawn new actor
Replace assertions Message |
Events | Dataspace 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 |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
Client |
|
Server |
|
Cache |
|
(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 |
|
| |
Server |
|
| |
Cache |
|
|
Client |
|
| |
Server |
|
| |
Cache |
|
|
Client |
|
| |
Server |
|
| |
Cache |
|
|
Client |
|
| |
Server |
|
| |
Cache |
|
|
Client |
|
| |
Server |
|
| |
Cache |
|
|
Client |
|
| |
Server |
|
| |
Cache |
|
|
Client |
|
| |
Server |
|
| |
Cache |
|
|
Client |
|
| |
Server |
|
| |
Cache |
|
|
Client |
|
| |
Server |
|
| |
Cache |
|
|
Client |
|
| |
Server |
|
| |
Cache |
|
|
Client |
|
| |
Server |
|
| |
Cache |
|
|
Client |
|
| |
Server |
|
| |
Cache |
|
|
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);
}
}
}
Quantitatively? | ✗ Benchmark suites ✗ Error rates ✗ Programmer productivity |
Qualitatively | ✓ Simplification of programs ✓ Asymptotic performance |
Quantitatively? | ✗ Benchmark suites ✗ Error rates ✗ Programmer productivity |
Qualitatively | ✓ Simplification of programs ✓ Asymptotic performance |
Quantitatively? | ✗ Benchmark suites ✗ Error rates ✗ Programmer productivity |
Qualitatively | ✓ Simplification of programs ✓ Asymptotic performance |
Quantitatively? | ✗ Benchmark suites ✗ Error rates ✗ Programmer productivity |
Qualitatively | ✓ Simplification of programs ✓ Asymptotic performance |
Quantitatively? | ✗ Benchmark suites ✗ Error rates ✗ Programmer productivity |
Qualitatively | ✓ Simplification of programs ✓ Asymptotic performance |
Quantitatively? | ✗ Benchmark suites ✗ Error rates ✗ Programmer productivity |
Qualitatively | ✓ Simplification of programs ✓ Asymptotic performance |
Quantitatively? | ✗ Benchmark suites ✗ Error rates ✗ Programmer productivity |
Qualitatively | ✓ Simplification of programs ✓ Asymptotic performance |
Quantitatively? | ✗ Benchmark suites ✗ Error rates ✗ Programmer productivity |
Qualitatively | ✓ Simplification of programs ✓ Asymptotic performance |
Simplify by eliminating patterns.
Programming Pattern [Felleisen 1991]
Design Pattern [Gamma et al. 1994]
Informal → Formal → Invisible
[Norvig 1996]
Event broadcasting | Observer pattern | State replication | |
Smalltalk | informal/invisible | formal | informal |
---|---|---|---|
Ruby | informal/invisible | formal | informal |
Java | informal/invisible | informal | informal |
Erlang/OTP | informal/invisible | informal | informal |
Syndicate | invisible | invisible | invisible |
Java | informal |
---|---|
Syndicate | invisible |
JavaScript | informal |
---|---|
Syndicate | invisible |
(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))))))
Message routing & delivery, sec/event vs k
Unicast: Õ(1) | Broadcast: Õ(1/k + 1) |
Assertion set update cost, sec/event vs k
k-independent: Õ(1) | k-dependent: Õ(1) |
TCP echo server, sec/conn vs k
Marginal cost of additional connection: Õ(1) |
new | → | design landscape |
effective | → | evaluation |
realizable | → | prototypes, tries |
linguistic | → | reified conversations |
mechanism for sharing state | → | dataspace model |
in a concurrent setting.
New expressions: |
|
Field access: |
|
Field update: |
|
New expressions: |
|
Field access: |
|
Field update: |
|
New expressions: |
|
Field access: |
|
Field update: |
|
New expressions: |
|
Field access: |
|
Field update: |
|
New expressions: |
|
Field access: |
|
Field update: |
|
New expressions: |
|
Field access: |
|
Field update: |
|
New expressions: |
|
Field access: |
|
Field update: |
|
New expressions: |
|
Field access: |
|
Field update: |
|
New expressions: |
|
Field access: |
|
Field update: |
|
(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)))))