[
https://issues.apache.org/jira/browse/CLOWNFISH-12?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14582320#comment-14582320
]
Nick Wellnhofer commented on CLOWNFISH-12:
------------------------------------------
When working on the prototype for the Rust bindings, it occurred to me that
Go-style interfaces aren't such a good idea after all. They don't map well to
statically typed languages like Rust, Java, or C++. For example, consider a
hash table with a {{Hashable}} interface and a method like
{noformat}
public Obj*
Fetch(Hash *self, Hashable *key);
{noformat}
In Java, the only type we could use for {{Hashable}} in the bindings would be
Java's {{Object}}. This means that we lose type checks at compile time and must
check whether the argument actually implements the {{Hashable}} interface at
runtime. This requires type introspection (reflection) features that aren't
available in a language like C++. From my understanding, Rust's {{Any}} type is
also too limited for this use case.
One of Clownfish's design principles is that it implements a subset of the host
language features. While Go-style interfaces map well to duck-typed languages
where there's runtime a check anyway, they aren't a good match for other
languages.
> Clownfish interfaces
> --------------------
>
> Key: CLOWNFISH-12
> URL: https://issues.apache.org/jira/browse/CLOWNFISH-12
> Project: Apache Lucy-Clownfish
> Issue Type: New Feature
> Components: Core
> Reporter: Nick Wellnhofer
> Priority: Minor
>
> Java-style interfaces would be a nice feature for Clownfish. Here's a sketch
> of how it could be implemented. It's basically an adaption of the technique
> described by Bjarne Stroustrup in his paper [Multiple Inheritance for
> C++|http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.23.4735].
> If a subclass implements an interface, an additional instance variable
> pointing to an interface method table is created. A pointer to this instance
> variable represents an interface reference. The interface method table
> contains
> * the offset of the pointer to the interface method table from the start of
> the object.
> * a variable length array of method pointers to the implementations of the
> interface's methods.
> * optionally a pointer to an Interface object for introspection.
> Every subclass/interface combination needs a separate interface method table.
> Subclasses that don't override any of the interface methods of a parent class
> can reuse the parent class's table.
> The memory layout would look like this:
> {noformat}
> object
> +--------+
> | head |
> | vtable | itable
> | ivars | +---------+
> -->| itable +-->| offset |
> | ivars | | method1 |
> +--------+ | method2 |
> | method3 |
> | method4 |
> | ... |
> +---------+
> {noformat}
> Converting an object to an interface reference is done by returning a pointer
> to the itable struct member. Converting back to the object is done by
> subtracting the offset in the itable. Method invocation from an interface
> reference is done by looking up the method pointer and calling it with the
> original object.
> In host languages, an interface is represented by a class with the
> interface's methods. Objects of this class contain the interface reference
> (address of the itable instance variable).
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)