Java, OCaml, and F# (<- is it done yet?)

I am in a state of transition: from Java to OCaml.

A Java Project in NetBeans

A Java Project in NetBeans

I like Java as a platform primarily for its matureness, static typing, and great IDE integration (Netbeans in particular). But lately I’ve been finding myself manipulating a lot of tree structures—ASTs, query plans, nested relations, automatically generated GUI layouts—and Java is just too verbose. Even using visitor patterns, the real application logic just gets too diluted among classes, methods, and variable declarations to help me gain any additional insights from the coding experience. I find this unacceptable, as one of the main reasons why I code is to solidify my understanding of otherwise theoretical ideas. It was time to move to OCaml.

Well, I only had experience with SML (a dialect of ML) from compiler and programming languages classes and a few smaller projects during undergrad, but I knew that sum types, pattern matching, and strong static inferred typing just might be what could fit 4000 lines of Java into 500 lines of functional goodness. OCaml turns out to be the more popular (and less obscure) dialect of ML, so it seemed like a good choice. I was concerned about tool integration, however.

I took it for granted that OCaml would force me to give up the many great IDE features I had been accustomed to with Java and Netbeans: code completion, editor/build system integration, live documentation browsing etc. Especially since I’m a Windows user (on the desktop, anyway), I had serious concerns about whether I would be able to set up a satisfactory work environment with OCaml. To the rescue came F# .NET, or so it seemed.

An F# Project in Visual Studio

An F# Project in Visual Studio

F# is Microsoft Research’s new adoption of OCaml for the .NET environment. In essence, F# is to OCaml what C# was to Java, and one of its big selling points is integration with Visual Studio. Excited, I bought Expert F# (a very good reference book, which I will use even as I learn OCaml) and downloaded the F# May 2009 Community Technology Preview for Visual Studio 2008. I spent the next two weeks trying to learn and set up the environment to suit my needs, which included parser generation using fsyacc/fslex and heavy use of the F# interpreter to debug my code.

Unfortunately, F#’s Visual Studio integration is to this date rather rudimentary. I understand that the plugin is still in early development, and I’m sure it will improve a lot in the next year or two, but meanwhile, here’s a quick grief list:

  • No syntax highlighting or code completion in fslex/fsyacc source files. (While parser generation might be seen as an obscure feature on any other platform, ML people do have a striking tendency to be compiler researchers or language designers…)
  • The FsYacc/FsLex MSBuild tasks do not consistently generate new parser/lexer files after the definition files have been modified, and a “clean” operation does not delete the generated files.
  • Console apps (e.g. “Hello, World!”) open in a new window which promptly disappears after the end of execution, instead of having their output routed to a console output window. Visual Studio might be a little weird in general here, but I couldn’t figure out how to fix it.
  • There is no easy way to use the interactive console in the context of the code that is being built in the current project. For instance, if my project code defines a number of modules, namespaces, functions, and data types which are all compiled into a DLL, I would like to always be able to access the most recent build of those definitions from the interactive console, without too much fuss (see below). Automatic copy-and-paste of raw source code into the interactive console does not do the job when you have multiple files (some possibly generated as part of the build process) and when you don’t want old definitions hanging around.

Currently, a single iteration of interactive testing would involve the following steps:

  1. Make a change to the source code.
  2. Manually delete fsyacc/fslex-generated files to make sure they are remade on the next build (see above).
  3. Reset the interactive console (step 5 below will lock up the output DLL, causing the build to fail if we don’t do this).
  4. Do a build.
  5. Issue a command like #r “Z:\\Unfinished\\EverythingCO\\trunk\\fswork\\qllib\\bin\Debug\\qllib.dll”;; to make the compiled definitions available from the interactive console.

Add this to the fact that the F# language itself is still bleeding edge, and the costs to productivity start outweighing the benefits. So for now, I decided to abandon F# in favor of OCaml, spending yet another two weeks trying to set up a great work environment.

Eclipse + OcaIDE

An OCaml Project with the OCaIDE Eclipse Plugin

And there it was. With Eclipse plus the OcaIDE plug-in (and Cygwin to provide some underlying prerequisites like make), I found everything I wanted. It took a little while to figure out, but in the end I had:

  • A Makefile-based build system which would not only work on my own Eclipse/Windows environment, but also for anyone else who might like to check out the code in the future, for instance on Linux. The plug-in has a centralized Preference page to set up all the necessary OCaml paths. Note that the build system I use is just the standard OCamlMakefile—other options are available.
  • Code completion and object browsing.
  • Syntax highlighting in ocamllex/ocamlyacc definition files (though no code completion in ocamlyacc semantic actions.)
  • Automatic rebuild every time I save a file (standard Eclipse stuff).
  • Compilation of custom OCaml toplevels, giving me the kind of interactive development I mentioned above (though you still have to manually kill the existing custom toplevel before rebuilding).
  • Console app output shows up in a console (compare above).

This, together with the matureness of the OCaml language, has made me choose OCaml over F# for now.

12 Responses to “Java, OCaml, and F# (<- is it done yet?)”

  • Ted says:

    Eirik, this is a really interesting writeup! Thanks! I know you’re partial to NetBeans.. maybe once you’ve used Eclipse & OCaml for a while you can do a “Eclipse v. NetBeans” shootout.

    Newbie question: When using OCaml / Eclipse, can you integrate with other languages easily? I’m not a MS developer, but my understanding is that all of their languages can be mashed together because of the CLI VM they use underneath.. is that true for F# too?

  • Eirik Bakke says:

    Ted: My NetBeans preference is strictly for Java development; for anything else Eclipse would probably be my best bet. My reason for preferring NetBeans with Java is that I started out with it and it did everything I ever wanted to do, right out of the box. (In fact, I think there is even a version of the NetBeans installer that includes all of JDK.) That includes some excellent tools for designing layout-managed windows and dialog boxes without typing a single line of code. I’m sure you can achieve the same thing within Eclipse, but you will have to find the right plugins. So it’s not so much a choice between NetBeans and Eclipse as between NetBeans and Eclipse with a particular set of plugins. Though maybe the default Eclipse/Java development bundle has been improved since I last tried it many years ago.

    OCaml itself compiles to machine code (unlike Java or .NET), and I think there are bindings for many languages (including C/C++, but I don’t know about high-level ones). As for how this would turn out in Eclipse, I don’t know, but it should probably work given that the build process is just a Makefile and other plugins are available for other languages. Typically header files (or similar) will be generated in one language for the definitions made available from the other language, so I think for instance code completion should work fine even across different languages.

  • According to this [1], F# is being transitioned to a “fully supported language” in the .NET world, so it looks like if not now, then at least soon, you should be able to build your F# code into assemblies that can be used by any other .NET language and vice-versa.

    Thanks for the write-up! I’m interested in playing around with more functional development, and hopefully your post here will save me the weeks you spent getting everything properly set up :)

    [1] http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/

  • Stuart says:

    Did you look at Scala?

    I’m coming from a longtime (mis) use of .net, and one of the appealing aspects of Java and Scala is Hadoop.

  • wheaties says:

    You aren’t disapointed by the lack of multi-processor support in OCaml? I thought the big thing about F# was not just “OCaml for .NET” but also built-in true threads.

  • Max says:

    check mythryl – still in early stages but might be interesting: http://mythryl.org/

  • James Hofmann says:

    Did you consider Scala as a way to stay with the JVM? It isn’t really equivalent to F# or Ocaml, but it does have local inference, functional features, and a large grab-bag of nifty, modern stuff, and my preliminary investigations indicate that the tools are now starting to get up to speed with Java.

  • Michael Tiller says:

    I’m surprised you don’t include any discussion of Scala. It gives you the pattern matching and functional semantics on the Java platform, allows interoperability between Java and Scala classes and it has an Eclipse plug-in.

  • Anonymous says:

    A simple Console.ReadLine() call at the end of your app will stop the terminal from closing until you press a key.

  • jerryjvl says:

    You probably already know this, but for anyone that visits here and doesn’t, Visual Studio 2010 (out in Beta 1 now, but do yourself a favour and wait for the imminent Beta 2 for better performance and stability) has F# integrated as a first-class citizen, and a lot of your grief-list will probably not be relevant anymore.

    Note that VS2010 is expected to do a full release sometime in the first half of next year, but from what I understand Beta 2 will be pretty close to what to expect from this final version.

  • Chris says:

    If you want to stay with Java IDEs and in the JVM, take a look at Scala. Scala and F# have gone under quite a bit of co-development in the past, and although they differ on a few fronts (Scala tries to be OO first), you can have the benefit of converting your Java app a couple lines at a time to Scala and see if it still works (since they all work on the same VM).

  • Eirik Bakke says:

    Ah, thanks for many informative comments, everyone (sorry they got stuck in the queue)!

    1) Several people have mentioned Scala, which I hadn’t heard of and will definitively check out. Thanks!

    2) wheaties, I wasn’t aware of the lack of multi-processor support in OCaml. In my particular application this won’t be a problem for the forseeable future, but I can see how it might be a significant limitation for other application. (Side question: are there any popular, garbage-collected languages that compile to machine code _and_ have true multiprocessor support?)

    3) jerryjvl, ah, yes, I did know F# would be part of Visual Studio 2010, but always assumed this just meant that it would come bundled with whatever latest version of the F# plug-in was available (see http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/release.aspx ). If there are more F# features in VS2010 than in the May 2009 plug-in for 2008 then that’s very relevant for anyone considering F# as a platform in the future.