Haskell and Maple FFI

Rafael Martinez Torres rmartine at fdi.ucm.es
Mon Sep 20 10:46:45 EDT 2004

> Making it possible to call Maple would be very cool.  Can you give more detail
> about Open Maple?

 OpenMaple is a suite of functions that allows you to access Maple
algorithms and data structures in your compiled C program. This is the
reverse of ExternalCalling, which allows access to C data structures from Maple.

> If I was doing this, I'd start by writing some C code that interfaces to
> Maple.  After that works, I'd translate it into Haskell.  That is, I would
> use the FFI to invoke the Maple FFI functions for pushing arguments, popping
> results, etc. and use the the FFI libraries which have lots of useful
> functions for marshaling arguments from Haskell to other formats.

> Start with something simple (e.g., a single argument function like 'sin'),
> prototype in C, translate to Haskell.  At this point, don't worry too much
> about the fact that the simplest function call seems to require 10-20 lines
> of code - we can suggest ways to fix that.  Keep trying new features (2
> arguments, strings, calling both Haskell->Maple and Maple->Haskell, etc.)
> [The Open Maple manual probably has a list of examples used to illustrate the
> interface - start by doing all those.]  If it isn't obvious how to do it or
> it just won't work, step back and write a prototype in C.

Examples ( taken from Open Maple . kv stands for a handle for the Maple

    #include "maplec.h"

    ALGEB M_DECL MyStats( MKernelVector kv, ALGEB *args )
        ALGEB mean, sd, f;

        if( 1 != MapleNumArgs(kv,(ALGEB)args) ) {
            MapleRaiseError(kv,"one argument expected");
            return( NULL );
        if( !IsMapleList(kv,args[1]) ) {
            MapleRaiseError(kv,"list expected");
            return( NULL );

        /* get the name of the function to call, and compute the mean */
        f = EvalMapleStatement(kv,"stats[describe,mean]:");
        mean = EvalMapleProc(kv,f,1,args[1]);

        /* compute the standard deviation using a different method -- build
           up the function object and call MapleEval on it
        f = EvalMapleStatement(kv,"stats[describe,standarddeviation]:");
        f = ToMapleFunction(kv,f,1,args[1]);
        sd = MapleEval(kv,f);

        /* return the pair */
        return( ToMapleExpressionSequence(kv,2,mean,sd) );

Is it what do you mean ?

Then, I could use the maple kernel under a "ccall" convention, I mean:

foreign export ccall "MyStats" MyStats :: MKenelVector -> [Args] ...

> Ask us as you run into problems.

Rather what I would like is to write code in a file foo.maple and then,
when invoking the function, to invoke the key funcion in C:

sd = MapleEval(kv,f)

IDEA : the RTS in the startup function should initialize
and instance of the Maple kernel (kv) given a (*.maple) file (exactly as a
JVM loads the .class file) , once  detected a maple call  at compiling time. The (*.maple)
should be provided by the end user, as when a dynamic library is provided.
OpenMaple allows the C-programmer to initialize the Maple Interpreter;

Further calls to Maple-wrapper functions will act only as calls the
"MapleEval" function, provided parameters... Once you have setup the
Maple handle, it seems like to deal with a C library like HOPenGL

Rigth ?

I don't know on Marshalling/UnMarshalling...

> Once you can do all that, there's a bunch of tricks you can play with
> typeclasses to reduce the number of lines of code you have to write from
> 10-20 lines down to just one or two.  (Ross Paterson has a very nice scheme
> for doing this - but I can't find it in the mail archives at the moment.)
> --
> Alastair Reid

More information about the FFI mailing list