View mode: basic / threaded / horizontal-split · Log in · Help
May 25, 2010
Re: To interface or not to interface
On Tue, 25 May 2010 09:26:20 -0400, Jacob Carlborg <doob@me.com> wrote:

> On 2010-05-24 21.08, Steven Schveighoffer wrote:
>>
>> Don't user interface objects have data? If a UI component is an
>> interface, how does it expose access to its data? For example, a .NET
>> ListView control contains an Items property which you can use to access
>> the elements in the list view. The Items property returns a
>> ListViewItemCollection which implements IList, IContainer, and
>> IEnumerable. I've found these types of abstractions useful when
>> adding/iterating, etc.
>> -Steve
>
>
> I would say that is a bad design, I would go with the MVC pattern. For  
> example, you have a ListView and when it's ready to display, say row 3,  
> it calls your delegate and request you to return the item that should be  
> visible on row 3. Then it's up to you to store the items in some  
> appropriate data structure, like a list or array.

I don't know if a delegate is enough to implement the pattern.  What you  
need is a set of delegates that perform operations on the container.  Oh  
wait, that's an interface!

One interesting difference between an interface and a delegate is that an  
interface is a single pointer, whereas a delegate is two.  With the  
context-pointer design, many more features are possible.  For instance,  
struct interfaces would be easy, as well as easily tacking on an interface  
to a class.

In any case, Windows Forms is probably the easiest UI toolkit I've worked  
with (which isn't saying much), I don't think it's a bad design.  That  
could be the Visual Studio talking though :)

-Steve
May 25, 2010
Re: To interface or not to interface
On 2010-05-25 00.13, Walter Bright wrote:
> Steven Schveighoffer wrote:
>> All an interface does is give an abstract representation of functions
>> that are *already there*. Removing the interface does not remove the
>> functions that implemented the interface.
>
> Then why do interfaces need to be part of the collection component? Why
> can't the user add them if he wants them?

How would the user do that? The user would need to create an interface 
and then a wrapper that implements the interface. An interface without 
implementations is useless. Or am I missing something ?

-- 
/Jacob Carlborg
May 25, 2010
Re: To interface or not to interface
On 2010-05-25 15.38, Steven Schveighoffer wrote:
> On Tue, 25 May 2010 09:26:20 -0400, Jacob Carlborg <doob@me.com> wrote:
>
>> On 2010-05-24 21.08, Steven Schveighoffer wrote:
>>>
>>> Don't user interface objects have data? If a UI component is an
>>> interface, how does it expose access to its data? For example, a .NET
>>> ListView control contains an Items property which you can use to access
>>> the elements in the list view. The Items property returns a
>>> ListViewItemCollection which implements IList, IContainer, and
>>> IEnumerable. I've found these types of abstractions useful when
>>> adding/iterating, etc.
>>> -Steve
>>
>>
>> I would say that is a bad design, I would go with the MVC pattern. For
>> example, you have a ListView and when it's ready to display, say row
>> 3, it calls your delegate and request you to return the item that
>> should be visible on row 3. Then it's up to you to store the items in
>> some appropriate data structure, like a list or array.
>
> I don't know if a delegate is enough to implement the pattern. What you
> need is a set of delegates that perform operations on the container. Oh
> wait, that's an interface!

What I was trying to say is that a ListView should not contain a data 
structure. I try to explain that I want to say in code instead:

auto data = new Item[10];
auto listView = new ListView;
listView.numberOfRows = size_t delegate (ListView lv) {
   return data.length;
}
listView.itemAtRow = Item delegate (ListView lv, size_t row) {
    return data[row];
}

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:

* 
http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSTableView_Class/Reference/Reference.html 


* 
http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/TableView/Tasks/UsingTableDataSource.html#//apple_ref/doc/uid/20000117

> One interesting difference between an interface and a delegate is that
> an interface is a single pointer, whereas a delegate is two. With the
> context-pointer design, many more features are possible. For instance,
> struct interfaces would be easy, as well as easily tacking on an
> interface to a class.
>
> In any case, Windows Forms is probably the easiest UI toolkit I've
> worked with (which isn't saying much), I don't think it's a bad design.
> That could be the Visual Studio talking though :)

I suggest you have a look at Cocoa, it uses the MVC pattern.

> -Steve


-- 
/Jacob Carlborg
May 25, 2010
Re: To interface or not to interface
On Tue, 25 May 2010 10:01:48 -0400, Jacob Carlborg <doob@me.com> wrote:

> On 2010-05-25 15.38, Steven Schveighoffer wrote:
>> On Tue, 25 May 2010 09:26:20 -0400, Jacob Carlborg <doob@me.com> wrote:
>>
>>> On 2010-05-24 21.08, Steven Schveighoffer wrote:
>>>>
>>>> Don't user interface objects have data? If a UI component is an
>>>> interface, how does it expose access to its data? For example, a .NET
>>>> ListView control contains an Items property which you can use to  
>>>> access
>>>> the elements in the list view. The Items property returns a
>>>> ListViewItemCollection which implements IList, IContainer, and
>>>> IEnumerable. I've found these types of abstractions useful when
>>>> adding/iterating, etc.
>>>> -Steve
>>>
>>>
>>> I would say that is a bad design, I would go with the MVC pattern. For
>>> example, you have a ListView and when it's ready to display, say row
>>> 3, it calls your delegate and request you to return the item that
>>> should be visible on row 3. Then it's up to you to store the items in
>>> some appropriate data structure, like a list or array.
>>
>> I don't know if a delegate is enough to implement the pattern. What you
>> need is a set of delegates that perform operations on the container. Oh
>> wait, that's an interface!
>
> What I was trying to say is that a ListView should not contain a data  
> structure. I try to explain that I want to say in code instead:
>
> auto data = new Item[10];
> auto listView = new ListView;
> listView.numberOfRows = size_t delegate (ListView lv) {
>     return data.length;
> }
> listView.itemAtRow = Item delegate (ListView lv, size_t row) {
>      return data[row];
> }

Yes, I get that.  What I'm saying is this is basically an interface.  The  
difference is that the interface is not required to be declared on the  
container class, and requires 2 words of storage in the ListView per  
function instead of 1 word for all the functions.

Another way to do this is:

listView.items = data;

Where listView.items is an interface that contains the functions you  
need.  If the set of functions is complex, then using the delegates could  
be tedious.

It's just a different way of doing it.  There are benefits to both ways.   
Using the delegates is more flexible because a delegate does not need to  
be defined in a class with a predefined interface being implemented.  It's  
also much easier to build a bunch of delegates on the fly rather than  
build an interface implementation.

-Steve
May 25, 2010
Re: To interface or not to interface
On 2010-05-25 10:01:48 -0400, Jacob Carlborg <doob@me.com> 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.

(Note to Cocoa programmers: Prior to the Mac OS X 10.6 SDK, 
NSTableViewDataSource was an informal protocol implemented as a 
category of unimplemented functions in NSObject. The 10.6 SDK changed 
it to be a formal protocol with optional methods, a feature added to 
Objective-C 2.0.)

In D, one could create one interface for each of these groups of 
things, but then you'll have a bazilion of small interfaces and either 
you lose the relation between them or you end up with a combinational 
explosion. For instance, let's create a bunch of interfaces for what I 
wrote above:

	interface TableDataSource {...}
	interface TableDataSourceEdit : TableDataSource {...}
	interface TableDataSourceSort : TableDataSource {...}
	interface TableDataSourceDrag : TableDataSource {...}
	interface TableDataSourceDropTarget : TableDataSource {...}

Now, when I implement the table view I could have one data source

	class TableView {
		TableDataSource dataSource;
	}

and then I'd dynamically check whether my data source implements each 
of the child interfaces:

	auto dataSourceEdit = cast(TableDataSourceEdit)dataSource)
	if (dataSourceEdit) {
		dataSourceEdit.setObject(object, row, column);
	} else {
		// data source cannot be edited
	}

That's essentially what is done in Cocoa, except that in Cocoa an 
object usually checks for the existence of one of its delegate function 
prior calling it instead of having a whole lot of interfaces. This is 
why protocols are allowed to have optional methods.

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

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/
May 26, 2010
Re: To interface or not to interface
Jason House wrote:
> Walter Bright Wrote:
> 
>> Jason House wrote:
>>> 7. Compiler-assisted verification.
>> For interfaces, the compile time checking is limited to verifying that
>> functions with the right signature are supplied. Templates can go
>> considerably beyond that with the constraint checking.
> 
> constraints are more powerful, but they have downsides: • If a class is
> incorrectly defined, failure to use a type without a constraint check leads
> to errors in the code using it instead of the class definition. Usage isn't
> always guaranteed to be correct either, so the developer must spend extra
> time diagnosing the real error. • If a class is incorrectly, initial usage
> without a constraint may completely miss the error. Easy examples would be a
> typo propogated with copy/paste, or neglecting to use save. • If a class is
> incorrectly defined and usage uses a constraint, the developer will simply
> get an error that there is no matching call. • If a constraint is incorrectly
> defined and usage uses the constraint, the developer will simply get an error
> that there is no matching call.
> 
> None of these scenarios are particularly helpful for a developer
> creating/expanding a family of objects.


You can also make constraints that give custom error messages, so you can do 
better than the compiler's stab at it. How good they are is up to the designer 
of the type.
May 26, 2010
Re: To interface or not to interface
Steven Schveighoffer wrote:
> On Mon, 24 May 2010 18:13:38 -0400, Walter Bright 
> <newshound1@digitalmars.com> wrote:
> 
>> Steven Schveighoffer wrote:
>>> All an interface does is give an abstract representation of functions 
>>> that are *already there*.  Removing the interface does not remove the 
>>> functions that implemented the interface.
>>
>> Then why do interfaces need to be part of the collection component? 
>> Why can't the user add them if he wants them?
> 
> How do you add an interface to a class?

Define an interface who's member functions call the class' member functions.
May 26, 2010
Re: To interface or not to interface
On 2010-05-25 17.03, Michel Fortin wrote:
> On 2010-05-25 10:01:48 -0400, Jacob Carlborg <doob@me.com> 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.

> (Note to Cocoa programmers: Prior to the Mac OS X 10.6 SDK,
> NSTableViewDataSource was an informal protocol implemented as a category
> of unimplemented functions in NSObject. The 10.6 SDK changed it to be a
> formal protocol with optional methods, a feature added to Objective-C 2.0.)
>
> In D, one could create one interface for each of these groups of things,
> but then you'll have a bazilion of small interfaces and either you lose
> the relation between them or you end up with a combinational explosion.
> For instance, let's create a bunch of interfaces for what I wrote above:
>
> interface TableDataSource {...}
> interface TableDataSourceEdit : TableDataSource {...}
> interface TableDataSourceSort : TableDataSource {...}
> interface TableDataSourceDrag : TableDataSource {...}
> interface TableDataSourceDropTarget : TableDataSource {...}
>
> Now, when I implement the table view I could have one data source
>
> class TableView {
> TableDataSource dataSource;
> }
>
> and then I'd dynamically check whether my data source implements each of
> the child interfaces:
>
> auto dataSourceEdit = cast(TableDataSourceEdit)dataSource)
> if (dataSourceEdit) {
> dataSourceEdit.setObject(object, row, column);
> } else {
> // data source cannot be edited
> }
>
> That's essentially what is done in Cocoa, except that in Cocoa an object
> usually checks for the existence of one of its delegate function prior
> calling it instead of having a whole lot of interfaces. This is why
> protocols are allowed to have optional methods.
>
> 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 ?

-- 
/Jacob Carlborg
May 26, 2010
Re: To interface or not to interface
Walter Bright Wrote:

> Jason House wrote:
> > Walter Bright Wrote:
> > 
> >> Jason House wrote:
> >>> 7. Compiler-assisted verification.
> >> For interfaces, the compile time checking is limited to verifying that
> >> functions with the right signature are supplied. Templates can go
> >> considerably beyond that with the constraint checking.
> > 
> > constraints are more powerful, but they have downsides: • If a class is
> > incorrectly defined, failure to use a type without a constraint check leads
> > to errors in the code using it instead of the class definition. Usage isn't
> > always guaranteed to be correct either, so the developer must spend extra
> > time diagnosing the real error. • If a class is incorrectly, initial usage
> > without a constraint may completely miss the error. Easy examples would be a
> > typo propogated with copy/paste, or neglecting to use save. • If a class is
> > incorrectly defined and usage uses a constraint, the developer will simply
> > get an error that there is no matching call. • If a constraint is incorrectly
> > defined and usage uses the constraint, the developer will simply get an error
> > that there is no matching call.
> > 
> > None of these scenarios are particularly helpful for a developer
> > creating/expanding a family of objects.
> 
> 
> You can also make constraints that give custom error messages, so you can do 
> better than the compiler's stab at it. How good they are is up to the designer 
> of the type.

So you're favoring an isXXX as well as a requireXXX?  Such duplication is both annoying and error prone. Making isXXX use requieXXX under the hood ishigher implementation complexity. I don't know about others, but I was drawn to its simplicity over C++. Many have praised its ability to make template programming simple. This feels like a step backwards.
May 26, 2010
Re: To interface or not to interface
On 24/05/2010 22:14, Marianne Gagnon wrote:
> In my experience (not related to DCollections), having interfaces is useful to ensure reduced coupling, thus enabling the use of mock classes for unit tests (or simply to test your module, when your module needs to use services provided by another module that is being written by a colleague but not yet usable, etc...)
>

That's generally true, but I don't think it applies to DCollections. 
Creating mock objects is for mocking complex subsystems and modules, 
such that setting up (and later verifying) the mock object is much 
easier than if the true object/subsystem was used. But that would not 
apply to a collection object, since a mock collection would not really 
be easier to work with than with the real collection object.


-- 
Bruno Medeiros - Software Engineer
1 2 3 4
Top | Discussion index | About this forum | D home