Immutability and other attributes, please review
Jonathan M Davis
jmdavisProg at gmx.com
Thu Jun 14 04:11:42 PDT 2012
On Thursday, June 14, 2012 12:31:16 Roman D. Boiko wrote:
> On Thursday, 14 June 2012 at 09:56:08 UTC, Roman D. Boiko wrote:
> > By the way, the whole data model is designed to be immutable.
> > Should I replace const with immutable then?
>
> The other thing I don't like is having to cast everywhere:
>
> struct Maybe(T)
> {
> immutable T* payload; // pointer to data
> pure nothrow this(T* payload)
> {
> this.payload = cast(immutable) payload;
> }
> pure nothrow @property T front() const in{ assert(!empty); }
> body{ return cast(T) *payload; }
> //...
> }
>
> OTOH, I'm not sure making input parameter immutable would be
> better for the user, same for function return type.
I haven't had the chance to look over your code yet, but this looks
_seriously_ suspect. Casting to and from immutable or cast away const are
things that should be done _very_ rarely. One of the few times that casting to
immutable makes any sense is when you need an object to be mutable while you
put it together and then immutable afterwards. But when you do that, that
reference or pointer is the _only_ reference to that data. e.g.
auto func(size_t numElems)
{
auto arr = new int[](numElems);
foreach(ref e; arr)
//do something to initialize e
return cast(immutable int[])arr;
}
Taking a function's parameter (which came from who-knows-where) and casting it
to immutable is almost certainly a terrible thing to do. If there are _any_
other references to that data, you will have bugs. immutable is supposed to
guarantee that the data is _never_ altered. So, when you cast something to
immutable, you're telling the compiler that it's okay to treat that data as
immutable and that you will _not_ have any mutable references to that data or
alter it in any way. If you do, you'll be breaking the compiler's guarantees.
Ideally, you would always construct immutable objects as immutable rather than
creating them as mutable and then casting them to immutable, but that's not
always possible.
And taking your payload, which is immutable, and casting away immutable when
you return it from front is truly bad. Casting away const or immutable and
then mutating that object is _undefined_ behavior. Do _not_ do it unless you
have to and know what you're doing.
These stackoverflow questions may help you understand better:
http://stackoverflow.com/questions/4219600/logical-const-in-d
http://stackoverflow.com/questions/10364837/why-do-i-have-to-cast-this
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list