Sunday 30 November 2008

I still have a problem with the DLR

Microsoft's Dynamic Language Runtime shipped its first Beta a few days ago. For those who don't know, the DLR is Microsoft's effort to bring support for Dynamic Languages on top of the .NET Virtual Machine. Catch it ? Dynamic Languages are the rage today, and .NET and Java now want to catch the trend on their respective VMs. The DLR initially lived in the IronPython codebase (IronPython is the .NET implementation of Python), but it now seems to live on its own.

I expressed some concerns about the state of the ongoing work for the DLR some time ago, and some people from the DLR team tried to answer. These concerns were (in short):

  • A lot of hard coded references to IronPython and IronRuby, the currently two Microsoft project heavily leveraging the DLR

  • Compilation directives looking for Silverlight everywhere in the code


In short, my concern was that the DLR may be too tied to Microsoft implementations specificities, and not really language / or implementation agnostic. I know this is not what Microsoft folks want, but all this just adds complex interwoven ties between parts of Microsoft's offerings that should never meet explicitly ;-). People already encounter repeated problems when trying to build IronRuby under Mono, this can only make it worse.

And sadly, when looking through the code, I saw as many Silverlight directives as before. And now, some new LINQ references that were not there before. My problem is not that there are dependencies, it's the fact that they seem to be everywhere in the code. I would greatly prefer to see them limited to a specific module in the code, and I'm worried about these new LINQ dependencies. Plus why compilation directives ? Why is it not possible to limit Silverlight specificities to a separated assembly (preferably implementing an interface with a default implementation), and link to this assembly at runtime ? And why Silverlight is so different from the core .NET runtime ?

Update 6/12/2008: Since Bill Chiles comment, I downloaded the code (before I just browsed in the codebase through the web access), and here is what I discovered:

  • 139 files with ifdefs for SILVERLIGHT in the code (that makes roughly 25% of the files), mostly in the Core package (71 files in Core and its subpackages), but widespreaded in the codebase.

  • 4 files referencing IronRuby, and 12 referencing IronPython !!! Again these are not limited to a particular package in the code, and I really wonder why there are more references to IronPython than IronRuby. In short, I don't know how anybody would be able to use the DLR for a new scripting language without changing the core DLR code

  • 302 files using Linq specific libraries and/or functions.


I'm sorry to say that it does not look to me as a well-designed code IMHO (for the moment). I would very much like to see:

  • ALL specific references to IronRuby and IronPython removed.

  • If it's not possible to avoid ifdefs for SILVERLIGHT (I hate ifdefs in general) at all, then limit them to a specific package in the code, and access these by a neutral interface

  • I really don't think that the idea to put Linq there was very good to begin with, but at least I would prefer to see Linq references limited to a Linq-specific package


Update 2 (7/12/2008): About references to IronRuby and IronPython, I maybe was a tad too fast to criticize (I still stick to my previous point with Silverlight references). There's only one file with a real hard reference to IronPython, IronRuby, and JScript. I really don't know why the PlatformAdaptationLayer class needs to explicitly add assembly mappings for these implementations. Why not leaving it to each implementation to add its own mappings ? How a new scripting language will be able to add its own mappings without changing the PlatformAdaptationLayer code ?
But there's still a lot of comments about IronPython in the code, which makes me think that some of the DLR code is still tied to this implementation. However, this should improve in the future. Except that... I now saw another file with an explicit new compilation directive (argghhh !!) referencing IRONPYTHON_WINDOW. That looks bad to me.
And to show my point about the SILVERLIGHT references, let's use one simple example, again in the PlatformAdaptationLayer class. The code is:

public virtual bool DirectoryExists(string path) {
#if !SILVERLIGHT
return Directory.Exists(path);
#else
throw new NotImplementedException();
#endif
}

OK I think its because Silverlight impose limitations on access to the File system (sandboxing), so you may not access directories at will. I have no problem with that limitation, but... It would have been very easy to access to a platform-specific assembly here, instead of using these dreadful compilation directives. The Windows platform assembly would simply return Directory.Exists(path), the Silverlight assembly would return the NotImplementedException. This would have been way better IMHO.

Saturday 8 November 2008

Web 2.0 taken hostage

I tried today to access the .NET 4.0 (Dublin) roadmap on Microsoft website. Unfortunately, you need to have a Word Office 2007 compliant reader to be able to even read this.

Want to access some (maybe) cool content on websites ? Be sure you have the last Silverlight plugin available. But for the moment it will not work on Linux, because Moonlight is still a work in progress.

Aren't you concerned by the fact that an increasingly number of Web sites use proprietary technology for their rendering ? Some time ago we only had to bother about Flash, but it was almost OK, we only had to download one plugin. Now it seems that every big Web 2.0 contender is trying to tie people to their own technology.

Web 2.0 is in danger of breaking in a myriad of little pieces. What is going on now is contrary to what made the web ubiquitous. I'm really looking forward to HTML 5, jitted Javascript and canvas rendering on HTML pages. I really want this to kill both Flash and Silverlight, else I don't know where we are heading.

Sunday 2 November 2008

new XUL on Java project

Remember this June post about using XUL, Javascript, and Beanshell in a ARINC 661 Client-Server framework ?
Well it occurred to me that the XUL / Javascript / Beanshell part of this was not specific to ARINC661 and could be useful to others as well.
Also if you look in the wild you will only find two Java XUL frameworks:

  • A Java project called jXUL had exactly this goal, but it seemed that its development stalled very quickly in 2001, while still in Beta or even Alpha stage (no activity since then)

  • Luxor is huge and complex, and also has no activities since some years


So why not sharing some code, being able to use XUL "out of the box" in Java can be useful, and even cool ;-)

So let me introduce my new project: javaXUL.

javaXUL is not intended to compete with much more complete RIA offerings, such as Flash, Silverlight or javaFX. Instead it tries to leverage the expressivity of XUL in the java developement area. Compatibility with Mozilla XUL (such as the Firefox implementation) is a goal, but ease to use in the Java world is also one.
The goal of version 0.1 (underway) is to be able to use javaXUL "out of the box" to add user-defined UIs on Java projects:

  • import existing sources and make them compile

  • make them work on simple use cases

  • add simple examples

  • allow setting of Look and Feel

  • ability to add other script engines than Javascript


And now, Just a simple example for your pleasure:

Lets look at the code for this example (its available in the javaXUL website):

import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
import java.awt.BorderLayout;
import java.net.URL;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import org.xul.script.scripts.AbstractScriptContext.JSFunctionBinding;
import org.xul.script.scripts.ScriptListener;
import org.xul.script.xul.DefaultScriptManager ;
import org.xul.script.xul.model.XULDocument;

public class BasicXULSample extends JFrame {
private JTabbedPane pane = new JTabbedPane();
private XULListener listener = new XULListener();

public BasicXULSample() {
super("Basic XUL Sample");
this.setLayout(new BorderLayout());
this.add(pane);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
init();
this.setSize(500, 500);
}

private URL getResource(String name) {
return Thread.currentThread().getContextClassLoader().getResource(name);
}

private void init() {
DefaultScriptManager manager = new DefaultScriptManager ();
manager.setLookAndFeel(new WindowsLookAndFeel());
manager.setScriptListener(listener);
try {
URL boxes = getResource("org/xul/samples/resources/boxes.xul");
XULDocument boxesdoc = manager.addXULScript(boxes.toString(), boxes);
JComponent boxescomp = boxesdoc.getRootComponent();
if (boxescomp != null) {
pane.addTab(boxesdoc.getFile().getName(), new JScrollPane(boxescomp));
}
URL test = getResource("org/xul/samples/resources/test.xul");
XULDocument testdoc = manager.addXULScript(test.toString(), test);
JComponent testcomp = testdoc.getRootComponent();
if (testcomp != null) {
pane.addTab(testdoc.getFile().getName(), new JScrollPane(testcomp));
}
URL buttons = getResource("org/xul/samples/resources/buttons.xul");
XULDocument buttonsdoc = manager.addXULScript(buttons.toString(), buttons);
JComponent buttonscomp = buttonsdoc.getRootComponent();
if (buttonscomp != null) {
pane.addTab(buttonsdoc.getFile().getName(), new JScrollPane(buttonscomp));
}
manager.setActive(true);
} catch (Exception ex) {
ex.printStackTrace();
}
}

public static final void main(String[] args) {
BasicXULSample sample = new BasicXULSample();
sample.setVisible(true);
}
private class XULListener implements ScriptListener {
public void print(String message) {
System.out.println(message);
}
public void setCurrentJSScript(JSFunctionBinding binding) {
}
public void showException(String message, Exception e) {
e.printStackTrace();
}
public void showException(Exception e) {
e.printStackTrace();
}
}
}

All you have to do is:

  • Create a Scriptmanager (the library provide a ready-to-use DefaultScriptManager implementation)

  • provide a ScriptListener which will be fired for actions on the javaScript side (for now, it is very very basic, I agree)

  • Add various XUL Scripts for this manager, and grab the corresponding components:

    URL test = ...;
    XULDocument testdoc = manager.addXULScript(test.toString(), test);
    JComponent testcomp = testdoc.getRootComponent();



You can already grab the code and make it work. a LOT of things need to be done on it of course, but I think it can already be useful. As soon as the ability to add other script engines than Javascript has been added I will post a first 0.1 version. For now, consider it a Beta ;-)