Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wishlist: C::SecondClass #25

Open
run4flat opened this issue Jan 15, 2017 · 3 comments
Open

Wishlist: C::SecondClass #25

run4flat opened this issue Jan 15, 2017 · 3 comments

Comments

@run4flat
Copy link
Owner

run4flat commented Jan 15, 2017

I had hoped to finish writing this and post it quickly, but that's taking a little longer than I had expected. The details are tricky! This system allows for single inheritance plus roles. It builds a class with fully equivalent representation in both C and Perl code. Derivative classes can override methods using both Perl and C. Anyway, the basic ideas follow:

Each object is a pointer to a struct which holds the object's attributes. The first element of every object is a pointer to the class method table (the vtable). Derived classes that have additional attributes always place those attributes after the attributes of the parent class. Thanks to C's structural equivalence, we can handle an object of a derived class as if it were an object of the parent class because the attributes are all in the same relative locations.

The details (metainformation) for the attributes, methods, and roles are maintained in Perl package globals within each class. The mechanics for handling derived classes amounts to copying the contents of these package globals and adding to them, then building the C and Perl code that reflects the class of the given structure. (Some day I'd like to figure out how to make this a Moose extension, but today isn't the day.)

The method tables hold all of the methods. Any new methods provided by derived classes are added on at the end o the method table. This means that an object of a derived class can be used as if it were an object of the parent class even including method invocation.

Roles were the tricky part of this design, particularly for C. Obviously in Perl if something is known to do a role, we just invoke the wanted role method. In C, we have the added issue of finding said role methods. I solve this by using role method tables. When a role is applied to a class, the role methods are added to the method table in the order specified by the role. The C implementation of the does method takes a role id (an integer) and finds the address of the first method in the method table. It then returns this address. Due to structural equivalence, this address can be safely cast as a role method table, because the order of the pointers starting from the first method are identical to the role method table's layout. Then, the C code can refer to the desired method from the role method table:

    My::Logger * role_table = obj->methods->does(My::Logger::Type);
    if (role_table) {
        role_table->log(obj);
    }

Note that there is no sensible way to directly access role attributes. Instead, attributes will have to be accessed via getters and setters.

Also, once a role is composed into the class, the class itself knows about the methods and attributes of the role and can use them directly.

@tsee
Copy link
Contributor

tsee commented Jan 24, 2017

Hi David,

apologies for the slow response time. Sick kids and busy work (annual company meetings) took all of my time.

I've read the above description several times now, and I can't see obvious flaws in it, but for the life of me, I can't figure out what one would actually want it for? It's a very complicated bit of structure that doesn't give me any immediate "doh, always wanted to do that" vibes.

Best regards,
Steffen

@devel-chm
Copy link

I just saw the discussion in #17 and here. Using the C Object System (COS) as I have proposed for a next generation PDL compute core could also address many of the points in this discussion. Among other things, COS provides:

  • multi-methods which allow dispatch based on all the arguments to a function
  • everything is a first class object including properties (e.g. types)
  • around methods which can be used to implement method modifiers
  • open classes and generic functions

See the Julia Language for examples of how this is used for fast computation. This dissertation by one of the developers/authors of Julia shows how these features are used and are an example of how one might use tcc+COS for similar problems and benefits.

@devel-chm
Copy link

Documents for COS are in the doc/ and the cos_perl_bin branch has ports to perl of the cosgen, cossym and cosprp tools used for COS building and linking. The idea is to replace the current shell scripts with an equivalent perl program to avoid messy shell and system deps (especially for windows which doesn't really have a viable shell).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants