Saturday 21 September 2013

Type-safe bindings (reflection) for Arena

Arena

Arena is UI framework strongly based on a pure MVC pattern through bindings and the ApplicationModel idea.

The UI elements are connected to the model through bindings, which are in charge of propagating changes between the two parties. If the model changes, then it will update the ui (view), and of course if the view changes because of user interaction (like changing a textbox value) then it will also change the model.
This simple idea reduces a lot of UI code, and introduces a new way for developing UI's.
Plus the fact that Arena makes your model object observables, transparently by means of AOP.

Sample Distance Converter Application


Here's a sample really small app whose functionality is to convert miles to kilometers.


Here's the model (in xtend language):

@Observable
class DistanceConverter {
    @Property Double miles
    @Property Double kilometers
   
    def convert() {
        kilometers = miles * 1.60934
    }
}


And here's the View, in terms of control objects.

class DistanceConverterWindow extends MainWindow<DistanceConverter> {
   
   
new() { super(new DistanceConverter) }

   
override createContents(Panel mainPanel) {
        title = "Miles To Kilometer Converter"

        mainPanel.layout = new VerticalLayout       
       
new Label(mainPanel).text = "Input in miles"
       
new TextBox(mainPanel)

       
new Button(mainPanel) => [
            caption = "Convert"
        ]

       
new Label(mainPanel) => [
             background = Color.ORANGE
        ]
       
new Label(mainPanel).text = " km"
    }
   

}


As you are probably thinking or maybe wondering, this is not the actually functional View implementation.
It is not actually connected to the model. If we start this app it will indeed show pretty much as the one on the screenshot but clicking on the button won't do anything. Changing the textbox neither. And we'll never actually see any converted kilometers.

That's because we are missing the Bindings. The stuff that glues together view + model.

Bindings


As you can see the UI is a direct view of the domain. Whenever the user changes the value of the textbox it will modify the "miles" property. When he presses the button it will call the "convert" method which doesn't receive any parameter (the converter already knows the input miles), and also doesn't return anything (because the converter also "remembers" the converted km value, it's one of its responsabilities).

All this wiring between the UI and the model is done through bindings.
Here's a sample  drawing:


Now lets change the UI code in order to express this bindings.

The textbox value will be sync'd with the "millas" property from the model

new TextBox(mainPanel) => [
            bindValueToProperty("miles")
        ]


The background colored label is also bound to the "kilometers" property. This time as the label is a "read-only" ui control it won't ever change the value from the model, it will just display it.

        new Label(mainPanel) => [
            background = Color.ORANGE
            bindValueToProperty("kilometers")
        ]


And at last the button's on click should execute the model's "convert" method.

        new Button(mainPanel) => [
            caption = "Convert"
            onClick [ |
this.modelObject.convert ]
        ]


Here we sue the power of xtend blocks/closures :)

Bindings, Reflection & Strings

Probably you are familiar with this kind of code. Frameworks are generic pieces of software, that provide some sort of functionality or lifecycle. But they don't do anything along. You "use" them. Or actually they "use" your code/objects. But anyway, eventually you need to instruct them in order to use your objects.
Because they know how to handle any object, but none in particular.

So they use metaprogramming techniques, and specifically Reflection API's in order to manipulate your objects.
Some examples of this are hibernate where you instruct it by means of mappings, for example in xml, or in the form of annotations. Or spring framework's xml, etc.

In our example Arena uses reflection for the bindings, in particular for reading and modifying the model's properties.

One of the big drawbacks of reflection in java is that there's no way to refer to a property in a safe way. The only way is to use a string, whose value is the "name" of property or method.

bindValueToProperty("miles")

So, what's the problem with it ?
Well, that you are in a statically compile-time checked language, but the compiler won't be able to help you on this one.
For it the "miles" is just that, a string. So it won't check if it's actually a valid property name, or if it exists a getMiles() method in the model class.

If you are building a middle/big sized application, and all the windows, panels and controls binds themselves in this way then you'll face a maintenance complexity.
For example:
  • if you change the name of the model's property in a refactor, then the IDE won't be able to help you changing this strings. And this will blow-up in runtime.
  • if you want to lookup references to a given method or property, then again the IDE won't help you. Then you might think that a property is not used by anyone, and go ahead and delete it. Again.. booom! only at runtime. Lucky you if you catch it before your user =)
So well, this is pretty bad ! But indeed we don't want to lose reflection. It's a very powerful mechanism !

Avoiding String problems when using reflection using constants

There are some tricks to tackle this problem list having the string declared as a constant string in only one place.
For example:

class DistanceConverter {
   
public static String MILES = "miles"
   
public static String KILOMETERS = "kilometers"
   
public static String CONVERT = "convert"
    ...

And now from the UI:

        new TextBox(mainPanel) => [
            bindValueToProperty(DistanceConverter.MILES)
        ]


So now we can look up references to the constant for usages. Also if we change the name of the property we'll only have to change the string value in on place, the constant.

But this still not perfect.
There's a better way :)
But first we need to see some other idea.

What's the mocking frameworks approach

Mocking frameworks face some similar problem. By nature they need to work with our own defined classes, but they cannot be coupled to them, of course. They don't know anything about our DistanceConverter for example.
But also they don't know what to expect and assert, so you need to instruct them.

But instead of using reflection with strings or a complicated API for expressing the expected behavior they use a quite interesting idea.
For example Mockito...

What's interesting here is the line:

when(mockedList.get(0)).thenReturn("first");

We are not actually interested in executing the "mockedList.get(0)". Instead we are "instructing" mockito telling him "when some calls the "get" method with a "0" as parameter, then you need to return the "first" string).

A normal string based reflection approach would be:

whenSomeoneCalls("get").on(mockedList).with(0).thenReturn("first")

(and this is still actually a good fluent API, could be really worst).

So, in conclusion, they found a way of actually using the type information and therefore the compiler in a statical way, to instruct a framework.

So the whole idea of this post was to get here. Can we do that same thing for Arena bindings ?

Type-Safe Arena Bindings

Yes we can !
This is just a really draft proof of concept that was done just in 30 minutes, so there's still a lot of work to be done, and many things to think about.
Let's get directly to the code:

        new TextBox(mainPanel) => [
            bindValue(
this, [ miles ])
        ]


        ...

        new Label(mainPanel) => [
            background = Color.ORANGE
            bindValue(
this, [kilometers])
        ]


Compare to the previous version. This one doesn't have any string for "miles" and "kilometers".

The new "bindValue" method receives an xtend block whose first and only parameter is the window's model object (that gets bound by means of generic types).

So [ miles ] here can be read as

[ it.miles]

Or

[ converter | converter.miles ]

Or even in the longest way

[ DistanceConverter converter | converter.miles ]

So in case you didn't notice this is code. We have a line of code that calls the "miles" property, and therefore it gets checked by the compiler.

But it's actually a trick. Pretty similar to the one that Mockito uses.
This code is not actually executed to get the property. We are not writting "[ miles ]" to execute it right away, but just to "instruct" arena "miles is the property I want you to bind to".

And it works flawlessly ! :)

In case you are interested in the implementation, what the "bindValue" does is:
  • receives your block
  • it gets the actual model (the converter) and with its class, it creates a new proxy instance. Kind of a "ghost" object of the same class.
  • it then calls your block with that proxy.
  • Your code sends the message "miles" (actually getMiles()).
  • The proxy "records" all the methods you called into it.
  • So, after the block finishes up, the next thing the bindValue does is to ask the proxy "hey, what property the guy accessed  ?".
  • In this case the proxy will tell "the miles property",
  • "Ah.. ok, then we need to bind to that one.
It's not as black magic as one thinks initially looking at Mockito. And it's all there. Just enter the "when" method and explore some code !

Further work

We still need to work on this, because we will like to add this feature to Arena's new version.
There are still many things to think about, like what if the developer writes some side-effect weird or long lines of code in the block ?.
How to support nested properties ? Like [ customer.address.street.number ]
Etc.
We should also remove the first parameter "this" on the bindValue method, but that's not easy because we will lose the typing of the closure (now bound to the window's generic type, the model class).

More about Arena

If you are interested in Arena framework here are a couple of links:

Thursday 5 September 2013

Extending classes with polymorphic extension methods in XTend



This is a purely just "playing-around" post.

In Uqbar Project we are now using several new languages both as part of teaching programming in a couple of universities, but also as one of our main/many languages of development for research projects.

But I'm not going to bore you with that right now. Probably this will be the start of a series of post related to this language (an why not some other regarding scala and groovy) and rethinking our programming practices and design decisions with its particular mechanisms.
At the end maybe some kind of summary post.

Anyway back to the original point then I wanted to try out extension methods.
But not just adding methods to a class. That's easy. Beyond just methods, OOP most important feature is polymorphism. So, how extension methods relates to polymorphism ??

Then, wait, maybe you are wondering what's this extension method thing ?

Extension Methods Explained


For those who are not familiar with the term extension methods is a language-level support for defining new behavior (methods) for existing classes, without actually touching the original classes.
And of course, then use those as regular methods.

Usually this  takes the form of a method whose first parameter is the target object. Belonging to the class we are extending.

For example you could add a "toCamelCase" method to the String class with something like this:

    def String toCamelCase(String aString) {
        // ....
    }

And then call it on any string:

    println("Hi there".toCamelCase())



There are several different implementations of this concepts in many languages.
But they are not always exactly the same and don't give you the same posibilites (power)
For example C# "Extension Methods" can only be defined as static methods.

 Adding polymorphic Extension Methods


So enough of introduction. Maybe we will create a separated post to compare the different extension method mechanisms in several languages.
And we could create another post just to talk about xtend's extension methods.

Adding a method to a class is great as you have seen to add some kind of "atomic" functionality. Like all utility classes that we use like CollectionUtils, ReflectionUtils, ListUtils, etc.

Now, can we use it to add polymorphic behavior ??

The short answer is ... YES !


Long answer: extension methods + multimethods


This can be achieved by combining extension methods with multiple dispatch, another nice feature of xtend.

Remember that the target object is the first parameter of the extension method.
Also remember that multiple dispatch is the ability to select the method implementation based on the actual type of the arguments.

So they complement each other quite well.

We can create an extension method, which is actually a set of different methods one for each target type (first argument).
Then call it as if it was a regular method with different implementations on each class. Like a regular polymorphism with classes overriding.

And here's a piece of code that demonstratse it.

Suppose we have some kind of CandyCrush object model.
There are Candy's and different classes for Movements (Move): to go North (move up a candy), go South, East, and West.

class Move {
    //...Some behavior here
}
class North extends Move { /* ... */ }class South extends Move { /* ... */ }class East extends Move { /* ... */ }class West extends Move { /* ... */ }


A candy has a coordinate  and knows how to move itself a delta (x-delta, and y-delta)

class Candy {
    @Property Pair<Integer, Integer> coordinates;

   
def move(int deltaX, int deltaY) {
        coordinates = 

coordinates.key + deltaX -> coordinates.value + deltaY
    }
}


Suppose the "Move" class don't actually have a method to move a candy (ok, sounds silly, but just for the sake of the example).

We will like to add a new method ----> Ahá !, Extension methods !!
But wait, each Move subclass will have a different implementation ! We need polymorphism !!! -----> Ahá!, Multiple dispatch !

So  we will like to do this:

    def static void main(String[] args) {
        val candy = new Candy => [ coordinates = (0 -> 0) ]
       
new Use().moveIt(candy)
    }
   
    def moveIt(Candy candy) {
        #[
new North, new East, new South, new West]
            .forEach[
                m| m.moveCandy(candy)
                println(candy.coordinates)
            ]
    }



The "moveCandy" is the actual polymorphic method that we want to add.

And it's defined in an extension class:

class CandyExtensions {
   
    def dispatch void moveCandy(North north, Candy candy) {

        candy.move(0, 1) 
    }
    def dispatch void moveCandy(South north, Candy candy) {

        candy.move(0, -1)
    }
    def dispatch void moveCandy(West north, Candy candy) {

        candy.move(-1, 0)
    }
    def dispatch void moveCandy(East east, Candy candy) {

        candy.move(1, 0)
    }
}


Eclipse's tooltip helps to see this:


Regular solution without extension methods

So even if we coded several methods (4), conceptually we have just added one method and several implementations for concrete types.

Without extensions it would be something like this:


class Move {
    def void moveCandy(Candy candy)
}class North extends Move {
    override void moveCandy(Candy candy) {
        candy.move(0, 1) 
    }

}class South extends Move {
    override void moveCandy(Candy candy) {
        candy.move(0, -1) 
    }

}class East extends Move { 
    override void moveCandy(Candy candy) {
        candy.move(1, 0) 
    }

}class West extends Move { 
    override void moveCandy(Candy candy) {
        candy.move(-1, 0) 
    }

}

Not it's actually 5 methods, 4 impl + the abstract declaration in Move

Limitations

That sounded great !! I can add polymorphic method to existing classes.
But can I do it to any class ?
Can I, from the outside, make two different classes polymorphic in respect to a new method ?
Yes, you can, but it will have some drawbacks.

In our example we added a polymorphic behavior to classes which already where polymorphic as part of being in the same hierarchy.

But what if they weren't ? What if they were just completely different classes with no hierarchy ?

Let's remove the Move class:

class North { /* ... */ }class South { /* ... */ }class East { /* ... */ }class West { /* ... */ }


Well there's still a multiple-dispatch method. That's fine.



It's just that it applies to any Object.
Mmm... that's not good, but, well.. at least it's there  and it still can be used in our main !


But what then if we call it with something else:

    def moveIt(Candy candy) {
        #[
new North, new East, new South, new West, new Banana]
            .forEach[
                m| m.moveCandy(candy)
                println(candy.coordinates)
            ]
    }


Of course.. boom !

Exception in thread "main" java.lang.IllegalArgumentException: Unhandled parameter types: [org.uqbar.xtend.playground.extensionpolymorphism.Banana@51d92803, org.uqbar.xtend.playground.extensionpolymorphism.Candy@7d206f0]
    at org.uqbar.xtend.playground.extensionpolymorphism.Extensions.moveCandy(Extensions.java:44)
    at org.uqbar.xtend.playground.extensionpolymorphism.Use$3.apply(Use.java:54)
    at org.eclipse.xtext.xbase.lib.IterableExtensions.forEach(IterableExtensions.java:399)
    at org.uqbar.xtend.playground.extensionpolymorphism.Use.moveIt(Use.java:59)
    at org.uqbar.xtend.playground.extensionpolymorphism.Use.main(Use.java:43)


So, in conclusion, you could add polymorphic methods to unrelated classes, but as you won't have any common type to bound it with, it will kind of confusing to use, and you'll need to be careful when using it. Kind of what happens with languages with run-time message checking (instead of compile-time)


Further Questions and Relation to other Concerns

AOP

An advantage of the polymorphic extension methods approach is that of course, it allows to add that behavior from outside of the class. Sometimes you cannot change the original classes.
But also another one (that could also be seen as a disadvantage) is that it groups together all the "move" behavior into a single place. Kind of a concern applied in AOP.

Visitor



This effect is also similar and sometimes part of the intention also present in the Visitor Pattern. Where the visited class only knows how to transverse each other in a general algorithm, then each visitor implements the actual logic for each visited class in a custom method. In order for this to work you need to simulate multimethods with double-dispatch.

So what happens with the visitor pattern now that we have multimethods, but also we can combine them with extension methods to actually "inject" the polymorphic behavior ?
Does it still make any sense ?

Structural Types and Duck-Typing


Last, we have saw that you can use this mechanism even for unrelated classes, but then you end up using Object, because you can add methods from outside, but you cannot change the type hierarchy or force classes to start implementing interfaces (like for example in AOP with weaving).
Related to this, there languages like Scala which implement a duck-typing in a strongly typed environment (checks on compile-time). These are a form of StructuralTypes.
Through extensions we have actually defined some kind of new "structural type". A new type which represents objects which can "move a candy".

Why should we type any other method that receives such an object via parameter with "object" ?
Would it make sense (or be possible) to introduce new types, using the extension type itself as a nominal type on top of the structural type defined by the  extension methods ?

Would it be possible to combine ext.methods + multiple-dispath + duck typing ?

If you check our Extension class after we've removed the hierarchy you'll see that there's enough information for a clever compiler to  see our modified main and know that it will fail !
It just needs to inspect all the dispatch methods to know which types are valid and which one are NOT !
Banana isn't a valid type.

This opens up a new world to explore !! :)


Different Extensions implementations


Extensions don't need to be static methods (as in C#) therefore they are implemented in instances of a class. Therefore, into an object.
But then you just call with the first arg as target.
Eventually there's an automatic delegation or dispatch to the method into the extension object instance that you have (from the piece of code you are calling it).

The extension itself is an object and a regular class, therefore you could create a hierarchy an use polymorphism, having different sets of implementations for the extension themselves.

Here's a silly new implementation for our extensions introducing a hierarchy:

abstract class AbstractExtensions {
   
def void moveCandy(Move north, Candy candy)
}


class ExtensionImpl extends AbstractExtensions {
   
def dispatch void moveCandy(North north, Candy candy)
        candy.move(0, 1) 
    }
   
def dispatch void moveCandy(South north, Candy candy) { 
        candy.move(0, -1) 
    }
   
def dispatch void moveCandy(West north, Candy candy) {  
        candy.move(-1, 0) 
    }
   
def dispatch void moveCandy(East east, Candy candy) { 
        candy.move(1, 0)
    }
}

class InversedExtensionImpl extends AbstractExtensions {
   
def dispatch void moveCandy(North north, Candy candy) { 
        candy.move(0, -1) 
    }
   
def dispatch void moveCandy(South north, Candy candy) { 
        candy.move(0, 1) 
    }
   
def dispatch void moveCandy(West north, Candy candy) { 
        candy.move(1, 0) 
    }
   
def dispatch void moveCandy(East east, Candy candy) {   
        candy.move(-1, 0) 
    }
}

Then in our main or piece of code that actually uses the moveCandy method we can control the real implementation of the set of methods:

class Use {
   
var extension AbstractExtensions myExtensions = new ExtensionImpl
   
    def moveIt(Candy candy) {
        #[
new North, new East, new South, new West]
            .forEach[
                m| m.moveCandy(candy)
                println(candy.coordinates)
            ]

        
        println("----------: new extension impl")
        //change IT !
       
this.myExtensions = new InversedExtensionImpl

        #[new North, new East, new South, new West]
            .forEach[
                m| m.moveCandy(candy)
                println(candy.coordinates)
            ]
    }

   /* ... main ...*/
}

In this case we have it just hardcoded there in the initialization. But the extension instance could be injected. Also note that we are also changing the extension instance with the new one.
This prints:

0->1
1->1
1->0
0->0
----------: new extension impl
0->-1
-1->-1
-1->0
0->0


Therefore just by changing the reference to the extension (like if it was a prototype's parent object) we change the implementation of all methods that affects several classes (North, South, etc). Also kind of changing an aspects implementation.