![]() |
The fundamental of Orc calculus is the execution of expressions, which are
built up recursively with concurrent combinators. During execution, an
expression may call sites (i.e., external services) or publish values. The
section served as the brief introduction of the language, for complete
coverage of the language, please refer to the [ORCUserGuide]. Site Sites are basic units of Orc language. A site can be an unreliable external
service (e.g., Google), or a predictable and well-defined local service (e.g.,
if). Henceforth, we will refer the former as external site or external service
and latter as local site or local service. The simplest Orc expression is a site
call M(p), where M is the service’s name and p is a list of parameters. The
effect of a site call can be response (when it returns a value), halted (when it
explicitly reports that it will never respond), or pending (neither response nor
halted). As an example, Google("Orc") calls the external service provided by
Google and its response is the search result for "Orc" by Google search
engine. Site calls are strict, which means that a site can only be called if all
its parameters have values. Function Like many other programming languages, functions are expressions with a
defined name and a list of parameters. When a function is called, the function
body is executed immediately if it does not make use of unbounded argument
expressions, and the argument expressions are executed in parallel with the
function body. Combinators There are four combinators: parallel, sequential, pruning, and otherwise
combinators. The parallel combinator F | G defines a parallel
expression, where expressions F and G execute independently, and its published
value can be the value published either by F or by G or both of them. As an
example, Google("Orc") | Yahoo("Orc") will call Google and Yahoo
site for searching "Orc" concurrently. The sequential combinator F > x > G defines a sequential expression,
where each value published by F initiates a separate execution of G wherein x
is bound to it. The execution of F is then continued in parallel with all
these executions of G. The values published by the sequential expression are
the values published by the executions of G. As an example,
(Google("Orc") | Yahoo(\Orc")) > x > Email(addr; x) will call
Google and Yahoo sites simultaneously. For each returned value, an instance of
x will be bound to it, and an email will be sent to addr for each instance of
x. Thus, up to two emails will be sent. If x is not used in G, F >>
G can be used as a shorthand for F > x > G. The pruning combinator F < x < G defines a pruning expression, where
initially F and G execute in parallel. However, when F needs the value of x it
will be blocked until G publishes a value to bind x and G terminates
immediately after that. As an example, Email(addr; x) < x <
(Google("Orc") | Yahoo("Orc")) will be able to get the faster
result for the email sending to addr. In contrast to sequential expressions,
it will publish at most one value. if x is not used in F, F << G
can be used as a shorthand for F < x < G. The otherwise combinator F ; G defines an otherwise expression, where F
executes first. The execution of F is replaced by G if F halts without any
published value. F halts if all site calls are responded or halted, and it
does not publish any more value or call any more site. As an example, in
(Google("Orc") ; Yahoo("Orc")) > x > Email(addr; x), expression
Yahoo("Orc") is used as a backup service for searching "Orc" and it will be
called only if the site call Google("Orc") halts without any result for "Orc".
Functional Core Language Orc is enhanced with functional core language (Cor) to support various data
types, mathematical operators (e.g., 1+2), conditional expressions (i.e., if E
then E else E), etc. The complete supported syntax can be found in Section
3.8.1.4. Cor structures are eventually translated into the
fundamental syntax of Orc. Example - Metronome Timer can be used to execute an action periodically, e.g. polling a service
on a regular interval. Following is a function that defines a metronome, which
executes an action at regular intervals. Note that the function is defined
recursively. def metronome(t) = signal | Rtimer(t)
>> metronome() The following example publishes "tick" once per second, and publishes "tock"
once per second after an intial half-second delay. Thus the publications are
"tick tock tick ... " where "tick" and "tock" alternate each
other metronome(1000) >> "tick"
| Rtimer(500) >>
metronome(1000) >> "tock"