www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Protocols vs Concepts?

reply Shammah Chancellor <anonymous coward.com> writes:
I just watched this talk from the goto conference by Walter Bright 
(https://www.youtube.com/watch?v=cQkBOCo8UrE) and he makes reference to 
"concepts."  However,  they look almost identical to Protocols in 
Smalltalk -- something which I would very much like to see in D.

It basically works much like an interface, but instead of declaring it, 
you check the type to see if it defines the appropriate methods.

In fact -- I believe this could be implemented today with __traits and 
static foreach to simply check to see if a type conforms to a protocol 
at compile time.

implementsProtocol!( R, InputRange!(int) );

where InputRange!() could just be a templated interface.

Having this in phobos would be really helpful!   If there is interest 
in this, I'll write a template up and submit it to phobos.

-Shammah
Nov 20 2013
next sibling parent reply "Meta" <jared771 gmail.com> writes:
On Wednesday, 20 November 2013 at 23:27:38 UTC, Shammah 
Chancellor wrote:
 I just watched this talk from the goto conference by Walter 
 Bright (https://www.youtube.com/watch?v=cQkBOCo8UrE) and he 
 makes reference to "concepts."  However,  they look almost 
 identical to Protocols in Smalltalk -- something which I would 
 very much like to see in D.

 It basically works much like an interface, but instead of 
 declaring it, you check the type to see if it defines the 
 appropriate methods.

 In fact -- I believe this could be implemented today with 
 __traits and static foreach to simply check to see if a type 
 conforms to a protocol at compile time.

 implementsProtocol!( R, InputRange!(int) );

 where InputRange!() could just be a templated interface.

 Having this in phobos would be really helpful!   If there is 
 interest in this, I'll write a template up and submit it to 
 phobos.

 -Shammah
Something that's almost exactly what you're looking for: http://dlang.org/phobos/std_typecons.html#.wrap http://dlang.org/phobos/std_typecons.html#.unwrap Also, note that this is pretty much how D templates work. The difference between concepts and protocols is that concepts work at compile time, while protocols work at runtime. Interfaces, a la Java are a hybrid. That's really just an implementation detail, though. None of these terms are all that well defined across all or even most programming languages.
Nov 20 2013
next sibling parent "Dicebot" <public dicebot.lv> writes:
On Wednesday, 20 November 2013 at 23:35:02 UTC, Meta wrote:
 Something that's almost exactly what you're looking for:

 http://dlang.org/phobos/std_typecons.html#.wrap
 http://dlang.org/phobos/std_typecons.html#.unwrap
Wrong-wrong-wrong! `wrap` is different, though with some implementation similarities. First, it only works on polymorphic types. Second, it actually creates a wrapper type while point of typical `implements!(T, I)` is duck typing verification as-is in templated code. It is basically a more generic form of `isXXXRange`.
Nov 20 2013
prev sibling parent reply Shammah Chancellor <anonymous coward.com> writes:
On 2013-11-20 23:35:00 +0000, Meta said:

 On Wednesday, 20 November 2013 at 23:27:38 UTC, Shammah Chancellor wrote:
 I just watched this talk from the goto conference by Walter Bright 
 (https://www.youtube.com/watch?v=cQkBOCo8UrE) and he makes reference to 
 "concepts."  However,  they look almost identical to Protocols in 
 Smalltalk -- something which I would very much like to see in D.
 
 It basically works much like an interface, but instead of declaring it, 
 you check the type to see if it defines the appropriate methods.
 
 In fact -- I believe this could be implemented today with __traits and 
 static foreach to simply check to see if a type conforms to a protocol 
 at compile time.
 
 implementsProtocol!( R, InputRange!(int) );
 
 where InputRange!() could just be a templated interface.
 
 Having this in phobos would be really helpful!   If there is interest 
 in this, I'll write a template up and submit it to phobos.
 
 -Shammah
Something that's almost exactly what you're looking for: http://dlang.org/phobos/std_typecons.html#.wrap http://dlang.org/phobos/std_typecons.html#.unwrap Also, note that this is pretty much how D templates work. The difference between concepts and protocols is that concepts work at compile time, while protocols work at runtime. Interfaces, a la Java are a hybrid. That's really just an implementation detail, though. None of these terms are all that well defined across all or even most programming languages.
Wrap does something similar, but more (since I don't want a wrapper). I just want to check it at compile time. Something like this should be standard instead of isInputRange!() and the plethora of "concept checkers" in various libraries. It seems like we're developing a web of these concept-checkers and it's hard to see what I should implement to be an "InputRange" from the documentation. If there was a standard interface for it, and a library-defined checker, it would be more consistent across the codebase and easier to see what specifically needs to be implemented.
Nov 20 2013
parent "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
On Wednesday, 20 November 2013 at 23:44:53 UTC, Shammah 
Chancellor wrote:
 Wrap does something similar, but more (since I don't want a 
 wrapper).  I just want to check it at compile time.   Something 
 like this should be standard instead of isInputRange!() and the 
 plethora of "concept checkers" in various libraries.   It seems 
 like we're developing a web of these concept-checkers and it's 
 hard to see what I should implement to be an "InputRange" from 
 the documentation.   If there was a standard interface for it, 
 and a library-defined checker, it would be more consistent 
 across the codebase and easier to see what specifically needs 
 to be implemented.
Well, if wrap functioned with structs then templates could use (probably with helper template) void foo(R)() if(is(typeof(wrap!Interface(R))) { }
 it's hard to see what I should implement to be an "InputRange" 
 from the documentation.
I disagree http://dlang.org/phobos/std_range.html#.isInputRange r.empty returns false iff there is more data available in the range. r.front returns the current element in the range. It may return by value or by reference. Calling r.front is allowed only if calling r.empty has, or would have, returned false. r.popFront advances to the next element in the range. Calling r.popFront is allowed only if calling r.empty has, or would have, returned false. Seems really specific about what is needed and a quick: unittest { static assert(isInputRange!MyType); } Gives a validation check. There are range interfaces in std.range already, they just don't include the bear minimum. Using traits provides more power than a simple interface, but sometimes an interface is all you need and should exist anyway. In those cases an easy trait that checks for the type matches the interface would be best.
Nov 20 2013
prev sibling next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 20 November 2013 at 23:27:38 UTC, Shammah 
Chancellor wrote:
 I just watched this talk from the goto conference by Walter 
 Bright (https://www.youtube.com/watch?v=cQkBOCo8UrE) and he 
 makes reference to "concepts."  However,  they look almost 
 identical to Protocols in Smalltalk -- something which I would 
 very much like to see in D.

 It basically works much like an interface, but instead of 
 declaring it, you check the type to see if it defines the 
 appropriate methods.
"concept" is a term from C++ standard discussions which is a bit closer to D and thus has priority ;)
 In fact -- I believe this could be implemented today with 
 __traits and static foreach to simply check to see if a type 
 conforms to a protocol at compile time.

 implementsProtocol!( R, InputRange!(int) );

 where InputRange!() could just be a templated interface.
It has been implemented a dozen of times at the very least, I have personally done it twice :D Key problem with having it as a library type is that it a) does not improve error messages at all over currently used constraints (isInputRange!T) - it can be potentially fixed by improving constraint error detection b) it is impossible to do partial semantic validation of template body based on concept limitation which is the original motivating reason behind concept designs in C++ (with no success so far) So yeah, it is neat, but not neat enough for anyone to actually bother to push it into Phobos :) If you want to do it, it is worth noting that you don't necessarily need to restrict to templated interfaces, normal are also legit.
Nov 20 2013
next sibling parent "froglegs" <barf barf.com> writes:
 b) it is impossible to do partial semantic validation of 
 template body based on concept limitation which is the original 
 motivating reason behind concept designs in C++ (with no 
 success so far)
I'm pretty sure I've read that they have it working in a GCC branch for C++ concepts lite, it does validation at compile time.
Nov 20 2013
prev sibling parent reply Shammah Chancellor <anonymous coward.com> writes:
On 2013-11-20 23:36:54 +0000, Dicebot said:

 So yeah, it is neat, but not neat enough for anyone to actually bother 
 to push it into Phobos :) If you want to do it, it is worth noting that 
 you don't necessarily need to restrict to templated interfaces, normal 
 are also legit.
It should be in phobos since it's widely used in most templated modules. Even if it's simple, it's used all over the place and should be standardized. As for the normals being legit, that's true. However, It would be nice to see an InputRange() interface in the library to be able to see "Ah yes, this is what needs to be implemented to be an input range at compile time."
Nov 20 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 20 November 2013 at 23:46:07 UTC, Shammah 
Chancellor wrote:
 It should be in phobos since it's widely used in most templated 
 modules.   Even if it's simple, it's used all over the place 
 and should be standardized.   As for the normals being legit, 
 that's true.   However,  It would be nice to see an 
 InputRange() interface in the library to be able to see "Ah 
 yes, this is what needs to be implemented to be an input range 
 at compile time."
http://dlang.org/phobos/std_range.html#isInputRange This is the very point - for simple stuff like Phobos ranges defining interface types is actually more verbose than simply creating unique constraints and does not really bring much. It would have been much more interesting if `std.typecons.wrap` would have accepted structs though.
Nov 20 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-11-21 00:48, Dicebot wrote:

 http://dlang.org/phobos/std_range.html#isInputRange

 This is the very point - for simple stuff like Phobos ranges defining
 interface types is actually more verbose than simply creating unique
 constraints and does not really bring much. It would have been much more
 interesting if `std.typecons.wrap` would have accepted structs though.
Currently isInputRange looks like this: template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = void; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); } void foo (R) (R r) if(isInputRange!(R)) I guess his suggestion would be something like this: interface InputRange (R) { property bool empty (); void popFront (); ElementType!(R) front (); } void foo (R) (R r) if(implements!(InputRange!(R))) Personally I think it's nice to have a concrete type like this. -- /Jacob Carlborg
Nov 20 2013
next sibling parent "Dicebot" <public dicebot.lv> writes:
On Thursday, 21 November 2013 at 07:50:11 UTC, Jacob Carlborg 
wrote:
 I guess his suggestion would be something like this:

 interface InputRange (R)
 {
      property bool empty ();
     void popFront ();
     ElementType!(R) front ();
 }

 void foo (R) (R r) if(implements!(InputRange!(R)))

 Personally I think it's nice to have a concrete type like this.
I perfectly understand his suggestion as I have implemented it already few times ;) Again - it is nice, but does not give you any real advantage unless can also be used with `wrap`.
Nov 21 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/20/13 11:50 PM, Jacob Carlborg wrote:
 I guess his suggestion would be something like this:

 interface InputRange (R)
 {
       property bool empty ();
      void popFront ();
      ElementType!(R) front ();
 }

 void foo (R) (R r) if(implements!(InputRange!(R)))
Interfaces can't check for a variety of things that Boolean conditions can (isInfinite comes to mind). Andrei
Nov 21 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-11-21 17:02, Andrei Alexandrescu wrote:

 Interfaces can't check for a variety of things that Boolean conditions
 can (isInfinite comes to mind).
Why wouldn't you be able to put the implementation of isInfinite in an interface? I might no be any advantage over a template like it is now, but it should be possible. One advantage interfaces have is that they support inheritance. It's easy to see which other properties are supported. Not as easy to see that isInfinite "inherits" from isInputRange. -- /Jacob Carlborg
Nov 21 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/21/13 10:45 AM, Jacob Carlborg wrote:
 On 2013-11-21 17:02, Andrei Alexandrescu wrote:

 Interfaces can't check for a variety of things that Boolean conditions
 can (isInfinite comes to mind).
Why wouldn't you be able to put the implementation of isInfinite in an interface?
It's a value, not a type. Walter and I went a couple of times over the idea of using interfaces for concept conformance during the early days, and figured general Boolean logic is more powerful for expressing constraints. Andrei
Nov 21 2013
parent Shammah Chancellor <anonymous coward.com> writes:
On 2013-11-21 19:30:00 +0000, Andrei Alexandrescu said:

 On 11/21/13 10:45 AM, Jacob Carlborg wrote:
 On 2013-11-21 17:02, Andrei Alexandrescu wrote:
 
 Interfaces can't check for a variety of things that Boolean conditions
 can (isInfinite comes to mind).
Why wouldn't you be able to put the implementation of isInfinite in an interface?
It's a value, not a type. Walter and I went a couple of times over the idea of using interfaces for concept conformance during the early days, and figured general Boolean logic is more powerful for expressing constraints. Andrei
I am not suggesting using polymorphism for this. That would to the same diamond problems when things support multiple concepts. All I am suggesting is that Phobos should have a a generalized checker for concepts rather than a bunch of specific templates. And I am suggesting that templated interfaces could be the thing this checks against (or other concrete types as needed) -Shammah
Nov 21 2013
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-11-21 00:27, Shammah Chancellor wrote:
 I just watched this talk from the goto conference by Walter Bright
 (https://www.youtube.com/watch?v=cQkBOCo8UrE) and he makes reference to
 "concepts."  However,  they look almost identical to Protocols in
 Smalltalk -- something which I would very much like to see in D.

 It basically works much like an interface, but instead of declaring it,
 you check the type to see if it defines the appropriate methods.

 In fact -- I believe this could be implemented today with __traits and
 static foreach to simply check to see if a type conforms to a protocol
 at compile time.

 implementsProtocol!( R, InputRange!(int) );

 where InputRange!() could just be a templated interface.

 Having this in phobos would be really helpful!   If there is interest in
 this, I'll write a template up and submit it to phobos.
D you mean something like this: http://forum.dlang.org/thread/l6jgha$1elj$1 digitalmars.com#post-l6kdvj:2428tr:241:40digitalmars.com I would like to have that. -- /Jacob Carlborg
Nov 20 2013
prev sibling parent reply "Dejan Lekic" <dejan.lekic gmail.com> writes:
 Having this in phobos would be really helpful!   If there is 
 interest in this, I'll write a template up and submit it to 
 phobos.

 -Shammah
Why not simply make your own repo somewhere (Gitorious, GitHub, Savannah, etc) and once you are done just announce it at here so we can try it? Or, alternatively, write a DIP for it (http://wiki.dlang.org).
Nov 21 2013
parent reply Shammah Chancellor <anonymous coward.com> writes:
On 2013-11-21 16:13:31 +0000, Dejan Lekic said:

 
 
 Having this in phobos would be really helpful!   If there is interest 
 in this, I'll write a template up and submit it to phobos.
 
 -Shammah
Why not simply make your own repo somewhere (Gitorious, GitHub, Savannah, etc) and once you are done just announce it at here so we can try it? Or, alternatively, write a DIP for it (http://wiki.dlang.org).
Because I currently do not use concepts explicitely anywhere in my Code.. I watched the talk and thought it was an awesome idea. I'm not going to invest the effort for something I am not currently using if everyone else thinks the idea is not useful enough to be part of the standard library. If and when I need to start using concepts more, I would implement a generic template for it, rather than the explicite one. Additionally, I left active participation in the D community about five years ago due to life circumstances -- and only recently rejoined. I am not familiar with the DIP procedures. -Shammah
Nov 21 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-11-22 01:17, Shammah Chancellor wrote:

 Additionally,  I left active participation in the D community about five
 years ago due to life circumstances -- and only recently rejoined. I am
 not familiar with the DIP procedures.
DIP - D Improvement Proposal. Just look at the other ones to get a feel for the structure. Then post here if you decide to write one. http://wiki.dlang.org/DIPs -- /Jacob Carlborg
Nov 21 2013