DJ - Distributed Java

A project to add type-safe higher-order code mobility to Java

Motivation and Examples

Functional programming treats the function as its most fundamental unit of abstraction. In functional languages, functions are first-class citizens, which means they can be passed as arguments to other functions along with being normally evaluated to compute a value. On the other hand, the Java programming language belongs to the object-oriented paradigm, in which the fundamental unit of abstraction is the object, and values are computed by asking questions of objects by invoking their methods.

DJ mixes the functional and object-oriented paradigms by adding functions to the Java programming language as first-class citizens, letting us express programs in a succinct, functional style, without losing all the benefits of the object-oriented paradigm. Also, DJ is fully compatible with Java RMI, so using the power of functional abstraction we can drastically simplify the construction of type-safe mobile applications and middleware.

The functional abstractions of DJ allow a programmer to compose different small (or large) pieces of program functionality together in a type-safe way by expressing them in terms of frozen expressions. Consider the following canonical example that prints a message:

class Main {
    public static void main(String[] args) throws Exception {
      
       (-> void) hello = freeze() { System.out.println("Hello, world!); };

       defrost(hello);
    }
}

A more complicated example, using higher-order functions (functions that take functions as parameters) is shown below:

class Map {
    public static void main(String[] args) throws Exception {

        // Create the map function
        ((int -> int),int[] -> int[]) map = freeze((int -> int) f, int[] arr) {
            int[] ret = new int[3];
            for (int i = 0; i < arr.length; i++) 
                ret[i] = defrost(arr[i], f);
                return ret;
        };

        // Function to increment a value
        (int -> int) inc = freeze(int f) {
            return ++f;
        };

        // Input data
        int[] t = {1, 2, 3};

        // Apply the function
        int[] q = defrost(inc, t, map);
        for (int i=0; i < q.length; i++) 
            System.out.println(q[i]);

        // Yields "2,3,4"
    }
}

Features

DJ builds on the Polyglot Extensible Compiler Framework and is implemented by translating DJ source into code that can be compiled by the standard Java compiler. This allows DJ code to be executed by any standard Java Virtual Machine requiring no modifications, except the installation of a small run-time helper library. Key contributions include:

People

Publications

  1. Alexander Ahern and Nobuko Yoshida. Formal Analysis of a Distributed Object-Oriented Language and Runtime Technical Report 2005/01, Department of Computing, Imperial College London. Abstract PDF PostScript
  2. Alexander Ahern and Nobuko Yoshida Formalising Java RMI with Explicit Code Mobility Abstract PDF PostScript. To appear OOPSLA 2005.
    1. A longer version of this paper, with detailed proofs. PDF PostScript.
    2. A summary of the operational semantics and typing rules. PDF PostScript

      This contains all the reduction and typing rules for the language.

  3. Alexander Ahern and Nobuko Yoshida. Explicit Code Mobility in Java RMI poster. PDF
  4. Slides for our talk at OOPSLA 2005. PDF (some slides may look a bit funny due to PDF limitations) PPT

Download

Currently only available for Linux/cygwin. DJ is released under the terms of the Lesser GNU GPL.

Please visit our SourceForge files page to download DJ.

Requirements

Building

  1. Obtain and compile polyglot.jar.
  2. Download and unpack a source package of DJ, or get the latest version from SourceForge CVS (for the brave).
  3. Copy polyglot.jar, java_cup.jar, JFlex.jar and bcel-5.1.jar into the lib subdirectory of the DJ source distribution.
  4. In the base directory, type ant dj-jar to build a dj.jar file.

Compiling Programs with DJ

$ ./djc Hello.dj
$ java Hello