View mode: basic / threaded / horizontal-split · Log in · Help
April 07, 2007
concepts and interfaces
Inspired by this video (linked by an earlier post, and very interesting; I really hope that D will get something similar)

http://video.google.com/videoplay?docid=-1790714981047186825&hl=en

I started to think about the relation of concepts and interfaces.
In a way both serve very similar purposes, namely supporting polymorphism. The major difference is of course that one is used at compile time and the other one at run-time. Still, in the end both are just a way to describe the constraints which have to be fulfilled by a type in order to be usable in a specific generic way.
Interestingly the syntactic differences are nevertheless considerable. 
My main point in this post is that this is mainly for historical reasons and that it might be beneficial to think about making interfaces and concepts more similar to each other.

Some more specific thoughts:

- why does conformance to an interface have to be specified explicitly (as in class C implements interface I)? Why not do post-hoc checking as with concepts/templates?
Using an object via an interface implies two things - the compiler has to check whether the objects class actually implements all methods required by the interface and the object reference has to be manipulated in such a way that when using it when assigned to an interface reference the right method calls are done. If we assume that all casts from an object to an interface reference are visible at compile time both of these could be done *at the point of the cast* (equivalent to the way type checking is done for template instantiation).

- why not make concepts obligatory?
One of the beneficial aspects of using interfaces is in my opinion that it forces you to be specific about which properties you expect from the plugged in types. This is something which is missing from generic programming and which is supposed to be improved by introducing concepts. C++ of course has to stay backwards-compatible therefore concepts will be completely optional.
In D OTOH concepts could actually be made obligatory forcing the programmer to be explicit about the properties of the types which can be plugged into a template/generic class.

- interface_maps
With implicit implementation of interfaces the concept_map idea might come in handy for interfaces as well, allowing to do some adjustments to make a class conforming to an interface.

Just some food for thought.

cheers
Martin Hinsch
April 08, 2007
Re: concepts and interfaces
Martin Hinsch wrote:
> Inspired by this video (linked by an earlier post, and very interesting; I really hope that D will get something similar)
> 
> http://video.google.com/videoplay?docid=-1790714981047186825&hl=en
> 
> I started to think about the relation of concepts and interfaces.
> In a way both serve very similar purposes, namely supporting polymorphism. The major difference is of course that one is used at compile time and the other one at run-time. Still, in the end both are just a way to describe the constraints which have to be fulfilled by a type in order to be usable in a specific generic way.
> Interestingly the syntactic differences are nevertheless considerable. 
> My main point in this post is that this is mainly for historical reasons and that it might be beneficial to think about making interfaces and concepts more similar to each other.
> 
> Some more specific thoughts:
> 
> - why does conformance to an interface have to be specified explicitly (as in class C implements interface I)? Why not do post-hoc checking as with concepts/templates?
> Using an object via an interface implies two things - the compiler has to check whether the objects class actually implements all methods required by the interface and the object reference has to be manipulated in such a way that when using it when assigned to an interface reference the right method calls are done. If we assume that all casts from an object to an interface reference are visible at compile time both of these could be done *at the point of the cast* (equivalent to the way type checking is done for template instantiation).
> 
> - why not make concepts obligatory?
> One of the beneficial aspects of using interfaces is in my opinion that it forces you to be specific about which properties you expect from the plugged in types. This is something which is missing from generic programming and which is supposed to be improved by introducing concepts. C++ of course has to stay backwards-compatible therefore concepts will be completely optional.
> In D OTOH concepts could actually be made obligatory forcing the programmer to be explicit about the properties of the types which can be plugged into a template/generic class.
> 
> - interface_maps
> With implicit implementation of interfaces the concept_map idea might come in handy for interfaces as well, allowing to do some adjustments to make a class conforming to an interface.
> 
> Just some food for thought.
> 
> cheers
> Martin Hinsch

I'm not sure D necessarily needs to support this the same way as C++. 
However the C++ developers of concepts are very smart people and have 
obviously put a lot of thought into this.  We should consider all options.

It would be nice when C++0x comes out we could say, D's had all these 
features for years.  If your going to switch, why not switch to D.

-Joel
April 08, 2007
Re: concepts and interfaces
I would imagine that complete compile-time introspection information 
would make a lot of this much easier in D -- a lot of it could be 
implemented in the libraries.

> - why does conformance to an interface have to be specified explicitly (as in class C implements interface I)? Why not do post-hoc checking as with concepts/templates?
> Using an object via an interface implies two things - the compiler has to check whether the objects class actually implements all methods required by the interface and the object reference has to be manipulated in such a way that when using it when assigned to an interface reference the right method calls are done. If we assume that all casts from an object to an interface reference are visible at compile time both of these could be done *at the point of the cast* (equivalent to the way type checking is done for template instantiation).
I agree. This idea (often called structural typing, as opposed to 
nominative typing) is often much more flexible. There can be a pitfall, 
though, in that you then have less distinction between types. For instance

   typedef FirstInterface SecondInterface;

would then be pointless, since they are (implicitly?) convertible to 
each other.

If you needed to explicitly specify the conversion, that problem might 
go away. And with compile-time introspection, you could implement it 
just in the compiler, without any compiler assistance:

   T convert(T, U)(U value)
   {
       static assert((is(U == interface) || is(U == class)) && is(T == 
interface));
       // Check that U conforms to T
       // Now grab pointers to each of U's relevant functions from its 
vtbl, and generate a new vtbl and object for T
   }

> - interface_maps
> With implicit implementation of interfaces the concept_map idea might come in handy for interfaces as well, allowing to do some adjustments to make a class conforming to an interface.
I agree. I think, with reflection, this could be implemented in userland 
like above. Perhaps also relevant is C#'s explicit interface 
implementation, which (IIRC) allows you to implement the interface under 
different names (but only within the class; not in retrospect).

> - why not make concepts obligatory?
> One of the beneficial aspects of using interfaces is in my opinion that it forces you to be specific about which properties you expect from the plugged in types. This is something which is missing from generic programming and which is supposed to be improved by introducing concepts. C++ of course has to stay backwards-compatible therefore concepts will be completely optional.
> In D OTOH concepts could actually be made obligatory forcing the programmer to be explicit about the properties of the types which can be plugged into a template/generic class.
Ideally, yes.

Just of the top of my head, though, there may be practical concerns 
which prevent this.  You can do complicated things with templates in D, 
so you can have complicated requirements. Specifying such constraints 
could perhaps be difficult, lengthy, or impossible, depending on the 
syntax of your constraint specifications. Sometimes it's just not worth 
it, and making it compulsory could just make it irritating. Since it's 
effectively type-checking for your template parameters, I guess we could 
expect the same annoyances that we get with static type checking. I 
think you can conclude from this that you would almost definitely need 
some kind of back door, like a cast.

C# makes the specifications compulsory with where clauses -- most of the 
time, this is a good feature; I would perhaps even say all the time 
except for it's limitation in specification, especially of constructors. 
Of course, you can't do any where near as much with C# generics as with 
D templates.

C++'s concepts seem to be quite expressive. Perhaps they would be 
expressive enough to make compulsory. Perhaps backwards compatibility 
with pre-concepts code is the reason they aren't compulsory.

Cheers,

Reiner
April 08, 2007
Re: concepts and interfaces
Martin Hinsch wrote

> The major difference

I do not see something like axioms in D.

-manfred
April 08, 2007
Re: concepts and interfaces
Manfred Nowak wrote:
> Martin Hinsch wrote
> 
>> The major difference
> 
> I do not see something like axioms in D.
> 
> -manfred
I've found it difficult to actually understand the use of axioms in 
C++0x concepts.  In general, assertions about semantic behaviors such as 
the examples show (Associativity, etc) can't be trivially (ie, through a 
simple type-checker) proven -- rather, it involves some more elaborate 
theorem proving. I haven't heard any hype about involving automated 
theorem proving in C++0x, so I guess checking of this is either:
  - nonexistent; or
  - done at runtime with asserts -- seems highly reminiscent of in and 
out bodies, and invariants.

I can see the possibility of allowing the compiler to transform the code 
based on these axioms, but it would have to be very insightful to really 
do this in the general case. I think built-in axioms like the 
equivalence (in D) of a = a + b; and a += b; have more room for 
exploitation.

As a form of documentation, it could be useful, but I'm not sure to what 
extent it is better than simply:

// must have a*(b*c) == (a*b)*c for all a, b, c

Maybe someone else knows what use axioms serve?

Cheers,

Reiner
April 08, 2007
Re: concepts and interfaces
Reiner Pope wrote
> Maybe someone else knows what use axioms serve?

Use your favorite search engine, Luke!

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2193.pdf

-manfred
April 08, 2007
Re: concepts and interfaces
janderson wrote:
> Martin Hinsch wrote:
>> Inspired by this video (linked by an earlier post, and very 
>> interesting; I really hope that D will get something similar)
>>
>> http://video.google.com/videoplay?docid=-1790714981047186825&hl=en
>>
>> I started to think about the relation of concepts and interfaces.
>> In a way both serve very similar purposes, namely supporting 
>> polymorphism. The major difference is of course that one is used at 
>> compile time and the other one at run-time. Still, in the end both are 
>> just a way to describe the constraints which have to be fulfilled by a 
>> type in order to be usable in a specific generic way.
>> Interestingly the syntactic differences are nevertheless considerable. 
>> My main point in this post is that this is mainly for historical 
>> reasons and that it might be beneficial to think about making 
>> interfaces and concepts more similar to each other.
>>
>> Some more specific thoughts:
>>
>> - why does conformance to an interface have to be specified explicitly 
>> (as in class C implements interface I)? Why not do post-hoc checking 
>> as with concepts/templates?
>> Using an object via an interface implies two things - the compiler has 
>> to check whether the objects class actually implements all methods 
>> required by the interface and the object reference has to be 
>> manipulated in such a way that when using it when assigned to an 
>> interface reference the right method calls are done. If we assume that 
>> all casts from an object to an interface reference are visible at 
>> compile time both of these could be done *at the point of the cast* 
>> (equivalent to the way type checking is done for template instantiation).
>>
>> - why not make concepts obligatory?
>> One of the beneficial aspects of using interfaces is in my opinion 
>> that it forces you to be specific about which properties you expect 
>> from the plugged in types. This is something which is missing from 
>> generic programming and which is supposed to be improved by 
>> introducing concepts. C++ of course has to stay backwards-compatible 
>> therefore concepts will be completely optional.
>> In D OTOH concepts could actually be made obligatory forcing the 
>> programmer to be explicit about the properties of the types which can 
>> be plugged into a template/generic class.
>>
>> - interface_maps
>> With implicit implementation of interfaces the concept_map idea might 
>> come in handy for interfaces as well, allowing to do some adjustments 
>> to make a class conforming to an interface.
>>
>> Just some food for thought.
>>
>> cheers
>> Martin Hinsch
> 
> I'm not sure D necessarily needs to support this the same way as C++. 
> However the C++ developers of concepts are very smart people and have 
> obviously put a lot of thought into this.  We should consider all options.
> 
> It would be nice when C++0x comes out we could say, D's had all these 
> features for years.  If your going to switch, why not switch to D.
> 
> -Joel


Just a thought, could concepts possibly be jammed into contracts?

void Foo(T)(T t)
in
{
    static assert(IsIterator!(T));
}
body
{

}

How IsIterator is defined is another matter.  Perhaps a compile-time 
function:

bool IsIterator(T)()
{
	if (T contains opEquals)
	{
		return true;
	}
	ect...
}

Something like that.  Probably would need some more thought to be a 
complete solution.

-Joel
April 08, 2007
Re: concepts and interfaces
janderson wrote:
> janderson wrote:
>> Martin Hinsch wrote:
>>> Inspired by this video (linked by an earlier post, and very
>>> interesting; I really hope that D will get something similar)
>>>
>>> http://video.google.com/videoplay?docid=-1790714981047186825&hl=en
>>>
>>> I started to think about the relation of concepts and interfaces.
>>> In a way both serve very similar purposes, namely supporting
>>> polymorphism. The major difference is of course that one is used at
>>> compile time and the other one at run-time. Still, in the end both
>>> are just a way to describe the constraints which have to be fulfilled
>>> by a type in order to be usable in a specific generic way.
>>> Interestingly the syntactic differences are nevertheless
>>> considerable. My main point in this post is that this is mainly for
>>> historical reasons and that it might be beneficial to think about
>>> making interfaces and concepts more similar to each other.
>>>
>>> Some more specific thoughts:
>>>
>>> - why does conformance to an interface have to be specified
>>> explicitly (as in class C implements interface I)? Why not do
>>> post-hoc checking as with concepts/templates?
>>> Using an object via an interface implies two things - the compiler
>>> has to check whether the objects class actually implements all
>>> methods required by the interface and the object reference has to be
>>> manipulated in such a way that when using it when assigned to an
>>> interface reference the right method calls are done. If we assume
>>> that all casts from an object to an interface reference are visible
>>> at compile time both of these could be done *at the point of the
>>> cast* (equivalent to the way type checking is done for template
>>> instantiation).
>>>
>>> - why not make concepts obligatory?
>>> One of the beneficial aspects of using interfaces is in my opinion
>>> that it forces you to be specific about which properties you expect
>>> from the plugged in types. This is something which is missing from
>>> generic programming and which is supposed to be improved by
>>> introducing concepts. C++ of course has to stay backwards-compatible
>>> therefore concepts will be completely optional.
>>> In D OTOH concepts could actually be made obligatory forcing the
>>> programmer to be explicit about the properties of the types which can
>>> be plugged into a template/generic class.
>>>
>>> - interface_maps
>>> With implicit implementation of interfaces the concept_map idea might
>>> come in handy for interfaces as well, allowing to do some adjustments
>>> to make a class conforming to an interface.
>>>
>>> Just some food for thought.
>>>
>>> cheers
>>> Martin Hinsch
>>
>> I'm not sure D necessarily needs to support this the same way as C++.
>> However the C++ developers of concepts are very smart people and have
>> obviously put a lot of thought into this.  We should consider all
>> options.
>>
>> It would be nice when C++0x comes out we could say, D's had all these
>> features for years.  If your going to switch, why not switch to D.
>>
>> -Joel
> 
> 
> Just a thought, could concepts possibly be jammed into contracts?
> 
> void Foo(T)(T t)
> in
> {
>     static assert(IsIterator!(T));
> }
> body
> {
> 
> }

Not nicely, as concepts are able to affect things
like overload resolution; what's wanted if Foo
requires IsIterator(T) is not a compile-time error
about an assertion failing, but that the function
simply drop out of the overload set (so that some
other function might match).  At least, that's
the C++ way.  Of course D can be Different.

-- James
April 08, 2007
Re: concepts and interfaces
Reiner Pope Wrote:

> I would imagine that complete compile-time introspection information 
> would make a lot of this much easier in D -- a lot of it could be 
> implemented in the libraries.
> 
> > - why does conformance to an interface have to be specified explicitly (as in class C implements interface I)? Why not do post-hoc checking as with concepts/templates?
> > Using an object via an interface implies two things - the compiler has to check whether the objects class actually implements all methods required by the interface and the object reference has to be manipulated in such a way that when using it when assigned to an interface reference the right method calls are done. If we assume that all casts from an object to an interface reference are visible at compile time both of these could be done *at the point of the cast* (equivalent to the way type checking is done for template instantiation).
> I agree. This idea (often called structural typing, as opposed to 

Cool, there's even a name for this! I considered myself quite clever to come up with the idea ;-). (so much for amateur-level computer science... ;-)

> nominative typing) is often much more flexible. There can be a pitfall, 
> though, in that you then have less distinction between types. For instance
> 
>     typedef FirstInterface SecondInterface;
> 
> would then be pointless, since they are (implicitly?) convertible to 
> each other.
> 

Hmm, I don't see why that would be a problem. Isn't that the whole point? You could get rid of the clumsy parallel inheritance hierarchy and even apply interfaces to classes retroactively. BTW, if I'm not mistaken, gcc had a c++ extension at some point that worked similar...
On second thought though, you of course lose the ability to "tag" classes by making them derive from a specific interface...

> If you needed to explicitly specify the conversion, that problem might 
> go away. And with compile-time introspection, you could implement it 
> just in the compiler, without any compiler assistance:
> 
>     T convert(T, U)(U value)
>     {
>         static assert((is(U == interface) || is(U == class)) && is(T == 
> interface));
>         // Check that U conforms to T
>         // Now grab pointers to each of U's relevant functions from its 
> vtbl, and generate a new vtbl and object for T
>     }
> 
> > - interface_maps
> > With implicit implementation of interfaces the concept_map idea might come in handy for interfaces as well, allowing to do some adjustments to make a class conforming to an interface.
> I agree. I think, with reflection, this could be implemented in userland 
> like above. Perhaps also relevant is C#'s explicit interface 
> implementation, which (IIRC) allows you to implement the interface under 
> different names (but only within the class; not in retrospect).
> 
> > - why not make concepts obligatory?
> > One of the beneficial aspects of using interfaces is in my opinion that it forces you to be specific about which properties you expect from the plugged in types. This is something which is missing from generic programming and which is supposed to be improved by introducing concepts. C++ of course has to stay backwards-compatible therefore concepts will be completely optional.
> > In D OTOH concepts could actually be made obligatory forcing the programmer to be explicit about the properties of the types which can be plugged into a template/generic class.
> Ideally, yes.
> 
> Just of the top of my head, though, there may be practical concerns 
> which prevent this.  You can do complicated things with templates in D, 
> so you can have complicated requirements. Specifying such constraints 
> could perhaps be difficult, lengthy, or impossible, depending on the 
> syntax of your constraint specifications. Sometimes it's just not worth 
> it, and making it compulsory could just make it irritating. Since it's 
> effectively type-checking for your template parameters, I guess we could 
> expect the same annoyances that we get with static type checking. I 

Could you give an example?

> think you can conclude from this that you would almost definitely need 
> some kind of back door, like a cast.
> 

The easiest solution would of course be to include a built in "any"-concept which forwards type checking to instantiation time.

> C# makes the specifications compulsory with where clauses -- most of the 
> time, this is a good feature; I would perhaps even say all the time 
> except for it's limitation in specification, especially of constructors. 
> Of course, you can't do any where near as much with C# generics as with 
> D templates.
> 
> C++'s concepts seem to be quite expressive. Perhaps they would be 
> expressive enough to make compulsory. Perhaps backwards compatibility 
> with pre-concepts code is the reason they aren't compulsory.
> 

They actually even say so in the talk.
April 08, 2007
Re: concepts and interfaces
James Dennett Wrote:

> janderson wrote:
> > janderson wrote:
> >> Martin Hinsch wrote:
> >>> Inspired by this video (linked by an earlier post, and very
> >>> interesting; I really hope that D will get something similar)
> >>>
> >>> http://video.google.com/videoplay?docid=-1790714981047186825&hl=en
> >>>
> >>> I started to think about the relation of concepts and interfaces.
> >>> In a way both serve very similar purposes, namely supporting
> >>> polymorphism. The major difference is of course that one is used at
> >>> compile time and the other one at run-time. Still, in the end both
> >>> are just a way to describe the constraints which have to be fulfilled
> >>> by a type in order to be usable in a specific generic way.
> >>> Interestingly the syntactic differences are nevertheless
> >>> considerable. My main point in this post is that this is mainly for
> >>> historical reasons and that it might be beneficial to think about
> >>> making interfaces and concepts more similar to each other.
> >>>
> >>> Some more specific thoughts:
> >>>
> >>> - why does conformance to an interface have to be specified
> >>> explicitly (as in class C implements interface I)? Why not do
> >>> post-hoc checking as with concepts/templates?
> >>> Using an object via an interface implies two things - the compiler
> >>> has to check whether the objects class actually implements all
> >>> methods required by the interface and the object reference has to be
> >>> manipulated in such a way that when using it when assigned to an
> >>> interface reference the right method calls are done. If we assume
> >>> that all casts from an object to an interface reference are visible
> >>> at compile time both of these could be done *at the point of the
> >>> cast* (equivalent to the way type checking is done for template
> >>> instantiation).
> >>>
> >>> - why not make concepts obligatory?
> >>> One of the beneficial aspects of using interfaces is in my opinion
> >>> that it forces you to be specific about which properties you expect
> >>> from the plugged in types. This is something which is missing from
> >>> generic programming and which is supposed to be improved by
> >>> introducing concepts. C++ of course has to stay backwards-compatible
> >>> therefore concepts will be completely optional.
> >>> In D OTOH concepts could actually be made obligatory forcing the
> >>> programmer to be explicit about the properties of the types which can
> >>> be plugged into a template/generic class.
> >>>
> >>> - interface_maps
> >>> With implicit implementation of interfaces the concept_map idea might
> >>> come in handy for interfaces as well, allowing to do some adjustments
> >>> to make a class conforming to an interface.
> >>>
> >>> Just some food for thought.
> >>>
> >>> cheers
> >>> Martin Hinsch
> >>
> >> I'm not sure D necessarily needs to support this the same way as C++.
> >> However the C++ developers of concepts are very smart people and have
> >> obviously put a lot of thought into this.  We should consider all
> >> options.
> >>
> >> It would be nice when C++0x comes out we could say, D's had all these
> >> features for years.  If your going to switch, why not switch to D.
> >>
> >> -Joel
> > 
> > 
> > Just a thought, could concepts possibly be jammed into contracts?
> > 
> > void Foo(T)(T t)
> > in
> > {
> >     static assert(IsIterator!(T));
> > }
> > body
> > {
> > 
> > }
> 
> Not nicely, as concepts are able to affect things
> like overload resolution; what's wanted if Foo
> requires IsIterator(T) is not a compile-time error
> about an assertion failing, but that the function
> simply drop out of the overload set (so that some
> other function might match).  At least, that's
> the C++ way.  Of course D can be Different.
> 
> -- James

Plus, the charme of C++ concepts is that they are completely separate entities with a syntax which is very similar to a class declaration. IMHO that makes it very easy to really think of them as abstract reusable entities which describe a _concept_.
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home