[ 
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)

Reply via email to