Sunday, April 29, 2007

Cohatoe extension wizardry

I have started to add some helpful tools to the Plugin Development Environment (PDE) in Eclipse to facilitate working with Cohatoe. One of the things that still take some time (in my experience when implementing the examples) is creating the source files and manifest entries that are needed for a new Haskell contribution via Cohatoe. It's not much (and mostly boilerplate that is always almost the same stuff), and it can actually be generated from very little input by the user.

So I have first added a wizard for creating a new Cohatoe extension. Suppose that you already have a plugin project. Then you can now just go to the Extensions Tab on the Plugin Manifest editor, click Add > Extension Wizards > Cohatoe Development Tools > Haskell Contribution, and you get a wizard that generates all the files and manifest entries that you need, namely:

  • It adds the dependency to the Cohatoe Core plugin to the META-INF/ file (if it is not already there).
  • It adds an extension in the plugin.xml file and declares the Haskell source file along with the Java implementation and interface types.
  • It generates the Java interface and implementation types, together with the code necessary to call the server (i.e. what happens inside the implementation class) and with a usage example that can be copied to where you want to call the function from your Java code.
  • It generates the skeleton source file for the Haskell module that is called.
The only things you have to specify are some workspace locations, in particular the source folder (there is usually only one, so that's probably trivial), a Java package name, and a name for your contribution, from which the name of the Haskell module and the Java types are derived.

For the time being, this supports only contributing source files, if you want to change this into an object file contribution, you have to enter the path to the object files manually in the plugin.xml, in the codeFile attribute (where originally the source file is specified in what the wizard has generated).

I think this should considerably ease and speed up the process of creating the plumbing for a new Haskell contribution, and help you to focus on the actually more interesting bits, namely the Haskell code itself, and the places where it is eventually called in the Eclipse plugin :-)

(NB: this is not yet in the downloadable preview, but in the Darcs repo. But I think I'll do another preview build soon.)

Sunday, April 22, 2007

Contributing source files

When working on new examples for Cohatoe, I noticed that it is still somewhat tedious to go through the usual cycle: write some code, compile and run it, make some changes, compile and run again ... One thing that makes it tedious is the need to compile the Haskell code into object files all the time.

In order to make this nicer, I have extended Cohatoe to run Haskell code from contributed source files. (The actual work of compiling and loading the code is again done by hs-plugins.) You can now just put a Haskell source file into your plugin project, and declare it similarly to how you would have declared an object file.

There a few rather minor details connected to that change I'm a little unhappy about. One is that I had to change the format of a Cohatoe extension in the plugin.xml once more. Instead of a (mandatory) objectFile attribute, the haskellFunction has now a codeFile attribute (which says nothing anymore about the content of the file). Whether we treat the file as a source code file or an object file is determined from the file extension. Currently recognized are .o as extension for object files and .hs and .lhs for source files. The alternative would have been to keep the old objectFile attribute and introduce a new one called sourceFile. But that would have meant to make them both optional, and the only way to validate that exactly one of them was specified is then in the Java code that reads the extension. The current way has also the advantage that it can be easily extended to other types of contributed Haskell code (I'm in particular thinking of Haskell code that is compiled to JVM bytcode, e.g. via LambdaVM).

On the downside, of course, that's one more API change which is annoying to any early adopters out there :-( Still I think it's better to make such changes now, that is, early in the cycle.

Another less-than-optimal thing is that the .o and .hi files that hs-plugins generates before loading them end up in the same folder in which the original source file is. There is a number of situations where this could be a problem, including running from a jarred plugin, running from a write-protected folder, and so on. Cohatoe can handle a number of these situations transparently already, but very likely I have still overlooked one or the other. Therefore I regard this as a somewhat unfinished detail.

Of course, the additional compilation step has an effect on the time needed when first accessing the function; in production mode you would probably still prefer a pre-compiled object file to contributing a source file.

Looking at the bright side, this new possibility to run contributed Haskell code as source code will help to make life easier during development, and also make it easier to provide platform-independent functionality (always assuming that the code itself doesn't make any assumptions about the OS it runs on, in which case there is no way around keeping platform-specific code in one manner or the other).

Thursday, April 05, 2007

Unit testing in Haskell

Test-Driven-Development is a programming technique where you write small programs (test cases) in advance of coding the actual piece of software you want to write. If done well, this helps to clarify the various combinations of input/output/environment for your code, and makes it easier to implement it. As a nice extra, you speed up testing - all you have to do is to run all those test cases again, and they will point out whether everything still works as expected.

So far so good. (And if you're coming from Java development, you know that song by heart anyway ;-). But can we do this in Haskell? Sure. There are actually two different well-supported approaches in Haskell to do test-driven development. One is more oriented towards functional programming, focusing on declaring properties of functions - this one is supported by QuickCheck (and not covered in this post); the other is aligned with the 'classical' JUnit tool. There is an implementation of this approach in the form of HUnit. I have written a tutorial that gives an introduction to unit testing with HUnit.

Again, I would have have preferred to post the full text here, but that is too inconvenient with all the code listings. But you are welcome to comment on the tutorial here on this post.