I spent a couple of afternoons last week beginning to compile our CamlPDF library under F#, with the intention of making our PDF Command Line Tools available as a .NET library.
CamlPDF + the command line suite is about 20000 lines of OCaml, so I’m loath to fork it. I’m half way through now.
Here’s how to deal with conditional compilation:
let digest = (*IF-OCAML*) Digest.string (*ENDIF-OCAML*) (*i*)(*F# function s -> let hasher = System.Security.Cryptography.MD5.Create () in let ascii = Bytearray.string_to_ascii s in Bytearray.ascii_to_string (hasher.ComputeHash ascii) F#*)(*i*)
(In this instance, making up for the fact that the Digest module from the standard OCaml distribution isn’t available in F#). The (*i*)
is to prevent OcamlWeb from asking TeX to interpret the F# part (TeX isn’t keen on the # character).
F# provides a library which gives some of the facilities of OCaml’s Pervasives library, and alternatives for Set and Map (F#’s functorial facilities differ from OCaml), so we have:
module PdfObjMap = Map.Make (struct type t = int let compare = compare end)
in OCaml, and in F#:
let PdfObjMap : (int, objectdata ref * int) Map.CMapOps = Map.Make compare
There are also subtle differences in the type systems, leading to changes in .mli files, but normally not too extensive. Some extra type annotations are required in ML code too, but again – not many.
A couple of important OCaml libraries are missing – for instance GenLex – in that case, I just wrote a simple lexer myself, to replace my uses of GenLex.
The current stumbling block is a file that simply won’t compile in F# – the compiler freezes – but back to that tomorrow. Once the main CamlPDF library is converted, we can get on to building a nice API for using the PDF tools from .NET languages such as C#, and working out how to package it into a distributable product.