Google's Go
Steven Schveighoffer
schveiguy at yahoo.com
Mon Jan 25 05:46:25 PST 2010
On Sun, 24 Jan 2010 04:25:21 -0500, grauzone <none at example.net> wrote:
> Or how inout(T) isn't just a shortcut to avoid writing
> const/immutable-aware code 3 times or putting it into a template?
The benefits are:
- Single implementation where all that is different is the type
qualifier. (also allows the function to be virtual)
- No propogation of contract through an accessor. In other words, using
an inout accessor on an object or struct does not alter the caller's
contract with the data itself.
The latter function is almost essential for properties, for without such a
mechanism, you are forced to write your property definitions in triplicate.
i.e.
class C {}
struct S
{
C c;
}
immutable s1 = S(new C);
S s2 = S(new C);
immutable c1 = s1.c;
C c2 = s2.c;
Now, change S.c into a property.
The first line of thinking is, "well, accessing c doesn't change the
object itself, so it should be const." But that means you must return a
const(C), so it breaks defining c1 and c2 (can't assign immutable or
mutable from const).
So, you say, "I'll just define it without const," but then you can't call
the property unless S is a mutable type, so that only works in c2's case
Maybe you think you can get away with just mutable and immutable, but
again, it doesn't work if the whole object is const, since you can't call
either function from there.
Templates won't work here, you cannot template the 'this' pointer. So you
end up with 3 identical implementations, and *no* const guarantee on the
mutable one:
@property C c() { return _c; }
@property const(C) c() const { return _c; }
@property immutable(C) c() immutable { return _c; }
Repeat this for all the properties in your object and you have a freaking
mess. You can't even compose these into a common implementation unless
you are willing to do some casting. The inout solution is simple to
understand, does exactly what you want, and provides the most efficient
binary representation (1 compiled function instead of 3 identical compiled
functions). It works because const and immutable are *compile-time*
restrictions, not runtime restrictions.
I came up with the idea because I was trying to port Tango to D2, and I
realized with the amount of properties and object use that Tango has, it
would be a nightmare.
It is not a hack, it is a complete, elegant solution to a very nasty
problem. I'm actually quite surprised that something like this was
possible, and how easy it would be to use.
I predict that most functions where you would normally write const, you
should write inout, and for free you get implementations for mutable,
const, and immutable that work exactly how you want them to (and guarantee
exactly what you want them to guarantee).
-Steve
More information about the Digitalmars-d
mailing list