Twitter icon.
Random notes on software, programming and languages.
By Adrian Kuhn

Archive for March, 2009

MVC Reloaded, the Data-Context-Interaction Paradigm


Sunday, March 29th, 2009

Context is in the air. Today, I stumbled via @frankgerhardt upon an article by Trygve Reenskaug (father of the Model-View-Controller paradigm, for those not familiar with his work) and Jim Coplien about a new architecture paradigm:

“The DCI Architecture: A New Vision of Object-Oriented Programming”
by Trygve Reenskaug and Jim Coplien

The article focuses on how to model Use Cases. They advise against using classes, but rather propose to put behavior in algorithms that are expressed in terms of roles rather than classes. Their approach is broken up into data, context and interaction.

  • The data that is stored in domain objects that are rooted in domain classes;
  • The context that assigns running objects, on demand, to their roles in a scenario;
  • The interactions that describe end-user algorithms in terms of the roles.

Thus, data and interaction are brought together in a specific context. The article goes on to further talk about nested contexts, and how traits can be used to implement their paradigm. They say that “if a role is an analysis concept (from the mind of the end user), then a trait is a general design concept that represents the role.”

I am not yet sure how their use of context fits into my attempt towards a taxonomy of context. Clearly their context is compositional and dynamic. Even though they discuss whether roles are to be injected into classes at compile time or dynamically at run time, the actual instantiation of a context, ie which object are mapped to which roles, is always dynamically established. (At least as far as I understood their approach.) Given the assignment of roles to objects their context affect both sender and receiver of messages.

Even though the DCI paradigm can be used to model external context, there is (to my relieve) no magic mechanism in place that switches context behind the programmers back, as many other proposals for context-oriented programming do. I am happy see the notion of context being approached from a compositional view, clearly breaking down what context means in both terms of analysis and design, rather than referring to blurry terms such as the weather and room temperature. Or even worse, telling me that the very meaning of context still has to be defined :)

Some further, more personal, notes and remarks:

  • “Even Smalltalk, whose initial vision of objects and a dynamic run-time environment was truly visionary, fell victim to the class compromise,” provides me with a new incentive to look at prototype-based systems, such as Self, and to explore new compositional abstractions built from object fragments and aliases, as I have started doing with Cells and Protalk. For example, how would a system look like whose main abstraction are traits rather than classes?
  • “There is another key learning: that domain classes should be dumb. [...] We must separate simple, stable data models from dynamic behavioral models,” reminds me of one of my initial visions for Fame (a now abandoned project) that was to turn Fame models into a typed subspace within a Squeak image. The idea there was to have this type model in your Smalltalk image, and then check the type annotations given in the source code not at compile time but rather generate runtime assertions. Which is, by the way, what I as a 2nd semester student thought that Java’s type system would do. I recall how shocked I was to learn that type checks are performed at compile time only!
  • And finally, I wonder how the composition of a system into dumb classes and smart interaction contextes is going to match the grouping of the system’s vocabulary (ie identifier names, etc) by topics. We know that classes and topics do not align well, will DCI do a better job? As long as current structural abstractions fail to capture the user’s mental model of a system, which is what Trygve Reenskaug and Jim Coplin’s article argues, any visualization based on structure alone must fail to address the developer’s model as well. And this reinforces my conviction that the vocabulary- and thus domain-based layout of Software Cartography is the way to go in software visualization.

Check printf at compile-time


Monday, March 16th, 2009

Since the introduction of #printf in Java 1.5, I always wished to check my format strings and their arguments at compile-time.

Now, it can be done.

The following compiler-plugin checks format string and format arguments of any call to #printf and #format. Of course, checking is limited to format-strings known at compile time.

Just put printf.jar in your classpath (works with javac only!)

javac -classpath printf.jar Example.java

Since there are numerous #printf and #format methods in the Java API, any method with one of said names and with parameters of type String and Object[] is checked. (A cleaner solution would use a @Printf annotation to mark these methods. Alas, I cannot touch the Java API just like that.)

The above plugin works with javac only. Why? Annotation processing is done before type attribution and thus type information is not available to a JSR 269 plugin. However, checking the type of format arguments cannot be done without type information. Thus, what I do is to manually invoke the compiler’s type attribution phase. This is done using the internal Attr component as follows.

import com.sun.tools.javac.comp.Attr;

@SupportedAnnotationTypes("*")
public class Printf extends AbstractProcessor {

    private Attr attr;

    public synchronized void init(ProcessingEnvironment processingEnv) {
        attr = Attr.instance(((JavacProcessingEnvironment) processingEnv).getContext());
        ...
    }

    public boolean process(Set annotations, RoundEnvironment roundEnv) {
        for (Element each: roundEnv.getRootElements()) {
            if (each.getKind() == ElementKind.CLASS) {
                attr.attribClass(null, (ClassSymbol) each);
                ...
           }
        }
    }

    ...

PS, type information is discarded after each annotation processor round. It is thus safe to apply type manipulating changes to the AST from within an annotation processor, since after the plugins have been run, type information is re-attributed again from scratch.

For the full sources, please refer to /Sources/b/Printf on the SCG repository.

Have fun!

What is Context Anyway?


Wednesday, March 11th, 2009

I just had a heated debate with Toon Verwaest about applications of context aware programming languages. Given his background with AmbientTalk his views are rather different than mine. To him, context includes availability and proximity of mobile devices, whereas I am more focused on programming-language specific context. In this post, I’d like to order the views and thoughts that we had been discussing. In particular I’ll try to identify different kinds of context with regard to message dispatch. 

  • The first distinction is between context of the sender and context of the receiver. In the first case, the behavior of an object depends on our view on it. In the second case, the behavior depends on the object itself. A special case of receiver (or is it sender?) context is multiple dispatch, that is context depending on the arguments of the sent message. 
  • The next distinction is between programming-specific context and external context. External context depends neither on the sender nor on any other construct of the programming language. Examples of external context are the weather, the current room temperature, or the availability of external resources such as the wireless telephone network or a the printer next doors. External context often is either categorical or numerical, that is, it is either modeled by an enumeration of states or by some numerical value.
  • I am unsure where spatial context deserves a distinction of its own. For example, for robots on a football field proximity to the other players and the goals is context as well (taken from Collaborative Confusion, via HOP). Clearly, external context is a generalization of spatial context but there may be good reasons to treat spatiality as a context of its own. Geometry and metric distance set spatial context apart from other external contexts. Actually, positions in any metric space can be used to define spatial proximity.
  • Programming-specific context is obviously further subdivided into lexical and dynamic context. Lexical context is typically given by the location in the source code. More general, it is given by location within an program’s structure. Dynamic context on the other hand is given by the flow of execution. Technically, dynamic context often boils down to the context given by the call stack.
  • However, lexical and dynamic context are not the only programming-specific context. Considering Adrian Lienhard’s theory of aliases we can dispatch messages based on the object flow. For example, the reference returned by a collection’s #get method could understand the context-aware method #next which yields the next object within the aforementioned collection. This approach may take us beyond a mere sender-receiver distinction to behavior that depends on the origin of a reference.
  • Other programming-specific contexts are composition and state. For example, messages sent to a collection could be dispatched to different methods depending on the type of the collection’s elements, which is what we do in Swarm Behavior. In the same way, we can imagine behavior that depends on the state of the sender. Given the popularity of both the State and the Strategy pattern, it seems useful to bring this kind of context closer to the language.

Enought brain dump, I am now off to read the Context-oriented Programming paper by Robert Hirschfeld, Pascal Costanza, and Oscar Nierstrasz. And as you can imagine, discussion with Toon is already continuing by chat…

Create Annotation Instance with Defaults


Thursday, March 5th, 2009

Working often with annotations, sometimes I feel the need to create an annotation instance that is filled with default values. Annotations are interfaces, thus we cannot create instances. Using dynamic proxies, however, it can be done as simple as follows

Ann ann = Defaults.of(Ann.class)

Just copy paste the following class into your project to make this work

class Defaults implements InvocationHandler {
    public static <A extends Annotation> A of(Class<A> annotation) {
        return (A) Proxy.newProxyInstance(annotation.getClassLoader(), new Class[] {annotation}, new Defaults());
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.getDefaultValue();
    }
}

This creates a dynamic proxy that implements a given annotation and returns the default value for each invoked method.

A more complete implementation should further distinguish between methods that represent actual annotation values and methods inherited from Annotation and Object. The latter require a more complete implementation. But how do they say? left to the read as an exercise, smile.

Have fun!

For.example is Digg proof thanks to caching by WP Super Cache!