There was a very long discussion on this before that lead me to write this:
http://www.prowiki.org/wiki4d/wiki.cgi?DocComments/Property
I should draw attention to the tables near the bottom. It is really too
bad that variables in D allow the taking of addresses by default. If
things were non-addressable by default, then they could always be
promoted to properly-implemented properties. Addressabilitiy could be
added explicitly by authors that are confident that they will never need
to turn their public fields into properties. Too late for all of that
now.
I tried to get DMD to do property rewriting in a vaguely general sense.
I think it's still very worthwhile to attempt it.
It didn't work for me because this was in the days of SVN and I tend to
get my free time in 1-3 hour chunks. By the time I had more free time
I'd spend it all merging/updating my code to the latest revision. I
also spent a lot of my time learning how DMD's semantic analysis works.
It's pretty tangled (sorry, Walter). So yeah, I didn't get to spend
much time actually working on the property rewrite due to confusion and
backtracking. I realized that while I really wanted the feature, I
wasn't having fun, nor did I have any free time to program at all.
(Implementing the recursive logic for such a rewrite is really easy!
Dealing with DMDs architectural corner cases... (was) not so easy.)
It'd probably be good to be minimal about it. We might not be able to
do property rewriting in a %100 awesome way without breaking backwards
compatibility. It'll still be worth it to get the property rewriting
that doesn't break backwards compatibility. Example:
struct Bar
{
private Foo m_a;
@property Foo a()
{
return m_a;
}
}
struct Foo
{
private int qux;
Foo opBinary(string op : "+")(Foo other)
{
Foo result;
result.qux = this.qux + other.qux
return result;
}
}
void main()
{
Bar a;
Foo b;
// Error: attempt to write to a non-writable property a.a
b = a.a + b;
}
To make the property rewrite bulletproof, we have to assume that (a.f +
b) will modify a.a because a.a.opBinary!("+") is non-const. We should
then compile-time-error because the property a.a does not have a setter.
However, in current code, this would not give a compile-time error.
Instead it would just work, because the caller and callee implicitly
assume that the opBinary call is const, even if it's not marked as such.
There is probably a significant amount of code that would no longer
compile because of this. The answer would be to mark all such functions
as const, but I'm not sure that Walter & Co would be fine with that.
It's OK though. If Walter & Co don't want to break various calls to
non-const functions at the end of expressions containing properties,
then we can let that slide and only focus on the more likely cases like
using += on a property field that returns a value type like an int
(array.length += 1 is the classic case, with its own special-cased
solution and everything). It'd be extremely useful and possibly remove
a lot of potential sources of bugs/headaches.
Anyhow, that's a lot of my background info on this subject. I do hope
someone else tackles this. They will probably be more successful than
I. If not, I might still try it someday if the pull request might get
accepted.