Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
September 21, 2010 LazyInterface (simplified Boost.Interfaces) | ||||
---|---|---|---|---|
| ||||
Hi. I heard Boost.Interfaces recently. Then, it implemented by D. http://github.com/9rnsr/scrap/blob/master/interfaces/interfaces.d How about you? |
September 21, 2010 Re: LazyInterface (simplified Boost.Interfaces) | ||||
---|---|---|---|---|
| ||||
Posted in reply to kenji hara | kenji hara:
> I heard Boost.Interfaces recently. Then, it implemented by D. http://github.com/9rnsr/scrap/blob/master/interfaces/interfaces.d How about you?
// static auto opDispatch(string Name, Args...)(Args args)
// {
// enum stc = 's';
// mixin(dispatch);
// }
}
But static opDispatch works:
struct Foo {
static void opDispatch(string name, Args...)(Args args) {
static assert(name == "hello");
}
}
void main() {
Foo.hello(10, 20);
}
So if you have found a bug you may add a minimized case in Bugzilla.
Bye,
bearophile
|
September 22, 2010 Re: LazyInterface (simplified Boost.Interfaces) | ||||
---|---|---|---|---|
| ||||
Posted in reply to kenji hara | On 9/21/10 14:36 CDT, kenji hara wrote:
> Hi.
>
> I heard Boost.Interfaces recently. Then, it implemented by D.
> http://github.com/9rnsr/scrap/blob/master/interfaces/interfaces.d
>
> How about you?
Hi Kenji,
Looking very interesting. One thing I'd change would be the interface definition. Ideally the client code would look like this:
static class A
{
int draw(){ return 10; }
}
static class B : A
{
int draw(){ return 20; }
}
interface Drawable
{
int draw();
};
unittest
{
Drawable d = adaptTo!Drawable(new A);
assert(d.draw() == 10);
d = adaptTo!Drawable(new B);
assert(d.draw() == 20);
}
adaptTo would rely on introspection and code generation to define an implementation of Drawable that forwards calls to an object.
Andrei
|
September 22, 2010 Re: LazyInterface (simplified Boost.Interfaces) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Thanks for your advise, Andrei. I will try to implement adaptTo!T . Kenji Hara 2010/9/22 Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>: > On 9/21/10 14:36 CDT, kenji hara wrote: >> >> Hi. >> >> I heard Boost.Interfaces recently. Then, it implemented by D. http://github.com/9rnsr/scrap/blob/master/interfaces/interfaces.d >> >> How about you? > > Hi Kenji, > > > Looking very interesting. One thing I'd change would be the interface definition. Ideally the client code would look like this: > > static class A > { > int draw(){ return 10; } > } > > static class B : A > { > int draw(){ return 20; } > } > > interface Drawable > { > int draw(); > }; > > unittest > { > Drawable d = adaptTo!Drawable(new A); > assert(d.draw() == 10); > d = adaptTo!Drawable(new B); > assert(d.draw() == 20); > } > > adaptTo would rely on introspection and code generation to define an implementation of Drawable that forwards calls to an object. > > > Andrei > |
September 23, 2010 Re: LazyInterface (simplified Boost.Interfaces) | ||||
---|---|---|---|---|
| ||||
I implemented adaptTo . http://github.com/9rnsr/scrap/blob/master/interfaces/interfaces.d Kenji Hara 2010/9/22 kenji hara <k.hara.pg@gmail.com>: > Thanks for your advise, Andrei. > > I will try to implement adaptTo!T . > > Kenji Hara > > 2010/9/22 Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>: >> On 9/21/10 14:36 CDT, kenji hara wrote: >>> >>> Hi. >>> >>> I heard Boost.Interfaces recently. Then, it implemented by D. http://github.com/9rnsr/scrap/blob/master/interfaces/interfaces.d >>> >>> How about you? >> >> Hi Kenji, >> >> >> Looking very interesting. One thing I'd change would be the interface definition. Ideally the client code would look like this: >> >> static class A >> { >> int draw(){ return 10; } >> } >> >> static class B : A >> { >> int draw(){ return 20; } >> } >> >> interface Drawable >> { >> int draw(); >> }; >> >> unittest >> { >> Drawable d = adaptTo!Drawable(new A); >> assert(d.draw() == 10); >> d = adaptTo!Drawable(new B); >> assert(d.draw() == 20); >> } >> >> adaptTo would rely on introspection and code generation to define an implementation of Drawable that forwards calls to an object. >> >> >> Andrei >> > |
September 23, 2010 Re: LazyInterface (simplified Boost.Interfaces) | ||||
---|---|---|---|---|
| ||||
Posted in reply to kenji hara | On 9/23/10 8:09 CDT, kenji hara wrote:
> I implemented adaptTo .
>
> http://github.com/9rnsr/scrap/blob/master/interfaces/interfaces.d
>
> Kenji Hara
This is great work, Kenji! I'm very glad about this because it uses introspection to implement an important feature. Such post-hoc interface binding is a core feature in quite a few languages.
If you agree, I am committed to advocate adopting this abstraction for Phobos in module std.typecons, with credit.
All - a bit of bikeshedding - what is a better name for adaptTo? I know there is a consecrated name for such late matching of an interface, but I can't remember it.
A few nits about the implementation:
* In line 73 it looks like you don't support covariance of return types. Could you fix that? Example (add it to the unittests, too):
class C
{
long draw(){ return 10; }
}
interface Drawable
{
int draw();
}
The override should be legit.
* Throughout: everything that is a value should start with a lowercase letter; everything that is not a value (e.g. type, type tuple) should start with an uppercase letter. In particular your "result" convention should use "Result" for type results and "result" for value results.
* Code shouldn't use uppercase "i" as a symbol name - it's confusable with "1".
Congratulations! This is great work indeed.
Thanks,
Andrei
|
September 23, 2010 Re: LazyInterface (simplified Boost.Interfaces) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Thanks very much! > If you agree, I am committed to advocate adopting this abstraction for Phobos in module std.typecons, with credit. Of couse, I agree. > All - a bit of bikeshedding - what is a better name for adaptTo? I know there is a consecrated name for such late matching of an interface, but I can't remember it. from here(http://www.coderage.com/interfaces/), I found two keywords. - Non-intrusive dynamic polymorphism - Aspect Oriented Programming How about you? I understood the covariance problem. I think that I should also support it. By the way, there is a question about this sample code. > class C > { > long draw(){ return 10; } > } > interface Drawable > { > int draw(); > } In my opinion, C can derive from Drawable ideally. so, it will be satisfied with this code. static assert(isCovariantWith!(typeof(C.draw), typeof(Drawable.draw))); Correctness of it is like this, isn't it? class C { int draw(){ return 10; } } interface Drawable { long draw(); } > The override should be legit. I will fix them. Kenji Hara |
September 23, 2010 Re: LazyInterface (simplified Boost.Interfaces) | ||||
---|---|---|---|---|
| ||||
I supported covariance of return types.
Please check it.
2010/9/24 kenji hara <k.hara.pg@gmail.com>:
> Thanks very much!
>
>> If you agree, I am committed to advocate adopting this abstraction for Phobos in module std.typecons, with credit.
> Of couse, I agree.
>
>
>> All - a bit of bikeshedding - what is a better name for adaptTo? I know there is a consecrated name for such late matching of an interface, but I can't remember it.
> from here(http://www.coderage.com/interfaces/), I found two keywords.
> - Non-intrusive dynamic polymorphism
> - Aspect Oriented Programming
> How about you?
>
>
> I understood the covariance problem. I think that I should also support it. By the way, there is a question about this sample code.
>> class C
>> {
>> long draw(){ return 10; }
>> }
>> interface Drawable
>> {
>> int draw();
>> }
> In my opinion, C can derive from Drawable ideally.
> so, it will be satisfied with this code.
>
> static assert(isCovariantWith!(typeof(C.draw), typeof(Drawable.draw)));
>
> Correctness of it is like this, isn't it?
> class C
> {
> int draw(){ return 10; }
> }
> interface Drawable
> {
> long draw();
> }
>
>
>> The override should be legit.
> I will fix them.
>
>
> Kenji Hara
>
|
September 24, 2010 Re: LazyInterface (simplified Boost.Interfaces) | ||||
---|---|---|---|---|
| ||||
Posted in reply to kenji hara | On 9/23/10 14:13 CDT, kenji hara wrote: > I supported covariance of return types. > Please check it. Excellent! And sorry, indeed I got it backwards: if the interface returns e.g. long, the implementation is allowed to return int. Generally if the interface returns T, the implementation is allowed to return any U implicitly convertible to T. > 2010/9/24 kenji hara<k.hara.pg@gmail.com>: >> Thanks very much! >> >>> If you agree, I am committed to advocate adopting this abstraction for Phobos in module std.typecons, with credit. >> Of couse, I agree. Perfect, thanks! Stay tuned. >>> All - a bit of bikeshedding - what is a better name for adaptTo? I know there is a consecrated name for such late matching of an interface, but I can't remember it. >> from here(http://www.coderage.com/interfaces/), I found two keywords. >> - Non-intrusive dynamic polymorphism >> - Aspect Oriented Programming >> How about you? Well the first term is, I think, invented by the author of the Interfaces Boost library, and the second is unrelated. I discussed your implementation with Walter and he recognized it as an instance of structural conformance. Indeed, check this paper that does the same for Java: http://tinyurl.com/2ct69t7. I think adaptTo should be therefore called structuralCast. Also, Kenji, I very much recommend you read this paper: http://tinyurl.com/2e3vmmx. It contains further idea on how you can extend structuralCast to multiple interfaces. I actually have some old code that might help there. Here are a few more suggestions for future work: * The object returned by structuralCast should offer the ability to access the original object, be it via an explicit function or an implicit mechanism such as alias this. * structuralCast should work with a struct as input. The object returned stores a copy of the struct inside and implements the interface in terms of calls to the struct's member functions. * structuralCast should work with a pointer to a struct as input and work as above, except it doesn't make a copy - it stores the pointer and forwards method calls to it. (This is unsafe.) * structuralCast should work to cast a struct to another. The requirements for accepting a structural cast from S to T are as follows: a) T must be a prefix of S, i.e. all fields in T appear in the same order and with the same names at the beginning of S. For example: struct Point2D { int x, y; } struct Point3D { int x, y, z; } struct Point2DColor { int x, y; Color color; } struct Point3DColor { int x, y, z; Color color; } In the example above, Point2D is a prefix of all others, and Point3D is a prefix of Point3DColor. b) All fields that are common to S and T must be public in both. structuralCast should not give access to private data and provide opportunity for breaking invariants. If these conditions are satisfied, then given a reference or a pointer to S, structuralCast gives you back (safely) a reference or a pointer to T. The implementation is a simple cast of pointers, but the point is that the function is @trusted, i.e. it provides a safe restricted interface over the unsafe cast. Andrei |
Copyright © 1999-2021 by the D Language Foundation