@autocall aka property for the millionth time
Adam D. Ruppe
destructionator at gmail.com
Thu Jul 4 08:26:42 PDT 2013
I have one more solution to the property situation. This punts
much of it to the library, but is actually easy to implement - I
just added a proof of concept to a devel dmd in about 15 minutes.
Overview:
1) this is purely additive, changing nothing with existing code.
Those are separate debates that I don't want to go over again.
2) Add an attribute @autocall that can be attached to functions.
If an @autocall function is ever mentioned anywhere, in any
context, it is rewritten foo -> foo().
Given that rewrite, it doesn't make sense for @autocall functions
to take any arguments, since it is impossible to pass it any.
3) The rest of the details in making properties work are done by
returning ref and/or helper structs.
Example:
struct S {
int delegate(int) func() @autocall {
return (int b) {
printf("hello!\n");
return 10;
};
}
}
S s;
auto a = s.func(10); // prints hello because s.func is
automatically rewritten to s.func(), so this becomes s.func()(10);
static assert(is(typeof(a) == int); // passes
Boom, that's one of the three big issues for properties for me,
solved.
What about setters? Last time I brought up this idea, setters are
what killed me. Well, I'm sidestepping it this time. Here's how
you could do that:
struct C {
struct Property {
int val;
void opAssign(int a) { val = a; }
int get() { return val; }
alias get this;
}
private Property _prop;
ref Property prop() @autocall {
return _prop;
}
}
C c;
int a = c.prop; // getter, works thanks to alias this (and if you
used auto, it would be typed Property sure, but does it matter?
It is still a value type btw despite being returned ref because
the ref doesn't remain outside the direct use)
a += 5;
c.prop = a; // setter, via the helper's opAssign
You could also make c.prop += 5 work and so on by overloading the
appropriate operators on the helper struct.
Overloads to opAssign let you do setters for various types too.
You might be thinking "blah, that's a little verbose". That's
where std.typecons could come in, or a mixin template, or
whatever. tbh I don't care, in the handful of cases where I want
this (and indeed, it is a very small handful, since the existing
D rules work fine in 95% of my cases), I'm return custom types
anyway, so it is no trouble to me. (As it stands, I used exactly
this pattern last time, with the only annoyance being if it is
callable, having to write ()(arg)... which I often forget to do.
It is so unnatural. Hence, @autocall)
But, with this pattern, the big items for properties are hit for
me:
1) returning callables
2) a.prop += 5; // a.prop could return a ref struct with
opOpAssign overloaded
3) hooking all the operations
And I'd like to remind everyone: this has ZERO effect on existing
code. It breaks nothing, it requires no changes to anything
except code we want to opt into this.
Walter, would you be willing to accept this?
More information about the Digitalmars-d
mailing list