Skip to content

Commit dd7f4f0

Browse files
committed
Replacing 'which' with 'that'
1 parent d4c838d commit dd7f4f0

File tree

1 file changed

+21
-21
lines changed

1 file changed

+21
-21
lines changed

notes/techreport.tex

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ \section{Introduction}
3131

3232
Scala-gopher is a library-level implementation of process algebra [Communication Sequential Processes, see \cite{Hoare85communicatingsequential} as ususally enriched by $\pi$-calculus \cite{Milner:1992:CMP:162037.162038} naming primitives] in scala. In addition to support of a 'limbo/go-like' \cite{Inferno:Limbo} \cite{golang} channels/goroutine programming style scala-gopher provides a set of operations following typical idiomatic scala.
3333

34-
At first, let's remind the fundamentals of a CSP model. The primary entities of this model are channels, coroutines and selectors. Coroutines are lightweight threads of execution, which can communicate with each other by passing messages between channels. Channels can be viewed as blocked multiproducer/multiconsumer queues. Sending message to unbuffered channel suspends producing coroutines until the moment when this message will have been read by some consumer. Buffered channels transfer control flow between sinks not on each message, but when internal channel buffer is full.
34+
At first, let's remind the fundamentals of a CSP model. The primary entities of this model are channels, coroutines and selectors. Coroutines are lightweight threads of execution, that can communicate with each other by passing messages between channels. Channels can be viewed as blocked multiproducer/multiconsumer queues. Sending message to unbuffered channel suspends producing coroutines until the moment when this message will have been read by some consumer. Buffered channels transfer control flow between sinks not on each message, but when internal channel buffer is full.
3535
In such way, communication via channel implicitly provides flow control functionality. At last, a selector statement is a way of coordination of several communication activities: like Unix select(2) system call, select statement suspends current coroutines until one of the actions (reading/writing to one of the channels in selector) will be possible.
3636

3737
Let's look at the one simple example:
@@ -56,7 +56,7 @@ \section{Introduction}
5656
}
5757
}
5858
\end{Verbatim}
59-
Here two channels and three goroutines are created. The first coroutine just generates consecutive numbers and sends one to channel \verb|in|, second - accepts this sequence as the initial state and for each number which has been read from state channel, writes one to \verb|out| and produces next step by filtering previous. The result of the fold is the \verb|in| channel whith applied filters for each prime. The third coroutine just maps range to values to receive a list of first \verb|n| primes in Future.
59+
Here two channels and three goroutines are created. The first coroutine just generates consecutive numbers and sends one to channel \verb|in|, second - accepts this sequence as the initial state and for each number that has been read from state channel, writes one to \verb|out| and produces next step by filtering previous. The result of the fold is the \verb|in| channel whith applied filters for each prime. The third coroutine just maps range to values to receive a list of first \verb|n| primes in Future.
6060

6161
If we look at the sequence of steps during code evaluation, we will see at first generation of
6262
number, then checks in filters and then if a given number was prime - final output. Note, that goroutine is different from JVM thread of execution: sequential code chunks are executed in configurable executor service; switching between chunks does not use blocking operations.
@@ -66,18 +66,18 @@ \section{Implementation of base constructs }
6666

6767
\subsection{Go: Translations of hight-order functions to asynchronous form.}
6868

69-
The main entity of CSP is a 'process' which can be viewed as a block of code which handles specific events. In Go CSP processes are represented as goroutines (aka coroutines).
69+
The main entity of CSP is a 'process' which can be viewed as a block of code that handles specific events. In Go CSP processes are represented as goroutines (aka coroutines).
7070

71-
\verb|go[X](x:X):Future[X]| is a thin wrapper arround SIP-22 async/await which does some preprocessing before async transformation:
71+
\verb|go[X](x:X):Future[X]| is a thin wrapper arround SIP-22 async/await that does some preprocessing before async transformation:
7272
\begin{itemize}
7373
\item do transformation of hight-order function in async form.
7474

7575

76-
Let $f(A \To B)\To C$ is a hight-order function, which accepts other function
76+
Let $f(A \To B)\To C$ is a hight-order function, that accepts other function
7777
$g:A \To B$ as parameter.
78-
Let's say that $g$ in $f$ is {\i invocation-only } if $f$ does not store $g$ in memory outside of $f$ scope and doesn't return $g$ as part of return value. Only one action which $f$ can do with $g$ is invocation or passing as a parameter to other invocation-only function. If we look at Scala collection API, we will see, that near all hight-order functions there are invocation-only.
78+
Let's say that $g$ in $f$ is {\i invocation-only } if $f$ does not store $g$ in memory outside of $f$ scope and doesn't return $g$ as part of return value. The only two things that $f$ can do with $g$ is an invocation or passing it as a parameter to other invocation-only function. If we look at Scala collection API, we will see, that near all hight-order functions there are invocation-only.
7979

80-
Now, if we have $g$ which is invocation-only in $f$, and if we have function $g' : (A \To Future[B])$ let build function $f':(A\To Future[B])\to Future[C]$ that if $await(g')==await(g)$ then $await(f'(g'))==f(g))$ in next way
80+
Now, if we have $g$ which is invocation-only in $f$, and if we have a function $g' : (A \To Future[B])$ let's build function $f':(A\To Future[B])\to Future[C]$ that if $await(g')==await(g)$ then $await(f'(g'))==f(g))$ in the following way
8181
\begin{itemize}
8282
\item $f'$ translated to $await(\makebox{transformed-body}(f))$
8383
\item $g(x)$ inside $f$ translated to $await(g'(x))$
@@ -100,7 +100,7 @@ \subsection{Go: Translations of hight-order functions to asynchronous form.}
100100
} }
101101
\end{Verbatim}
102102

103-
which after simplification step become
103+
that after simplification step becomes
104104

105105
\begin{Verbatim}[fontsize=\small]
106106
(1 to n).mapAsync(i => out.aread)
@@ -133,7 +133,7 @@ \subsection{Channels: callbacks organized as waits}
133133
Here we can read argument type as protocol where each arrow is a step:
134134
$f$ is called on opportunity to read and
135135
$ContRead[A,B] \To Option[ContRead.In[A] \To Future[B]]$ means that when reading is
136-
possible, we can ignore this opportunity (i.e. return None) or return handler which will
136+
possible, we can ignore this opportunity (i.e. return None) or return handler that will
137137
consume value (or \verb|end-of-input| or few other special cases) and return future to the next
138138
computation state.
139139

@@ -180,7 +180,7 @@ \subsection{Selectors: process composition as event generation}
180180

181181
Appropriative expression in CSP syntax: $*[(c_{1} ? x \to P)\square(c_{2} ! y \to Q)]$
182182

183-
Scala-gopher provides \verb|select| pseudo-object which provides set of high-order pseudo-functions over
183+
Scala-gopher provides \verb|select| pseudo-object that provides a set of higher-order pseudo-functions over
184184
channels, which accept syntax of partial function over channel events:
185185

186186
\begin{Verbatim}[fontsize=\small]
@@ -192,7 +192,7 @@ \subsection{Selectors: process composition as event generation}
192192
}
193193
\end{Verbatim}
194194

195-
or version which must not be wrapped by \verb|go| stamenet:
195+
or version that must not be wrapped by \verb|go| stamenet:
196196

197197
\begin{Verbatim}[fontsize=\small]
198198
select.aforever {
@@ -225,11 +225,11 @@ \subsection{Selectors: process composition as event generation}
225225

226226
Here we see the special syntax for tuple state. Also note, that \verb|afold| macro assumes that \verb|s match| must be the first statement in the argument pseudo-function. \verb|select.exit| is used for returning result from the flow.
227227

228-
Events which we can check in select match statement are reading and writing of channels and select timeouts. In future we will think about extending the set of notifications - i.e. adding channel closing and overflow notifications, which are needed in some rare scenarios.
228+
Events that we can check in select match statement are reading and writing of channels and select timeouts. In future we will think about extending the set of notifications - i.e. adding channel closing and overflow notifications, which are needed in some rare scenarios.
229229

230-
\subsection{Transputer: an entity which encapsulates processing node. }
230+
\subsection{Transputer: an entity that encapsulates processing node. }
231231

232-
The idea is to have an actor-like object, which encapsulates processing node: i.e., reads input data
232+
The idea is to have an actor-like object, that encapsulates processing node: i.e., reads input data
233233
from the set of input ports; writes a result to the set of output ports and maintaines a local
234234
mutable state inside.
235235

@@ -310,7 +310,7 @@ \subsection{ Programming Techniques based on dynamic channels }
310310

311311
\item{ Channel-based API where client supply channel where to pass reply }
312312

313-
Let we want provide API which must on request return some value to the caller. Instead of providing a method which will return a result on the stack we can provide endpoint channel, which will accept method arguments and channel where to return a result.
313+
Let we want provide API that must on request return some value to the caller. Instead of providing a method that will return a result on the stack we can provide endpoint channel, that will accept method arguments and channel where to return a result.
314314

315315
Next example illustrates this idea:
316316

@@ -355,7 +355,7 @@ \subsection{ Programming Techniques based on dynamic channels }
355355

356356
To register listener channel for receiving notification client sends this channel to newListener
357357

358-
The internal state contains message bus represented by a channel which is replaced during each new input message. Each listener spawns the process which reads messages from the current message bus.
358+
The internal state contains message bus represented by a channel which is replaced during each new input message. Each listener spawns the process that reads messages from the current message bus.
359359

360360

361361
\end{itemize}
@@ -368,26 +368,26 @@ \section{ Connection with other models }
368368
of composable operations and clear high-level functionality but lack of flexibility,
369369
at the other side - very flexible but low-level models like actors.
370370

371-
Scala-gopher provides uniform API which allows build systems from different parts of spectrum:
371+
Scala-gopher provides uniform API that allows build systems from different parts of spectrum:
372372
it is possible to build dataflow graph in a declarative manner and connect one with a dynamic part.
373373

374374
The reactive isolates model\cite{Prokopec:2015:ICE:2814228.2814245} is close to scala-gopher model with dynamically-grown channel buffer (except that reactive isolates support distributed case).
375-
Isolate here corresponds to Transputer, Channel to Output and Events to gopher Input. Channels in reactive isolates are more limited: only one isolate which owns the channel can write to it when in the scala-gopher concept of channel ownership is absent.
375+
Isolate here corresponds to Transputer, Channel to Output and Events to gopher Input. Channels in reactive isolates are more limited: only one isolate that owns the channel can write to it when in the scala-gopher concept of channel ownership is absent.
376376

377-
Communicating Scala Objects\cite{CSO} is a direct implementation of CSP model in Scala which allows
377+
Communicating Scala Objects\cite{CSO} is a direct implementation of CSP model in Scala that allows
378378
building expressions in internal Scala DSL, closed to original Hoar notation with some extensions, like extended rendezvous for mapping input streams. Processes in CSO are not lightweight: each process requires Java thread which limits the scalability of this library until lightweight threading will be implemented on JVM level.
379379

380380
Subscript\cite{vanDelft:2013:DCL:2489837.2489849} is a Scala extension which adds to language new constructions for building process algebra expressions. Although extending language can afford fine-grained interconnection of process-algebra and imperative language notation in far perspective, now it makes CPA constructs a second-class citizen because we have no direct representation of process and event types in Scala type system.
381381

382382

383383
\section{ Conclusion and future directions }
384384

385-
Scala-gopher is a relatively new library which has not yet reached 1.0 state, but we have the early experience
385+
Scala-gopher is a relatively new library that has not yet reached 1.0 state, but we have the early experience
386386
reports from using the library for building some helper components in an industrial software project.
387387

388388
In general, feedback is positive: developers enjoy a relatively simple mental model and ability to freely use asynchronous operations inside higher-order functions. So, we can recommend to made conversion of invocation-only functions into async form to be available into the async library itself.
389389

390-
The area which needs more work: error handling in \verb|go| statements: now \verb|go| returns
390+
The area that needs more work is an error handling in \verb|go| statements: now \verb|go| returns
391391
\verb|Future| which can hold a result of the evaluation or an exception. If we ignore statement result then we miss handling of exception; from another side, it unlikely handle errors there, because we must allow a developer to implement own error processing. The workaround is to use different method name for calling statement in the context with ignored return value, but it is easy to mix-up this two names.
392392
We think, that right solution can be built on language level: we can bind handling of ignored value to type by providing appropriative implicit conversion or use special syntax for functions which needs
393393

0 commit comments

Comments
 (0)