Table of Contents
In Chapter 1, we described the syntax and semantics of the Orc language. Now, we turn our attention to how the language is used in practice, with guidelines on style and programming methodology, including a number of common concurrency patterns.
In this section we suggest some syntactic conventions for writing Orc programs. None of these conventions are required by the parser; newlines are used only to disambiguate certain corner cases in parsing, and other whitespace is ignored. However, following programming convention helps to improve the readability of programs, so that the programmer's intent is more readily apparent.
When the combined expressions are small, write them all on one line.
F | G | HNote that we do not need parentheses here, since
| is fully associative and commutative.
When the combined expressions are large enough to take up a full line, write one expression
per line, with each subsequent expression aligned with the first and preceded by |.
Indent the first expression to improve readability.
long expression | long expression | long expression
A sequence of parallel expressions often form the left hand side of a sequential combinator. Since the sequential combinator has higher precedence, use parentheses to group the combined parallel expressions together.
( expression | expression ) >x> another expression
When the combined expressions are small, write a cascade of sequential combinators all on the same line.
F >x> G >y> H
Remember that sequential is right associative; in this example, x is bound in both G and H, and y is
bound in H.
When the combined expressions are large enough to take up a full line, write one expression per line; each line ends with the combinator which binds the publications produced by that line.
long expression >x> long expression >y> long expression
For very long-running expressions, or expressions that span multiple lines, write the combinators on separate lines, indented, between each expression.
very long expression >x> very long expression >y> very long expression
When the combined expressions are small, write them on the same line:
F <x< GWhen multiple pruning combinators are used to bind multiple variables (especially when the scoped expression is long), start each line with a combinator, aligned and indented, and continue with the expression.
long expression <x< G <y< H
The pruning combinator is not often written in its explicit form
in Orc programs. Instead, the val declaration is often more
convenient, since it is semantically equivalent and mentions the variable
x before its use in scope, rather than after.
val x = G val y = H long expression
Additionally, when the variable is used in only one place, and the expression is small, it is often easier to use a nested expression. For example,
val x = G val y = H M(x,y)is equivalent to
M(G,H)
Sometimes, we use the pruning combinator simply for its capability to terminate
expressions and get a single publication; binding a variable is irrelevant. This
is a special case of nested expressions. We use the identity site let
to put the expression in the context of a function call.
For example,
x <x< F | G | His equivalent to
let(F | G | H)
The translation uses a pruning combinator, but we don't need to write the combinator, name an irrelevant variable, or worry about precedence (since the expression is enclosed in parentheses as part of the call).
Declarations should always end with a newline.
def add(x,y) = x + y val z = 7 add(z,z)While the parser does not require a newline to end a declaration, it uses the newline to disambiguate certain corner cases in parsing, such as function application.
When the body of a declaration spans multiple lines, start the body on a new line
after the = symbol, and indent the entire body.
def f(x,y) = declaration declaration body expression
Apply this style recursively; if a def appears within a def, indent its contents even further.
def f(x,y) = declaration def helper(z) = declaration in helper declaration in helper body of helper declaration body expression