CEP 522 - Fused Types, a.k.a implicit interfaces
Status: None
Implementation status: None
Often one wants to write a single piece of code that can operate on several different types. C++ accomplishes this with templates, which are powerful but add an enormous level of complexity to the language. There is also the issue of requiring implementations to be in header files and re-compiled for every computational unit. Java generics can only operate on boxed values, which is unsuitable for scientific computation (though one does get type safety vs. typing everything as object). This CEP is an alternative to full parameterized types for the common usecase where the set of needed types is small and fixed ahead of time.
Fused types
There will be a new "fused type" which represents an implicit interface, the intersection of its component types. E.g.
ctypedef cython.fused_type(float, double, long double) floating
Arithmetic can be done iff all specifications can be done, common attributes accessed.
Functions
One could write
cdef floating f(floating x, floating y):
cdef floating tmp = ...
if typeof(x) is double: # or floating is double or isinstance(x, double)
[double specific code, methods/attributes specific to double can be accessed here]
return x + ywhich would get expanded out into *2* specializations. Calling f(1.0f, 2) or f(1.0f, 2.0) would dispatch to the float and double specification respectively. f[double] would obtain an exact specialization (in both Cython and Python space).
cdef floating f(floating x, integral y):
cdef floating tmp = ...
return x + ywould create 4 specializations.
Classes
One could also write
cdef class A:
cdef floating x
cdef __init__(self):
self.x = 1Again, A[double] would produce a specialization, and could be used for instantiation. The specialization could be inferred, if possible, from constructor arguments. If there are multiple fused types, we may require the declaration to be cdef class A[floating, integral] to force an ordering for access purposes.
Special cases
It may make sense to provide some special types.
floating -- float, double, long double
integral -- all int types
numeric -- all numeric types
cdef complex floating supported if floating is a numeric type
Open issues
- What do do with external types? Switch statement to the right dispatch based on their size (the way python object conversion is done)?
- signed/unsigned integral types?
