so what exactly is const supposed to mean?
kris
foo at bar.com
Mon Jul 3 13:20:49 PDT 2006
Chris Nicholson-Sauls wrote:
> Technically no. Although at present, there are precisely two possible
> methods, and both require wrapping every single field up with a D-style
> property. (True properties could actually have the potential to make
> this simpler... but we don't have those either.)
>
> Method #1 - Write the class as innately immutable, then write a mutable
> subclass. This is the methodology at work in Mango, for example, where
> the module mango.io.FilePath actually defines two classes,
> FilePath:Object and MutableFilePath:FilePath.
>
> Method #2 - Same as above, but with one class that has a pair of methods
> (mutable() and immutable() for example) that activate/deactivate
> mutability, usually locking on something such as instance of another
> class (the identity of which doesn't particularly matter). For
> (quick'n'dirty) example:
Method #3 - each mutator function/method actually creates a clone of the
original, mutates it, and returns that instead.
Method #1 & #2 are typically the most efficient, but can expose an
achilles heel. For instance, suppose you had an immutable String class?
At some point, it will need to expose the content therein -- perhaps via
a toString() method, or perhaps something more subtle? At that point,
the class either returns a .dup of the internal content, or it exposes
the internal content directly by returning it (as an array). Neither of
these options are entirely attractive, and it's the reason why fully
immutable classes/structs are not entirely practical in D at this time.
This "return value" concern is also the reason why I believe that a
"minimalist" support for "read-only" would be to protect just the return
values. With the latter, one could happily return internal aggregate
content (as arrays) and be safe in the knowledge that the compiler will
catch pedestrian errors. However, I'd much rather see const-by-default
instead -- that's a more practical solution, and should offer notable
opportunities for optimization.
One should note that the goal of such mechanisms is to tighten up the
"contract" between caller and callee. This becomes increasingly
important within multithreaded designs, to the point of becoming a
fundamental requirement in some ways (in terms of robustness,
simplicitly, efficiency, deterministic behaviour, etc). CoW is another
mechansism intended to achieve similar results, but the key distinction
is the lack of an enforceable contract. With mutable/immutable decls,
the compiler has the necessary information to catch cases where the
contract is being broken. With CoW, the compiler does not have that meta
information available (whether the design says it's OK to alias or not).
Of course, this won't stop some determined fool from bypassing the
contract altogether: even with immutable-by-default, one could
presumably cast() lvalues in some manner to subvert the contract. But
that's not the point -- the compiler would be looking to catch honest
mistakes, and not trying to cure stupidity :p
Hope this helps.
More information about the Digitalmars-d-learn
mailing list