SuperPascal
SuperPascal is an imperative, concurrent computing programming language developed by Per Brinch Hansen.[1] It was designed as a publication language: a thinking tool to enable the clear and concise expression of concepts in parallel programming. This is in contrast with implementation languages which are often complicated with machine details and historical conventions. It was created to address the need at the time for a parallel publication language. Arguably, few languages today are expressive and concise enough to be used as thinking tools. History and developmentSuperPascal is based on Niklaus Wirth's sequential language Pascal, extending it with features for safe and efficient concurrency. Pascal itself was used heavily as a publication language in the 1970s. It was used to teach structured programming practices and featured in text books, for example, on compilers[2] and programming languages.[3] Hansen had earlier developed the language Concurrent Pascal,[4] one of the earliest concurrent languages for the design of operating systems and real-time control systems. The requirements of SuperPascal were based on the experience gained by Hansen over three years in developing a set of model parallel programs, which implemented methods for common problems in computer science.[5] This experimentation allowed him to make the following conclusions about the future of scientific parallel computing:
These then led to the following requirements for a parallel publication language:
FeaturesThe key ideas in the design of SuperPascal was to provide a secure programming, with abstract concepts for parallelism.[6][7] SecuritySuperPascal is secure in that it should enable its compiler and runtime system to detect as many cases as possible in which the language concepts break down and produce meaningless results.[8] SuperPascal imposes restrictions on the use of variables that enable a single-pass compiler to check that parallel processes are disjoint, even if the processes use procedures with global variables, eliminating time-dependent errors. Several features in Pascal were ambiguous or insecure and were omitted from SuperPascal, such as labels and ParallelismThe parallel features of SuperPascal are a subset of occam 2, with the added generality of dynamic process arrays and recursive parallel processes.[7] A parallel source() | sink() end A forall i := 0 to 10 do something() Channels and communicationParallel processes communicate by sending typed messages through channels created dynamically. Channels are not variables in themselves, but are identified by a unique value known as the channel reference, which are held by channel variables. A channel is declared, for example, by the declaration type channel = *(boolean, integer);
var c: channel;
which defines a new (mixed) type named channel and a variable of this type named c. A mixed type channel is restricted to transmitting only the specified types, in this case boolean and integer values. The channel c is initialised by the open(c) Message communication is then achieved with the var left, right: channel; a: number;
receive(left, a);
send(right, a)
The functions send(channel, e1, e2,..., en); receive(channel, v1, v2,..., vn) The following runtime communication errors can occur:
Parallel recursionRecursive procedures can be combined with procedure pipeline(min, max: integer; left, right: channel);
var middle: channel;
begin
if min < max then
begin
open(middle);
parallel
node(min, left, middle) |
pipeline(min + 1, max, middle, right)
end
end
else node(min, left, right)
end;
Another example is the recursive definition of a process tree: procedure tree(depth: integer, bottom: channel);
var left, right: channel;
begin
if depth > 0 then
begin
open(left, right);
parallel
tree(depth - 1, left) |
tree(depth - 1, right) |
root(bottom, left, right)
end
end
else leaf(bottom)
Interference controlThe most difficult aspect of concurrent programming is unpredictable or non-reproducible behaviour caused by time-dependent errors. Time-dependent errors are caused by interference between parallel processes, due to variable updates or channel conflicts. If processes sharing a variable, update it at unpredictable times, the resulting behaviour of the program is time-dependent. Similarly, if two processes simultaneously try to send or receive on a shared channel, the resulting effect is time-dependent. SuperPascal enforces certain restrictions on the use of variables and communication to minimise or eliminate time-dependent errors. With variables, a simple rule is required: parallel processes can only update disjoint sets of variables.[1] For example, in a Structure and syntaxSuperPascal is a block structured language, with the same basic syntax as Pascal. A program consists of a header, global variable definitions, function or procedure definitions and a main procedure. Functions and procedures consists of blocks, where a block is a set of statements. Statements are separated by semicolons, as opposed to languages like C or Java, where they are terminated by semicolons. The following is an example of a complete SuperPascal program, which constructs a pipeline communication structure with 100 nodes. A master node sends an integer token to the first node, this is then passed along the pipeline and incremented at each step, and finally received by the master node and printed out. program pipeline;
const
len = 100;
type
channel = *(integer);
var
left, right: channel;
value: integer;
procedure node(i: integer; left, right: channel);
var value: integer;
begin
receive(left, value);
send(right, value+1)
end;
procedure create(left, right: channel);
type row = array [0..len] of channel;
var c: row; i: integer;
begin
c[0] := left;
c[len] := right;
for i := 1 to len-1 do
open(c[i]);
forall i := 1 to len do
node(i, c[i-1], c[i])
end;
begin
open(left, right);
parallel
send(left, 0) |
create(left, right) |
receive(right, value)
end;
writeln('The resulting value is ', value)
end.
ImplementationThe SuperPascal software can be accessed freely from the Brinch Hansen Archive.[9] It consists of a compiler and interpreter, which are both written in normal, sequential Pascal (ISO Level 1 standard Pascal). This is supported by the GNU Pascal compiler and newer versions of the Free Pascal compiler (2.7.1+) with the For GPC, the file Free Pascal also needs a solution to the above "clock" problem (On windows, just declare gettickcount as external with "clock" as name). Further, the reset/rewrites that are marked as non-standard in the source code must be changed to assign/reset (or rewrite) pairs. (GPC probably only errors on this if you enable strict flags), and the C preprocessor commands #include 'xx' must be changed to {$include 'xx'}. { Time code for readtime in Freepascal on unix systems }
Function FpTime(var tloc : integer): integer; external name 'FPC_SYSC_TIME';
procedure readtime(
var t: integer);
begin
{ A nonstandard function reads
the processor time in ms }
t:=fptime(t);
end;
References
External links
|