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
|
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename join-python.info
@settitle join-python
@afourpaper
@documentencoding UTF-8
@documentlanguage en
@finalout
@c %**end of header
@dircategory Python
@direntry
* join-python: (join-python). Join-calculus for Python
@end direntry
@copying
Copyright @copyright{} 2014 Mattias Andrée
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts. A copy of the license is included in the section entitled
``GNU Free Documentation License''.
@end quotation
@end copying
@ifnottex
@node Top
@top Join Python -- Join-calculus for Python
@insertcopying
@end ifnottex
@titlepage
@title Join Python
@subtitle Join-calculus for Python
@author by Mattias Andrée (maandree)
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage
@contents
@menu
* Overview:: Brief overview of Join Python.
* Signals:: The signal construct.
* Fragments:: The fragment join construct.
* GNU Free Documentation License:: Copying and sharing this manual.
@end menu
@node Overview
@chapter Overview
Join Python is a Python 3 library that implements join-calculus.
Join Python can be used by importing the module @code{join} in
any Python 3 program, provided that Join Python is installed.
Join Python provides the ability to write more concise code using
almost any published concurrency pattern with explicit monitor calls.
@node Signals
@chapter Signals
A signal it as function that runs asynchronously. It is put
in its own thread. To declare a signal, add the @code{@@signal}
decorator to a function definition or pass function to the
the constructor of the class @code{signal}.
@cartouche
@example
>>> from join import *
>>> import time
>>>
>>> @@signal
>>> def sig(delay, value):
>>> time.sleep(delay)
>>> print(value)
>>>
>>> sig(0.25, 'first')
>>> print('last')
last
first
@end example
@end cartouche
@cartouche
@example
>>> from join import *
>>> import time
>>>
>>> def f(delay, value):
>>> time.sleep(delay)
>>> print(value)
>>>
>>> signal(f)(0.25, 'first')
>>> print('last')
last
first
@end example
@end cartouche
As an extension to join-calculus, signals
in Join Java can be joined with the returned
value of the function can be fetched when joined.
@cartouche
@example
>>> from join import *
>>> import time
>>>
>>> def f(delay, value):
>>> time.sleep(delay)
>>> return value ** 2
>>>
>>> sig = signal(f)(0.25, 2)
>>> print('between')
>>> print(sig.join())
between
16
@end example
@end cartouche
In the next chapter fragments will be introduced.
If you want a signal without a fragment capability
use @code{@@puresignal} or @code{puresignal} instead
of @code{@@signal} or @code{signal}.
@node Fragments
@chapter Fragments
A fragment is a partial function. What this means is
that you can make functions that block until all its
fragments have returned. Signals return immediately.
Waiting for a fragment is called joining,@footnote{Yes,
it is a bit inconvenient that waiting for a thread
or signal is also called joining.} when joining when
a fragment you receive the arguments in was invoked with
and the value it returned, the latter being an extension
to join-calculus. Remember that a signal returns an
object with an argumentless method name @code{join} that
joins with the signal and returns that value the signal
function returned.
@cartouche
@example
>>> from join import *
>>>
>>> @@fragment
>>> def fragment(value):
>>> return value ** 2
>>>
>>> def f(value):
>>> ((fragment_value,), _kwargs, rc) = join(fragment)
>>> return rc + fragment_value + value
>>>
>>> fragment(2)
>>> print(f(3))
10
@end example
@end cartouche
The function @code{join} returns a tuple of the positional
arguments, the named arguments and the returned value.
But you can also join with multiple fragemnts, in which case
@code{join} returns a list of these tuples, one tuple for
each fragment, in the same order as they appear as arguments
for the @code{join} call.
@cartouche
@example
>>> from join import *
>>>
>>> @@fragment
>>> def f1(value):
>>> return value ** 2
>>>
>>> @@fragment
>>> def f2(value):
>>> return value ** 3
>>>
>>> def f(value):
>>> ((_args1, _kwargs1, rc1), (_args2, _kwargs2, rc2)) = join(f1, f2)
>>> return value + rc1 + rc2
>>>
>>> f1(2)
>>> f2(2)
>>> print(f(2))
14
@end example
@end cartouche
@node GNU Free Documentation License
@appendix GNU Free Documentation License
@include fdl.texinfo
@bye
|