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