Writing const-correct code in D
Johan Granberg
lijat.meREM at OVEgmail.com
Wed Mar 8 06:35:49 PST 2006
xs0 wrote:
> Kevin Bealer wrote:
>> Also, this is not full "C++ const", only parameter passing and const
>> methods, which seems to be the most popular parts of the const idea.
>> It seems like it should require more syntax that C++, but it only
>> takes a small amount.
>>
>>
>> When working with types like "int", use "in" - const is not too much
>> of an issue here.
>>
>> The same is true for struct, it gets copied in, which is fine for
>> small structs. For larger structs, you might want to pass by "in *",
>> i.e. use "in Foo *". You can modify this technique to use struct, for
>> that see the last item in the numbered list at the end.
>>
>>
>> For classes, the issue is that the pointer will not be modified with
>> the "in" convention, but the values in the class may be.
>>
>> // "Problem" code
>
> OK, this is like the 5000th post I've read regarding const correctness
> and related issues in D. Can we really not come to some kind of an
> agreement on what would be best? I'm sure if there's a consensus about a
> solution, Walter will eventually implement it.
>
> I've read the paper Andrew posted a link to in the last const thread,
> and I really like that system:
> http://pag.csail.mit.edu/pubs/ref-immutability-oopsla2005-abstract.html
>
> Walter, have you also read it? What do you think?
>
> Here's a bad summary, if you don't feel like reading 20 pages :)
>
> References/pointers have two properties, assignability and mutability.
> Assignability is already handled in D by declaring something const,
> which prevents reassignment, but there is no notion of immutability.
>
> Javari introduces a readonly keyword, which applies to a reference. When
> a reference/pointer is readonly, it means that the data it points and
> also all transitively reachable data cannot be changed.
>
> Note that there is no implication that the data will not change through
> other references.
>
> And, obviously, you can't assign a readonly reference into a mutable
> var, and you can do the opposite.
>
> Well, that's the gist of it, other features in random order include:
>
> - overloading based on mutability of this:
>
> class StringWithDate {
> Date getDate() { return m_date; }
> // returns a mutable Date, can be called
> // only through a mutable reference
>
> readonly Date getDate() readonly { return m_date; }
> // - the second readonly applies to this
> // - can be called only through a readonly ref
> // - the Date returned could still be mutable
> // but probably the implementation would dup it first
> }
>
>
> - romaybe keyword for simple cases like above:
>
> romaybe Date getDate() romaybe { return m_date; }
> // is exactly the same as the two funcs above; romaybe
> // basically expands into two methods, one replaces
> // all romaybes with readonly, the other with mutable
>
>
> - readonly classes:
>
> readonly class ConstString { ... }
> // will make all references to ConstString immutable
> // (much like how auto classes work)
>
>
> - conceptually, each class definition (say Foo : Bar) produces two new
> types, "readonly Foo : readonly Bar" and "Foo : readonly Foo, Bar", the
> first of which only contains readonly methods, while the second contains
> all others. That makes it trivial to do verification and overloading,
> and has a nice feature that there is no need to actually compile the
> readonly version, as all verification is done statically, so there is no
> increase in code size etc.
>
>
> - one can still explicitly allow changing an object's fields even
> through readonly references, which is useful for things like caching
> hashcodes, logging, etc., which do not change an object's "abstract
> state" but do still have side effects
>
>
> The problem of having to write two versions of functions, depending on
> mutability, is somewhat helped by "romaybe", and could be further eased
> if the compiler did some simple inference on its own:
>
> - class fields are "important" by default and "ignorable" if they are
> explicitly declared "mutable" or "readonly" (readonly is ignorable,
> because it cannot be changed in the first place; mutable actually
> declares the field to be ignorable)
>
> - any method that could write to important fields or could call
> non-readonly method on them is inferred to be mutable, unless specified
> otherwise
>
> - other methods are considered readonly, unless specified otherwise
>
> - "in" parameters are resolved analogous to above, "inout" and "out"
> default to mutable
>
> - return values default to mutable
>
>
> So, would a system like this be acceptable?
>
>
> xs0
I would like it this is how I have been using const in c++
More information about the Digitalmars-d
mailing list