View mode: basic / threaded / horizontal-split · Log in · Help
October 02, 2006
Informal interfaces
An interface is a definition of what *must* be implemented.
An informal interface is a definition of what *could* be implemented.


Java's awt uses the EventListener interface for defining delegate object 
that can handle UI controls events. The idea is sound, but the 
implementation has a few flaws.

As it uses events, all methods must be implemented, even if only a 
single event is of interest. To solve this there are classes for most 
interfaces that implements all methods with dummy methods, and then you 
just override what you need. As Jave (And D) does not have multiple 
inheritance this add another restriction; a delegate object can only 
handle a single control (or type of control), not a whole window.


In Cocoa (Objecive-C) interfaces are called protocols, different name, 
same thing. Cocoa also have informal protocols. Event listening 
protocols are informal. An informal protocol only declare what methods 
can be implemented, without enforcing them. Not implementing a method 
simply means that you are not interested int hat event, and the runtime 
will filter it for you.


I suggest that D add support for informal interfaces using one new 
keyword, and one new property on all objects.


First methods in interfaces could be marked with he keyword "optional". 
Marking a method as optional in an interface will make the interface 
informal, just as marking a method abstract in a class will make the 
class abstract. A method marked as optional would have two properties:
1. Not even a warning if unimplemented by a class implementing the 
interface,
2. Calling the method if unimplemented will do nothing if void, or 
return a default value if any other type.
Example:
interface FooDelegate {
  optional void doA();
  optional int askB();
  optional bool isC() = true;
}
All three methods are optional. If doA() is unimplemented nothing will 
happen if it is called. if askB() is called then int.init will be 
returned. And if isC() is called true will be returned.

If any or all of the three are implemented then it is naturaly up to the 
implementation to return a proper value.


I attach a file with a longer example fo how it could be useful and work 
in a real world example.


All problems from Java EventListener paradigm are solved; no need to 
implement unneeded methods, a delegate object can listen to any number 
of objects, the object declaring the informal protocol is also free to 
declare the defaults.


I believe the actual implementation can be very simple. All optional 
methods need to be virtual. Optional methods and unimplemented methods 
have a NULL entry int the virtual method table. A method dispatch that 
normally would be (I use 68k asm for readability :) ):
  move.l 16(a1),a0
  jsr    (a0)
Would now become:
  move.l 16(a1),a0
  beq.s  .skip
  jsr    (a0)
.skip:

A small price to pay, slightly more for non voids. Non default return 
values, anything different from type.init could be a problem, at least 
if no access to the original source. The value to use must be available 
somehow. I have though about letting the optional methods have dumy 
implementation returning the value, that could then be an expression and 
not a constant. But I think the testing for implemented methods would 
become more complex, and calling a method could be more costly that 
testing for NULL and branch, todays CPUs are good at branch prediction.


Secondly all objects need a new property, a simple property to test for 
the availability of a method on objects. I suggest this:

public bool implements(method_signature);

And it would be used something along this line:
if (someObject.implements(doSomething(int))) {
  // prepare some costly stuff stuff
  someObject.doSomething(the_costly_result);
}



// Fredrik Olsson
October 02, 2006
Re: Informal interfaces
Fredrik Olsson schrieb:

I like this idea.

 As Jave (And D) does not have multiple
> inheritance this add another restriction; a delegate object can only 
> handle a single control (or type of control), not a whole window.

Using the *Twin pattern* allow us to model multiple inheritance in 
languages like D, Java.

A pretty straightforward example in Java  is available at :
http://www.ssw.uni-linz.ac.at/Research/Papers/Moe99/Paper.pdf

Björn
October 02, 2006
Re: Informal interfaces
On Mon, 02 Oct 2006 11:42:43 +0300, Fredrik Olsson <peylow@gmail.com>  
wrote:
> An interface is a definition of what *must* be implemented.
> An informal interface is a definition of what *could* be implemented.
[snip]

I think informal interfaces would be good to have.


> A small price to pay, slightly more for non voids. Non default return
> values, anything different from type.init could be a problem, at least
> if no access to the original source. The value to use must be available
> somehow. I have though about letting the optional methods have dumy
> implementation returning the value, that could then be an expression and
> not a constant. But I think the testing for implemented methods would
> become more complex, and calling a method could be more costly that
> testing for NULL and branch, todays CPUs are good at branch prediction.

Hmm, if an interface would have a 'static vtable' containing addresses for  
the default functions (that return the default values), then the calling  
of functions could be done as follows:

1) Get the address of an function to be called to ADDR.
2) If ADDR is not null, goto case 4.
3) Get the address of the corresponding default function of the interface  
to ADDR.
4) Call the function pointed by ADDR.

(Of course, instead of using static table for function addresses, an  
interface could have a table pointing to the default values directly.)
October 02, 2006
Re: Informal interfaces
Fredrik Olsson skrev:
> I attach a file with a longer example fo how it could be useful and work 
> in a real world example.

Some other places where an informal protocol could be useful could be 
for a URL-request delegate:

interface URLRequestDelegate {
  optional bool acceptUnsignedCertificateForURL(char[] url) = true
  optional void userCredentials(char[] url, out char[] usr,
                                out char[] pwd);
}

Delegating the work would be an easy task, be it automagic, or simply 
asking the user. And best of all the the delegate informal interfaces 
would be very clear views of what a class expects of the world. 
Self-documenting, and easy to model code.


Or as a data source delegate for a table view:

interface CellValue {
  char[] toString();
  optional void drawInRect(Rect);
}

interface TableViewDatasource {
  uint numberOfRows();
  CellValue getCellValue(uint row, uint col);
  optional void setCellValue(CellValue cv, uint row, uint col);
}

Where implementing numberOfRows and getCellValue are required, and would 
make a read only table. Optionally implementing setCellValue would make 
the table view editable as well.


// Fredrik Olsson
October 02, 2006
Re: Informal interfaces
On Mon, 02 Oct 2006 11:57:37 +0200, BLS wrote:

> Fredrik Olsson schrieb:
> 
> I like this idea.
> 
>   As Jave (And D) does not have multiple
>> inheritance this add another restriction; a delegate object can only 
>> handle a single control (or type of control), not a whole window.
> 
> Using the *Twin pattern* allow us to model multiple inheritance in 
> languages like D, Java.
> 
> A pretty straightforward example in Java  is available at :
> http://www.ssw.uni-linz.ac.at/Research/Papers/Moe99/Paper.pdf
> 

The twin pattern seem like an unattractive last resort for someone faced
with an existing language and class hierarchy.   

If one were designing solutions for the problems related to multiple
inheritance, starting from D as it is now, I'd suggest the following:

1) the flexible general solution with a small run-time overhead - allow
functions to be written using interfaces as arguments.   Implementation
could save space on the stack for what would basically be a run-time
determined vtable and lazily fill in the values as needed by the function
body;

2) efficient (time) code solution - use templates; for extra safety, allow
a mechanism for compile time checking that the template argument actually
implements the given interface rather than just having a name collision;
member templates would make this more convenient, but are not really
necessary.
Top | Discussion index | About this forum | D home