| Thread overview | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 24, 2010 ReturnThis/@chain | ||||
|---|---|---|---|---|
| ||||
I'm working on the next iteration of my Plot2Kill library, and I **really**
have fallen in love with property chaining. It's the greatest thing since
sliced arrays. However, I've run into an issue that I had previously overlooked:
class Foo {
Type _val;
typeof(this) val(Type newVal) {
_val = newVal;
return this;
}
}
class Bar : Foo {
// More properties.
}
void main() {
auto bar = new Bar;
bar.val(someValue).barProperty(someOtherValue); // Won't work.
}
Given that D2 is mostly finalized, it may be a little late for this, but would
it be feasible, at least far down the road, to add something like an @chain
annotation, which would only allow a member function to return this and would
implicitly downcast it to the subtype that was passed in as the this pointer?
For example, assume we attached @chain to Foo.val():
pragma(msg, typeof(bar.val(someValue))); // Bar, not Foo.
| ||||
July 24, 2010 Re: ReturnThis/@chain | ||||
|---|---|---|---|---|
| ||||
Posted in reply to dsimcha | On 7/23/2010 10:21 PM, dsimcha wrote:
> class Foo {
> Type _val;
>
> typeof(this) val(Type newVal) {
> _val = newVal;
> return this;
> }
> }
>
> class Bar : Foo {
> // More properties.
> }
>
> void main() {
> auto bar = new Bar;
> bar.val(someValue).barProperty(someOtherValue); // Won't work.
> }
What about using templates? I haven't tested this code but it seems like I've accomplished something similar before.
class Foo(T=Foo) {
Type _val;
T val(Type newVal) {
_val = newVal;
return this;
}
}
class Bar : Foo!(Bar) {
// More properties.
}
| |||
July 24, 2010 Re: ReturnThis/@chain | ||||
|---|---|---|---|---|
| ||||
Posted in reply to dsimcha | "dsimcha" <dsimcha@yahoo.com> wrote in message news:i2dio5$25mi$1@digitalmars.com... > > It's the greatest thing since sliced arrays. That's the greatest quote since...well, I can't top that one, so I'm not going to try :) | |||
July 24, 2010 Re: ReturnThis/@chain | ||||
|---|---|---|---|---|
| ||||
Posted in reply to dsimcha | dsimcha wrote:
> I'm working on the next iteration of my Plot2Kill library, and I **really** have fallen in love with property chaining. It's the greatest thing since sliced arrays. However, I've run into an issue that I had previously overlooked:
>
> class Foo {
> Type _val;
>
> typeof(this) val(Type newVal) {
> _val = newVal;
> return this;
> }
> }
>
> class Bar : Foo {
> // More properties.
> }
>
> void main() {
> auto bar = new Bar;
> bar.val(someValue).barProperty(someOtherValue); // Won't work.
> }
>
> Given that D2 is mostly finalized, it may be a little late for this, but would
> it be feasible, at least far down the road, to add something like an @chain
> annotation, which would only allow a member function to return this and would
> implicitly downcast it to the subtype that was passed in as the this pointer?
> For example, assume we attached @chain to Foo.val():
>
> pragma(msg, typeof(bar.val(someValue))); // Bar, not Foo.
Why not use covariance? Or is that too much boilerplate?
this will work:
class Bar : Foo {
override typeof(this) val(Type newVal) {
return super(newVal);
}
}
This could be automated with a mixin.
| |||
July 24, 2010 Re: ReturnThis/@chain | ||||
|---|---|---|---|---|
| ||||
Posted in reply to dsimcha | Dnia 24-07-2010 o 04:21:57 dsimcha <dsimcha@yahoo.com> napisał(a):
> I'm working on the next iteration of my Plot2Kill library, and I **really**
> have fallen in love with property chaining. It's the greatest thing since
> sliced arrays. However, I've run into an issue that I had previously overlooked:
>
> class Foo {
> Type _val;
>
> typeof(this) val(Type newVal) {
> _val = newVal;
> return this;
> }
> }
>
> class Bar : Foo {
> // More properties.
> }
>
> void main() {
> auto bar = new Bar;
> bar.val(someValue).barProperty(someOtherValue); // Won't work.
> }
>
> Given that D2 is mostly finalized, it may be a little late for this, but would
> it be feasible, at least far down the road, to add something like an @chain
> annotation, which would only allow a member function to return this and would
> implicitly downcast it to the subtype that was passed in as the this pointer?
> For example, assume we attached @chain to Foo.val():
>
> pragma(msg, typeof(bar.val(someValue))); // Bar, not Foo.
This looks like a job for the template this parameter:
T val(this T)(int newVal) {
_val = newVal;
return cast(T) this;
}
Funny enough, if you put Bar into Foo (Foo bar = new Bar; ) it doesn't work no more.
Tomek
| |||
July 24, 2010 Re: ReturnThis/@chain | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Tomek Sowiński | Dnia 24-07-2010 o 12:52:51 Tomek Sowiński <just@ask.me> napisał(a):
> Funny enough, if you put Bar into Foo (Foo bar = new Bar; ) it doesn't work no more.
Eh, not funny at all. It doesn't work because it shouldn't (I think).
| |||
July 24, 2010 Re: ReturnThis/@chain | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Tomek Sowiński | I also found chaining more cumbersome than it should be, and made a bug report http://d.puremagic.com/issues/show_bug.cgi?id=2295 and it turned out I wasn't the first thinking along those lines, as http://d.puremagic.com/issues/show_bug.cgi?id=1835 shows. Maybe it is time to revisit the proposal? In the meantime for example for i/o in blip I created a templated Dumper object that does call chaining (only with opCall, but in D2 with opDot one could do it for basically all methods... see http://github.com/fawzi/blip/blob/master/blip/io/BasicIO.d#L505 for a D1 example using the helper function then I simply do dumper(s)(bla)(bla)(bla); :) one has to be a bit careful if the s object is a struct or any non ref object, as call chaining would modify the copies, so I have some checks for that. Fawzi | |||
July 24, 2010 Re: ReturnThis/@chain | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Tomek Sowiński | == Quote from Tomek Sowiński (just@ask.me)'s article
> > pragma(msg, typeof(bar.val(someValue))); // Bar, not Foo.
> This looks like a job for the template this parameter:
> T val(this T)(int newVal) {
> _val =3D newVal;
> return cast(T) this;
> }
> Funny enough, if you put Bar into Foo (Foo bar =3D new Bar; ) it doesn't=
> =
> work no more.
> Tomek
NO #$(&$# WAY!!!!! I (ab)use D metaprogramming constantly and was completely unaware of template this parameters. This is **exactly** what I needed and I can't believe it's in the language already.
| |||
July 24, 2010 Re: ReturnThis/@chain | ||||
|---|---|---|---|---|
| ||||
Posted in reply to dsimcha | On Sat, 24 Jul 2010 16:44:38 +0200, dsimcha <dsimcha@yahoo.com> wrote: > == Quote from Tomek Sowiński (just@ask.me)'s article >> > pragma(msg, typeof(bar.val(someValue))); // Bar, not Foo. >> This looks like a job for the template this parameter: >> T val(this T)(int newVal) { >> _val =3D newVal; >> return cast(T) this; >> } >> Funny enough, if you put Bar into Foo (Foo bar =3D new Bar; ) it doesn't= >> = >> work no more. >> Tomek > > NO #$(&$# WAY!!!!! I (ab)use D metaprogramming constantly and was completely > unaware of template this parameters. This is **exactly** what I needed and I > can't believe it's in the language already. What, this is seriously already here? Why the fuck was I not informed? Seriously, this is one under-advertised feature. -- Simen | |||
July 24, 2010 Re: ReturnThis/@chain | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | == Quote from Simen kjaeraas (simen.kjaras@gmail.com)'s article > On Sat, 24 Jul 2010 16:44:38 +0200, dsimcha <dsimcha@yahoo.com> wrote: > > =3D=3D Quote from Tomek Sowi=C5=84ski (just@ask.me)'s article > >> > pragma(msg, typeof(bar.val(someValue))); // Bar, not Foo. > >> This looks like a job for the template this parameter: > >> T val(this T)(int newVal) { > >> _val =3D3D newVal; > >> return cast(T) this; > >> } > >> Funny enough, if you put Bar into Foo (Foo bar =3D3D new Bar; ) it = > >> doesn't=3D > >> =3D > >> work no more. > >> Tomek > > > > NO #$(&$# WAY!!!!! I (ab)use D metaprogramming constantly and was = > > completely > > unaware of template this parameters. This is **exactly** what I neede= > d = > > and I > > can't believe it's in the language already. > What, this is seriously already here? Why the fuck was I not informed? > Seriously, this is one under-advertised feature. > -- = > Simen ...but on attempting to use it, it's rather useless in cases where you also want to provide a getter because: 1. You can't overload functions against templates, even in situations where this would be completely unambiguous (see bug 2972 http://d.puremagic.com/issues/show_bug.cgi?id=2972). 2. If you make your getter also have a template this parameter, it doesn't work because your getter isn't returning this. | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply