-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patharchitecture.lyx
2942 lines (2483 loc) · 74.4 KB
/
architecture.lyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#LyX 2.2 created this file. For more info see http://www.lyx.org/
\lyxformat 508
\begin_document
\begin_header
\save_transient_properties true
\origin unavailable
\textclass extreport
\use_default_options true
\begin_modules
fixltx2e
fix-cm
theorems-ams-bytype
\end_modules
\maintain_unincluded_children false
\language british
\language_package default
\inputencoding auto
\fontencoding global
\font_roman "default" "default"
\font_sans "default" "default"
\font_typewriter "default" "default"
\font_math "auto" "auto"
\font_default_family default
\use_non_tex_fonts false
\font_sc false
\font_osf false
\font_sf_scale 100 100
\font_tt_scale 100 100
\graphics default
\default_output_format default
\output_sync 0
\bibtex_command default
\index_command default
\paperfontsize default
\spacing single
\use_hyperref false
\papersize default
\use_geometry false
\use_package amsmath 1
\use_package amssymb 1
\use_package cancel 1
\use_package esint 1
\use_package mathdots 1
\use_package mathtools 1
\use_package mhchem 1
\use_package stackrel 1
\use_package stmaryrd 1
\use_package undertilde 1
\cite_engine basic
\cite_engine_type default
\biblio_style plain
\use_bibtopic false
\use_indices false
\paperorientation portrait
\suppress_date true
\justification true
\use_refstyle 1
\index Index
\shortcut idx
\color #008000
\end_index
\secnumdepth 3
\tocdepth 1
\paragraph_separation indent
\paragraph_indentation default
\quotes_language english
\papercolumns 1
\papersides 2
\paperpagestyle default
\tracking_changes false
\output_changes false
\html_math_output 0
\html_css_as_file 0
\html_be_strict false
\end_header
\begin_body
\begin_layout Chapter
\begin_inset CommandInset label
LatexCommand label
name "chap:Language-Design-Decisions"
\end_inset
Language Design Decisions
\end_layout
\begin_layout Standard
Pony is a language predicated on the idea that a sufficiently powerful static
type system can be leveraged to write a faster runtime.
In particular, such a type system could make guarantees that result in
eliminating many dynamic checks, not just related to dynamically checking
data types, but also eliminating checks that would otherwise be required
for safe concurrency, garbage collection, and security.
\end_layout
\begin_layout Section
\begin_inset CommandInset label
LatexCommand label
name "sec:Single-Model-for"
\end_inset
Single Model for Concurrent and Distributed Execution
\end_layout
\begin_layout Standard
One of the driving principles behind the design of Pony has been the desire
for a single model for both concurrent and distributed execution, as described
in chapter
\begin_inset CommandInset ref
LatexCommand ref
reference "chap:Syntax-and-Operational"
\end_inset
.
As a result, the communication mechanism between units of execution cannot
rely on shared mutable state, since such shared memory is not available
in a distributed setting.
In addition, the communication mechanism cannot be synchronous, as relying
on synchronous communication in a distributed context can introduce severe
performance problems.
These are also important considerations when ensuring that maximum use
is made of the hardware available on a single node.
For example, synchronous messaging can introduce deadlocks and priority
inversion, and shared mutable state can cause data races and put a heavy
load on cache coherency hardware.
\end_layout
\begin_layout Standard
This is a different approach than languages such as C/C++, C#, Java, Javascript,
Python, and other languages that treat both concurrency and distribution
as library-level rather than language-level features.
Such languages are in some sense sequential-first.
Pony instead takes a concurrent-first approach that is more in the style
of Erlang, in which concurrency and distribution are language-level features
that inform the design of the sequential portion of the language.
As such, problems endemic to sequential-first languages when concurrency
is introduced, such as non-composable concurrent libraries, garbage collectors
that must cope with shared mutable state, deadlocking, and data-races,
are avoided by design.
\end_layout
\begin_layout Standard
Like Erlang, Pony uses asynchronous message passing for communicating between
units of execution.
This decision, combined with a desire to provide dynamic topology and object
capabilities, lead to the decision to use actors as the unit of execution.
The actor model has been implemented in many ways, but at its core it has
three fundamental requirements
\begin_inset CommandInset citation
LatexCommand cite
key "agha1986actors,agha1987concurrent"
\end_inset
:
\end_layout
\begin_layout Enumerate
An actor can send messages to other actors or itself.
\end_layout
\begin_layout Enumerate
An actor can create new actors.
\end_layout
\begin_layout Enumerate
An actor can choose the way in which it will respond to the next message
it receives.
\end_layout
\begin_layout Standard
These requirements are intentionally weak.
For example, while the model does require that messages are eventually
delivered, it does not require a delivery order.
Similarly, while the third requirement allows actors to encode state, the
model does not require an implementation to encode state in any particular
way.
For example, encoding state via recursion or via mutating object fields
are both allowable strategies.
\end_layout
\begin_layout Standard
On the other hand, there are subtle implications of these three requirements.
For example, since an actor can send a message to itself, and message delivery
is guaranteed, messages must be buffered, as otherwise an actor would deadlock
when attempting to send itself a message.
Interestingly, while real world constraints limit the size of a message
buffer, the model implicitly requires that buffer space is logically unbounded:
any upper bound devolves to the possibility that an actor will be blocked
if it tries to send a message to itself, because its message buffer is
full and it cannot clear it.
That is, the actor can neither enqueue the message and continue execution,
nor can it dequeue messages to create space, as the actor must not interleave
message handling executions.
\end_layout
\begin_layout Standard
Another subtle implication is that there can be no shared mutable state
across actors.
This follows from the requirement that an actor
\begin_inset Formula $\alpha$
\end_inset
can only send a message to another actor
\begin_inset Formula $\alpha'$
\end_inset
in response to some message
\begin_inset Formula $m$
\end_inset
if:
\end_layout
\begin_layout Enumerate
\begin_inset Formula $\alpha'$
\end_inset
was known to
\begin_inset Formula $\alpha$
\end_inset
before
\begin_inset Formula $m$
\end_inset
was received, or
\end_layout
\begin_layout Enumerate
\begin_inset Formula $\alpha'$
\end_inset
is contained in
\begin_inset Formula $m$
\end_inset
, or
\end_layout
\begin_layout Enumerate
\begin_inset Formula $\alpha$
\end_inset
created
\begin_inset Formula $\alpha'$
\end_inset
while handling
\begin_inset Formula $m$
\end_inset
.
\end_layout
\begin_layout Standard
This is the
\emph on
introduction requirement
\emph default
, as detailed in Gul Agha's Ph.D.
thesis
\begin_inset CommandInset citation
LatexCommand cite
key "agha1986actors"
\end_inset
: an actor
\begin_inset Formula $\alpha$
\end_inset
can only send a message to another actor
\begin_inset Formula $\alpha'$
\end_inset
if they have been properly introduced.
Shared mutable state would allow an actor to send messages without prior
introduction: namely,
\begin_inset Formula $\alpha$
\end_inset
could read the address of
\begin_inset Formula $\alpha'$
\end_inset
from some shared variable that a third-party actor modified, without
\begin_inset Formula $\alpha$
\end_inset
either receiving
\begin_inset Formula $\alpha'$
\end_inset
in a message or creating
\begin_inset Formula $\alpha'$
\end_inset
.
\end_layout
\begin_layout Standard
The implementation of the actor model in Pony is intended to satisfy all
of these aspects of the actor model, including the more subtle implications.
\end_layout
\begin_layout Section
Tools for Correctness and Reasoning
\end_layout
\begin_layout Standard
Pony makes additional guarantees that extend the fundamental requirements
of the actor model:
\end_layout
\begin_layout Enumerate
Both mutable and immutable state are supported, both within an actor and
in messages between actors, as described in chapter
\begin_inset CommandInset ref
LatexCommand ref
reference "chap:Reference-Capabilities"
\end_inset
.
\end_layout
\begin_layout Enumerate
Data-race freedom, including mutable state isolation, is guaranteed statically,
as described in section
\begin_inset CommandInset ref
LatexCommand ref
reference "subsec:Static-Data-Race-Freedom"
\end_inset
and chapter
\begin_inset CommandInset ref
LatexCommand ref
reference "chap:Reference-Capabilities"
\end_inset
.
\end_layout
\begin_layout Enumerate
Message handling is
\emph on
logically atomic
\emph default
, as described in section
\begin_inset CommandInset ref
LatexCommand ref
reference "subsec:Logically-Atomic-Behaviours"
\end_inset
and chapter
\begin_inset CommandInset ref
LatexCommand ref
reference "chap:Reference-Capabilities"
\end_inset
.
\end_layout
\begin_layout Enumerate
The language is
\emph on
capabilities secure
\emph default
, as described in section
\begin_inset CommandInset ref
LatexCommand ref
reference "subsec:Capabilities-Security"
\end_inset
and chapter
\begin_inset CommandInset ref
LatexCommand ref
reference "chap:Reference-Capabilities"
\end_inset
.
\end_layout
\begin_layout Enumerate
Within a node, message delivery is
\emph on
causal
\emph default
, and across nodes, message delivery is pairwise FIFO ordered, and can be
made optionally
\emph on
causal
\emph default
, as described in section
\begin_inset CommandInset ref
LatexCommand ref
reference "subsec:Causal-Messaging"
\end_inset
and chapter
\begin_inset CommandInset ref
LatexCommand ref
reference "chap:Syntax-and-Operational"
\end_inset
.
\end_layout
\begin_layout Enumerate
Both actors and objects are garbage collected without requiring coordination
outside of the underlying message passing system, as described in section
\begin_inset CommandInset ref
LatexCommand ref
reference "subsec:Message-based-Garbage-Collection"
\end_inset
and chapters
\begin_inset CommandInset ref
LatexCommand ref
reference "chap:Actor-Collection"
\end_inset
and
\begin_inset CommandInset ref
LatexCommand ref
reference "chap:Object-Collection"
\end_inset
.
\end_layout
\begin_layout Enumerate
Within a node, messages are
\emph on
zero-copy
\emph default
, as described in chapter
\begin_inset CommandInset ref
LatexCommand ref
reference "chap:Object-Collection"
\end_inset
.
\end_layout
\begin_layout Standard
Each of these guarantees is made possible due to the interaction between
the type system and the runtime.
In some cases this interaction is obvious, such as the semantics of the
language providing no global variables, which is important for capabilities
security, and in other cases it is more subtle, such as data-race freedom
being important for logically atomic message handling, which is in turn
important for both causal messaging and garbage collection.
\end_layout
\begin_layout Standard
It is important to note that, while Pony makes some guarantees that are
useful for ensuring correctness and reasoning about programs, Pony is not
a tool for formal verification, nor is the implementation of the runtime
itself formally verified.
It would be extremely interesting to apply techniques used in formal verificati
on tools, such as Dafny and F*, to allow Pony to function as its own proof
assistant, and to implement a formally verified runtime (perhaps using
an extended Pony that provides for formal verification), but that must
be left for future work.
\end_layout
\begin_layout Subsection
\begin_inset CommandInset label
LatexCommand label
name "subsec:Static-Data-Race-Freedom"
\end_inset
Static Data-Race Freedom
\end_layout
\begin_layout Standard
If the type system can statically ensure data-race freedom, the runtime
and every program written in the language need not contain dynamic locking
mechanisms.
This is a significant performance gain, and the impact is felt not just
in computational performance, but, as we will see later, also in parallel
scalability and garbage collection.
\end_layout
\begin_layout Standard
To ensure data-race free concurrent execution, it is sufficient to enforce
a single principle: if a unit of execution (whether it is a thread, a process,
or any other implementation) can write to a data structure, no other unit
of execution can read from that data structure.
This has a natural corollary: if a unit of execution can read from a data
structure, no other unit of execution can write to that data structure.
\end_layout
\begin_layout Standard
Enforcing this property on individual memory locations, as opposed to complete
data structures, is insufficient, as it could result in the data structure
as a whole being inconsistent, even though the individual reads and writes
were safe.
For example, a data structure comprised of a linked list and a count of
the number of nodes in the list cannot be safely updated by controlling
access to individual memory locations: either the count or the list itself
would have to be changed first, resulting in a period where the count does
not accurately reflect the number of nodes in the list.
\end_layout
\begin_layout Standard
As a result, in order to enforce this property dynamically, access to a
data structure must be controlled with some form of runtime locking mechanism.
For example, the counted linked list could also include a mutex that must
be acquired in order to read from or write to the data structure.
However, this does not address safe access to the contents of the list
nodes.
If two units of execution each read the first element of the list, two
threads now have access to the same contained data.
In order to make the list as a whole data-race safe, every data element
that could be put in the list must also be protected by a mutex.
This problem is recursive: the data elements themselves may contain references
to data structures that must also be lockable.
\end_layout
\begin_layout Standard
This is the fine-grained locking problem.
There are many approaches to mitigating this problem, particularly in database
research.
The most common approach is to rely on a programer's domain knowledge to
correctly guess what the minimum level of locking is to ensure correct
behaviour.
However, all of these approaches are domain specific, are subject to programmin
g errors, and rely on locking mechanisms that are expensive on shared memory
systems and prohibitive in distributed systems.
\end_layout
\begin_layout Standard
A type system that allows only immutable data types solves the data-race
problem by disallowing all mutation.
This is an approach favoured by functional programming languages.
Since no unit of execution can write to the data structure, it is trivial
to guarantee without dynamic checks that the program is data-race free.
However, some algorithms are faster to compute or easier to implement over
mutable data structures than immutable ones.
As such, a type system that can express data-race free mutable data types
might offer advantages over a type system that can express only immutable
data types.
\end_layout
\begin_layout Standard
Purely static data-race free mutability has been expressed several ways,
including via ownership types, fractional permissions, and uniqueness and
immutability type systems.
In Pony, the type system incorporates
\emph on
deny capabilities
\emph default
, expressed as
\emph on
reference
\emph default
capabilities
\emph on
.
\emph default
Deny capabilities are a form of uniqueness and immutability type system
influenced by both
\emph on
object capabilities
\begin_inset CommandInset citation
LatexCommand cite
key "miller2003capability"
\end_inset
\emph default
and
\emph on
deny guarantee reasoning
\emph default
\begin_inset CommandInset citation
LatexCommand cite
key "dodds2009deny"
\end_inset
.
\end_layout
\begin_layout Standard
Deny capabilities describe what other aliases are
\emph on
denied
\emph default
by the existence of a reference.
Furthermore, they distinguish between what is denied
\emph on
locally
\emph default
(i.e.
aliases reachable via the same actor) and what is denied
\emph on
globally
\emph default
(i.e.
aliases reachable via other actors).
The result is a matrix of
\emph on
deny properties
\emph default
, with notions such as isolation, mutability, and immutability all being
derived from these deny properties.
What aliases to the object are allowed to do is explicit rather than implied,
whereas what the reference is allowed to do is derived.
\end_layout
\begin_layout Standard
Importantly, reference capabilities obey simple type checking rules that
allow for reasoning about data-race freedom to be done locally, both by
the programmer and by the compiler, rather than requiring global knowledge
about a program.
That is, the existence of some reference capability in some lexical scope
explicitly indicates that:
\end_layout
\begin_layout Enumerate
No other alias to that object can exist that violates that reference capability'
s deny properties.
\end_layout
\begin_layout Enumerate
No other alias to that object can exist whose deny properties would be violated
by that reference capability.
\end_layout
\begin_layout Standard
Such reasoning is both local (i.e.
can be done without reference to implementation details outside of the
function being reasoned about) and modular (i.e.
reasoning about a function once is sufficient regardless of the context
in which that function is used), even in the presence of type variables,
i.e.
generic types.
The Pony type system accomplishes this through a combination of
\emph on
viewpoint adaptation
\emph default
\begin_inset CommandInset citation
LatexCommand cite
key "cunningham2008universe"
\end_inset
, which determines a reference capability for a path based on all elements
of that path, rather than simply the reference capability of the final
element of the path, a separate and more liberal treatment of the types
of temporary values (that is, the result of an expression which is then
used in another expression, without establishing a path to the value by
assigning it to a field or a stack variable), and
\emph on
aliased and unaliased
\emph default
types, which provide a way to refer to the alias of a reference capability
(the type that results when a new path to a reference capability is created)
and the unalias of a reference capability (the type that results when a
path to a reference capability is removed, either through destructive read
or by explicitly removing a variable in the lexical scope).
\end_layout
\begin_layout Subsection
\begin_inset CommandInset label
LatexCommand label
name "subsec:Logically-Atomic-Behaviours"
\end_inset
Logically Atomic Behaviours
\end_layout
\begin_layout Standard
The code that an actor executes upon receipt of some message
\begin_inset Formula $m$
\end_inset
is termed a
\emph on
behaviour
\emph default
.
In Pony, every behaviour on every actor is
\emph on
logically atomic
\emph default
.
\end_layout
\begin_layout Standard
When a behaviour begins execution, it has a set of object and reference
capabilities defined by the actor's state and the contents of the message
\begin_inset Formula $m$
\end_inset
that has been received.
In Pony, an actor's state is represented as fields of the actor, and the
contents of the message
\begin_inset Formula $m$
\end_inset
are represented as arguments to the behaviour, in much the same way as
an object-oriented method call has a receiver and a set of arguments.
This initial state of capabilities is the total set of capabilities that
the behaviour will have.
No new capabilities that are not present when the behaviour begins executing
can be acquired.
Note that the behaviour may still create new actors and objects, but these
new actors and objects do not represent an expansion of the set of capabilities
: they must be created with the capabilities that were initially available.
\end_layout
\begin_layout Standard
As a result, a behaviour cannot witness heap mutation that the behaviour
does not itself perform.
This is a result of combining the reference capability type system, which
statically guarantees that if an actor can read from a memory address then
no other actor can write to it, with the guarantee that the initial set
of capabilities available to a behaviour cannot be expanded.
\end_layout
\begin_layout Standard
It is interesting to note that, while the set of capabilities cannot be
expanded, it is possible for it to be contracted.
Specifically, a capability that allows mutation of an address can be
\emph on
sent
\emph default
to another actor, and the data-race free type system guarantees that the
sending actor retains neither the ability to read from nor write to that
address.
As a result, it is possible for a behaviour to have the capability to read
or write some memory address, to give up that capability, and for the contents
of that address to be mutated by some other actor while the original behaviour
is still executing.
However, in this case, the behaviour will not be able to expand its set
of capabilities to once again include the capability to read from that
memory address.
As a result, the behaviour will not be able to witness the heap mutation.
\end_layout
\begin_layout Subsubsection
Reasoning About Atomic Behaviours
\end_layout
\begin_layout Standard
Requiring logically atomic behaviours is a powerful tool for reasoning about
actors.
Each behaviour can be considered as a separate sequential program, with
a separate heap, that operates on some set of preexisting state (fields
of the actor) and a set of input values (behaviour arguments).
The resulting program will produce output in four forms:
\end_layout
\begin_layout Enumerate
Sending a finite number of messages to other actors or itself.
\end_layout
\begin_layout Enumerate
The creation of a finite number of new actors.
\end_layout
\begin_layout Enumerate
Changes to the executing actor's state that will be propagated to the next
behaviour on that actor.
\end_layout
\begin_layout Enumerate
Side effects in the form of output to some device, for example a file system,
network, display, etc.
\end_layout
\begin_layout Standard
Note that these possible outputs correspond to the fundamental requirements
of the actor model, with the addition of device output.
\end_layout
\begin_layout Standard
Reasoning about individual behaviours as separate sequential programs removes
the need to consider concurrency within a behaviour.
This significantly simplifies the reasoning process.
However, it does not remove the need to consider concurrency in a program
as a whole.
While interleaved concurrent reads and writes to memory locations no longer
must be considered, message ordering remains non-deterministic where a
causal relationship is not present, which can introduce program executions
that exhibit race conditions at the logical level while still being data-race
free.
\end_layout
\begin_layout Subsubsection
Asynchronous Function Results
\end_layout
\begin_layout Standard
There are three primary techniques for returning asynchronous results from
asynchronous functions.
The first is blocking futures, where an asynchronous function returns a
value that may not yet be the result, but will be populated with the result
in the future.
The caller can then choose to block execution at some point until the result
has been populated.
The second is non-blocking futures, also referred to as asynchronous await.
This approach captures the stack as a continuation that will be executed
when the asynchronous result is available, and allows the caller to continue
handling other messages in the meantime.
The third is promises, which are similar to non-blocking futures, but instead
of capturing the stack as a continuation, closures are explicitly specified.
Promises allow more than one receiver of an asynchronous result, and also
allow exceptional behaviour to be propagated in the form of separate closures
for successful and unsuccessful execution.
\end_layout
\begin_layout Standard
These approaches are closely related, and each can be used, with some effort,
to implement the others.
Pony uses promises rather than blocking or non-blocking futures.
This decision is motivated by reasoning rather than performance: logically
atomic behaviours require asynchronous results to be returned via promises
rather than futures in order to avoid expanding the available set of capabiliti
es during execution of a behaviour.
\end_layout
\begin_layout Standard
Arguably, logically atomic behaviours could be considered an implicit requiremen
t of the actor model.
Specifically, the
\emph on
introduction requirement
\emph default
that implies that there can be no shared mutable state could be read to
also imply that a memory location that is not readable when a behaviour
begins executing must not become readable during execution.
This is because a newly readable memory location could contain an actor
address previously unknown to the actor executing the behaviour.
\end_layout
\begin_layout Standard
On the other hand, if the event of a previously unreadable memory location
becoming readable is considered to be a new message
\begin_inset Formula $m'$
\end_inset
, with the response to
\begin_inset Formula $m$
\end_inset
being considered finished and any remaining code to execute being considered
a response to
\begin_inset Formula $m'$
\end_inset
, then the introduction requirement is not violated.
Such an approach treats messages as more abstract than actual messages
in a mail queue: any expansion of the set of capabilities is treated as
the logical arrival of a new message.
This would allow, for example, blocking futures, which prevent shared mutable
state but allow expanding the set of capabilities.
\end_layout
\begin_layout Standard
Awaiting an asynchronous result, i.e.
using a non-blocking future, pauses a behaviour until an asynchronous result
is returned, but allows the actor to continue receiving messages and executing
their associated behaviours in the meantime.
Effectively, the behaviour stack is captured as a continuation and resumed
when the asynchronous result becomes available.
This approach also results in non-atomic behaviours, as the actor may have
been given new capabilities by intervening messages, resulting in the continuat
ion being executed with a larger set of capabilities than existed when
\begin_inset Formula $m$
\end_inset
initially arrived.
\end_layout
\begin_layout Standard
Both blocking and non-blocking futures can be encoded with logically atomic
behaviours, either with or without promises, but doing so can result in
code that is difficult to understand.
A non-blocking future (asynchronous await) can be encoded as a closure
that will be executed upon receipt of a message containing the expected
result.
This is continuation-passing style for asynchronous messages.
Encoding a blocking future involves combining continuation-passing style
with a queue to store messages that arrive before the message containing
the expected result.
The processing of these queued messages is delayed until after the expected
result is received and the associated closure executed.
In both cases, the programmer writes code to explicitly do what a compiler
transformation would implicitly do.
\end_layout
\begin_layout Standard
Using promises, which are implemented in Pony as part of the standard library
rather than as a language feature, preserves the introduction requirement
without requiring the fulfilment of a future to be treated as a equivalent
to a new message.
The semantics of both blocking and non-blocking futures are still possible
to achieve, but the underlying complexity of these approaches is directly
exposed to the programmer.
\end_layout
\begin_layout Subsection
\begin_inset CommandInset label
LatexCommand label
name "subsec:Capabilities-Security"
\end_inset
Capabilities Security
\end_layout
\begin_layout Standard
A capability is an unforgeable token that both designates an object and
provides access to that object.
Capabilities security uses the possession of such tokens to control access
to resources.
Capabilities have a long history, stretching from operating system research
(such as KeyKOS
\begin_inset CommandInset citation
LatexCommand cite
key "hardy1985keykos"
\end_inset
, EROS
\begin_inset CommandInset citation
LatexCommand cite
key "shapiro2002eros"
\end_inset
, Coyotos
\begin_inset CommandInset citation
LatexCommand cite
key "shapiro2007coyotos"
\end_inset
, and seL4
\begin_inset CommandInset citation
LatexCommand cite
key "klein2009sel4"
\end_inset
) to programming languages (such as Joule
\begin_inset CommandInset citation
LatexCommand cite
key "tribble1995joule"
\end_inset
, E
\begin_inset CommandInset citation
LatexCommand cite
key "miller2005concurrency"
\end_inset
, AmbientTalk
\begin_inset CommandInset citation
LatexCommand cite
key "van2007ambienttalk"
\end_inset
, Caja
\begin_inset CommandInset citation
LatexCommand cite
key "miller2008safe"