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

Julien Fischer juliensf at csse.unimelb.edu.au
Sat Jul 8 00:48:32 AEST 2006

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.

> > (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.

> 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

> 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.

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