الجمعة، 26 يونيو 2009

GWT's future: 2.0 and my wishes

Programming web applications with GWT has been a revelation. Having mature tools and a single code base for client and server is great. In this blog post, we'll first look at the new features of the upcoming version 2.0 of GWT. Then I'll list a few wishes that are still unanswered by 2.0.

New features in GWT 2.0

GWT 2.0 has some incredible features in store:
  • In-browser hosted mode: see your hosted mode webapp in a real web browser. This obviates many needs for compilation. Plus both compilation and starting hosted mode will become faster.
  • Developer-guided code splitting: you tell the compiler roughly were to split to lazily load code and the compiler figures out how to package your code.
  • Better layout: the GWT team seems to have worked on better CSS-based layouts. I'll believe it when I see it, but if this works, it will fix one of the biggest Ajax problems.
Get more details about GWT 2.0 at “GWT Can Do What?! A Preview of Google Web Toolkit 2.0”.

Open wishes

Alas, a few of my wishes are still unfulfilled. I've collected them below, they are the result of my experiences while implementing Hyena. If all of these wishes were to come true, then this would make web applications true competitors to desktop applications (well, one would still have to figure out packaging and access to desktop features; Trephine is very useful here, but an even cleaner solution would be nice).
Platform
  • Server-side image generation: generate a JPG, PNG or SVG image on the server, send it to the client, display it in an image. Right now, the work-around is to use a data: URL with base-64 encoded binary data and assign it to an image. But that wastes space and does not work with SVG in a cross-browser fashion.
  • @Ignore annotation for methods: This would mark server-only methods and prevent client-side code from being generated. The current work-around is to move server-only code to static methods in a different class.
  • Swapping a server-only implementation of an interface with a client-side place holder: With custom field serializers you can control how a class is serialized but not what class is instantiated. This is a problem whenever you have a nested data structure that contains server-only implementations. I currently do my own reflection-based traversal and swap implementations to solve this problem (directed by annotations). Hardly a simple solution.
  • True dynamic loading of client-side GWT code: would be the perfect client-side complement to server-side OSGi modules. Then OSGi modules (or even just plug-in JARs) could bring their own client-side code. Currently this does not work, because GWT always compiles the reachable code of all used modules into a single monolithic "binary". The kind of code splitting that is planned for GWT 2.0 seems to be almost there, but serves a different purpose.
  • GWT API for Bespin's widget library: This widget library is completely drawn by JavaScript in the canvas tag. Sounds crazy, works really well, because JavaScript has gotten so fast.
Language
  • Full client-side regular expressions (preferably with an API that works server-side, too).
  • Non-static GWT.create(): It would be nice if class objects could be sent to the client for instantiation. Currently, the only work-around is to register serializable factories (that actually do the instantiation, statically) and send those to the client.
  • String.format(): is useful, easy to implement, and should work on the client.
  • Class.getSimpleName(): same as above.
GUI
  • Better layout: Hopefully GWT 2.0 delivers on this front. What I miss is to be able to specify “take up as little space as possible” (as opposed to * or fixed spaces). Vertical spacing is often tricky, too.
  • Better widgets: The scarcity of widgets is still one of GWT's weak spots. Mappings to JavaScript widget libraries are possible, but then one does not profit from GWT's small code size. A few widgets I'd like to see are:
    • A more flexible suggest box (that can make suggestions anywhere and has a configurable trigger character; both things are relatively easy to add to the current suggest box).
    • A tab bar where one can add widgets to the right of the tabs (right-justified).
    • A span-based HTML widget.
    • Tables: a table that can be translated back to a model (with the incubator's ScrollTable, row numbers change when sorting), a table with grouping (see SmartGwt), and a tree table.
    • More events: an OnEnterKey event for TextBox and onChange events that are fired whenever a change happens; not just when un-focusing a TextBox or TextArea.

الأحد، 21 يونيو 2009

I think I figured out Apple's Java 6 strategy

Apple has been really negligent with Java: First there wasn't a Java 6 for ages, then it only ran on 64 bit machines. And while all current Macs are 64bit, this excludes a lot of Intel Macs. Thus, targetting Java 6 on the Mac was not practical. Fortunately, one of the WWDC 2009 sessions was “Java 6 on Snow Leopard”:
As Snow Leopard moves to Java 6, learn modern techniques for the best possible Mac experience while maintaining cross-platform compatibility using the latest version of Java. Find out how Mac OS X continues to build on its strong Java support with new UI enhancements, new APIs, and a next-generation Java Applet browser plug-in.
Now I think I understand Apple's Java 6 strategy:
  • Don't support PowerPC, ever.
  • Initially support Java 6 as quickly as possible on currently sold Macs (with the limited resources Apple has allocated to Java). This meant support for 64bit Intel only.
  • Eventually support all Intel Macs. Well, at least I don't see any other way of interpreting the WWDC session (if Java 6 is standard on Snow Leopard and Snow Leopard runs on all Intel Macs...).
And while I'm still underwhelmed, this is acceptable. What is not acceptable is not having communicated this strategy for years.

الاثنين، 8 يونيو 2009

JavaFX authoring tool

The blog post “JavaFX Authoring tool demo at JavaOne 2009 (with video)” shows two videos of a prototype of the JavaFX authoring tool in action. Very nice, the binding stuff reminds me a bit of the Mac OS X interface builder. I still wonder though, how useful binding is in multi-threaded settings.

الجمعة، 5 يونيو 2009

Microsoft and netbooks

The same old anti-competitive tactics: Microsoft strikes back at Linux netbook push. Sad, really. And all that while they have a reasonably strong offering with Windows 7 and it's not clear how much mainstream appeal Linux will ever have (I've heard good things about the latest Ubuntu, though). [Source: dzone.com]

الأربعاء، 27 مايو 2009

Eclipse E4 is getting interesting

I initially was very sceptical of Eclipse E4: in a lot of ways it smelled like design by committee. Eclipse's main problem has always been its heavy coding style (factories everywhere, downcasts, code snippets that expose the innards of the platform, hard-to-reach service objects, etc.) and it seemed like E4 was continuing that trend.
Thankfully, the latest information on E4 paints a more positive picture:
  • I have been thinking a lot about how to write applications that work well as both web applications and as desktop applications. E4 is trying to go in the direction of a universal platform. I used to think that this was just a gimmick (as most multi-target GUIs, that I've seen, are), based on their preference of RAP. But it turns out that they are considering all kinds of options, including GWT, Bespin, and Flex.
  • The E4 team also reported that, when cross-compiling to other platforms, the snippets are a major hindrance and thus will probably go away in the long run.
  • They really seem to be eager to remove some of the cruft. For example, dependency injection is going to work wonders for discoverability of the API.
More information:

الجمعة، 1 مايو 2009

Multiple dispatch: a fix for some problems of single dispatch (Java etc.)

Almost all well-known object oriented languages (Java, C#, JavaScript, Python, Ruby, ...) have single dispatch: Methods are chosen depending on the (single) receiver of a message. On the other hand, there is multiple dispatch which is an interesting mix of functional method selection with mutable state. It is used in less-known object-oriented languages such as Common Lisp.



In this article, we'll first look at Java's single dispatch and Java's overloading and then use what we have learned to understand multiple dispatch and how it solves some design dilemmas that can't be solved with single dispatch.



Let's start with dynamic dispatch:

    public class Empty extends Object {

@Override
public String toString() {
return "Empty";
}

public static void main(String[] args) {
Object empty = new Empty();
System.out.println(empty.toString());
}
}



What is the output of this program? It is “Empty”. If this seems obvious, it is because you are already very familiar with dynamic dispatch: Java determines at runtime what class an instance belongs to and chooses the appropriate, possibly overridden, method. For the example above, this means that we don't use the toString() method from class Object, but the toString() method from class Empty. In some languages, such as C++, you have to explicitly state that you want dynamic dispatch.



Now on to overloading, another way of picking a method implementation.

    public class Printer {
public void print(String str) {
System.out.println("String: "+str);
}
public void print(Object obj) {
System.out.println("Object: "+obj);
}
public static void main(String[] args) {
Object obj = "abc";
new Printer().print(obj);
}
}

Here the output is “Object: abc”. The method implementation is chosen statically, at compile time: Internally, the compiler uses the static types of the method arguments to disambiguate the method names. This time, the result is unexpected, even really good Java programmers that I've asked get it wrong. Due to dynamic dispatch feeling so natural for the receiver of a message (=“this”), we expect it to work the same for the arguments. There is a kind of asymmetry between the receiver and the arguments of a method and that asymmetry is reflected in the invocation syntax, too.



With multiple dispatch, methods become top-level constructs. This is similar to implementing a single dispatch method “foo” with two arguments as a static method:

    public static void foo(this, arg1, arg2) {
if (this instanceof A) {
...
} else if (this instanceof B) {
...
} ...
}

The message receiver “this” becomes just another argument and all variations of the method are united in a single place (having this kind of view on a method helps with understanding implementations that use polymorphism, but I digress). Instead of the myObj.foo(x,y) you now invoke foo as foo(myObj,x,y). This is still single dispatch. Multiple dispatch nests instance-of checks for arg1 and arg2 inside the checks for “this”. Only after checking the types of all arguments do we decide which variation of the method to use. Common Lisp calls foo a generic function and the code snippets inside it methods.



Note that the if statements were for illustration only, languages with multiple dispatch have efficient algorithms for performing the checks and selecting a method.



What advantages does this have?



A generic function can “belong” to several classes. This helps whenever method arguments are not true parameters (data), but rather collaborators (that offer services) for an algorithm. For example, if you have a method Database.export(Filesystem,UserFeedback), this method might contain as many Database invocations as Filesystem invocations. The special case of binary operators as methods exhibits the same difficulty: Should the operator “String + Integer” be considered part of class Integer or part of class String? It is for a reason that UML has special diagrams for collaborations and that these diagrams cross-cut classes.



One more example of collaborating objects is the visitor pattern: It is a clumsy simulation of multiple dispatch with single dispatch. What you have at its core is the object for the algorithm collaborating with the object for the data. With multiple dispatch, things are much simpler, there is less code to write and the data objects do not have to be prepared for visitors. Interestingly, even the explicit object for the algorithm disappears, because the generic function replaces it.



Another area where the asymmetry of single dispatch shows is with the null value. For example, "abc".equals(null) is OK while null.equals("abc") causes an exception (and is not even directly syntactically correct). If you introduce null checks as selection criterion for methods, then handling null values is simple with multiple dispatch.



Extending a class is trivial with multiple dispatch, just create a new generic function that accepts instances of that class as its argument. With Java, people often overlook external static methods that actually extend a given class, because they don't know where to look. For example, if you don't know Java well, you might be puzzled as to why List has no sort() method. If you do, you know that the class Collections has a static method sort(List) that you have to use. In languages with multiple dispatch, one already assumes that in general, a generic function is relevant for several classes. The development tools help one with finding all functions that apply to a given class, making sure that code is re-used instead of re-invented.



Having code tightly integrated with the data is less desirable in settings where you serialize objects. With generic functions, code and data are separate and it is easier to use the same data structures on the server and the client. The server can host a lot of code that generates or modifies data. The client only has to display the data and lets the server handle the more complicated stuff. This is a frequent scenario when doing client-server communication with the Google Web Toolkit. As Java does not have generic functions, the server-only functionality has to be moved to external static helper methods. Consequently, things are even less encapsulated, slightly messy and one loses polymorphism.



Predicate dispatch



A generalization of multiple dispatch is predicate dispatch. With multiple dispatch, the methods of a function are selected based on the types of the arguments. With predicate dispatch, more complex conditions can be specified. This simplifies changing the behavior of an instance depending on its state and obviates the need for the strategy pattern. For example: Let's assume that an instance of class Bar has to behave differently if an error flag is set to true. The relevant generic functions will contain one method that is invoked if the flag is true and another one if the flag is false. Attached to the first method is an explicit selection condition such as myBar.error. The second method has a condition such as !myBar.error. These selection conditions are additional ways of classifying instances. One could say that myBar changes its class depending on the value of its field error.



Conclusion



We have seen that multiple dispatch can do several things that single dispatch can't. But I think that both are complementary. Message passing is a nice and clean metaphor for method invocation that works well with distributed computing. It views objects as components that provide services. On the other hand, objects-as-data result in phenomena (binary operators etc.) that are best implemented with multiple dispatch.


Further reading



The basics in depth




Advanced topics




Languages close to Java with multiple dispatch