ChiMu  
 
Menu Edge About   Products   Services   Projects   Publications  
  Publications                 

Dynamic capabilities in Java

Overview

This is a discussion of adding dynamic capabilities to Java (specifically when coming from Smalltalk)

The following is a reference to the main thread-point that this short paper is on:

Original Posting: Fourth normal form and normalization

gafni@vnet.ibm.com wrote:
> We have a prototype written in Smalltalk that heavily relies on using
> Smalltalk dynamic features such as:
> 1. Dynamically creating new classes
> 2. Dynamically adding instance variables to an existing class
> 3. Dynamically adding methods to an existing class
>
> We are considering writing the production solution in Java. Is it
> possible to implement workarounds so these features will work in Java?
> Any Ideas? How much work would it be?

It is certainly possible to make a Java program as dynamic as a Smalltalk program, but you will need to do it through new instances of existing (generalized) types as opposed to relying on the extensible meta-class capabilities of Smalltalk.

For example, your items (2) and (3) are ways to maintain new kinds of state and perform new kinds of behavior for existing objects. Both of these can be done with encapsulated "Dictionaries of Objects", where the objects are just state value holders for (2) and the objects are Functors (blocks, closures, simple classes) for (3). This moves you a step above core language capabilities, but the ultimate functionality is the same:

   anObject x.
becomes
   (anObject getVariable: #x) value.
and
   anObject perform: #foo.
becomes
   (anObject getFunctor: #foo) execute.

The important aspect for migration to Java is that the interfaces for the above are known at compile time. For the first we just need a ValueHolder type interface:

   interface ValueHolder {
       Object getValue();
       void setValue(Object newValue);
   }

For the second we need a few variations of Functor types of interface:

   interface Procedure0Arg extends Functor {
       void run();
   }

   interface Function1Arg extends Functor {
       Object getValueWith(Object arg);
   }

etc.

And to pull it all together we would have something like:

   interface DynamicObject {
       ValueHolder   getVariableNamed(String name);
       Functor       getFunctorNamed(String name);
       //or return a type-specific Functor
       Procedure0Arg getProcedure0ArgNamed(String name);
   }

With this relatively limited set of interfaces, we can define all the external behavior we require and then we just need suitably generic implementations. We could also create somewhat optimized implementations by generating new Classes that support the generic protocol.

Although the above shows a very generalized approach, you should only make the areas you require general (in the ways necessary at that point). If all aspects of your whole program are very dynamic than it would make more sense to keep with languages like Smalltalk, Python, Lisp, etc. that inherently support those capabilities.

Do not consider Java's Reflection capabilities as worth anything in this process except for (possibly) implementation prototyping support or areas that have almost no performance restrictions.

Conversion process

Although it may be peculiar to do in Smalltalk, you could test out the above capabilities with your existing Smalltalk prototype to get a feel of the changes required. Make the rule simply: do not create new classes or add methods/instance-variables to existing classes. Instead, create new instances of these kinds of generalized classes (ValueHolders, Functors, DynamicObjects). You will need more syntactic glue but the functionality will be the same. After this conversion, the movement to Java will be relatively painless.

--Mark
mark.fussell@chimu.com

PS: You can see some of the publications at 'www.chimu.com' for more information on this type of approach for GUI, Domain, and other areas.

 
Publications