Copyright Tristan Aubrey-Jones May 2008.
Abstract: A project investigating and developing an implicitly concurrent programming language, based on a metaphor taken from the physical world is reported. Uses a programming paradigm where programs consist of systems of autonomous agents, or active objects which communicate via message passing. A language enhancing Java with actors and linear types is presented. Example programs are written, compiled, and executed to evaluate the usefulness of the language. The language found to provide a familiar notation for implicit parallelism, and a compelling new model for concurrency, combining the performance of shared variables with the elegance of message passing.
Introductory Slides (PDF),
Report (PDF),
ActiveJava compiler prototype (ajavac),
ActiveJava runtime library (ajava_lang).
Examples:
calc - pocket calculator actor program dining - dining philosophers actor program (never deadlocks) sort - parallel quicksort implementation ("SortBenchmark" sorts 10,000 random integers using actors, java threads, and sequentially and compares)To compile examples use:
compile.bat ./calc compile.bat ./sort compile.bat ./diningTo run examples use:
run ./calc Main run ./dining Main run ./dining Main fast run ./sort Main run ./sort SortingBenchmark
import javax.swing.*;
import java.awt.*;
public aclass Calculator extends AFrame {
// members
final ALU alu;
final NumberBox display;
final ADigitPad digitPad;
final AOpPad opPad;
// constructor
public Calculator() {
super("Calculator");
frame.setSize(300, 200);
this <-- new SetCloseOperation(SetCloseOperation.EXIT_ON_CLOSE);
// alu
alu = new ALU();
// create panel
APanel panel = new APanel();
contentPane <-- new AContainer.AddComponent(panel);
// number display
display = new NumberBox();
display.OnOperation <-- new Event.Subscribe(alu);
alu.OnResult <-- new Event.Subscribe(display);
panel <-- new AContainer.AddComponent(display);
// create digit pad
digitPad = new ADigitPad();
digitPad.OnClick <-- new Event.Subscribe(display);
panel <-- new AContainer.AddComponent(digitPad);
// create operation buttons
opPad = new AOpPad();
opPad.OnClick <-- new Event.Subscribe(this);
panel <-- new AContainer.AddComponent(opPad);
// register for key presses
OnKeyTyped <-- new Event.Subscribe(this);
digitPad.OnKeyTyped <-- new Event.Subscribe(this);
opPad.OnKeyTyped <-- new Event.Subscribe(this);
}
// receives an operation command
public react (char op) {
if (validOperator(op)) {
display <-- new Operation(op);
}
}
// key press
public react (KeyboardEvent e) {
// numeric digit
if (Character.isDigit(e.character) || e.character == '.') {
display <-- e.character;
}
// return
else if (e.character == '\r' || e.character == '\n')
this('=');
// operator
else this(e.character);
}
// operations
public class Operation {
public char operator; // operation to perform
public double operand; // value of number register when op is pressed
public Operation(char op) {
this.operator = op;
}
}
private static boolean validOperator(char c) {
switch (c) {
case '+': case '-':
case '*': case '/':
case '^': case '=':
return true;
default:
return false;
}
}
}