[m-dev.] pragma foreign_export_enum

Zoltan Somogyi zoltan.somogyi at runbox.com
Tue Nov 28 18:06:31 AEDT 2017

On Tue, 28 Nov 2017 11:58:15 +1100 (AEDT), Julien Fischer <jfischer at opturion.com> wrote:
> > I have been working on making the infrastructure for type representations
> > more flexible, since this is needed to enable more compact data representations.
> Are there some concrete proposals for what these more compact data
> representations are?

One is extending the current algorithm that puts several adjacent enum arguments
of a term into a single word to also treat {int,uint}{8,16,32} arguments as
sub-word-sized entities that can be packed into a single 64 bit word.
(Mutatis mutandis for 32 bit platforms.)

Another is Peter's proposal in Mantis 432: representing terms such as
f(bool, bool) in a single word by storing the sub-word arguments
next to the primary tag. And the obvious extension with small ints.

A third is to make packing sub-word-sized arguments together more
effective by reordering the arguments to put them next to each other.
Currently, a term such as f(bool, int, bool) requires a three word cell;
reordering it as f(int, bool, bool) reduces that to two.

A fourth is a version of Mantis 432 that would be effective only
in the presence of such reordering, and when the type has many
non-constant function symbols: storing sub-word-sized arguments
next to the *secondary* tag in heap cells.

> > In the process, I have come across something odd that I need resolved.
> >
> > Section 14.5 of the language reference manual, for foreign_export_enum pragmas,
> > states (near the end) that
> >
> > "It is an error if the mapping between constructors and symbolic names
> > does not form a bijection. A program can contain multiple ‘pragma foreign_export_enum’
> > declarations for a single Mercury type. The implementation is not required to check
> > that the symbolic names generated by separate ‘pragma foreign_export_enum’
> > declarations are unique."
> >
> > The second sentence is a bit ambiguous; it does not say whether you can have
> > code like this:
> >
> > :- pragma foreign_export_enum("C", type_foo/0, [prefix("FOO_")]).
> > :- pragma foreign_export_enum("C", type_foo/0, [prefix("BAR_")]).
> >
> > or whether having two foreign_export_enum (fee for short) pragmas for the
> > same type is allowed ONLY if they are for different target languages.
> The intention was that you may have multiple foreign_export_enum pragmas
> for the same type as above.  If you do, then the corresponding symbols
> in each set are synonyms.
> The bit about the bijection was intended to refer to the mapping
> established by each fee pragma _in isolation_; they are not meant be
> considered collectively.

That was not at all clear from the wording, which I suspect was cut-and-pasted
from the section of foreign_enums. I will change the description.

Any objection to moving the documentation of foreign_enum before
the documentation of foreign_export_enum, i.e. swapping the order
of 14.5 and 14.6? I think that would make the distinction between the two
easier to describe.
> If the foreign language API exported by a Mercury module is
> transitioning from one set of names to another, being able to provide
> both sets is useful for backwards compatability with existing foreign
> code.  (In the absence of allowing multiple fee pragmas, such backwards
> compatibility would need to be defined by hand in the foreign code.)

I will mention this in my rewrite.

> > Having both a foreign_enum and a foreign_export_enum pragma
> > for the same type and the same language is required to be allowed by
> > tests/hard_coded/exported_foreign_enum.m, though I can't see anything
> > in the reference manual that expressly allows it. And having both
> > will generate more than one target language name for a given constructor,
> > just like multiple fee pragmas would.
> Note that fee pragams are not restricted to the modules defining their
> subject Mercury type.  That again, was intentional: if I have a third
> party library, I may want to export the constructors of one of its
> enumeration types to a foreign language even though the library code
> itself does not do that.  As a user of the third party libray I don't
> care if the enumeration is defined via a foreign_enum pragma or not.
> (In principle I may not even now that a Mercury enumeration is a
> foreign enum, although in practice I could dig into the interface
> files and find out.)

Yes, I knew that. The "nothing in the reference manual that expressly allows it"
part was meant as a criticism of the reference manual, not as a proposal
to change the language to disallow that situation.


More information about the developers mailing list