[Haskell-cafe] GHC for .NET?
Don Syme
dsyme at microsoft.com
Wed Jan 5 06:58:14 EST 2005
> Next, you need to think about how to inter-operate with .NET
> libraries. You don't really want to write "foreign import..."
> for each and every import. You'd like GHC to read the CLR
> meta-data directly. But there are lots of tricky issues here;
> see the paper that Mark Shields and I wrote about "Object-oriented
> style overloading for Haskell".
>From what I've seen, .NET interoperability (i.e. API access) is too
important to simply encode into a language using existing language
mechanisms. Let's be honest: there isn't a single language that has
succeeded in giving decent inter-operability without modifying and/or
substantially extending the language (there are several faithful
language implementations, e.g. OCamlIL, but these efforts have not
covered interoperability). I really don't see why Haskell will be any
different.
Of course no design group _wants_ to change or extend their existing
language, and on the whole they do not end up doing it because of
limitations in the CLR. Instead they eventually come around to the fact
that there are big benefits to providing .NET API access that "feels
right" to the programmer, rather than forcing the programmer to use
arcane encodings into existing language constructs, even if that means
changing and/or extending the language.
Some see this as a weakness of the .NET approach to interoperability
(because it forces too much on each language, e.g. generics, classes,
interfaces, properties, namespaces). Some also see it as its strength
(because it gives the API designer a better set of tools, all of which
will be understood by each language - at least better when compared to
COM or C). Many in the first camp are language designers and/or
implementers, while many in the second are working programming teams who
are very happy to be able to use high-level, extensible APIs from a
number of programming languages. You can argue over whether .NET has
made good choices for the primitives used to express APIs (some hate
classes, some hate generics), but the fundamental principle won't
change: if you want rich common constructs for expressing APIs, then the
language designers and implementers pay the price (by having to support
a common set of non-trivial constructs), while the programmers reap the
benefits.
Understandably, however, there is real resistance in language
communities like Haskell's to changing or even extending a language for
the sake of interoperability and API access: instead people work
incredibly hard to encode interoperability via existing mechanisms. In
the end, whoever picks up the burden of doing Haskell.NET will face the
same unenviable choice that every other .NET language design group has
faced:
(a) do you modify and/or extend the language to make "the nicest
possible Haskell-like language in the context of .NET"
or (b) do you implement Haskell faithfully without language extensions,
but where using the .NET libraries is in practice somewhat arcane and
unpleasant, probably sufficiently so that you'll be unable to attract
.NET-savvy programmers to your language.
Personally I think language designs in space (a) are more interesting,
since perfectly good native implementations of Haskell are already
available on most platforms. I also think you learn a lot more by
trying to create something new, and you give yourself the maximum
possible long-term chance of rivalling other .NET languages (which I
think should be an important goal for a Haskell.NET). But people
devoted to the Haskell standard will no doubt prefer (b), as may people
whose main interest is in presenting .NET functionality in a
Haskell-esque way (e.g. via Fran-like libraries).
Finally, all this just deals with "import" interoperability. Nearly as
important in practice is "export" interoperability, i.e. how is your
Haskell code going to look to other .NET languages, and is it going to
be usable by those languages.
Just my 2c worth for the New Year :-)
Cheers
Don
-----Original Message-----
From: Simon Peyton-Jones
Sent: 04 January 2005 12:18
To: Don Syme; John Goerzen; haskell-cafe at haskell.org
Cc: GHC users
Subject: RE: [Haskell-cafe] GHC for .NET?
| "The GHC compiler for .NET is currently under development at
| Microsoft Research, Cambridge".
|
| Hmm. That location sounds familiar :-) Does anyone know if this is
| actually going to happen? Or if there's any code anywhere, however
| experimental, to try?
It'd make a lot of sense to give GHC a .NET back end, and it's a
question that comes up regularly. The reason that we haven't done it
here, at GHC HQ, is because it's a more substantial undertaking than
might at first appear (see below). Furthermore, it'd permanently add a
complete new back-end platform for us to maintain. Given our rather
limited development effort (= Simon and me), we have so far not bitten
the bullet, and we have no immediate plans to do so.
It'd be a good, well-defined project for someone else to tackle, and
there is some good groundwork already done:
* Sigbjorn Finne did a simple interop implementation that allows a
Haskell program
to be compiled to native code (as now) but to call .NET programs
via a variant
of the FFI. I don't think this work is in active use, and I'd
be surprised if it worked
out of the box, but it could probably be revived with modest
effort
* Andre Santos and his colleagues at UFPE in Brazil are working on a
.NET back end,
that generates CLR IL, though I don't know where they are up to.
* GHC.Net would be extra attractive if there was a Visual Studio
integration for GHC.
Substantial progress on this has been made in 2004 by Simon
Marlow, Krasimir
Angelov, and Andre Santos and colleagues.
There may be others that I don't know of. If anyone wants to join in
this effort, do contact the above folk. And please keep us informed!
Simon
Here's a summary of why it's a non-trivial thing to do:
- The first thing is to generate native CLR Intermediate Language (IL).
That's not
really hard. Requires thinking about representations for thunks
and functions,
and it may not be particularly efficient, but it can surely be
done. An open
question is about whether to generate verifiable IL or not. The
trouble here
is that Haskell's type system is more expressive than the CLR's
in some ways,
notably the use of higher-kinded type variables. So, to
generate verifiable IL
one is bound to need some run-time casts, and it's not clear how
to minimise
these.
At first blush this is *all* you need do. But it isn't!
- Next, you need to think about how to inter-operate with .NET
libraries. You don't
really want to write "foreign import..." for each and every
import. You'd like
GHC to read the CLR meta-data directly. But there are lots of
tricky issues here;
see the paper that Mark Shields and I wrote about
"Object-oriented style overloading
for Haskell".
- Now you need to figure out how to implement GHC's primitive
operations:
the I/O monad
arbitrary precision arithmetic
concurrency
exceptions
finalisers
stable pointers
software transactional memory
Not all of these are necessary, of course, but many are used in the
libraries. The CLR
supports many of them (e.g. concurrency) but with a very different
cost model.
- Last, you have to figure out what to do for the libraries. GHC has a
pretty large
library, and you either have to implement the primops on which
the library
is based (see previous point), or re-implement it. For example,
GHC's
implementation of I/O uses mutable state, concurrency, and more
besides.
For each module, you need to decide either to re-implement it
using .NET
primitives, or to implement the stuff the module is based on.
These challenges are mostly broad rather than deep. But to get a
production quality implementation that runs a substantial majority of
Haskell programs "out of the box" requires a decent stab at all of them.
More information about the Haskell-Cafe
mailing list