- A flexible dispatching framework


 

 

This web page collects information and files related to PolyD, a dispatching framework for Java developed in the context of the Ovm project at Purdue University.

PolyD is a pure Java tool that, using dynamic bytecode generation, allows the user to define customized dispatching policies, altering many aspects of message dispatching that are usually predermined and that cannot be easily changed.

In simpler words, using PolyD you can define a set of methods and invoke them according to user-defined criteria. For example, PolyD can be used to implement a visitor-like mechanism, or general multiple dispatching, or more unusual dispatching policies. PolyD makes it possible to personalize many aspects of the dispatching process: the handling of null arguments, of missing methods, of ambiguities, of the method invocation, and so on. In that respect, PolyD is a more general and flexible solution to the "expression problem" than other tools.

As an added advantage, PolyD is a pure Java tool that does not require special syntax, special bytecode, preprocessors, or custom VMs. The performance of the tool is well-suited to real-life applications: for unary methods PolyD has performance similar, or even better, than the Runabout and the Sprintabout, for other arities we find that PolyD scales better than MultiJava and JMMF.

Update: Dispatchers can now be even more general! Additional values can be used to perform the method selection, besides the dynamic class of the message arguments. Non-caching dispatchers are now also supported. Please read the updated manual for more information.

 


A simple example

Let's assume that we want to describe the effect of a Person dancing in a given Place. For this example we will use multiple dispatching, although a different policy could be used.

First of all, we need an interface:


   @ PolyD
   @ DispatchingPolicy (MultiDisp.class)
   interface Dance { void dance(Person p,Place q); }

Using PolyD we can decouple the interface from the actual implementation, and combine the two at a later stage. This is the implementation that we will be using in our example:


   class Impl {
    void dance(Dancer p, Stage q) {
     printComment("Dance is an expression of art!");
    }
    void dance(Person p, Stage q) {
     printComment("What is that guy doing on the stage?");
    }
    void dance(Person p, Place q) {
     printComment("That person is dancing. Strange.");
    }
   }

The code, quite simple, describes the most appropriate response to combinations of different kinds of Persons and Places. We can now test our dispatcher:

   Person nureyev = new Dancer();
   Person     joe = new Person();
   Place  bolshoi = new Stage();
   Place   office = new Place(); 
   
   Dance d = PolyD.build(Dance.class,new Impl());

   d.dance(joe,bolshoi);
   d.dance(nureyev,bolshoi);
   d.dance(nureyev,office);

In all three cases the arguments to dance() are statically a Person and a Place, but nothing more specific. The dispatcher uses the real dynamic class of the arguments to find the most appropriate method.

If we want to replace multiple dispatching with another dispatching policy, overloading for instance, we can create a new interface specifying @DispatchingPolicy (Overloading.class) instead. The two interfaces can also share a common superinterface, allowing the same client code to be tried using different dispatching policies, as shown in this example.

 


More features

PolyD allows dispatching on an arbitrary number of receivers, return values are supported as are primitive types. Multiple bodies can be specified with a single interface, offering a "mix-in"-like structure:

   Dance d = PolyD.build(Dance.class,body1,body2,body3);

All of the methods available in the various bodies will be combined to satisfy the prototypes declared in the interface. It is also possible to share one body among multiple dispatchers, and to call the same group of methods using different names.

The standard dispatching policies available are multiple dispatching, overloading, and a "non-subsumptive" policy that only calls a method if the classes of the arguments match exactly those of the method parameters. It is possible to define personalized dispatching policy using a simple API. The multiple dispatching policy also implements a form of symmetric multiple inheritance, treating equally interfaces and classes (MultiJava, for instance, only deals with subclasses).

It is possible to define custom invocation policies, that define which operations should be performed when a method is called. For instance, it is possible to log all method calls, or inspect the arguments on-the-fly for debugging purposes, or gather statistics. In this sense, PolyD offers some features typical of aspect-oriented programming.

It is possible to specify exactly what should happen if null arguments are encountered (an aspect that is not normally customizable in programming languages), restrict the interpretation of the dynamic class of arguments in order to implement a more general version of "super", define custom handlers for messages that cannot be satisfied by any methods according to the dispatching policy in use. Included is also a Runabout emulation layer, that allows existing programs that use that tool to take advantage of the new features without sacrifying compatibility.

There are even more features and ways to use PolyD; for a complete reference, the full manual is available below.

 


Download PolyD Here!

 

  • PolyD can be downloaded from the links below, in both binary and source form. Full API documentation and a reference manual are also available.
PolyD is distributed under the GNU Lesser General Public License. It can be used in free software and in proprietary programs under the terms of that license.
Java-5.0 version, binary as a JAR file. If you use a Java-5.0 VM, you need this file and ASM, below. polyd-20050403-0031.jar
To use PolyD you will need asm-1.5.3.jar Download it from this page.
Pre-5.0 version, binary as a JAR file. We tested it on Sun's 1.3.1 VM, and it also ran on 1.2.2 (with minor warnings). It only uses 1.1 bytecode. polyd-pre50-20050403-0031.jar
PolyD in source form polyd-src-20050403-0031.tgz

 

  • The Runabout Emulation Layer for PolyD offers a number of classes that can be used as a "drop-in" replacement for the Runabout.
The Runabout Emulation Layer for PolyD is distributed under the GNU General Public License. It can only be used in free software, according to the terms of that license.
Java-5.0 version, binary as a JAR file polyd-runemu-20050403-0031.jar
Pre-5.0 version, binary as a JAR file polyd-runemu-pre50-20050403-0031.jar
Source code polyd-runemu-src-20050403-0031.tgz

 

  • Documentation and test code.
The documentation available below is distributed under the terms of the GNU Free Documentation License, unless indicated otherwise.
API documentation, online polyd-javadoc-20050403-0031
API documentation, downloadable polyd-javadoc-20050403-0031.tgz
PolyD Reference Manual PolyD-Manual-20050403.pdf
Test files, containing test code for both the 5.0 and pre-5.0 versions. polyd-test-20050403-0031.tgz
Slides from an older presentation on PolyD browse here
A paper on PolyD is available Software: Practice & Experience, 38(1):33–73, January 2008

More information on the GNU licenses mentioned above is available on this page.

 


Links

PolyD is related, to varying degrees, to a number of tools and projects. The main inspiration was certainly the Runabout, written by Christian Grothoff, from which PolyD borrows the idea of using dynamic bytecode generation to speed up dispatching. Other related tools and pages are:

Visitor-related:

Multidispatching-related:

Other:

 


Contact

PolyD was written by Antonio Cunei
in collaboration with Jan Vitek
Department of Computer Science
Purdue University

Please report errors and comments to: polyd1@cunei.com.