logical const is a subset of transitive const

Steven Schveighoffer schveiguy at yahoo.com
Fri Sep 14 11:36:38 PDT 2007


"Janice Caron" wrote
> On 9/14/07, Steven Schveighoffer <schveiguy at yahoo.com> wrote:
> I can't argue with your reasoning.

Thanks, that helps my self confidence :) Seriously!  (sometimes electronic 
communication seems sarcastic, but I assure you this is genuine)  I respect 
your opinion greatly.

> ...but...
>
> It's a paradigm thing. Logical const is all about *interface*;
> physical const is all about *implementation*.

Then declare everything lconst.  You will not get compiler optimizations.  I 
have no problem with that.

> If keywords existed for both paradigms, I think there would only be
> more confusion. Writers of classes would have to choose between
> viewpoints, and there would be no consistency.

I think the alternative is too restrictive.  Only using transitive const 
restricts those who wish to have the benefits of the compiler helping them 
prevent mistakes in logical-const type situations.  Only using logical const 
prevents the compiler from making assumptions about const, and could hamper 
D in the future of multi-core systems (Walter's suggestion, not mine).

I think this medium allows both to co-exist.  There is only one viewpoint. 
Use logical const if you need it, otherwise, use const to get compiler 
optimizations.  If you are unsure whether you are going to need logical 
const, make it logical const.

> If I choose "const", then I am implicitly saying "it is safe for
> multiple threads simultaneously to reference the same instance of
> const(Date) without mutex locking".

I disagree.  Declaring it const means that calling that function will not 
change any members of the date object.

Declaring it pure means that it will always return the same value, which 
means it would be safe for multiple threads to access without locking (I am 
very new to this concept, but I got all my knowledge from wikipedia: 
http://en.wikipedia.org/wiki/Functional_programming)

If the class is non-mutable after creation, then declare the methods to be 
pure.  Otherwise declare it const.  const does NOT mean thread safe.

> So programmers would be free to
> use the class in just that way. If I choose "lconst" then I am
> implicitly saying "it is /not/ safe".

No, const/lconst has nothing to do with thread safety.  It only has to do 
with whether the method changes anything local to the object or objects it 
contains or associates with.  Even with only transitive const, you cannot 
ensure thread safety just becase a method is const.

e.g.

const void method()
{
   globalVariable++;
}

> Why would I want to declare it not threadsafe, when it in fact, is?
> Because of the possibility that I might change the implementation
> later? What if I don't plan to. Am I allowed to change my mind.
>
> It turns out, the answer is no. Suppose I chose to go with const,
> reflecting the current, physically const, implementation, and people
> start writing code with it. Suppose then that at a later date I change
> the implementation so it's now no longer physically const. Then I'd
> need to change the declaration to lconst or it wouldn't compile. But
> that wouldn't help all the people who are already using my class in
> multithreaded applications - particularly becase, as Walter is fond of
> pointing out, this circumstance is not compiler checkable. All the
> hapless programmer would know that, at some time after upgrading to
> the latest version of Date, their program randomly crashes in an
> almost-impossible-to-diagnose way.

I think this is incorrect.  It would not randomly crash, it would not 
compile.  They would not be able to call the now lconst method through a 
const reference.

If you were using the method previously assuming it was thread safe because 
it was const, then you were not understanding const properly.

I think your argument stems from the incorrect assumption that const == 
thread safe, which I think I've argued against above.

> In summary - we've already got two keywords for constness (const and
> invariant), and that's already one too many from the point of view of
> seeming confusing. I'd rather not see another one.

I think invariant, const, and lconst all have clear meanings, are clearly 
separated.  Since lconst/invariant would be new to D, a new programmer would 
need to know about them to use them, so they would need to read 
documentation and descriptions of the keywords to understand them.  I agree 
that in learning a new language, it would be a slightly larger learning 
curve, but with simple examples (please note, examples are key, I love 
examples) and a concise explanation would make learning const take at most 1 
hour.  At least for me :)

What I think WOULD be confusing and ambiguous is to allow logical const, but 
to use const to refer to both logically const and transitive const 
references.

What I think would be error prone is to not allow logical const, or only 
allow it through complicated template wrappers.  This would dissuade people 
from using logical const as a tool to help them design better software.

And I'm not dead-set on lconst.  I actually don't like it.  But it seemed 
logical (no pun intended).  If someone has a better idea for a keyword, then 
I'm all for it.  But I do think another keyword is required to clarify what 
the author of the code wants.

Janice, thanks for your views, I don't think I would have understood this 
whole const battle enough if it weren't for your persistance :)

-Steve 





More information about the Digitalmars-d mailing list