www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - On const and inout (was Re: Logical const)

On 02/12/2010 09:18, Don wrote:
 Walter Bright wrote:
 spir wrote:
 What would be the consequences if D had no const, only immutable
 (that, IIUC, removes the latter non-guarantee)?

You'd have to write most every function twice, once to take immutable args and again for mutable ones.

Doesn't 'inout' do almost the same thing? The only difference I can see between const and inout, is that inout tells which parameters could be aliased with the return value.

Yes, that is more or less it, although it may not the best way to think about it. I've come to realize an interesting parallel between inout and Java wildcards. In fact, that might give inspiration for another way to explain inout and const. Let's go back a little, to think about const itself. Ask yourselves this, does it makes sense to *instantiate* data typed as const, such as this: auto blah = new const(int[4]); ? The answer is no (even though the compiler allows it). The resulting data would effectively be the same as immutable, so you might as well instantiate it as immutable. The key thing here is that const(int), and any other const(T), is actually kinda like an abstract type. It tells you some of the things you can do with the data, but the data itself must be of a concrete type, which is mutable or immutable, but not const. It is entirely accurate to think of const(T) as some T that can be mutable or immutable, but one don't know which, so one can only work on the lowest common assumptions. So const is like a wildcard. Why is this interesting? Because it helps us understand what inout does. (if some people have trouble understanding and/or explaining const, then inout will be much worse). inout is based on const, it also says "I don't know if this data is mutable or not". However, it adds the guarantee/restriction that all data typed as inout in the function parameters and return type actually has the same *concrete* type, with regards to immutability. So if you have this function: inout(int)[] func(inout(int)[] arr, int x, int y) { return arr[x .. y]; } You are specifying: I don't know what arr's actual/real/runtime immutability is (so I'll treat is an unknown), but I guarantee that the actual/real/runtime immutability of the return type will be that same as that of arr's. This pretty much the same conceptually as creating a binding of a wildcard type in Java (I'm not sure these are the correct terms). Java's wildcard support is much more... err.. of a generic solution (I mean generic as in http://www.answers.com/generic, not as in related to generics). For example, in Java you can specify a function signature such as this: public static <T> T get(T obj) { //... Which guarantees that the static return type is the same as the static type of the argument. So for example this will compile: String foo = get(new String()); Number foo = get(new Integer()); but this will not: Number foo = get(new String()); Conceptually this is pretty much the same as with inout in D, where inout is only able to bind to one type modifier, and it does so anonymously. Also D's support for this is only with regards to immutability, otherwise D is not able to define _one_ function with a signature/contract like the above. -- Bruno Medeiros - Software Engineer
Dec 03 2010