Sunday, January 07, 2007

Cohatoe 0.2 preview

I have just released another preview version of Cohatoe. It contains a number of improvements and a cool new example.

As before, please keep in mind that this is still experimental and the APIs are bound to change a few times more. Actually, a rather severe change has been made already in 0.2 to the format of the plugin.xml when declaring a Haskell function (see below). (I promise I will stop doing such things of course once the APIs are more mature ;-).

There is now a changelog file in the SDK feature, where you can check what is new in which versions. The changelog is cumulative and contains all changes since the very beginning. In what follows, I'm giving a commented version of the changelog contents.

Declaring Haskell functions

As I mentioned, there have been changes to the schema of the haskellFunctions extension point (in the plugin de.leiffrenzel.cohatoe.server.core The attribute objectCode has been renamed to objectFile. This means that all plugin.xml declarations that use this extension point must be updated.

The old attribute is left in and tagged as deprecated, so that uses of the old format can be detected more easily. It will be removed in 0.3. That the attribute is still there doesn't mean that it still works, however. Eclipse will give a warning for each occurrence, so I have decided to leave it in. But the Cohatoe code doesn't read it anymore.

For situations where the Haskell code that you want to call is distributed over multiple modules, and you would consequently have more than one object file to declare, I have added some support. In the case where your modules are all in the same folder as the declared .o file, Cohatoe makes sure that they all are passed to hs-plugins, which will be able to load them. In the case where your object files are in a different folder (inside the plugin's directory structure, of course), you can specify that folder in the plugin.xml. Here is an example (taken from my unit test cases):

<haskellFunction
implementation="de.leiffrenzel.cohatoe.server.core.test.functions.MultiFolderModule"
interface="de.leiffrenzel.cohatoe.server.core.test.functions.IMultiFolderModule"
name="Multi-modules in different folders"
objectFile="$os$/obj/MultiFolderModule1.o">
<objectCodeFolder>$os$/obj2/</objectCodeFolder>
</haskellFunction>
There may be zero or more objectCodeFolder elements inside a haskellFunction element in your declarations now, each of which can declare a plugin-relative path, and all these paths are resolved and passed to the Haskell side where they are used for tracking module dependencies. (As usual, this works also when plugins are deployed and live in a .jar file.)

I'm planning to add further support for packages of object files (as created by the archiver tool). You will be able to declare these packages in a similar manner, but that support is not yet included as of version 0.2.

Next, I have added some helpful functions that can be used for marshalling data to the Haskell side and unmarshalling the results back. They are located in the class CohatoeUtils. Actually, they were already available in version 0.1, but there they were not well organized, well named and not even completely implemented. I've done a bit in that area, too.

Error handling

I have also started to improve Cohatoe in the area of error handling. This belongs to the large topic of robustness. Since Cohatoe will execute any Haskell code, it is important that its functioning is not impaired by code that crashes or perhaps is even malicious. Currently, a problem inside contributed code will cause the Haskell server executable to exit, and a restart of Eclipse is needed to get it working again. That is of course not acceptable, and so I have started to tackle the possibly problematic situations one by one.

The first case, the one that is now handled by Cohatoe, is when your contributed Haskell code calls the Prelude.error function. This will now no longer break the server, but is instead caught at the Haskell side and reported to the Eclipse side, where the exception is re-thrown as a CohatoeException.

The exception type (CohatoeException) is a subtype of Eclipse's CoreException, and it carries some useful information in addition to the usual Java exception information. It contains the error message that was used on the Haskell side, and it also knows the plugin identifier of the plugin that contributed the code which has caused the exception.

Since it is a CoreException, it also contains an Eclipse IStatus object that you can conveniently write to the workspace log, like so:
try {
// ...
} catch( final CohatoeException cohex ) {
// we don't handle this here, just
// write it to the workspace log
CohatoeExamplesPlugin plugin = CohatoeExamplesPlugin.getDefault();
plugin.getLog().log( cohex.getStatus() );
}
The exception knows also an identifier for the type of exception that was raised. I want to use that for distinguishing between calls to the error function and other types of errors, such as IO Errors, or problems that occured when hs-plugins tried to load code it couldn't. But that is not yet in - currently only Prelude.error is handled by Cohatoe.

New example - Sudoku solver

A new example has been introduced: a Sudoku solver View. The View can be found via the menu Window > Show View > Cohatoe Examples. The Haskell code that does the actual work is a Sudoku solver written by Graham Hutton which can be found at http://www.cs.nott.ac.uk/~gmh/sudoku.lhs (thanks to Graham for giving permission to include this code :-).

This example demonstrates how Haskell code is handled that spans more than just one object file (more background discussion can be found at in my earlier post about module dependencies in multiple modules), and it also gives an example for accessing multiple Haskell functions through a single interface on the Java side.

I will comment this example in more detail in one of my next posts, but I want to give you at least a screenshot here:

That's it from me for now - have fun! Any feedback is very welcome.

No comments: