March 09, 2005
"Martin M. Pedersen" <martin@moeller-pedersen.dk> wrote in message news:d0lj8v$quo$1@digitaldaemon.com...
> "Walter" <newshound@digitalmars.com> skrev i en meddelelse news:d0lha7$p50$1@digitaldaemon.com...
> > I've seen a lot of C++ code, and when the author of it has made the
effort
> > to make it const-correct, it's pretty loaded up with const keywords. I believe it adds a lot of visual complexity, without commensurate
benefits.
> > If const came with guarantees that the data would not be modified
(unlike
> > C++), then it might have value.
>
> I'm also in the camp missing the 'const'. I easily see your point about it having no value to the compiler/optimizer, but that is not the only point. In this article:
>
>     http://www.developerdotstar.com/mag/articles/reeves_design_main.html
>
> the author argues that the code is the design, and coding is a design activity. He also argues that:
>
>     "What we really need is more expressive programming languages.
>     This is what led to my statement about C++ being a major advance
>     in software design art. C++ is a more expressive programming
>     language, which makes it a better software design tool."

In general, I agree with the author that the code is the design. I also agree that C++ is very expressive, and a big advance in programming.

> 'const' is one of those features that makes it a more expressive language and a better software design tool. Your point about it being useless to
the
> compiler doesn't really matter in this respect.

True, it does add some semantic information, and as such, it can be used to improve design. But if its semantic value is useless to the compiler, then you are relying on it having semantic value based on a convention of usage, and are assuming that the author is following the convention and has applied it correctly. It's value is more than adding a comment /*const*/, but not much more.

For comparison, C++ doesn't have in, out or inout for function parameters. This is a serious deficiency in the expressivity of a function's interface, leading to such commenting conventions as /*[in]*/, /*[out]*/, /*[out][in]*/ for parameters. I think these being part of D are far more valuable in expressing a function's interface than const, especially since they can be relied upon. Some have argued here that 'in' parameters in D should be not modifiable. It's a perfectly reasonable convention, and if one adopts it, doesn't that provide what you're looking for?

I have a couple other beefs with C++ const. The first is that it's misleading, and lures even experienced programmers into thinking that the values actually are constant. The second is that pretty much nobody knows how it works. I regularly receive emails the gist of which reads like "I'm having a problem using const. Compilers from X, Y, Z all behave differently. I don't know which is right." These emails aren't coming from C++ newbies - they come from acknowledged experts in the field, people who have used C++ for over a decade, people who are published C++ authors. The behavior is so murky that they can't figure out what the Standard says, and instead pick compiler Brand X as the arbiter of "how it's supposed to work." If a decade of language lawyers can't clearly express how it works, I suspect it may not be the best way to express a design. (Granted, the examples giving grief tend to be less common usages, and convoluted to boot, but they should be understandable by applying simple, standard rules, and they're not.)


March 09, 2005
"Walter" <newshound@digitalmars.com> skrev i en meddelelse news:d0n7pu$2kf2$1@digitaldaemon.com...
> True, it does add some semantic information, and as such, it can be used
> to
> improve design. But if its semantic value is useless to the compiler, then
> you are relying on it having semantic value based on a convention of
> usage,
> and are assuming that the author is following the convention and has
> applied
> it correctly. It's value is more than adding a comment /*const*/, but not
> much more.

How much more can always be discussed, and our experiences will vary. I see it as a tool for expressing design, and having the compiler help me enforcing it. Even if the compiler cannot give me any guarentees, it can help me in the right direction. To me, that is much more value than a comment.

I will not argue that C++ has got the const-stuff right. But is has got quite a few mechanisms that all help express a design:

    1. References that are really pinned pointers; ie. the pointer itself is
'const'.
    2. 'const' arguments
    3. 'const' methods
    4. 'const' member variables

Why references syntaxtically are different beast than pointers, beats me. The reason may be found in the C inheritage. D does not have that inheritage and combined the concepts, which is a good thing.

We can easily agree that 'const' is overly misused and misleading.

'const' arguments as found in C++ really does mean read-only as you and others have pointed out. But even though not perfect, it does help express design.

Then we have 'const' methods, which have nothing const about them either. A better term would be "non-mutable" or even "pure" which is stronger because it says something about side-effects too. Still, I can use 'const' in the sense of "non-mutable" to help express and enforce design.

In C++, I do not see 'const' member variables as important simply because a good interface does not expose them. I see them more as a necessity for having non-mutable methods. A wierd thing is "mutable" that introduces "faked non-mutable" as a language concept in its own right :-( Please promise never to add that kind of thing to D. In D the situation is different, though, because the concept of properties better allow them to be exposed. Perhaps "final" as you have proposed is the way to go - I don't know, but I do think its needs consideration.

> For comparison, C++ doesn't have in, out or inout for function parameters.
> This is a serious deficiency in the expressivity of a function's
> interface,
> leading to such commenting conventions as /*[in]*/, /*[out]*/,
> /*[out][in]*/
> for parameters. I think these being part of D are far more valuable in
> expressing a function's interface than const, especially since they can be
> relied upon. Some have argued here that 'in' parameters in D should be not
> modifiable. It's a perfectly reasonable convention, and if one adopts it,
> doesn't that provide what you're looking for?

I agree that "in", "out", and "inout" are good, but I can't see how they can replace the C++ mechanisms.

If 'in' arguments were read-only by convention only, it would have no more value than adding the /* const */ comment. Having it enforced by the compiler would bring me a bit further, but not as long as I can come with C++. In C++ I can specify if it is the pointer and/or the referenced object that is read-only. The pointer is specify as read-only by using a reference instead. The referenced object is specified read-only by applying 'const'. Then there is the situation where the 'in' reference is stored in a member variable. C++ can help me enforce (even if it cannot make any guarantee) my design in this situation.

'out' and 'inout' does not have any counterparts in C++. As such, they provide a valuable addition.

Another valuable addition in D compared to C++ is interfaces. Explicit interfaces are very good compared to C++ where a class can be an interface as a consequence of something you don't write.

> The second is that pretty much nobody knows
> how it works. I regularly receive emails the gist of which reads like "I'm
> having a problem using const.

I'm have made a habit of using 'const' all the time. I do that by intuition, and are not very conscious about it anymore. I simply do not write code that is not const-correct, and I haven't experienced such problems. But perhaps I'm not experienced enough to get myself into those situations you mention, and stick to simpler code.

I suspect part of the problem is the obscure declarators of C that is even worse in C++. Is that correct? It that is so, D has the oppertunity to rectify the situation, and I believe D had already largely done that. 15 years ago, I moved from Turbo Pascal to C and C++. One of the major obstacles I experienced was the declarators. They still puzzles me, and yet, they do not provide anything that I could not do in Pascal.

Regards,
Martin


March 09, 2005
"Anders F Björklund" <afb@algonet.se> wrote in message news:d0mnlt$221c$1@digitaldaemon.com...
> Walter wrote:
>
>>>The only place for "const" seems to be protecting read-only attribute ?
>>
>> I like "const" as meaning it really is constant. Read-only is a side
>> effect
>> of that. C++ const stuff may be read only, but it isn't constant.
>> Other
>> threads, and other references to the same data can change it at any
>> time,
>> which is why the C++ const is overrated.
>
> This sounds a bit to me like how "typedef" and "alias" work, in D ?
>
>
> Which means that if "const" ever surfaced in D, which seems to be unlikely since it is so easy to cast away and be a Bad Boy, it would probably be called "readonly" instead - to reflect use ?
>
> Since "const" are reserved in D for things that are... well... constant, and "typedef" are reserved for stuff that... errr... actually define new types. Then "readonly" sounds approriate.
>
> Or perhaps the write-once declaration of "final", that Java has. (works a little like a CD-rom disc burner, doesn't it, where you can write stuff to the disc only once - and then it's "constant")
>
>
> I like D's const. Whether "readonly" is needed, remains to be seen...
> (but it would probably have to be enforced with massive military
> force,
> for instance like string literals on GCC that are placed in R/O
> memory?)

I know that it's never going to surface with the scope of C++'s const, but I see no reason why we can't have readonly members, i.e. they must be explicitly initialised in all ctor bodies.

And Walter's been completely silent about this exact point, instead banging on about const subversion in C++, which has precisely nothing to do with the request.

Walter??



March 09, 2005
"pragma" <pragma_member@pathlink.com> wrote in message news:d0n4cl$2g4k$1@digitaldaemon.com...
> [Chopped down from its original length]
>
> In article <d0mrip$2656$1@digitaldaemon.com>, Matthias Becker says...
>>
>>>> > Walter wrote:
>>>> >> As a *language*, what does C++ have over D?
>>>> >> Implicit function template instantiation. It's hard to find much
>>>> >> else.
>>>
>>>>     compilers that warn
>>>
>>>Thrashed that one to death <g>.
>>>
>>>>     proper cast operators,
>>>
>>>I know there's a thread on that, but I haven't gotten to it yet.
>>
>>cast(Foo)bar looks cool at first, but you can't do something that
>>looks like a
>>cast on your own (e.g boost::lexical_cast looks like the other
>>C++-cast). And
>>the C++-Casts are more powefull. If you defenitly know that an object
>>has the
>>type you want to cast to, you can use a static cast, if you aren't
>>sure, you can
>>use a dynamic cast. In D you allways have to use a dynamic cast, which
>>is far
>>more expensive.
>
> Sorry to butt-into the discussion, but I have some insight to share
> with respect
> D's casting mechanism.
>
> First off, one can accomplish a static-cast in D, although it looks a
> bit
> hackish:
>
>> myvar = cast(MyVar)cast(void*)myothervar;
>
> I assume that casting through "void*" is waved away by the compiler
> into
> something more succinct, so I wouldn't expect this to be any less
> efficient than
> C.
>
> Secondly, one can also write their own cast routine from scratch, as I
> have done
> already:
>
> http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/18665
>
> .. which is a dynamic cast based on class/interface name.  D's
> built-in casting
> mechanism is based on typeinfo reference.
>
> By this you get "dyn_cast!(Type)(arg)" which IMO, is no less a cast
> than
> "boost::lexical_cast<Type>(arg)" since its still relying on a
> template.
>
> The ABI documentation is out of date, but all one needs to do is poke
> around in
> phobos/object.d.  I would suspect that the future will bring an ABI
> that can be
> used to code any manner of runtime-type mechanisms.
>
> So with respect to cast(), D is surely on the same footing as C/C++,
> if not on
> higher ground.

Unless I'm stunningly misinformed - possible - this is complete piffle. In a recent conversation Walter informed me that cast() has pretty much sledge-hammer semantics. That was his main basis for not wanting warnings about truncation, since it would incline people to overuse casts, and casts can cast anything. I've not tested this out, yet, but I'm inclined to take it from the horse's mouth.

Given that, D's cast mechanism is nothing more than C's cast mechanism with more greppable syntax, and is, therefore, complete crap.

We need fine grained casts. There is no debate. The only question is whether we'll get them. C++'s casts, for all their comparative richness and syntactic extensibility, are not popular with Walter. Therefore, we will have another uphill battle to reach a sensible state. I'm a bit weary from the last few battles to take this on just now - and I want to delete delete first! - so maybe others might weigh in with what will undoubtedly be more reasoned language than I would conjure at this point ...



March 09, 2005
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d0nsvs$c1h$1@digitaldaemon.com...
> I know that it's never going to surface with the scope of C++'s const, but I see no reason why we can't have readonly members, i.e. they must be explicitly initialised in all ctor bodies.

A readonly property is completely orthogonal to a property requiring explicit initialization. Both are orthogonal to having const as a type modifiier. C++ mushes all these together into its notion of 'const'. I've been trying to separate them out in these discussions.

My distaste for const is its use as a type modifier. Not its incidental use for other purposes.

> And Walter's been completely silent about this exact point, instead banging on about const subversion in C++, which has precisely nothing to do with the request.

I believe I replied at length about exactly what Java did in this regard. This is important, as there is a distinction between an explicit initialization in a constructor, and explicit initialization at the member declaration. Java does the latter, C++ the former. The two are very different, and as your writings implied that Java had adopted the C++ notion, I wish for you to comment on which way you feel is the important way, and why.


March 09, 2005
Walter wrote:

> A readonly property is completely orthogonal to a property requiring
> explicit initialization. Both are orthogonal to having const as a type
> modifiier. C++ mushes all these together into its notion of 'const'. I've
> been trying to separate them out in these discussions.

I think I will call them "readonly" (const in C++), "final" (as in Java)
for the property requiring explicit initialization (a.k.a "blank final")
and "const" (like in D, meaning constant: instead of "#define PI 3.14",
free for the compiler to literally replace and "inline" with the value?)

And just like with typedef/alias, I think C picked the "wrong" keyword ?

--anders
March 10, 2005
"Martin M. Pedersen" <martin@moeller-pedersen.dk> wrote in message news:d0nj0k$bi$1@digitaldaemon.com...
> I'm have made a habit of using 'const' all the time. I do that by
intuition,
> and are not very conscious about it anymore. I simply do not write code
that
> is not const-correct, and I haven't experienced such problems. But perhaps I'm not experienced enough to get myself into those situations you
mention,
> and stick to simpler code.

Oddly, I took the opposite approach. I dropped all use of 'const' that wasn't for declaration of constants. Instead, I treat all function parameters as read only unless documented otherwise. And in fact, rarely do functions need to change their parameters. It works, I simply have never had a problem with it.

> I suspect part of the problem is the obscure declarators of C that is even worse in C++. Is that correct? It that is so, D has the oppertunity to rectify the situation, and I believe D had already largely done that. 15 years ago, I moved from Turbo Pascal to C and C++. One of the major obstacles I experienced was the declarators. They still puzzles me, and
yet,
> they do not provide anything that I could not do in Pascal.

The problem roots from const having an influence over the overloading and partial template specialization matching algorithms. Sometimes const makes one match 'better' than another, sometimes it doesn't, depending on an arcane list of rules. (This is one big reason why, in D, overload resolution explicitly ignores things like in, out, inout, and only looks at the types.)


March 10, 2005
"Matthias Becker" <Matthias_member@pathlink.com> wrote in message news:d0mrip$2656$1@digitaldaemon.com...
> cast(Foo)bar looks cool at first, but you can't do something that looks
like a
> cast on your own (e.g boost::lexical_cast looks like the other C++-cast).
And
> the C++-Casts are more powefull. If you defenitly know that an object has
the
> type you want to cast to, you can use a static cast, if you aren't sure,
you can
> use a dynamic cast. In D you allways have to use a dynamic cast, which is
far
> more expensive.

You can do what you ask in D by first passing it through a 'void*' cast:

    b = cast(B)cast(void*)a;

which will do the same thing as C++:

    b = static_cast<B*>(a);


March 10, 2005
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d0nsvu$c1h$2@digitaldaemon.com...
> Unless I'm stunningly misinformed - possible - this is complete piffle. In a recent conversation Walter informed me that cast() has pretty much sledge-hammer semantics. That was his main basis for not wanting warnings about truncation, since it would incline people to overuse casts, and casts can cast anything. I've not tested this out, yet, but I'm inclined to take it from the horse's mouth.

I remember saying that to you, but when casting class references, it does behave like C++'s dynamic_cast. We weren't talking about class reference conversions at the time, so I did not think to bring it up.


March 10, 2005
"Walter" <newshound@digitalmars.com> wrote in message news:d0o1l2$hdo$1@digitaldaemon.com...
>
> "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d0nsvs$c1h$1@digitaldaemon.com...
>> I know that it's never going to surface with the scope of C++'s
>> const,
>> but I see no reason why we can't have readonly members, i.e. they
>> must
>> be explicitly initialised in all ctor bodies.
>
> A readonly property is completely orthogonal to a property requiring
> explicit initialization. Both are orthogonal to having const as a type
> modifiier. C++ mushes all these together into its notion of 'const'.
> I've
> been trying to separate them out in these discussions.

I completely agree with that

> My distaste for const is its use as a type modifier. Not its
> incidental use
> for other purposes.

Great!

>> And Walter's been completely silent about this exact point, instead
>> banging on about const subversion in C++, which has precisely nothing
>> to
>> do with the request.
>
> I believe I replied at length about exactly what Java did in this regard.

True. I was wrong about that.

> This is important, as there is a distinction between an explicit
> initialization in a constructor, and explicit initialization at the
> member
> declaration. Java does the latter, C++ the former. The two are very
> different, and as your writings implied that Java had adopted the C++
> notion, I wish for you to comment on which way you feel is the
> important
> way, and why.

I already acknowledged that I'd misspoke regarding Java's final a couple of days ago.