Fpylll makes heavy use to Cython to expose Fplll’s functionality to Python. Fplll, in turn, makes use of C++ templates. For example, `double`

, `long double`

, `dd_real`

(http://crd.lbl.gov/~dhbailey/mpdist/) and `mpfr_t`

(http://www.mpfr.org/) are supported as floating point types. While Cython supports C++ templates, we still have to generate code for all possible instantiations of the C++ templates for Python to use/call. The way I implemented these bindings is showing its limitations. For example, here’s how attribute access to the dimension of the Gram-Schmidt object looks like:

@property def d(self): """ Number of rows of ``B`` (dimension of the lattice). >>> from fpylll import IntegerMatrix, GSO, set_precision >>> A = IntegerMatrix(11, 11) >>> M = GSO.Mat(A) >>> M.d 11 """ if self._type == gso_mpz_d: return self._core.mpz_d.d IF HAVE_LONG_DOUBLE: if self._type == gso_mpz_ld: return self._core.mpz_ld.d if self._type == gso_mpz_dpe: return self._core.mpz_dpe.d IF HAVE_QD: if self._type == gso_mpz_dd: return self._core.mpz_dd.d if self._type == gso_mpz_qd: return self._core.mpz_qd.d if self._type == gso_mpz_mpfr: return self._core.mpz_mpfr.d if self._type == gso_long_d: return self._core.long_d.d IF HAVE_LONG_DOUBLE: if self._type == gso_long_ld: return self._core.long_ld.d if self._type == gso_long_dpe: return self._core.long_dpe.d IF HAVE_QD: if self._type == gso_long_dd: return self._core.long_dd.d if self._type == gso_long_qd: return self._core.long_qd.d if self._type == gso_long_mpfr: return self._core.long_mpfr.d raise RuntimeError("MatGSO object '%s' has no core."%self)

In the code above uppercase `IF`

and `ELSE`

are compile-time conditionals, lowercase `if`

and `else`

are run-time checks. If we wanted to add `Z_NR<double>`

to the list of supported integer types (yep, Fplll supports that), then the above Python approximation of a switch/case statement would grow by a factor 50%. The same would have to be repeated for *every* member function or attribute. There must be a *more better* way.