On 16/09/2014 04:39, Marvin Humphrey wrote:
So we go from ~15.9 cycles for our current class method dispatch to ~17.9
cycles for this flavor of interface method dispatch.
I'm more concerned with the waste of memory. I'd happily sacrifice some more
cycles to find a solution that doesn't need those sparse arrays.
Sure, but how much cheaper can we get? It doesn't seem like the penalty is
all that severe.
Memory-wise, we can get a lot cheaper.
It occurs to me that an additional optimization is possible for all flavors of
interface method dispatch. Since adding a new abstract method to an interface
is a backwards compatibility break, we could sort the abstract methods by name
and assign fixed offsets.
Adding a new interface method isn't always a compatibility break. If module A
uses (not implements) an interface of module B, and module B adds a new
interface method, module A should continue to function unless the semantics of
the other methods change (just like with classes). Even if a class from module
A implements an interface of module B, it's possible that the class already
provides the added method or that the new method has a concrete implementation
defined in the interface (like you suggest below).
This leads to another topic I wanted to cover: I would really like to allow
interfaces to define concrete methods in addition to abstract methods.
Allowing concrete methods facilitates stuff like Ruby's Comparable, where
defining `<=>` gets you 6 other methods:
http://www.ruby-doc.org/core-2.1.2/Comparable.html
Sometimes people use "trait", "role", or "mixin" instead of "interface" to
describe such a construct. In any case, for Clownfish I'm suggesting that
interfaces may define additional methods but with the limitation that these
methods may not access any ivars.
We would a need a way to mark interface methods that are non-abstract and
store them in the itable as default methods if there's no implementation in a
class. The default methods would take an interface object as "self". If
interface object pointers aren't equivalent to object pointers, we'd need an
auto-generated wrapper that does the conversion.
Nick