Re: To interface or not to interface

2010-05-27 Thread Martin Hinsch
== Quote from Steven Schveighoffer (schvei...@yahoo.com)'s article
> On Tue, 25 May 2010 23:29:34 -0400, Walter Bright
>  wrote:
> > Steven Schveighoffer wrote:
> >> On Mon, 24 May 2010 18:13:38 -0400, 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 do you add an interface to a class?
> >
> > Define an interface who's member functions call the class' member
> > functions.
> Quoting from earlier message:
>Wrapping seems like it would add more overhead than just implementing
> the interface, especially since D's inliner has some strange restrictions.
> -Steve

I think the main problem is that adding an interface post-hoc on the user's side
is a cumbersome error-prone process. This problem has been avoided quite 
elegantly
by Go by the way, which allows interfaces to be "applied" to all types that
conform without requiring inheritance (can't resist to mention that I proposed
this exact approach some years ago (long before Go was released) in this news
group ;-) ).

cheers
Martin


Re: To interface or not to interface

2010-05-27 Thread Steven Schveighoffer
On Tue, 25 May 2010 23:29:34 -0400, Walter Bright  
 wrote:



Steven Schveighoffer wrote:
On Mon, 24 May 2010 18:13:38 -0400, 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 do you add an interface to a class?


Define an interface who's member functions call the class' member  
functions.


Quoting from earlier message:

  Wrapping seems like it would add more overhead than just implementing  
the interface, especially since D's inliner has some strange restrictions.


-Steve


Re: To interface or not to interface

2010-05-27 Thread Kagamin
> ICollection acoll;
> ICollection bcoll;
> A[] cat;
> ICollection.CopyTo(A[],int)
> ICollection.CopyTo(B[],int) - note the signature, the destination array 
> can't be an array of supertype. There's no chance to throw an exception 
> because the code doesn't pass type check at compile time.

To ease understanding:

ICollection acoll;
ICollection ccoll;
Animal[] animals;
ICollection.CopyTo(Animal[],int)
ICollection.CopyTo(Cat[],int)


Re: To interface or not to interface

2010-05-27 Thread Kagamin
Steven Schveighoffer Wrote:

> On Tue, 25 May 2010 02:26:02 -0400, Kagamin  wrote:
> 
> > Recently I've hit a problem with collections in C#. Given classes
> > class A {}
> > class B {}
> > And two collections Collection and Collection it's possible to  
> > concat them into an array A[]. The efficient way to do it is to use  
> > CopyTo(T[],int) method, but it accepts only array of exact collection  
> > item's type, so I had to change the Collection type to Collection.
> 
> Did you mean
> 
> class B : A {} ?

Ah, yes.

> According to this page, it says that an exception could be thrown if "Type  
> T cannot be cast automatically to the type of the destination array."   
> This implies that a destination array type to which T could automatically  
> be cast should work.

ICollection acoll;
ICollection bcoll;
A[] cat;
ICollection.CopyTo(A[],int)
ICollection.CopyTo(B[],int) - note the signature, the destination array 
can't be an array of supertype. There's no chance to throw an exception because 
the code doesn't pass type check at compile time.


Re: To interface or not to interface

2010-05-26 Thread Michel Fortin

On 2010-05-26 15:44:58 -0400, Jacob Carlborg  said:


On 2010-05-26 16.20, Michel Fortin wrote:


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.


If I had to guess those things would need to be done:

1. Add the "@optional" attribute token to the lexer
2. Allow @optional to be attached to functions in an interface
3. When checking if a class correctly implements an interface, allow 
unimplemented @optional functions
4. When generating the interface's vtable, use null for unimplemented 
@optional functions


I think that's all. Checking for null is easily done by retrieving the 
delegate pointer (which you can already do), and calling the function 
uses the usual calling mechanism for interfaces. I expect that trying 
to call an unimplemented interface function would be like trying to 
call a null function pointer.


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: To interface or not to interface

2010-05-26 Thread Jacob Carlborg

On 2010-05-26 16.20, Michel Fortin wrote:

On 2010-05-26 06:55:14 -0400, Jacob Carlborg  said:


On 2010-05-25 17.03, Michel Fortin wrote:

On 2010-05-25 10:01:48 -0400, Jacob Carlborg  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


Re: To interface or not to interface

2010-05-26 Thread Walter Bright

Jason House wrote:

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.


In C++, the concepts design died. There's nothing you can do in C++ about the 
bad error messages. Furthermore, compile time error checking in C++ is limited 
to types. If something cannot be expressed as a distinct type, it cannot be 
checked in C++. (BTW, interfaces in D have the same problem, you can only check 
the type with them. With templates, you can check behavior and other 
characteristics.)


The fundamental problem is a compiler can only see a worm's eye view of what a 
component is supposed to do. There's no algorithm in the world that can take a 
block of code and have the compiler figure out that this is a hash map 
collection class, and give lucid error messages in those terms rather than low 
level operations.


As a component designer, however, D gives you the ability to detect usage errors 
at compile time in ways that go far beyond just type errors, and inform the user 
about them in high level terms.


You're right in that D doesn't do this automatically, just like a browser cannot 
automatically make attractive web pages. You as the component designer have to 
write the code to make it work the way you want.


Re: To interface or not to interface

2010-05-26 Thread Michel Fortin

On 2010-05-26 06:55:14 -0400, Jacob Carlborg  said:


On 2010-05-25 17.03, Michel Fortin wrote:

On 2010-05-25 10:01:48 -0400, Jacob Carlborg  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.




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...
}

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.

--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: To interface or not to interface

2010-05-26 Thread Bruno Medeiros

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


Re: To interface or not to interface

2010-05-26 Thread Jason House
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.


Re: To interface or not to interface

2010-05-26 Thread Jacob Carlborg

On 2010-05-25 17.03, Michel Fortin wrote:

On 2010-05-25 10:01:48 -0400, Jacob Carlborg  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


Re: To interface or not to interface

2010-05-25 Thread Walter Bright

Steven Schveighoffer wrote:
On Mon, 24 May 2010 18:13:38 -0400, 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 do you add an interface to a class?


Define an interface who's member functions call the class' member functions.


Re: To interface or not to interface

2010-05-25 Thread Walter Bright

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.


Re: To interface or not to interface

2010-05-25 Thread Michel Fortin

On 2010-05-25 10:01:48 -0400, Jacob Carlborg  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.for...@michelf.com
http://michelf.com/



Re: To interface or not to interface

2010-05-25 Thread Steven Schveighoffer

On Tue, 25 May 2010 10:01:48 -0400, Jacob Carlborg  wrote:


On 2010-05-25 15.38, Steven Schveighoffer wrote:

On Tue, 25 May 2010 09:26:20 -0400, Jacob Carlborg  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


Re: To interface or not to interface

2010-05-25 Thread Jacob Carlborg

On 2010-05-25 15.38, Steven Schveighoffer wrote:

On Tue, 25 May 2010 09:26:20 -0400, Jacob Carlborg  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/2117



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


Re: To interface or not to interface

2010-05-25 Thread Jacob Carlborg

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


Re: To interface or not to interface

2010-05-25 Thread Steven Schveighoffer

On Tue, 25 May 2010 09:26:20 -0400, Jacob Carlborg  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


Re: To interface or not to interface

2010-05-25 Thread Jacob Carlborg

On 2010-05-24 21.08, Steven Schveighoffer wrote:

On Mon, 24 May 2010 14:36:57 -0400, Walter Bright
 wrote:


Steven Schveighoffer wrote:

On Mon, 24 May 2010 14:10:26 -0400, Walter Bright
 wrote:


Steven Schveighoffer wrote:

I'd ask the naysayers of interfaces for dcollections, and also the
supporters: what is the point of having interfaces in D? Are
interfaces pretty much obsolete, and I am just nostalgic about
their utility?


Interfaces are for runtime polymorphism, rather than compile time
polymorphism. They are especially useful for things like:

1. runtime plugin interfaces
2. designs where strict implementation hiding is desired
3. to have binary libraries (shared and static)
4. to support Java/C# style coding
5. reduced code memory footprint
6. experience shows they are an excellent fit for user interfaces


Compile time polymorphism, such as what templates provide, are most
useful for:

1. maximum performance
2. minimal data memory consumption
3. better compile time checking


I believe the tradeoffs for collection types favor compile time
polymorphism because:

1. performance is often critical for collections
2. C++ STL has shown the success of this approach
3. collections must fit in naturally with ranges, and ranges are
compile time polymorphic

I'd counter point 2 by saying that 1. C++ classes are value-types by
default and 2. C++ doesn't have interfaces, so it's not exactly fair
to say that the STL author considered interfaces but rejected them.


C++ certainly does have interfaces. The whole COM system is based on
them, for example. Technically, D interfaces are just a subset of C++
multiple inheritance.


And if STL looked like COM, I think it would have been a miserable
failure indeed.




and on point 3, why is it not OK to *also* provide interfaces in
addition to ranges as dcollections does? That is, take away
dcollections' interfaces, and you have essentially compile-time
polymorphism, they all support ranges etc. Interfaces are also there
in case you want to use them in things like runtime plugin interfaces.


The best reason I can think of is to avoid kitchen-sink style
components. Components should do one thing well. Adding capability
should be done with aggregation by the user.


What if it can do both things well (I would propose that dcollections
does)?





Basically, my point is, compile time interfaces does not mean you
can't also have runtime interfaces. In fact, interfaces can be
compile-time parameterized.


Sure, but I'd argue that adding such runtime polymorphism should be
done with a separate add-on component. It should not be part of the
collection component.


So I should specifically have to wrap a collection type in order to make
it runtime polymorphic, forwarding all the operations to the collection?
Essentially something like:

class WrappedSet(Impl, V) : Set!V
{
Impl!V impl;

bool contains(V v) { return impl.contains(v);}
...
}

For what reason? Why is it so bad to just stick Set!V on the end of the
implementation class?





Also, much of a user interface consists of various collections
(listview, treeview, child widgets, etc.). Why is runtime
polymorphism good there, but not on a generic collections package
(not as the only means of access of course)?


A user interface object is not a collection component, I think there's
a confusion in the design there.


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.


--
/Jacob Carlborg


Re: To interface or not to interface

2010-05-25 Thread Steven Schveighoffer
On Mon, 24 May 2010 18:13:38 -0400, 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 do you add an interface to a class?  Wrapping seems like it would add  
more overhead than just implementing the interface, especially since D's  
inliner has some strange restrictions.


-Steve


Re: To interface or not to interface

2010-05-25 Thread Steven Schveighoffer
On Tue, 25 May 2010 09:03:34 -0400, 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.


These all boil down to the fact that you must declare an interface up  
front, whereas constraints are not required.


You can get to about the same level as an interface by using static  
asserts, but this is optional (it probably should be a "best practice"  
though somewhere).


-Steve


Re: To interface or not to interface

2010-05-25 Thread Jason House
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.

PS: The use of the word class above is for clarity instead of using type or 
object. I could have said struct as well.  


Re: To interface or not to interface

2010-05-25 Thread Steven Schveighoffer

On Tue, 25 May 2010 02:26:02 -0400, Kagamin  wrote:


Recently I've hit a problem with collections in C#. Given classes
class A {}
class B {}
And two collections Collection and Collection it's possible to  
concat them into an array A[]. The efficient way to do it is to use  
CopyTo(T[],int) method, but it accepts only array of exact collection  
item's type, so I had to change the Collection type to Collection.


Did you mean

class B : A {} ?

According to this page, it says that an exception could be thrown if "Type  
T cannot be cast automatically to the type of the destination array."   
This implies that a destination array type to which T could automatically  
be cast should work.


http://msdn.microsoft.com/en-us/library/0efx51xw%28v=VS.100%29.aspx

But the larger point that compile-time code generation can help with this  
is valid.


-Steve


Re: To interface or not to interface

2010-05-24 Thread Kagamin
Recently I've hit a problem with collections in C#. Given classes
class A {}
class B {}
And two collections Collection and Collection it's possible to concat 
them into an array A[]. The efficient way to do it is to use CopyTo(T[],int) 
method, but it accepts only array of exact collection item's type, so I had to 
change the Collection type to Collection.


Re: To interface or not to interface

2010-05-24 Thread Alex Makhotin

Walter Bright wrote:
 
The extra complexity is in the container supporting very different ways 
to do the same thing.




A I understand from the current discussion, interfaces meet a strong 
debate. And yes, I also understand that the interfaces are considered 
unnecessary bloat that makes execution speed slower which is critical 
for performance.

Personally, I think they should be accessible.

But, can there be a compromise to satisfy both sides?

To illustrate the idea:
C# has a feature called "Partial types".
A little excerpt from C# 4.0 specs(page 285):

The partial modifier indicates that additional parts of the type declaration 
may exist elsewhere, but the existence of such additional parts is not a 
requirement;


I see as a potential benefit for the D to have some sort of it.

For those who need templates for speed, or any other motive:

1. Import .di header with needed partial declaration of the required type.
2. The compiler injects exactly the code generated from the 
implementation of the header and nothing more.


For those who need interfaces for the reasons of maintainability, 
compatibility and interoperability:


1. Import .di header with needed partial declaration of the required 
type interfaces.
2. The compiler injects exactly the code generated from the 
implementation of the header or links with the provided library with the 
exact implementation.


The user source includes required .di header, which declares partial 
type declarations. The specified partial types from the header may have 
the implementation, but this should not be a requirement. In case of 
partially not implemented type the user gets 'not implemented' error, 
linkage fault, or something similar.


Is there a possibility for such solution?


--
Alex Makhotin,
the founder of BITPROX,
http://bitprox.com


Re: To interface or not to interface

2010-05-24 Thread Walter Bright

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.


Re: To interface or not to interface

2010-05-24 Thread Jason House
Walter Bright Wrote:

> Steven Schveighoffer wrote:
> > I'd ask the naysayers of interfaces for dcollections, and also the 
> > supporters: what is the point of having interfaces in D?  Are interfaces 
> > pretty much obsolete, and I am just nostalgic about their utility?
> 
> Interfaces are for runtime polymorphism, rather than compile time 
> polymorphism. 
> They are especially useful for things like:
> 
> 1. runtime plugin interfaces
> 2. designs where strict implementation hiding is desired
> 3. to have binary libraries (shared and static)
> 4. to support Java/C# style coding
> 5. reduced code memory footprint
> 6. experience shows they are an excellent fit for user interfaces

7. Compiler-assisted verification.

 
> Compile time polymorphism, such as what templates provide, are most useful 
> for:
> 
> 1. maximum performance
> 2. minimal data memory consumption
> 3. better compile time checking
> 
> 
> I believe the tradeoffs for collection types favor compile time polymorphism 
> because:
> 
> 1. performance is often critical for collections
> 2. C++ STL has shown the success of this approach
> 3. collections must fit in naturally with ranges, and ranges are compile time 
> polymorphic

How does error message quality compare between failing to conform to an 
interface verse conforming to an isXXX template? Anything that increases the 
time gap between code writing and code verification is bad. Does Phobos 
consistently use an isXXX template-based self-check that other writers of 
ranges can copy? Certainly, inheritance syntax is easier in this regard.



Re: To interface or not to interface

2010-05-24 Thread Walter Bright

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?


Re: To interface or not to interface

2010-05-24 Thread Steven Schveighoffer
On Mon, 24 May 2010 17:11:49 -0400, Walter Bright  
 wrote:



Steven Schveighoffer wrote:
It's a logical conclusion.  You provide a map-type collection, call it  
a HashMap.  Then, a UI designer wants to abstract his specific Map-like  
container that exposes his elements, so you provide him a Map  
interface.  But HashMap implements all the required functions to be  
able to implement the Map interface, so you slap Map on the back of the  
class definition, and presto!  It implements the map interface.   
Where's the extra complexity?


The extra complexity is in the container supporting very different ways  
to do the same thing.


I don't see this being "very different":

coll.add(coll2); // uses coll2 as interface.
coll.add(coll2[0..5]); // uses coll2 slice as a range.
coll.add(arr); // adds an array.




I don't see how that's a bad thing.


If the user wants an interface, he can add one on to the front of the  
collection. It doesn't need to be in the collection itself.


We're going in circles here.  I feel like pointing back to my previous  
post with the wrapping example...


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.


The "bad" thing is the component integrating in capability that is  
easily done as an add-on.


This reminds me of a fellow I worked with years ago who would provide  
both a free-function interface and a class interface to each of his  
components. It was completely redundant to do both, and added pages of  
complexity and documentation.


This is completely different, I'm tacking on one small piece of  
declaration and the class becomes an interface.  I'm not reimplementing or  
wrapping anything.  Surely you can see that.


In a related story, I *did* have to do something like this when someone  
wanted a Java interface to some C++ code we had.  In order to do this, we  
had to declare extern "C" functions that Java could interface via JNI.


-Steve


Re: To interface or not to interface

2010-05-24 Thread Marianne Gagnon
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...)

> A long discussion on the utility of interfaces has taken place on the  
> announce newsgroup following my announcement of dcollections for D2.
> 
> Dcollections supports interfaces peripherally.  Meaning the types in  
> dcollections are essentially concrete classes with interfaces tacked on  
> for cases where interfaces make sense.
> 
> Whenever I've used dcollections (D1 included) I don't think I've ever used  
> the interface for a container, only the concrete type.  But within  
> dcollections, there's some functions that use the interface type to do  
> (IMO) nifty things like compare two sets that have different  
> implementations.
> 
> The general consensus is that interfaces for dcollections do not add any  
> meaningful value, and that I should do everything with generic programming  
> and templates.  My view is that interfaces are useful for binary  
> compatibility and in reducing the footprint of executables.  But that  
> doesn't mean much at the moment, because D is statically linked.
> 
> I'd ask the naysayers of interfaces for dcollections, and also the  
> supporters: what is the point of having interfaces in D?  Are interfaces  
> pretty much obsolete, and I am just nostalgic about their utility?
> 
> What do you think?
> 
> -Steve



Re: To interface or not to interface

2010-05-24 Thread Walter Bright

Steven Schveighoffer wrote:
It's a logical conclusion.  You provide a map-type collection, call it a 
HashMap.  Then, a UI designer wants to abstract his specific Map-like 
container that exposes his elements, so you provide him a Map 
interface.  But HashMap implements all the required functions to be able 
to implement the Map interface, so you slap Map on the back of the class 
definition, and presto!  It implements the map interface.  Where's the 
extra complexity?


The extra complexity is in the container supporting very different ways to do 
the same thing.



I don't see how that's a bad thing.


If the user wants an interface, he can add one on to the front of the 
collection. It doesn't need to be in the collection itself.


The "bad" thing is the component integrating in capability that is easily done 
as an add-on.


This reminds me of a fellow I worked with years ago who would provide both a 
free-function interface and a class interface to each of his components. It was 
completely redundant to do both, and added pages of complexity and documentation.


Re: To interface or not to interface

2010-05-24 Thread Steven Schveighoffer
On Mon, 24 May 2010 16:27:40 -0400, Walter Bright  
 wrote:



Steven Schveighoffer wrote:
On Mon, 24 May 2010 14:36:57 -0400, Walter Bright  
 wrote:
and on point 3, why is it not OK to *also* provide interfaces in  
addition to ranges as dcollections does?  That is, take away  
dcollections' interfaces, and you have essentially compile-time  
polymorphism, they all support ranges etc.  Interfaces are also there  
in case you want to use them in things like runtime plugin interfaces.


The best reason I can think of is to avoid kitchen-sink style  
components. Components should do one thing well. Adding capability  
should be done with aggregation by the user.
 What if it can do both things well (I would propose that dcollections  
does)?


Probably for the same reason I don't want a microwave built in to my TV  
set. It's not a question of can it do both well, it's a question of is  
it a distinct component or not.


We're not talking microwave and TV set here.  We're talking more like  
microwave and a cooking device.





Sure, but I'd argue that adding such runtime polymorphism should be  
done with a separate add-on component. It should not be part of the  
collection component.
 So I should specifically have to wrap a collection type in order to  
make it runtime polymorphic, forwarding all the operations to the  
collection?  Essentially something like:

 class WrappedSet(Impl, V) : Set!V
{
   Impl!V impl;
bool contains(V v) { return impl.contains(v);}
   ...
}
 For what reason?  Why is it so bad to just stick Set!V on the end of  
the implementation class?


Because then everyone who just wants a hash table winds up carrying  
around the complexity for things they don't want. The idea behind  
pluggable components is that each component should be minimal, and then  
the user aggregates them to meet his needs.


What extra complexity?  That's what I'm trying to get at, there is none.   
The complexity of "being a set" is builtin to the fact that HashSet is a  
set!


Also, much of a user interface consists of various collections  
(listview, treeview, child widgets, etc.).  Why is runtime  
polymorphism good there, but not on a generic collections package  
(not as the only means of access of course)?


A user interface object is not a collection component, I think there's  
a confusion in the design there.
 Don't user interface objects have data?  If a UI component is an  
interface, how does it expose access to its data?


That's up to the UI interface designer. It has nothing to do with how it  
implements the collection under the hood.


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.


A graphical component can wrap a collection component. I see no reason  
why the collection needs to have runtime polymorphism to enable that.


It's a logical conclusion.  You provide a map-type collection, call it a  
HashMap.  Then, a UI designer wants to abstract his specific Map-like  
container that exposes his elements, so you provide him a Map interface.   
But HashMap implements all the required functions to be able to implement  
the Map interface, so you slap Map on the back of the class definition,  
and presto!  It implements the map interface.  Where's the extra  
complexity?


I don't see how that's a bad thing.

-Steve


Re: To interface or not to interface

2010-05-24 Thread Walter Bright

Steven Schveighoffer wrote:
On Mon, 24 May 2010 14:36:57 -0400, Walter Bright 
 wrote:
and on point 3, why is it not OK to *also* provide interfaces in 
addition to ranges as dcollections does?  That is, take away 
dcollections' interfaces, and you have essentially compile-time 
polymorphism, they all support ranges etc.  Interfaces are also there 
in case you want to use them in things like runtime plugin interfaces.


The best reason I can think of is to avoid kitchen-sink style 
components. Components should do one thing well. Adding capability 
should be done with aggregation by the user.


What if it can do both things well (I would propose that dcollections 
does)?


Probably for the same reason I don't want a microwave built in to my TV set. 
It's not a question of can it do both well, it's a question of is it a distinct 
component or not.



Sure, but I'd argue that adding such runtime polymorphism should be 
done with a separate add-on component. It should not be part of the 
collection component.


So I should specifically have to wrap a collection type in order to make 
it runtime polymorphic, forwarding all the operations to the 
collection?  Essentially something like:


class WrappedSet(Impl, V) : Set!V
{
   Impl!V impl;

   bool contains(V v) { return impl.contains(v);}
   ...
}

For what reason?  Why is it so bad to just stick Set!V on the end of the 
implementation class?


Because then everyone who just wants a hash table winds up carrying around the 
complexity for things they don't want. The idea behind pluggable components is 
that each component should be minimal, and then the user aggregates them to meet 
his needs.




Also, much of a user interface consists of various collections 
(listview, treeview, child widgets, etc.).  Why is runtime 
polymorphism good there, but not on a generic collections package 
(not as the only means of access of course)?


A user interface object is not a collection component, I think there's 
a confusion in the design there.


Don't user interface objects have data?  If a UI component is an 
interface, how does it expose access to its data?


That's up to the UI interface designer. It has nothing to do with how it 
implements the collection under the hood.


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.


A graphical component can wrap a collection component. I see no reason why the 
collection needs to have runtime polymorphism to enable that.


Re: To interface or not to interface

2010-05-24 Thread Steven Schveighoffer
On Mon, 24 May 2010 14:36:57 -0400, Walter Bright  
 wrote:



Steven Schveighoffer wrote:
On Mon, 24 May 2010 14:10:26 -0400, Walter Bright  
 wrote:



Steven Schveighoffer wrote:
I'd ask the naysayers of interfaces for dcollections, and also the  
supporters: what is the point of having interfaces in D?  Are  
interfaces pretty much obsolete, and I am just nostalgic about their  
utility?


Interfaces are for runtime polymorphism, rather than compile time  
polymorphism. They are especially useful for things like:


1. runtime plugin interfaces
2. designs where strict implementation hiding is desired
3. to have binary libraries (shared and static)
4. to support Java/C# style coding
5. reduced code memory footprint
6. experience shows they are an excellent fit for user interfaces


Compile time polymorphism, such as what templates provide, are most  
useful for:


1. maximum performance
2. minimal data memory consumption
3. better compile time checking


I believe the tradeoffs for collection types favor compile time  
polymorphism because:


1. performance is often critical for collections
2. C++ STL has shown the success of this approach
3. collections must fit in naturally with ranges, and ranges are  
compile time polymorphic
 I'd counter point 2 by saying that 1. C++ classes are value-types by  
default and 2. C++ doesn't have interfaces, so it's not exactly fair to  
say that the STL author considered interfaces but rejected them.


C++ certainly does have interfaces. The whole COM system is based on  
them, for example. Technically, D interfaces are just a subset of C++  
multiple inheritance.


And if STL looked like COM, I think it would have been a miserable failure  
indeed.




and on point 3, why is it not OK to *also* provide interfaces in  
addition to ranges as dcollections does?  That is, take away  
dcollections' interfaces, and you have essentially compile-time  
polymorphism, they all support ranges etc.  Interfaces are also there  
in case you want to use them in things like runtime plugin interfaces.


The best reason I can think of is to avoid kitchen-sink style  
components. Components should do one thing well. Adding capability  
should be done with aggregation by the user.


What if it can do both things well (I would propose that dcollections  
does)?





Basically, my point is, compile time interfaces does not mean you can't  
also have runtime interfaces.  In fact, interfaces can be compile-time  
parameterized.


Sure, but I'd argue that adding such runtime polymorphism should be done  
with a separate add-on component. It should not be part of the  
collection component.


So I should specifically have to wrap a collection type in order to make  
it runtime polymorphic, forwarding all the operations to the collection?   
Essentially something like:


class WrappedSet(Impl, V) : Set!V
{
   Impl!V impl;

   bool contains(V v) { return impl.contains(v);}
   ...
}

For what reason?  Why is it so bad to just stick Set!V on the end of the  
implementation class?





Also, much of a user interface consists of various collections  
(listview, treeview, child widgets, etc.).  Why is runtime polymorphism  
good there, but not on a generic collections package (not as the only  
means of access of course)?


A user interface object is not a collection component, I think there's a  
confusion in the design there.


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


Re: To interface or not to interface

2010-05-24 Thread Walter Bright

Steven Schveighoffer wrote:
On Mon, 24 May 2010 14:10:26 -0400, Walter Bright 
 wrote:



Steven Schveighoffer wrote:
I'd ask the naysayers of interfaces for dcollections, and also the 
supporters: what is the point of having interfaces in D?  Are 
interfaces pretty much obsolete, and I am just nostalgic about their 
utility?


Interfaces are for runtime polymorphism, rather than compile time 
polymorphism. They are especially useful for things like:


1. runtime plugin interfaces
2. designs where strict implementation hiding is desired
3. to have binary libraries (shared and static)
4. to support Java/C# style coding
5. reduced code memory footprint
6. experience shows they are an excellent fit for user interfaces


Compile time polymorphism, such as what templates provide, are most 
useful for:


1. maximum performance
2. minimal data memory consumption
3. better compile time checking


I believe the tradeoffs for collection types favor compile time 
polymorphism because:


1. performance is often critical for collections
2. C++ STL has shown the success of this approach
3. collections must fit in naturally with ranges, and ranges are 
compile time polymorphic


I'd counter point 2 by saying that 1. C++ classes are value-types by 
default and 2. C++ doesn't have interfaces, so it's not exactly fair to 
say that the STL author considered interfaces but rejected them.


C++ certainly does have interfaces. The whole COM system is based on them, for 
example. Technically, D interfaces are just a subset of C++ multiple inheritance.


and on point 3, why is it not OK to *also* provide interfaces in 
addition to ranges as dcollections does?  That is, take away 
dcollections' interfaces, and you have essentially compile-time 
polymorphism, they all support ranges etc.  Interfaces are also there in 
case you want to use them in things like runtime plugin interfaces.


The best reason I can think of is to avoid kitchen-sink style components. 
Components should do one thing well. Adding capability should be done with 
aggregation by the user.



Basically, my point is, compile time interfaces does not mean you can't 
also have runtime interfaces.  In fact, interfaces can be compile-time 
parameterized.


Sure, but I'd argue that adding such runtime polymorphism should be done with a 
separate add-on component. It should not be part of the collection component.



Also, much of a user interface consists of various collections 
(listview, treeview, child widgets, etc.).  Why is runtime polymorphism 
good there, but not on a generic collections package (not as the only 
means of access of course)?


A user interface object is not a collection component, I think there's a 
confusion in the design there.


Re: To interface or not to interface

2010-05-24 Thread Steven Schveighoffer
On Mon, 24 May 2010 14:10:26 -0400, Walter Bright  
 wrote:



Steven Schveighoffer wrote:
I'd ask the naysayers of interfaces for dcollections, and also the  
supporters: what is the point of having interfaces in D?  Are  
interfaces pretty much obsolete, and I am just nostalgic about their  
utility?


Interfaces are for runtime polymorphism, rather than compile time  
polymorphism. They are especially useful for things like:


1. runtime plugin interfaces
2. designs where strict implementation hiding is desired
3. to have binary libraries (shared and static)
4. to support Java/C# style coding
5. reduced code memory footprint
6. experience shows they are an excellent fit for user interfaces


Compile time polymorphism, such as what templates provide, are most  
useful for:


1. maximum performance
2. minimal data memory consumption
3. better compile time checking


I believe the tradeoffs for collection types favor compile time  
polymorphism because:


1. performance is often critical for collections
2. C++ STL has shown the success of this approach
3. collections must fit in naturally with ranges, and ranges are compile  
time polymorphic


I'd counter point 2 by saying that 1. C++ classes are value-types by  
default and 2. C++ doesn't have interfaces, so it's not exactly fair to  
say that the STL author considered interfaces but rejected them.


and on point 3, why is it not OK to *also* provide interfaces in addition  
to ranges as dcollections does?  That is, take away dcollections'  
interfaces, and you have essentially compile-time polymorphism, they all  
support ranges etc.  Interfaces are also there in case you want to use  
them in things like runtime plugin interfaces.


Basically, my point is, compile time interfaces does not mean you can't  
also have runtime interfaces.  In fact, interfaces can be compile-time  
parameterized.


Also, much of a user interface consists of various collections (listview,  
treeview, child widgets, etc.).  Why is runtime polymorphism good there,  
but not on a generic collections package (not as the only means of access  
of course)?


-Steve


Re: To interface or not to interface

2010-05-24 Thread Walter Bright

Steven Schveighoffer wrote:
I'd ask the naysayers of interfaces for dcollections, and also the 
supporters: what is the point of having interfaces in D?  Are interfaces 
pretty much obsolete, and I am just nostalgic about their utility?


Interfaces are for runtime polymorphism, rather than compile time polymorphism. 
They are especially useful for things like:


1. runtime plugin interfaces
2. designs where strict implementation hiding is desired
3. to have binary libraries (shared and static)
4. to support Java/C# style coding
5. reduced code memory footprint
6. experience shows they are an excellent fit for user interfaces


Compile time polymorphism, such as what templates provide, are most useful for:

1. maximum performance
2. minimal data memory consumption
3. better compile time checking


I believe the tradeoffs for collection types favor compile time polymorphism 
because:


1. performance is often critical for collections
2. C++ STL has shown the success of this approach
3. collections must fit in naturally with ranges, and ranges are compile time 
polymorphic