Crossing the Rubicon: from Haskell to .NET through COM
by Beatriz Alarcón and Salvador Lucas
.NET is an emerging Microsoft project which promotes a new framework for Software Development that emphasizes the use of Internet resources and the interaction between components written in different programming languages. Whereas functional programming languages such as Haskell are well suited for developing tools to analyse, verify and transform programs, typical Haskell compilers do not provide sophisticated capabilities such as support for XML-Web services, assisted GUI development and so on, which occur frequently in most .NET development frameworks. This article reports on our experience in the integration of Haskell applications into the .NET framework.
The CLR (Common Language Runtime) is the heart of the .NET framework; together with the FCL (Framework Class Library), a consistent, object-oriented set of classes, they both provide a platform supporting multiple programming languages. The idea is that the developers should use the language they are most familiar with or the one best suited to the task at hand. The (.NET) language compilers should then convert source code into Intermediate Language (IL) code, which is used by CLR to convert language-independent IL code into the machine code of the device on which it is intended to run. In this way, different languages can be combined to write a single application.
While this description of the basics of the CLR may suggest that making a programming language into .NET is a simple task, this is, of course, not the case. There exist many different kinds of programming languages inspired by quite different programming paradigms, which exploit and exhibit quite different features. Functional programming languages, for instance, deal with higher-order functions, fully parametric polymorphism in data structures and function definitions and lazy evaluation of expressions. These features are typically missing in imperative (object-oriented) languages like C, C++, or C#, which are the natural .NET evolution of previous forms. Fortunately, however, a number of different attempts have successfully fitted functional languages into the .NET platform, namely, SML.NET and Mondrian.
Haskell is a general purpose, purely functional programming language with an impressive number of libraries, extensions, compilers and projects for current and future developments (see the Haskell Communities URL below). During recent years, we have used Haskell to develop several tools that implement the compilers, termination analyses, and declarative debugging techniques available for programming and specification languages like Maude, CafeOBJ, OBJ and XHTML. All these tools target different but complementary purposes, and programming languages would greatly benefit from an integrated framework in which full interaction and combination is possible. As remarked above, .NET has excellent capabilities in this regard. Although the Haskell community is also interested in this, the functional language Haskell has yet not been ported into .NET.
The figure summarizes how it works: our starting point is HaskellDirect (HDirect) which provides a Foreign Function Interface (FFI) for Haskell based in the standard IDL (Interface Definition Language). This permits the specification of a programming interface which does not depend on any concrete programming language. With HDirect it is possible to build COM components in Haskell that are then imported and used by a .NET application by means of a COM DLL (Dynamically Linked Library). In the figure, an input IDL file (Example.idl) containing the appropriate interface information given by the programmer is processed by HDirect. A file (ExampleProxy.hs) is automatically generated. Together with Example.hs (which contains the Haskell code of the COM component), the HDirect library Com.lhs and a Run Time Support (RTS) C module, the COM module is obtained after processing everything with the Glasgow Haskell Compiler (GHC). The output is a COM DLL that requires the use of a Runtime Callable Wrapper (RCW) to become part of a .NET application. The RCW is part of the .NET SDK. We are now able to see the application written in native (unmanaged, in the .NET terminology) Haskell code as managed code, which can be executed by the CLR together with the other components of the .NET Framework.
We are using these ideas to make our software tools available within the .NET framework. Moreover, the
COM DLLs that we are producing are a good basis for easily extending the original capabilities of our Haskell applications.
Haskell Communities: http://www.haskell.org/communities
Salvador Lucas, Universidad Politécnica de Valencia / SpaRCIM