[Haskell] Re: ANN: Efficient, dynamically compiled, lazy functional semantics on JVM, having tight integration with the Java language

apfelmus at quantentunnel.de apfelmus at quantentunnel.de
Fri Sep 29 09:28:04 EDT 2006

I'd like to summarize why you chose to create a new language instead of
a Haskell->JVM backend and to throw in ideas which address these points
in Haskell.

> 1. Java
> 2) Why did we create CAL instead of just using Haskell?
> 2)b) CAL is a low-risk choice for business applications
> 2)c) Programs do not need to be entirely written,
>   or even primarily written in CAL
> 2)d) CAL seeks to be as comfortable as possible for mainstream
>   developers to use
> 3. Simple syntax, appropriate features

The functional stuff should be integrated as tightly as possible with
Java which means a foreign function interface that blurs the lines and
using the JVM runtime and its garbage collector.

When it goes to marshaling, the Haskell FFI does not blur anything.
Perhaps this could be remedied by adding a foreign data interface:

foreign data c-struct Foo { bar :: Int, bar2 :: Bool }
foreign export foobar :: Foo -> Int
foobar f = (if bar2 f then id else negate) $ bar f

foreign data java-object Foo { bar :: Int, bar2 :: Bool, foobar :: Foo
-> Int}

so that foreign data things become first class values.

In the paper "Strongly typed memory areas", something similar is done
for memory areas. The type of such areas gets a special kind different
from *. For conservative reasons, this could be done here, too. With
some form of kind polymorphism, one could trash all CInt and the like
and have the kind annotation (Int :: forall * . *). The function (+)
f.i. could then be specialized for (CInt :: C) and Haskell (Int :: *).

The main problem is an embedding of System F into Java (or any other
foreign language, strictly speaking -fvia-C already provides such an
embedding) with the additional property that "normal functions" are
exported *without marshaling*. Viewed as a mathematical map, the
embedding should be a projection, so to speak. Maybe a kind system can
help: everything that can be exported transparently gets a "simple" kind
and is automatically exported/imported. So (foreign export) and (foreign
import) should be dropped altogether. Those things using System F
features (polymorphism, rank-n-types etc.) get a complicated kind which
clearly marks them as "to be marshaled".

One tricky point is how to marshal laziness and it looks like Business
Objects solved this in a very pragmatic way (i.e. Java objects are
always strict)?
The point
> 3. CAL performance
also falls under this category: no marshaling means compiling to loops etc.

To summarize, there is a need for a very sophisticated foreign language
interface / foreign run-time system integration.

> 2. Dynamic compilation

With lambdabot, "Dynamic applications from the ground up" and
hs-plugins, there are some things underway.

Clean seems to offer a potent solution, where one can pattern match
against types:

foo :: Dynamic -> Dynamic -> Dynamic
foo (Dyn f :: a -> b) (Dyn x :: a) = Dyn (f a) :: b
foo _ _ = error "foo falls through"

Values of type Dynamic are/can be serialized which allows one to
serialize functions (!). I don't know exactly, but I think its even
possible to use the Clean compiler as a library and compile things at
runtime to values of type Dynamic. The paper "Towards a strongly typed
operating system" mentions some things in that direction.

Maybe there is no need for another language construct to allow the
pattern matching of types, some approach to generic programming à la
Hinze already could do things like that. Somehow, it becomes a problem
of representing and manipulating types at runtime.

Leaving aside the syntactic differences, I think that these two points
are actually the essence of what separates CAL from Haskell?

A minor motivation why busy enterprise business integration applications
need the two mentioned features might be:
1. Java is the "official machine architecture of business applications".
Point. At least, so it seems to me. The need for a foreign language
interface (software reuse!) is obvious, then.
2. Software for a banking-house that handles all the financial
transactions just cannot be shut down for bug fixing or rewrites. The
same goes for lambdabot :)


More information about the Haskell mailing list