Parrot_PyClass_get_repr is one such wrapper. How could it be done better? If you make a specific suggestion there, I'll either adopt it or produce a test case as a counter example.
You'd need in pyclass.pmc:
PMC* get_repr() { return pmc_new_string( ... "<class ...>") }
Just to be clarify, this is from the header comment in pyclass.pmc:
These are the vtable functions for the Python Class base class (i.e., methods you would expect to see on python objects).
For reference, here is the current definition of get_repr.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/*
=item C<STRING *get_repr()>
Return the representation of this object.
=cut
*/
STRING* get_repr() { PMC *repr = VTABLE_find_method(INTERP, SELF, REPR);
if (repr) {
PMC *temp = Parrot_run_meth_fromc_args(INTERP, repr, SELF, REPR,
"PP", SELF);
return VTABLE_get_string(INTERP, temp);
}
else {
STRING *res;
res = string_from_cstring(INTERP, "<", 0); res = string_append(INTERP, res, VTABLE_name(INTERP, VTABLE_get_class(INTERP, SELF)), 0); res = string_append(INTERP, res, const_string(INTERP, " instance at "), 0); res = string_append(INTERP, res, Parrot_sprintf_c(INTERP, "%#x", (INTVAL) SELF), 0); res = string_append(INTERP, res, const_string(INTERP, ">"), 0);
return res; } }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
In this case, there is a Python specific default. In other cases, there are other Python specific behaviors like mapping not found to an exception or to None. In short, I don't see wrappers going away.
A method that returns the string representation of a PyClass object.
That's not a wrapper but an implementation for one specific class. No wrapper for other classes or a dispatch through run_meth_fromc_args is needed.
Nothing more will be needed, *when* all is fixed:
* we return PMCs normally (other types are optimizations) * the methods create new PMCs - no LHS PMC is passed in * all overloadable MMDs and vtables are registered as NCI methods like the current METHOD syntax in .pmc files.
get_repr is overloadable. Being overloadable is the norm rather than the exception in Python.
* Parrot knows common type names (Integer, Float, String, Bool, ...) of the supported languages
The alternative (which is supported today) is that callers pass in a PMC which defines a morph method which maps common type names to language specific alternatives. Take a look at PyObject.pmc where I substitute PyLong for BigInt.
The advantage of what exists today is that adding a new language does not require any changes to Parrot. The caller defines the mapping.
* all dispatch is based on VTABLE_find_method
Just to be clear, in the cases where a wrapper is needed (which I would argue is the majority of cases), this works out to be: a call to VTABLE_find_method for the wrapper which in turn uses VTABLE_find_method to access the "real" logic.
That's a simple scheme and should be well suited for all current target languages - IMHO.
Again, just to be clear: this hinges on dual assumptions: (1) that wrappers aren't needed in the majority of cases, and (2) every time someone gets or sets a method, a mapping can be done from language defined names to Parrot conventions.
Note that in Python, all attributes may potentially be a method.
- Sam Ruby