-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
enhancements overloading
- Status: Open - partially superceeded by CEP 522 - Fused Types
- Implementation status: Not started
- Comments: This is part of DagSverreSeljebotn's GSoC 2008 project proposal
Function/method overloading is about calling different functions depending on the types of the arguments:
cdef int min(int a, int b): return a if a <= b else b cdef float min(float a, float b): return a if a <= b else b
So, whenever min
is called the arguments are first checked for an exact match, then automatic conversions are tried until an unambigious match is found. If the match is ambigious or there is no match it is a compile-time error.
As C++ developers know, it is almost a necessity when working with typed code if one is working with multiple data types. These kind of functions often also can replace macros.
Also, when combined with templates it makes it possible to write Python-like generic "duck-typed" code that still is efficient.
The proposal is to restrict this to cdef functions only, and doesn't do anything to figure out which type of "object" to influence on which method to choose.
- If Python functions should be supported these are the issues:
-
- The exported Python name can not be mangled (and the callers don't pass typed arguments anyway), so a Python wrapper function would have to keep its name.
- It would then be difficult for the wrapper to figure out which overloaded C function to call.
While overloaded Python functions could in theory be supported by generating run-time checks on the arguments to see in which direction they would most readily convert, this is probably better left for explicit code/manual wrappers.
In C++ the return type is not allowed (as in many situations the return type might be ignored and unspecificed while parameters are always mandatory). One might want to be consistent with this.
However, allowing it would allow a simple __coerce__
operator declaration for declaring possible coercions (C++ handles this by having the typename in the method signature for the cast operator, double operator double()
, which is basically a way of allowing overloading on return types in that specific case).
Also it would solve things like the getitem operator needing different return types depending on parameters (the method to use would be decided on the needed return type, and one would use assertions on the method arguments in addition).
- Making this work with Python duck-typing style template code (see the templates spec) leads to some complexity:
-
- A single template method may contain code to return multiple types at run-time depending on parameters and the environment (ie if writing in Python duck-typing style)
- With overloaded return types, the form of the call decides the type of the return value, and then a copy of the method with this return type is compiled...
- ...which will give problems for the returns having the wrong type.
- A proposed solution then is to simply replace the return statements returning a value with the wrong type with a run-time instruction to raise a TypeError, since control should not have reached that place. The exact set of returns statements replaced with raising a TypeError will be different for each template instantiation.
Overloaded functions must simply have their names mangled in C output, and calls replaced correspondingly.
Also, if outputting C++ code, one could simply leave the name mangling to C++ (ie an optional mode for when outputting C++ code that would integrate better with debuggers etc. - outputting C code should still be supported though).
Potential problems: Using a name mangling policy that will work across different compiled modules will probably be difficult, especially since we (unlike C++) don't know the full type of typedef-ed symbols.
Potential solutions: First see what C++ has done in details and see if we get any more ideas. But for now: a) Leave it for now (don't support overloading exported functions). b) Allow exporting functions but require a special "mangled name" to be declared as well in the pxd file. c) If precompiled pxd support arrives then the mangling could be done in the precompilation stage, enabling one to store the mangling together with the pxd (however recompilation of the pxd would break "binary" compatability...so probably not!).