Joyce (programming language)
Joyce is a secure programming language for concurrent computing designed by Per Brinch Hansen in the 1980s. It is based on the sequential language Pascal and the principles of communicating sequential processes (CSP). It was created to address the shortcomings of CSP to be applied as a programming language, and to provide a tool, mainly for teaching, for distributed computing system implementation. The language is based around the concept of "agents"; concurrently executed processes that communicate only by the use of channels and message passing. Agents may activate subagents dynamically and recursively. The development of Joyce formed  the foundation of the language SuperPascal, also developed by Hansen around 1993. Features. Joyce is based on a small subset of Pascal, extended with features inspired from CSP for concurrency. The following sections describe some of the more novel features that were introduced. Agents. An agent is a procedure consisting of a set of statements and possibly nested definitions of other agents. An agent may dynamically "activate" subagents which execute concurrently with their "creator". An agent can terminate only when all of its subagents have also terminated. For example, an agent codice_1 activates codice_2: agent process1(x, y: integer); begin end ; agent process2(); use process1; begin end; The activation of an agent creates new instances of all local variables and the value of each formal parameter is copied to a local variable. Hence, agents cannot access variables of other agents and are allowed only to communicate through the use of channels. This restriction prevents problems associated with the use of shared variables such as race conditions. Communication. Agents communicate through entities called "channels". Channels have an alphabet, defining the set of symbols which may be transmitted. Channels are created dynamically and accessed through the use of "port" variables. A port  type is defined by a distinct set of symbols constituting its alphabet. Symbols with multiple values are defined with a specific type. For example: stream = [int(integer), eos]; The symbol codice_3 denotes a "message" symbol called codice_4 of any integer value. The second typeless symbol declaration codice_5 (end of stream) is named a "signal". Once a port type has been defined, a port variable of that type can be declared: out : stream in : stream And then a channel entity, internal to the agent creating it, can be activated as follows: +out; Symbols can then be sent and received on  channels using the CSP-style input and output operators codice_6 and codice_7 respectively. A communication can occur only if there is a receiving agent matching the sending agent. The receiving agent must expect to receive the symbol type being sent. For example, the value 9 followed by the codice_5 symbol is sent on port codice_9: out ! int(9) out ! eos And an integer message is received into a variable of a matching type, followed by the codice_5: received : integer in ? int(received) in ? eos Polling statements. Polling statements are based the CSP concept of guarded alternatives. A polling statement is made up  of a set of statements, each guarded by an input channel statement. When a communication is matched between a transmitting agent and a guard, the guard is executed, followed by the corresponding statement. For example: poll end Where the port codice_11 is monitored for the signals codice_12 or codice_13, on a matching communication, the corresponding variables codice_14 or codice_15 are incremented. Security. Joyce was designed to be a "secure" language in the sense that a compiler would be able to detect all violations of the language rules. Example program. The following is a complete example program, taken from the original  paper introducing the Joyce programming language, implementing an algorithm to generate prime numbers based on a sieving technique for generation of primes. A codice_16 agent is sent a stream of integers from its predecessor, the first being a prime. It removes all multiples of this prime from the stream and activates a successor. This continues until the codice_5 signal is propagated along the set of sieves. agent sieve(inp, out: stream); var more: boolean; x, y: integer; begin end; The following agent initialises the set of sieve agents and inputs into them a stream of integers between 3 and 9999. agent  primes; use generate, sieve, print; var a, b: stream; begin end; Implementation. Stack allocation. Due to concurrent execution of agent procedures, a conventional sequential stack allocation scheme cannot be used as the activation records of the agent calls do not follow a last-in first-out pattern. Instead, the creator-subagent relationships form a tree-structured stack. A simple scheme is used to implement this behaviour, which works by allocating new activation records at the top of the stack, and linking subagents' activation records to their creator's record. These records are freed only when the agent has terminated  and they are at the top of the stack. The effectiveness of this scheme depends on the structure and behaviour of a program, which in some cases will result in poor memory use. A more effective scheme was implemented in Hansen's language SuperPascal. External links. , Brinch Hansen Archive, a set of his papers