Tutorial

English

Français

Atomic Operations in SugarCubes

Goals:


Nothing

An atomic operation in SugarCubes is an instruction whose the whole execution is not interruptible. The simplest operation of that king is the nothing instruction which does... nothing.

Source: Nothing.java
import inria.meije.rc.sugarcubes.Machine;
import inria.meije.rc.sugarcubes.Program;
import inria.meije.rc.sugarcubes.SC;

public class Nothing
{
    public static void main(final String[] args){
        final Machine machine = SC.machine();
// What a powerfull program !
        final Program print = SC.nothing();
        machine.addProgram(print);
        for(int i = 1; i <= 10; i++){
            System.out.println("instant "+i+": ");
            machine.react();
        }
    }
}

The nothing instruction is not a very useful instruction by itself but it can be used to build reactive instructions in which some sub-programs are not needed. For example let's one want to build a If instruction where one doesn't want an else branch. One can use the nothing instruction for the else branch. This instruction is in fact the ultimate form of every finite instructions after some instant of reaction. Any reactive instruction which executes in a finite number of instants, lasts as being equivalent to the nothing instruction. Re-writting of such code (one shows more about that in code migration examples) gives the nothing instruction.

How to compile?

javac -classpath SugarCubesv4.0.0a4.jar Nothing.java

How to execute?

java -classpath SugarCubesv4.0.0a4.jar:. Nothing

You should get the following result:

instant 1: 
instant 2: 
instant 3: 
instant 4: 
instant 5: 
instant 6: 
instant 7: 
instant 8: 
instant 9: 
instant 10: 

As you see there's not much to say here ;-).


Nothing with the Junior API

One considers now the same example but using the Junior API.

Source: Junior_Nothing.java
import junior.Machine;
import junior.Jr;
import junior.Program;

public class Junior_Nothing
{
    public static void main(final String[] args){
// As we see in the HelloWorld example, a reactive machine in Junior needs
// an initial program when created. So on just use the nothing instruction
// here.
        final Machine machine = Jr.Machine(Jr.Nothing());
        for(int i = 1; i <= 10; i++){
            System.out.println("instant "+i+": ");
            machine.react();
        }
    }
}

How to compile?

javac -classpath SugarCubesv4.0.0a4.jar Junior_Nothing.java

How to execute?

java -classpath SugarCubesv4.0.0a4.jar:. Junior_Nothing

There is a lot of SugarCubes instructions that are in fact atomic operations (generate, print, behavior, addToShell, ...), one talks in more details about those instructions later.


Atomic Actions in Java

Atomic actions are the mechanism through which tasks described in Java are controlled by reactive programs.
Atomic actions are implemented by the programmer, implementing the interface JavaAction. Then, those actions are handled in a reactive program using the reactive instruction action. Atomic actions, as their name lets think, are not interruptible in SugarCubes, so it is the responsibility of the programmer to ensure that they terminate in a finite time (the shortest as possible). So, in general atomic actions must be very simple tasks in Java, without infinite loops (a good solution is often to avoid loops at all), that performs their actions very quickly. While scheduling and control (means sequences, loops, ...) is handled by the reactive program itself.

Source: AtomicActions.java
import inria.meije.rc.sugarcubes.Machine;
import inria.meije.rc.sugarcubes.SC;
import inria.meije.rc.sugarcubes.Program;
import inria.meije.rc.sugarcubes.JavaAction;
import inria.meije.rc.sugarcubes.LocalVariables;
import inria.meije.rc.sugarcubes.ReactiveEngine;

public class AtomicActions
{
    public static void main(final String[] args){
        // First one writes a reactive program.
        final Program print = SC.action(new AtomExample());
        
        // Then one makes a reactive execution machine.
        final Machine machine = SC.machine();
        
        // One adds the program into the machine.
        machine.addProgram(print);
        
        // One makes the machine reacts for ten consecutive instants.
        for(int i = 1; i <= 10; i++){
            System.out.println("instant "+i+": ");
            machine.react();
        }
    }
}

// The atomic action itself is implementes by the SugarCubes user by
// implementing the JavaAction
class AtomExample implements JavaAction
{
// The only method to implement here is execute method which contains the code
// to execute in Java. In our example one simply display a message on the
// standard output.
    public void execute(final Object self
                        , final LocalVariables vars
                        , final ReactiveEngine engine){
        System.out.println("This is an example of atomic action.");
    }
}

One has to implement its atomic java action in a class that implements the JavaAction interface.

class AtomExample implements JavaAction

One puts the java code which describes the atomic action in the method execute. The meaning of the self, vars and engine parameter will be discussed later. They provide information on the context of execution for the atomic action.
To handle atomic actions in a reactive program one uses the action instruction, which execute the java code in an atomic way (not interruptible).

final Program print = SC.action(new AtomExample());

The action instruction gets a JavaAction object as parameter. And invoke the execute method when it gets the control. SugarCubes doesn't do any verification on what the action really does. So it is the responsibility of the programmer to make the atomic action cooperative enough to terminate quickly (in a finite time). To get a good reactive system (that doesn't block for a while at a point of its execution, preventing the whole system to progress), the programmer must ensure that its atomic actions are "reactive" enough (fast enough to ensure a good response time).
A bad atomic action could be a simple code like that:

class BadAtom implements JavaAction
{
    public void execute(final Object self
                        , final LocalVariables vars
                        , final ReactiveEngine engine){
        for(;;);
    }
}

SugarCubes reactive machine assumes that atomic actions terminates in a finite amount of time and so to preserve the right semantics of execution no control (for example using an heuristics based on a maximum duration of the execution of an atomic action) is done. So, in this case, when the execute method of the BadAtom object get invoked, the control never returns to the reactive execution machine, and so the overall system is live-locked.

The simplest atomic instruction that exist in SugarCubes is the instruction nothing which does ... nothing and so terminates immediately.

final Program p = SC.nothing();

The print instruction, used in the HelloWorld example, is a shortcut for an atomic action which displays a message on the standard output. A similar instruction exists also to print a message on the standard error output.

Program p = SC.printError("Error: This is an error message\n");

There are also variants that automatically add a new Line at the end of the message : println, printlnError

How to compile?

javac -classpath SugarCubesv4.0.0a4.jar AtomicActions.java

How to execute?

java -classpath SugarCubesv4.0.0a4.jar:. AtomicActions

You should get the following result:

instant 1: 
This is an example of atomic action.
instant 2: 
instant 3: 
instant 4: 
instant 5: 
instant 6: 
instant 7: 
instant 8: 
instant 9: 
instant 10: 

Atomic actions with the Junior API

One considers now the same example but using the Junior API.

Source: Junior_AtomicActions.java
import junior.Machine;
import junior.Jr;
import junior.Program;
import junior.Action;
import junior.Environment;

public class Junior_AtomicActions
{
    public static void main(final String[] args){
        // First one writes a reactive program.
        final Program print = Jr.Atom(new Junior_AtomExample());
        
        // Then one makes a reactive execution machine.
        final Machine machine = Jr.Machine(print);
        
        // One makes the machine reacts for ten consecutive instants.
        for(int i = 1; i <= 10; i++){
            System.out.println("instant "+i+": ");
            machine.react();
        }
    }
}

// The interface to implement in Junior is the Action interface
class Junior_AtomExample implements Action
{
// The execute method in Junior has only one parameter
    public void execute(final Environment env){
        System.out.println("This is an example of atomic action using the Junior API.");
    }
}

How to compile?

javac -classpath SugarCubesv4.0.0a4.jar Junior_AtomicActions.java

How to execute?

java -classpath SugarCubesv4.0.0a4.jar:. Junior_AtomicActions

You should get the following result:

instant 1: 
This is an example of atomic action using the Junior API.
instant 2: 
instant 3: 
instant 4: 
instant 5: 
instant 6: 
instant 7: 
instant 8: 
instant 9: 
instant 10: 

Atomic Expressions

An atomic expressions in SugarCubes is very close to an atomic action in the sense that it is a piece of java code whose execution is not interruptible. The main difference is that an atomic expression returns a value which is used as a parameter for the execution of reactive instruction which use that atomic expression. This example shows how to implement a reactive expression to parameter the execution of a print instruction. The message to dump on the standard error output is computed at runtime.

Source: PrintExp.java
import inria.meije.rc.sugarcubes.Machine;
import inria.meije.rc.sugarcubes.Program;
import inria.meije.rc.sugarcubes.SC;
// Import the interface the programmer must implement to use runtime computed
// message in print Expressions
import inria.meije.rc.sugarcubes.JavaStringExpression;
import inria.meije.rc.sugarcubes.LocalVariables;
import inria.meije.rc.sugarcubes.ReactiveEngine;

public class PrintExp
{
    public static void main(final String[] args){
        final Machine machine = SC.emptyMachine();
        // dump the runtime computed message on the standard error stream
        final Program print = SC.printlnError(new MyJavaStringExpression());
        machine.addProgram(print);
        int i = 1;
        do{
            System.out.println("instant "+(i++)+": ");
        }while(!machine.react());
    }
}

// The String Expression on implements here procduces a string computed at runtime
// using the real time date at the very instant of expression activation
class MyJavaStringExpression implements JavaStringExpression
{
    public String evaluate(final Object self
                           , final LocalVariables vars
                           , final ReactiveEngine engine){
        return "Hello World! at "+(new java.util.Date()).toString();
    }
}

// Result may be different according to real date of execution

The react method of a reactive machine returns a boolean value which is false while the program is not terminated and true when the program terminates. To be able to use this capability, one must create an empty execution machine using the emptyMachine variant in the SC class. The diference between machine and emptyMachine is that the first one variants are constructing machines that put an initial program made of a halt instruction (one talks of the halt instruction in more details later). This initial program will remain forever in the reactive machine executing in parallel to any other program added. That prevents reactive machines to terminate when all added programs have terminated their execution. In this example one uses the boolean value returned by the react method to know when to stop cyclic calls to the react method. When a reactive machine has terminated (which means that all its programs are terminated) the reactive machine becomes useless and cannot be used anymore even adding new programs.

How to compile?

javac -classpath SugarCubesv4.0.0a4.jar PrintExp.java

How to execute?

java -classpath SugarCubesv4.0.0a4.jar:. PrintExp

You should get the following result:

instant 1: 
Hello World! at Tue Jun 13 14:09:28 CEST 2006

Note about the Junior API: In Junior, expressions are built using a wrapper interface (BooleanWrapper, IdentifierWrapper, ...). print instructions based on StringWrapper as in SugarCubes doesn't exist.