[m-dev.] completing the new foreign language interface

Jonathan Morgan jonmmorgan at gmail.com
Sat Jul 8 20:17:31 AEST 2006

On 7/8/06, Julien Fischer <juliensf at csse.unimelb.edu.au> wrote:
> On Fri, 7 Jul 2006, Jonathan Morgan wrote:
> > On 7/7/06, Julien Fischer <juliensf at csse.unimelb.edu.au> wrote:
> > > Currently the reasons given in the reference manual for not deprecating the
> > > old C interface are that the new foreign language interface has no equivalent
> > > for `pragma import' and `pragma export'.  (It also says that the new one isn't
> > > as well tested as the old one but for the most part that's not really valid
> > > anymore.)
> > >
> > > In order to "complete" the new foreign language interface (at least to a point
> > > where we can start to get rid of the old one), I am proposing the following:
> > >
> > > (1) that the new interface does not need an equivalent for `pragma import'.
> >
> > I have never used it, but it could provide a useful shorthand.
> The existing version of pragma import is rather poorly defined in the
> reference manual especially with regard to purity.  Also it to be useful it
> would need the ability to specify imports for different backends and also all
> of the foreign code attributes.  Once you add all of that it's beginning to
> get indistinguishable from a foreign_proc anyway.
> As for it being a useful shorthand, it's pretty much unused in most of the
> substantial bodies of Mercury code that I have access to.  A quick grep
> through the compiler sources reveals:
>         standard library (80 KLOC)
>          - 0 pragma imports
>          - 481 pragma foreign_proc("C", ...)
>         compiler (320 KLOC)
>          - 7 pragma imports
>          - 124 pragma foreign_proc("C", ...)
>         debugger (20 KLOC)
>          - 0 pragma imports
>          - 34 pragma foreign_proc("C", ...)
>         deep profiler (15 KLOC)
>          - 0 pragma imports
>          - 28 foreign_proc("C", ...)
> I couldn't find any uses of it in the G12 source code either.
> Granted not all of those foreign_procs will be pragma import equivalents.
> In short, the existing form will go with the old C interface and I'm not
> convinced that there is any point replacing it.

I'm willing to accept that.

> > > (2) that we introduce `pragma foreign_export' declarations to the new
> > >     interface.  These carry out the function of `pragma export' in the old
> > >     interface but are intended to work with backends other than the C
> > >     backends.
> >
> > I have used pragma export with the IL backend (both C# and IL).  It
> > seemed to work OK.
> I believe a lot of the machinary necessary to implement it for the .NET
> backend is already there so the fact that it does _something_ is not really
> all that suprising.  (In fact section of the reference manual makes
> mention of pragma export in the context of IL foreign types - although that
> looks like a cut-and-paste error **).
> Furthermore, "seems to work" and "does work" are different things.  Notably
> there's nothing currently in the reference manual that tells me how it
> *should* work for the .NET backend.
> ** in fact this is almost certain; there are a number of comments in the
> library source code mentioning that it isn't implemented for the .NET backend.
> > > (2)  Unlike (1) we definitely need this.  I'm proposing that in introducing
> > >      `pragma foreign_export' we make a fairly minimal change and just require
> > >      that a language be specified in addition to the other information that
> > >      is already in export pragmas.
> > >
> > >      foreign_export pragmas would work in a similar fashion to the other
> > >      `foreign_*' pragmas. i.e they would only be considered by the compiler
> > >      when compiling to a compatible backend, so that
> > >      `:- pragma foreign_export("C", ...)' would only apply for the C backends,
> > >      `:- pragma foreign_export("Java", ...) for the Java backend etc.
> > >
> > >      For the .NET backend, where we support several possible foreign languages,
> > >      we would use the same technique that we do with foreign_procs.
> > >      C# and MC++ exports would be hoisted into separate C# and MC++ files
> > >      and compiled separately.
> >
> > Currently pragma export under the .NET backend make the exported
> > function part of the generated IL code, wrapped in the mercury_code
> > class.  This shouldn't cause any problems for users, and can be
> > accessed from C# and MC++ code.

On the one hand, exports could be restricted to IL, in the same way as
foreign_types are restricted to IL.  On the other hand it certainly
would be more convenient to access exports in the current module,
rather than having to go through to the IL module (as is currently the

> > In what situations would it be necessary to export different functionality
> > to different backends?
> Be able to export a procedure under different names to different backends
> would be one obvious example.
> Another matter is that we may eventually want to specify attributes for the
> foreign_export declaration, similar to the way we do with foreign_decls and
> foreign_procs.
> > Does it really matter if functionality is just exported to all backends?
> My view is that if a backend doesn't need a procedure exported then it
> shouldn't be exported.
> > It is obviously necessary to have different implementations
> > for the different backends - I don't think that it is so necessary to
> > have different exports for the different backends, and it could be
> > much more cumbersome.
> That's overstating the case.  Exporting something to all three targets is
> going to be a matter of two more lines in most cases.

Make that two more lines per exported procedure.  However, probably
not too bad.  These things are probably merely academic concerns, as,
to the best of my knowledge, both the IL backend and the Java backend
are currently broken.

However, my fear is that these things could make the dependency step
for IL even worse than it currently is.  Currently mmc --make will
refuse to build anything with C# foreign code, as it complains of a
forbidden foreign_import_module cycle.  With the ability to export
your Mercury procedure to a C# file it would require the C# file to
call the IL file in order to expose the exported procedure, while the
IL file must call the C# file in order to generate its foreign proc
(this happens with pragma export too).  .NET and mmake are able to
handle such dependencies, but mmc --make is not.  The real problem is
that we have one logical module being split into two or three modules
based on language, and I don't know of any fix.

I'm certainly in favour of removing the old foreign interface.

mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au

More information about the developers mailing list