On 2010-05-26 16.20, Michel Fortin wrote:
On 2010-05-26 06:55:14 -0400, Jacob Carlborg <[email protected]> said:

On 2010-05-25 17.03, Michel Fortin wrote:
On 2010-05-25 10:01:48 -0400, Jacob Carlborg <[email protected]> said:

Now Item could be an interface but it don't have to be. I suggest you
have a look at Apple's documentation of NSTableView:

What Cocoa is doing is basically allowing 'optional' methods in an
interface (a protocol in Objective-C). Taking your example, the
NSTableViewDataSource protocol contains a lot of functions to provide
the required data to a table. But many of them are optional: for
instance a data source that does not implement the
"...setObjectValue..." method will prevent the table's content from
being edited, one that doesn't implement the
"...sortDescriptorsDidChange..." method prevents the table from being
sorted by clicking on its column headers, one that doesn't implement the
various methods for drag and drop will prevent rows from being dragged.

I've always thought that this design and the similar Java uses with
interfaces, anonymous classes and adapters is just a design chosen
because the languages are limited, don't support delegates.

Indeed.

Well, I think you could use runtime-reflection to achieve the same thing
in Java, but that would make your interfaces "informal", in the sense
that you just can't put those optional functions in the interfaces. (And
it'd uglify the code a lot.) Technically, this is what was done prior
Mac OS X 10.6 with informal protocols; I say "almost" since the method
signatures being added as unimplemented categories to NSObject, they
could still checked for correctness by the compiler.

If I recall correctly writing code that uses runtime-refelection in Java isn't pretty, especial compared to something like Ruby where it's just as easy as any other code you write.

Perhaps interfaces could be allowed to have optional methods that would
require you to check if they're implemented before use.

How would you check if a method is implemented or not ?

In Objective-C, it's quite easy. For instance, I've made my own subclass
of NSTableView querying the delegate for a background color for a given
row. So here's how you use the delegate:

id delegate = [self delegate];

if ([delegate
respondsToSelector:@selector(tableView:backgroundColorForRow:)]) {
NSColor *color = [delegate tableView:self backgroundColorForRow:row];
...draw background color...
}

Yes, Objective-C makes that easy with its message passing system.

In D you can't do that currently, but here's how it could be added.
First add an optional attribute for interface members:

interface TableDelegate {
...
@optional NSColor backgroundColorForRow(NSTableView table, size_t row);
}

Classes implementing the interface can omit the @optional methods. When
omitted, the interface function is null. When using the interface, you
must check first if the optional function is implemented by making sure
the address isn't null:

TableDelegate delegate = this.delegate;

if (&delegate.backgroundColorForRow != null) {
NSColor color = delegate.backgroundColorForRow(this, row);
...draw background color...
}

This would work somewhat similarily to weak-linked symbols.

That is quite a clever idea, to check for null. The question is then how much trouble would that be to implement.


--
/Jacob Carlborg

Reply via email to