> <\body> <\hide-preamble> > > <\flat-size> <\std-mmx-code> > <\flat-size> <\std-cpp-code> > \; <\doc-data| with C++>|||<\author-affiliation> Laboratoire d'Informatique UMR 7161 CNRS Campus de l'École polytechnique 91128 Palaiseau Cedex France |>>|<\doc-note> This work has been partly supported by the grant of the Région Ile-de-France. ||<\author-affiliation> Laboratoire d'Informatique UMR 7161 CNRS Campus de l'École polytechnique 91128 Palaiseau Cedex France |>>> \; ||>> <\abstract> In this paper, we give a detailed description of the interface between the language and C++. In particular, we describe the mechanism which allows us to import a C++ template library (which only permits static instantiation) as a fully generic template library. > Until the mid nineties, the development of computer algebra systems tended to exploit advances in the area of programming languages, and sometimes even influenced the design of new languages. The system was developed shortly after the introduction of . Symbolic algebra was an important branch of the artificial intelligence project at during the sixties. During a while, the system was the largest program written in , and motivated the development of better compilers. The system was at the origin of yet another interesting family of computer algebra systems, especially after the introduction of domains and categories as function values and dependent types in and II>. These developments were at the forefront of language design and type theory. later evolved into the system. In the project, later renamed into , the language and compiler were redesigned from scratch and further purified. After this initial period, computer algebra systems have been less keen on exploiting new ideas in language design. One important reason is that a good language for computer algebra is more important for developers than for end users. Indeed, typical end users tend to use computer algebra systems as enhanced pocket calculators, and rarely write programs of substantial complexity themselves. Another reason is specific to the family of systems that grew out of : after IBM's decision to no longer support the development, there has been a long period of uncertainty for developers and users on how the system would evolve. This has discouraged many of the programmers who did care about the novel programming language concepts in these systems. In our opinion, this has led to an unpleasant current situation in computer algebra: there is a dramatic lack of a modern, sound and fast general purpose programming language. The major systems > and > are both interpreted, weakly typed, besides being proprietary and expensive. The system relies on and merely contents itself to glue together various existing libraries and other software components. The absence of modern languages for computer algebra is even more critical whenever performance is required. Nowadays, many important computer algebra libraries (such as , , , , etc.) are directly written in C or C++. Performance issues are also important whenever computer algebra is used in combination with numerical algorithms. We would like to emphasize that high level ideas can be important even for traditionally low level applications. For instance, in a suitable high level language it should be easy to operate on vectors of, say, bit floating point numbers. Unfortunately, would have to be completely redesigned in order to make such a thing possible. For these reasons, we have started the design of a new software, , based on acompiled and strongly typed language, featuring signatures, dependent types, and overloading. is intended as a general purpose language, which supports both functional and imperative programming styles. Although the design has greatly been influenced by II> and its successors and , the type system of contains several novel aspects, as described in. is also a free software, which can be downloaded from |http://www.mathemagix.org>. with C++> One major design goal of the compiler is to admit a good compatibility with existing programming languages. For the moment, we have focussed onC andC++. Indeed, on the one hand, in parallel with the development of the compiler, we have written several high performance C++ template libraries for various basic mathematical structures (polynomials, matrices, series, etc.). On the other hand, the compiler currently generates C++ code. We already stated that was inspired by and in many respects. Some early work on interfacing with C++ was done in the context of . There are two major differences between C++ and which are important in this context. On the one hand, provides support for genuine generic functional programming: not only functions, but also data types can be passed as function arguments. For instance, one may write a routine which takes a ring and an integer on input and which returns the ring |]> \ |]>>. The language also provides support for dependent types: a function may very well take a ring together with an instance of as its arguments or return value. On the other hand, provides support for templates. We may write a routine which takes an instance of an arbitrary type on input and returns . However, and even though there is some work in this direction, it is currently not possible to add the requirement that must be a ring when declaring the template . Hence, the correctness of the template body can only be checked at the moment when the template is instantiated for a particular type . Furthermore, only a finite number of these instantiations can occur in a program or library, and template parameters cannot be passed to functions as objects. In , there is no direct equivalent of templates. Nevertheless, it is possible to implement a function which takes a ring and an instance of on input, and which returns . It thus makes sense to consider the importation of C++ template libraries into . Although contain a precise strategy for realizing such interfacing, part of the interface still had to be written by hand. features two main novelties with respect to the previous work which was done in the context of and . First of all, the language itself admits full support for templates with typed parameters; see our paper on the type system for more details. Secondly, C++ template libraries can be imported into in a straightforward way, without the need to write any non trivial parts of the interface by hand. The ability to transform a C++ template library which only permits static instantiation into a fully generic template library is somewhat surprising. Part of the magic occurs in the specification of the interface itself. Indeed, the interface should in particular provide the missing type information about the parameters of the C++ templates. In this paper, we will describe in more details how this mechanism works. We think that similar techniques can be applied for the generic importation of C++ templates into other languages such as or . It might also be useful for future extensions of C++ itself. The paper is organized as follows. In Section, we describe how to import and export non templated classes and functions from and to . In Section, we briefly recall how genericity works in , and we describe what kind of C++ code is generated by the compiler for generic classes and functions. The core of the paper is Section, where we explain how C++ templates are imported into . In Section we summarize the main C++ libraries that have been interfaced to , and Section contains a conclusion and several ideas for future extensions. Different programming languages have different conventions for compiling programs, organizing projects into libraries, and mechanisms for separate compilation. C++ is particularly complex, since the language does not provide any direct support for the management of big projects. Instead, this task is delegated to separate configuration and Makefile systems, which are responsible for the detection and specification of external and internal dependencies, and the determination of the correct compilation flags. Although these tasks may be facilitated up to a certain extent when using integrated development environments such as > (trademark of Foundation, Inc.), > (trademark of Inc.), or Builder> (trademark of Embarcadero Technologies, Inc.), they usually remain non trivial for projects of a certain size. uses a different philosophy for managing big projects. Roughly speaking, any source file contains all information which is necessary for building the corresponding binary. Consequently, there is no need for external configuration or Makefile systems. Whenever we import functionality from C++ into , our design philosophy implies that we have to specify the necessary instructions for compiling and/or linking the imported code. To this effect, provides special primitives , and for specifying the compilation and linking flags, and C++ header files to be included. For instance, the library of contains implementation for various numerical types. In particular, it contains wrappers for the and libraries with implementations of arbitrary precision integers, rational numbers and floating point numbers. The interface for importing the wrapper for arbitrary precision integers starts as follows: <\mmx-code> foreign cpp import { \ \ cpp_flags \ \ "\0numerix-config --cppflags\0"; \ \ cpp_libs \ \ \ "\0numerix-config --libs\0"; \ \ cpp_include "numerix/integer.hpp"; \ \ ... } On installation of the library, a special script is installed in the user's path. In the above example, we use this script in order to retrieve the compilation and linking flags. Notice also that is the C++ header file for basic arbitrary precision integer arithmetic. Ideally speaking, the bulk of an interface between and a foreign language is simply a dictionary which specifies how concepts in one system should be mapped into the other one. For ordinary classes, functions and constants, there is a direct correspondence between and C++, so the interface is very simple in this case. Assume for instance that we want to map the C++ class from into the class , and import the basic constructors and arithmetic operations on integers. This is done by completing the previous example into: <\mmx-code> foreign cpp import { \ \ cpp_flags \ \ "\0numerix-config --cppflags\0"; \ \ cpp_libs \ \ \ "\0numerix-config --libs\0"; \ \ cpp_include "numerix/integer.hpp"; \; \ \ class Integer == integer; \ \ literal_integer: Literal -\ Integer == \ \ \ \ make_literal_integer; \; \ \ prefix -: Integer -\ Integer == prefix -; \ \ infix +: (Integer, Integer) -\ Integer == infix +; \ \ infix -: (Integer, Integer) -\ Integer == infix -; \ \ infix *: (Integer, Integer) -\ Integer == infix *; \; \ \ ... } The special constructor allows us to write literal integer constants such as using the traditional notation. This literal constructor corresponds to the C++ routine <\cpp-code> integer make_literal_integer (const literal&); where is a special C++ class for string symbols. The syntax of C++ is quite rigid and often directly related to implementation details. For instance, in C++ the notation necessarily presupposes the definition of a class or structure with a field . In , the operator .x> can be defined anywhere. More generally, the language provides a lot of syntactic sugar which allows for a flexible mapping of C++ functionality to .\ Another example is type inheritance. In C++, type inheritance can only be done at the level of class definitions. Furthermore, type inheritance induces a specific low level representation in memory for the corresponding class instances. In , we may declare any type to inherit from a type by defining an operator U>. This operator really acts as a converter with the special property that for any second converter T>, automatically generates the converter U>. This allows for a more high level view of type inheritance. also provides a few built-in type constructors: T> provides adirect equivalent for the C++ reference types, the type T> can be used for writing functions with an arbitrary number of arguments of the same type , and T> corresponds to a stream of coefficients of type . The built-in types T>, T> and T> are automatically mapped to the C++ types, T\> and T\> in definitions of foreign interfaces. The containers T\> and T\> are defined in the C++ support library for , where represents the namespace. When importing a C++ class into , we finally notice that the user should implement a few compulsory operators on . These operators have fixed named in C++ and in , so it is not necessary to explicitly specify them in foreign interfaces. The first compulsory operator is Syntactic>, which converts instances of type into syntactic expression trees which can then be printed in several formats (ASCII, , , etc.). The other compulsory operators are three types of equality (and inequality) tests and the corresponding hash functions. Indeed, distinguishes between ``semantic'' equality, exact ``syntactic'' equality and ``hard'' pointer equality. Finally, any C++ type should provide a default constructor with no arguments. Simple classes and functions can be exported to C++ in a similar way as C++ classes and functions are imported. Assume for instance that we wrote a class with a constructor, accessors, and a few operations on points. Then we may export this functionality to as follows: <\mmx-code> foreign cpp export { \ \ class Point == point; \ \ point: (Double, Double) -\ Point == \ \ \ \ keyword constructor; \ \ postfix .x: Point -\ Double == get_x; \ \ postfix .y: Point -\ Double == get_y; \ \ middle: (Point, Point) -\ Point == middle; } > Before we discuss the importation of C++ template libraries into , let us first describe how to define generic classes and functions in , and how such generic declarations are reflected on the C++ side. provides the construct for the declaration of generic functions. For instance, a simple generic function for the computation of a cube is the following: <\mmx-code> forall (M: Monoid) cube (x: M): M == x*x*x; This function can be applied to any element whose type is a monoid. For instance, we may write <\mmx-code> c: Int == cube 3; The parameters of generic functions are necessarily typed. In our example, the parameter is a type itself and the type of a . The category specifies the requirements which are made upon the type , and a typical declaration would be the following: <\mmx-code> category Monoid == { \ \ infix *: (This, This) -\ This; } Hence, a type is considered to have the structure of a in a given context, as soon as the function M> is defined in this context. Notice that the compiler does not provide any means for checking mathematical axioms that are usually satisfied, such as associativity. Already on this simple example, we notice several important differences with the C++ ``counterpart'' of the declaration of : <\cpp-code> template\typename M\ M cube (const M& x) { return x*x*x; } First of all, C++ does not provide a means for checking that admits the structure of a monoid. Consequently, the correctness of the body can only be checked for actual instantiations of the template. In particular, it is not possible to compile a truly generic version of . By default, always compiles functions such as in a generic way. Let us briefly describe how this is implemented. First of all (and similarly to), the definition of the category gives rise to acorresponding abstract base class on the C++ side: <\cpp-code> class Monoid_rep: public rep_struct { \ \ inline Monoid_rep (); \ \ virtual inline ~Monoid_rep (); \ \ virtual generic mul (const generic&, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ const generic&) const = 0; \ \ ... \ }; A concrete monoid is a ``managed pointer'' ( the objects to which they point are reference counted) to a derived class of with an actual implementation of the multiplication . Instances of the type correspond to managed pointers to objects of arbitrary types. The declaration of gives rise to the following code on the C++ side: <\cpp-code> generic cube (const Monoid& M, const generic& x) { \ \ // x is assumed to contain an object "of type M" \ \ return M-\mul (x, M-\mul (x, x)); } The declaration gives rise to the automatic generation of a class which corresponds to the class with the structure of a: <\mmx-code> struct Int_Ring_rep: public Ring_rep { \ \ ... \ \ generic \ \ mul (const generic& x, const generic& y) const { \ \ \ \ return as_generic\int\ (from_generic\int\ (x) * \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ from_generic\int\ (y)); \ \ } \ \ ... }; The declaration itself corresponds to the following C++ code: <\cpp-code> Monoid Int_Ring= new Int_Ring_rep (); int c= from_generic\int\ \ \ \ \ \ \ \ \ \ (cube (Int_Ring, as_generic\int\ (3))); Notice that we did not generate any specific instantiation of for the type. This may lead to significantly smaller executables with respect to C++ when the function is applied to objects of many different types. Indeed, in the case of C++, a separate instantiation of the function needs to be generated for each of these types. In particular, the function can only be applied to a finite number of types in the course of a program. <\remark> Of course, for very low level types such as , the use of generic functions does imply a non trivial overhead. Nevertheless, since the type is essentially a , the overhead is kept as small as possible. In particular, the overhead is guaranteed to be bounded by a fixed constant. We also notice that provides an experimental keyword which allows for the explicit instantiation of a generic function. <\remark> Although generic functions such as are not instantiated by default, our example shows that we do have to generate special code for converting the type parameter to a . Although this code is essentially trivial, it may become quite voluminous when there are many different types and categories. We are still investigating how to reduce this size as much as possible while keeping the performance overhead small. also allows for the declaration of generic container classes; the user simply has to specify the typed parameters when declaring the class: <\mmx-code> class Complex (R: Ring) == { \ \ re: R; \ \ im: R; \ \ constructor complex (r: R, i: R) == { \ \ \ \ re == r; \ \ \ \ im == i; \ \ } } Again, only the generic version of this class is compiled by default. In particular, the internal representation of the corresponding C++ class is simply a class with two fields and of type . Regarding functions and templates, there are a few other important differences between C++ and : <\enumerate> Dependencies are allowed between function and template parameters and return values, as in the following example: <\mmx-code> forall (R: Ring, M: Module R) infix * (c: R, v: Vector M): Vector M == \ \ [ c * x \| x: M in v ]; Template parameters can be arbitrary types or (not necessarily constant) instances. For instance, one may define a container for vectors with a fixed size. Functions can be used as arguments and as values: <\mmx-code> compose (f: Int -\ Int, g: Int -\ Int) \ \ \ \ \ \ \ \ (x: Int): Int == \ \ f g x; Notice that and admit the same advantages with respect to C++. One of the most interesting aspects of our interface between and C++ is its ability to import C++ template classes and functions. This makes it possible to provide a fully generic interface on top of an existing C++ template library. We notice that the interface between and C++ also provided a strategy for the importation of templates. However, the bulk of the actual work still had to be done by hand. Before coming to the technical details, let us first give a small example of how to import part of the univariate polynomial arithmetic from the C++ template library , which is shipped with : <\mmx-code> foreign cpp import { \ \ ... \ \ class Pol (R: Ring) == polynomial R; \ \ \ \ forall (R: Ring) { \ \ \ \ pol: Tuple R -\> Pol R == keyword constructor; \ \ \ \ upgrade: R -\> Pol R == keyword constructor; \; \ \ \ \ deg: Pol R -\> Int == deg; \ \ \ \ postfix []: (Pol R, Int) -\> R == postfix []; \; \ \ \ \ prefix -: Pol R -\> Pol R == prefix -; \ \ \ \ infix +: (Pol R, Pol R) -\> Pol R == infix +; \ \ \ \ infix -: (Pol R, Pol R) -\> Pol R == infix -; \ \ \ \ infix *: (Pol R, Pol R) -\> Pol R == infix *; \ \ \ \ ... \ \ } } As is clear from this example, the actual syntax for template imports is a straightforward extension of the syntax of usual imports and the syntax of generic declarations on the side. Actually, the above code is still incomplete: in order to make it work, we also have to specify how the ring operations on should be interpreted on the C++ side. This is done by the category toC++: <\mmx-code> foreign cpp export category Ring == { \ \ convert: Int -\> This == keyword constructor; \ \ prefix -: This -\> This == prefix -; \ \ infix +: (This, This) -\> This == infix +; \ \ infix -: (This, This) -\> This == infix -; \ \ infix *: (This, This) -\> This == infix *; } This means that the ring operations in C++ are the constructor from and the usual operators , and. The programmer should make sure that the C++ implementations of the imported templates only rely on these ring operations. The first thing the compiler does with the above C++ export of is the creation of a C++ class capable of representing generic instances of arbitrary ring types. Any mechanism for doing this has two components: we should not only store the actual ring elements, but also the rings themselves to which they belong. This can actually be done in two ways. The most straightforward idea is to represent an instance of a generic ring by a pair >, where is the actual ring (similar to the example of the C++ counterpart of a monoid in Section) and an actual element of . This approach has the advantage of being purely functional, but it requires non trivial modifications on the C++ side. Indeed, whenever a function returns a ring object, we should be able to determine the underlying ring from the input arguments. In the case of afunction such as R>, this means that has to be read off from the coefficients of the input polynomial. But the most straightforward implementation of the zero polynomial does not have any coefficients! In principle, it is possible to tweak all C++ containers so as to guarantee the ability to determine the underlying generic parameters from actual instances. We have actually implemented this idea, but it required a lot of work, and it violates the principle that writing a interface for a C++ template library should essentially be trivial. The second approach is to store the ring in a global variable, whose value will frequently be changed in the course of actual computations. In fact, certain templates might carry more than one parameter of type , in which case we need more than one global ring. For this reason, we chose to implement a container Cat,Nr\> for generic instances of a type of category , with an additional integer parameter for distinguishing between various parameters of the same category. The container Cat,Nr\> is really a wrapper for: <\cpp-code> template\typename Cat, int Nr\ class instance { public: \ \ generic rep; \ \ static Cat Cur; \ \ inline instance (const instance& prg2): \ \ \ \ rep (prg2.rep) {} \ \ inline instance (const generic& prg): \ \ \ \ rep (prg) {} \ \ instance (); \ \ template\typename C1\ instance (const C1& c1); \ \ ... }; For instance, objects of type Ring,2\> are instances of the second generic parameter of templates. The corresponding underlying ring is stored in the global static variable Ring,2\::Cur>. When exporting the category to C++, the compiler automatically generates generic C++ counterparts for the ring operations. For instance, the following multiplication is generated for Ring,Nr\>: <\cpp-code> template\int Nr\ inline instance\Ring,Nr\ operator * (const instance\Ring,Nr\ &a1, \ \ \ \ \ \ \ \ \ \ \ \ const instance\Ring,Nr\ &a2) { \ \ typedef instance\Ring,Nr\ Inst; \ \ return Inst (Inst::Cur-\>mul (a1.rep, a2.rep)); } Since all C++ compilers do not allow us to directly specialize constructors of Cat,Nr\>, we provide a general default constructor of Cat,Nr\> from an arbitrary type, which relies on the in place routine <\cpp-code> void set_as (instance\Ring,Nr\&, const T&); This routine can be specialized for particular categories. For instance, the converter This> from gives rise to following routine, which induces aconstructor for Ring,Nr\> from : <\cpp-code> template\int Nr\ inline void set_as (instance\Ring,Nr\ &ret, const int &a1) { \ \ typedef instance\Ring,Nr\ Inst; \ \ ret = Inst (Inst::Cur-\>cast (a1)); } In this example, cast> represents the function that sends an into an element of the current ring. Now that we have a way to represent arbitrary classes with the structure of a by a C++ type Ring,Nr\>, we are in a position to import arbitrary C++ templates with parameters. This mechanism is best explained on an example. Consider the importation of the routine <\mmx-code> forall (R: Ring) infix *: (Pol R, Pol R) -\ Pol R; The compiler essentially generates the following C++ code for this import: <\cpp-code> polynomial\generic\ mul (const Ring &R, \ \ \ \ \ const polynomial\generic\ &p1, \ \ \ \ \ const polynomial\generic\ &p2) { \ \ typedef instance\Ring,1\ Inst; \ \ Ring old_R= Inst::Cur; \ \ Inst::Cur= R; \ \ polynomial\Inst\ P1= as\polynomial\Inst\ \ (p1); \ \ polynomial\Inst\ P2= as\polynomial\Inst\ \ (p2); \ \ polynomial\Inst\ R = P1 * P2; \ \ polynomial\generic\ r= \ \ \ \ as\polynomial\generic\ \ (R); \ \ Inst::Cur= old_R; \ \ return r; } There are two things to be observed in this code. First of all, for the computation of the actual product , we have made sure that contains the ring corresponding to the coefficients of the generic coefficients of the inputs and. Moreover, the old value of is restored on exit. Secondly, we notice that Inst\> and generic\> have exactly the same internal representation. The template simply casts between these two representations. In the actual code generated by the compiler, these casts are done without any cost, directly on pointers. The above mechanism provides us with a fully generic way to import C++ templates. However, as long as the template parameters are themselves types which were imported from C++, it is usually more efficient to shortcut the above mechanism and directly specialize the templates on the C++ side. For instance, the program <\mmx-code> p: Pol Integer == ...; q: Pol Integer == p * p; is compiled into the following C++ code: <\cpp-code> polynomial\integer\ p= ...; polynomial\integer\ q= p * p; Currently, most of the mathematical features available in are imported from C++ libraries, either of our own or external. In this section, we briefly describe what these libraries provide, and the main issues we encountered. libraries> C++ libraries of the project provide the user with usual data types and mathematical objects. We have already mentioned the library which is devoted to vectors, iterators, lists, hash tables, generic objects, parsers, pretty printers, system commands, and the interface. The library is dedicated to numerical types including integers, modular integers, rational numbers, floating point numbers, complex numbers, intervals, and balls. Univariate polynomials, power series, fraction fields, algebraic numbers, and matrices are provided by the library, completed by for when working with numerical coefficient types. Multivariate polynomials, jets, and power series and gathered in the library. Finally implements analytic functions and numerical homotopy continuation for polynomial system solving. The compiler is itself written in on the top of the library. In order to produce a first binary for this compiler, we designed a mechanism for producing standalone C++ sources from its sources (namely the package). This mechanism is made available to the user via the option of the compiler command. In the following example we illustrate simple calculations with analytic functions. We use the notation > for macro definitions. We first construct the polynomial indeterminate of >, and convert it into the analytic function indeterminate. We display , , and > on the standard output . Internal computations are performed up to bits of precision, but printing is restricted to decimal digits. Analytic functions are displayed as their underlying power series at the origin, for which we set the output order to. <\mmx-code> include "basix/fundamental.mmx"; include "numerix/floating.mmx"; include "numerix/complex.mmx"; include "continewz/analytic.mmx"; \; R ==\> Floating; C ==\> Complex R; Pol ==\> Polynomial C; Afun ==\> Analytic (R, C); bit_precision := 256; \; x: Pol == polynomial (complex (0.0 :\> R), \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ complex (1.0 :\> R)); z: Afun == x :\> Pol; f: Afun == exp z; \; significant_digits := 5; set_output_order (x :\> (Series C), 5); \; mmout \\ "f= " \\ f \\ lf; mmout \\ "f (1)= " \\ f (1.0 :\ C) \\ lf; mmout \\ "f (1 + z)= " \\ move (f, 1.0 :\ C) \\ lf; \; Compiling and running this program in a textual terminal yields: \; <\verbatim> f= 1.0000 + 1.0000 * z + 0.50000 * z^2 + 0.16667 * z^3 + 0.041667 * z^4 + O (z^5) f (1)= 2.7183 f (1 + z)= 2.7183 + 2.7183 * z + 1.3591 * z^2 + 0.45305 * z^3 + 0.11326 * z^4 + O (z^5) Importing a library that is completely external to the project involves several issues. First of all, as mentioned in Section, all the data types to be imported should satisfy mild conditions in order to be properly usable from . Usually, these conditions can easily be satisfied by writing a C++ wrapper whenever necessary. However, when introducing new types and functions, one usually wants them to interact naturally with other librairies. For instance, if several libraries have their own arbitrarily long integer type, straightforward interfaces introduce several types of such integers, leaving to the user the responsibility of the conversions in order to use functions of different librairies within a single program. For C and C++ libraries involving only a finite number of types, we prefer to design lower level interfaces to the C++ libraries of . In this way, we focus on writing efficient converters between external and C++ objects, and then on interfacing new functions at the language level. This is the way we did for instance with lattice reduction of the library, where we mainly had to write converters for integer matrices. Similarly the interface with mainly consists in converters between different representations of multivariate polynomials. When libraries contain many data types, functions, and have their own memory management, the interface quickly becomes tedious. This situation happened with the library. We first created a C++ wrapper of generic objects, so that wrapped objects are reference counted and have memory space allocated by . Before calling a function, the arguments are copied onto the stack. Once the function has terminated, the result from the stack is wrapped into a object. Of course converters for the different representations of integers, rationals, polynomials and matrices were needed. The following example calls the function to compute an integral basis of the number field defined by +x-1001>: <\mmx-code> include "basix/fundamental.mmx"; include "mpari/pari.mmx"; Pol ==\> Polynomial Integer; x: Pol == polynomial (0 :\> Integer, 1 :\> Integer); p: Pol == x^2 + x - 1001; mmout \\ pari_nf_basis p \\ lf; The current mechanism for importing C++ template libraries has been tested for the standard mathematical libraries which are shipped with . For this purpose, it has turned out to be very user friendly, flexible and robust. We think that other languages may develop facilities for the importation of C++ template libraries along similar lines. In the future, our approach may even be useful for adding more genericity to C++ itself. A few points deserve to be developed further: containers and templates>So far, we have focussed on the importation of C++ containers and templates, and only allows for the exportation of simple, non generic functions and non parameterized classes. Nevertheless, it should not be hard to add support for the more general exportation of generic functions and parameterized classes. Of course, the types of the template parameters would be lost in this process and the resulting templates will only allow for static instantiation. The main disadvantage of relying on global variables for storing the current values of template parameters is that this strategy is not thread-safe. In order to allow generic code to be run simultaneously by several threads, the global variables have to be replaced by fast lookup tables which determine the current values of template parameters as a function of the current thread. The current interface only allows for the importation of C++ templates with type parameters. This is not a big limitation, because templates with value parameters are only supported for built-in types and they can only be instantiated for constant values. Nevertheless, it is possible to define auxiliary classes for storing mutable static variables, and use these instead as our template parameters; notice that this is exactly the purpose of the Cat,Nr\> template. In , we also use this mechanism for the implementation of modular arithmetic, with a modulus that can be changed during the execution. After fixing a standard convention for the creation of auxiliary classes, our implementation could be extended to the importation of C++ with ``value parameters'' of this kind. Interfacing libraries often involves portability issues, and also create dependencies that have a risk to be broken in case the library stops being maintained. In the project we considered that functionalities imported from an external library should be implemented even naively directly in (excepted for and ). This represents a certain amount of work (for lattice reduction, Gröbner basis, finite fields, etc), but this eases testing the interfaces and allows the whole software to run on platforms where some libraries are not available. We would like to thank Jean-Charles Faugère for helping us in the interface with , and also Karim Belabas and Bill Allombert for their precious advices in the design of our interface with the library. <\bibliography|bib|plain|mmx_cpp> <\bib-list|10> Axiom computer algebra system. Software available from . E.Bond, M.Auslander, S.Grisoff, R.Kenney, M.Myszewski, J.Sammet, R.Tobey, and S.Zilles. FORMAC an experimental formula manipulation compiler. In , ACM '64, pages 112.101--112.1019, New York, NY, USA, 1964. ACM. D.Cade, X.Pujol, and D.Stehlé. Fplll, library for LLL-reduction of Euclidean lattices. Software available from , 1998. Y.Chicha, F.Defaix, and S.M. Watt. Automation of the Aldor/C++ interface: User's guide. Technical Report Research Report D2.2.2c, FRISCO Consoritum, 1999. Available from . J.-C. Faugère. FGb: A Library for Computing Gröbner Bases. In K.Fukuda, J.vander Hoeven, M.Joswig, and N.Takayama, editors, , volume 6327 of , pages 84--87. Springer Berlin / Heidelberg, 2010. L.Fousse, G.Hanrot, V.Lefèvre, P.Pélissier, and P.Zimmermann. MPFR: A multiple-precision binary floating-point library with correct rounding. , 33(2), 2007. Software available from . M.Gaëtano and S.M. Watt. An object model correspondence for Aldor and C++. Technical Report Research Report D2.2.1, FRISCO Consortium, 1997. Available from . R.Garcia, J.Järvi, A.Lumsdaine, J.G. Siek, and J.Willcock. A comparative study of language support for generic programming. In , October 2003. J.Y. Girard. Une extension de l'interprétation de Gödel à l'analyse, et son application à l'élimination de coupures dans l'analyse et la théorie des types. In J.E. Fenstad, editor, , pages 63--92. North-Holland Publishing Co., 1971. T.Granlund and the GMP development team. GNU MP: The GNU Multiple Precision Arithmetic Library. Software available from , 1991. J.H. Griesmer, R.D. Jenks, and D.Y.Y. Yun. . Computer Science Department monograph series. IBM Research Division, 1975. W.Hart. An introduction to Flint. In K.Fukuda, J.vander Hoeven, M.Joswig, and N.Takayama, editors, , volume 6327 of , pages 88--91. Springer Berlin / Heidelberg, 2010. J.vander Hoeven. Overview of the Mathemagix type system. In , Beijing, China, October 2012. Available from . J.vander Hoeven, G.Lecerf, B.Mourrain, etal. Mathemagix, 2002. Software available from . J.vander Hoeven, G.Lecerf, B.Mourrain, Ph. Trébuchet, J.Berthomieu, D.Diatta, and A.Manzaflaris. Mathemagix, the quest of modularity and efficiency for symbolic and certified numeric computation. , 45(3/4):186--188, 2012. R.D. Jenks. The SCRATCHPAD language. , 9(4):101--111, 1974. R.D. Jenks. MODLISP -- an introduction (invited). In , EUROSAM '79, pages 466--480, London, UK, UK, 1979. Springer-Verlag. R.D. Jenks and R.Sutor. . Springer-Verlag, New York, NY, USA, 1992. R.D. Jenks and B.M. Trager. A language for computational algebra. , 16(11):22--29, 1981. Maple user manual. Toronto: Maplesoft, a division of Waterloo Maple Inc., 2005--2012. Maple is a trademark of Waterloo Maple Inc. . W.A. Martin and R.J. Fateman. The MACSYMA system. In , SYMSAC '71, pages 59--75, New York, NY, USA, 1971. ACM. P.Martin-Löf. Constructive mathematics and computer programming. , pages 153--175, 1979. Maxima, a computer algebra system (free version). Software available from , 2011. R.Milner. A theory of type polymorphism in programming. , 17:348--375, 1978. J.Moses. Macsyma: A personal history. , 47(2):123--130, 2012. W.A. Stein etal. . The Sage Development Team, 2004. Software available from . R.S. Sutor and R.D. Jenks. The type inference and coercion facilities in the Scratchpad II interpreter. , 22(7):56--63, 1987. The PARIGroup, Bordeaux. , 2012. Software available from . S.Watt, P.A. Broadbery, S.S. Dooley, P.Iglio, S.C. Morrison, J.M. Steinbach, and R.S. Sutor. A first report on the A# compiler. In , ISSAC '94, pages 25--31, New York, NY, USA, 1994. ACM. S.Watt etal. Aldor programming language. Software available from , 1994. S.Wolfram. . Addison-Wesley, second edition, 1991. Mathematica is a trademark of Wolfram Research, Inc. . <\initial> <\collection> <\references> <\collection> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > <\auxiliary> <\collection> <\associate|bib> Formac MF71 Maxima Mos12 Scratchpad Jen74 Jen79 JT81 SJ87 Gir71 ML79 Mil78 Axiom JS92 Watt94 Aldor Mathematica Maple Sage GMP MPFR Flint FGb vdH:mmx vdH:issac11 vdH:mmxtyping CDW99 GW97 GJLSV03 CDW99 GW97 vdH:mmxtyping MPFR GMP CDW99 GW97 CDW99 GW97 vdH:issac11 fplll FGb PARI2 <\associate|toc> |math-font-series||1Introduction> |.>>>>|> |1.1Motivation behind |Mathemagix> |.>>>>|> > |1.2Interfacing |Mathemagix> with C++ |.>>>>|> > |math-font-series||2Basic interface principles to C++> |.>>>>|> |2.1Preparing imports from C++ |.>>>>|> > |2.2Importing simple classes and functions |.>>>>|> > |2.3Syntactic sugar |.>>>>|> > |2.4Compulsory functions |.>>>>|> > |2.5Exporting basic functionality to C++ |.>>>>|> > |math-font-series||3Categories and genericity in |Mathemagix>> |.>>>>|> |math-font-series||4Importing C++ containers and templates> |.>>>>|> |4.1Example of a generic C++ import |.>>>>|> > |4.2Generation of generic instance classes |.>>>>|> > |4.3Importing C++ templates |.>>>>|> > |math-font-series||5Currently interfaced C++ libraries> |.>>>>|> |5.1|Mathemagix> libraries |.>>>>|> > |5.2External libraries |.>>>>|> > |math-font-series||6Conclusion and future extensions> |.>>>>|> |Exporting |Mathemagix> containers and templates |.>>>>|> > |Multi-threading |.>>>>|> > |Non class parameters |.>>>>|> > |Interfacing more libraries |.>>>>|> > |Acknowledgments |.>>>>|> > |math-font-series||Bibliography> |.>>>>|>