On Thu, Apr 26, 2012 at 1:10 PM, Nathan Kurz <[email protected]> wrote:
> I was confused by the _OVERRIDE functions
> that are (were?) used to provide Perl callbacks. I thought at first
> that the existence of this symbol was a signaling mechanism, but now
> realize that it's just the name of the wrapper function.
Yes. I can see now how _OVERRIDE might have been misleading.
> I wonder if naming _WRAPPER, or _CALLBACK, or something host language
> specific like _PERL might be clearer.
It's an implementation detail, so no big deal what we go with. _CALLBACK was
being used for something else until very recently, but has become available
once again. _WRAPPER is fine. I might suggest _HOSTCALL.
_PERL would be inappropriate right now because these autogenerated functions
are part of the host-agnostic core. Consider this function, which makes it
possible to override Query#set_boost via the host:
void
lucy_Query_set_boost_OVERRIDE(lucy_Query* self, float boost) {
cfish_Host_callback(self, "set_boost", 1,
CFISH_ARG_F64("boost", boost));
}
If that were _PERL, we would eliminate Host_callback() indirection layer and
flesh out the function body with raw XS:
void
lucy_Query_set_boost_PERL(lucy_Query* self, float boost) {
dSP;
EXTEND(SP, 2);
ENTER;
SAVETMPS;
PUSHMARK(SP);
PUSHs(sv_2mortal((SV*)Lucy_Query_To_Host(self)));
PUSHs(sv_2mortal(newSVnv(boost)));
PUTBACK;
call_method("set_boost", G_VOID | G_DISCARD);
FREETMPS;
LEAVE;
}
Hmm... that might not be a bad idea. The CFC sprintfs to generate XS would be
hilariously ugly, but there's nothing stopping us.
> In a previous message, Marvin writes:
>> Supporting CPAN/Rubygems/PyPI-style development for compiled extensions is of
>> paramount importance, IMO.
>
> I think I'm now understanding the implications of this, which means I
> forgot something from the list of requirements:
>
> 7) It must be possible to dynamically subclass a core class at runtime.
+1
You might say "non-final public class", since we support "final" classes.
(InStream and OutStream are both final.)
> Currently, this is distinct from loading a C extension compiled as a
> shared object, in that when we subclass from a scripting language the
> _OFFSET globals are not created. With our current mechanism, I think
> this means that the dynamically created subclasses (and possibly the
> dynamically loaded subclasses) are not quite whole: one can't (I
> think) dynamically subclass these subclasses.
It is true that subclasses written in pure Perl do not have C APIs. It's
impossible to subclass something like LucyX::Remote::ClusterSearcher from
host-agnostic C because you can't get at its Perl-space-only constructor. You
would need to write callback wrappers -- at which point it's no longer a
pure-host-language subclass.
> I think these should be harmonized, and that there should also be:
> 7) a. Dynamically created subclasses should be indistinguishable from
> and interchangeable with core classes.
I prefer your other formulation. I don't think the inability to get at
pure-host-language subclasses from C poses a major impediment.
> Before thinking about approaches, there is at least one more potential
> constraint questions that concerns me: How important is the ability
> to for objects to be able to have a "private" VTable?
I interpret your phrase '"private" VTable' as meaning "a dedicated VTable
singleton for each subclass, distinct from the VTable singleton belonging to
the parent class" -- in which case the answer is that per-class VTable
singletons are mandatory. Even if you don't override any methods, the VTable
stores other metadata, like the class name. (Which is why "VTable" should be
renamed to "MetaClass" -- it's not just an array of function pointers any
more.)
...
Thanks for starting up a requirements list, as recommended in that
Joshua Bloch presentation.
Marvin Humphrey