www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Writing C in D

reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
One aspect of D that is nice (or at least flexible ?)
is that you can write programs in ancient C style...

Without using objects, and without using exceptions,
garbage collection and other such modern facilities :-)


All you need to do is provide hooks for a few required
aspects of Phobos, such as GC and assert / OutOfMemory.

 import std.c.stdio;
 import std.c.stdlib;
 
 int main(char[][] args)
 {
     printf("Hello, World!\n");
     return EXIT_SUCCESS;
 }
 
 extern (C) void _d_OutOfMemory()
 {
     fprintf(stderr,"Out of memory!\n");
     exit(1);
 }
 
 extern (C) void _d_assert(char[] filename, uint line)
 {
     fprintf(stderr,"%s:%u: failed assertion\n",
             cast(char *) filename, line);
     exit(1);
 }

And such "C" code should compile with the regular D too (with regular asserts and exceptions and GC) ? A no-GC patch for Phobos (0.110) can be found here: http://svn.dsource.org/svn/projects/bindings/trunk/ (coded by James Dunne, as posted on this NG earlier) Of course, you would then have to 'delete' things yourself - or face the wrath of the memory leaks... (or to really get in the spirit, use malloc/free) But you *can*. If you want to. (no flames, please) --anders
Mar 05 2005
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Sat, 05 Mar 2005 11:29:33 +0100, Anders F Björklund wrote:

 One aspect of D that is nice (or at least flexible ?)
 is that you can write programs in ancient C style...
 
 Without using objects, and without using exceptions,
 garbage collection and other such modern facilities :-)
 
 
 All you need to do is provide hooks for a few required
 aspects of Phobos, such as GC and assert / OutOfMemory.
 
 import std.c.stdio;
 import std.c.stdlib;
 
 int main(char[][] args)
 {
     printf("Hello, World!\n");
     return EXIT_SUCCESS;
 }
 
 extern (C) void _d_OutOfMemory()
 {
     fprintf(stderr,"Out of memory!\n");
     exit(1);
 }
 
 extern (C) void _d_assert(char[] filename, uint line)
 {
     fprintf(stderr,"%s:%u: failed assertion\n",
             cast(char *) filename, line);
     exit(1);
 }

And such "C" code should compile with the regular D too (with regular asserts and exceptions and GC) ? A no-GC patch for Phobos (0.110) can be found here: http://svn.dsource.org/svn/projects/bindings/trunk/ (coded by James Dunne, as posted on this NG earlier) Of course, you would then have to 'delete' things yourself - or face the wrath of the memory leaks... (or to really get in the spirit, use malloc/free) But you *can*. If you want to. (no flames, please)

I agree with you that this is also a strength of D. Sometimes, OOP-everything is just overkill. -- Derek Parnell Melbourne, Australia 5/03/2005 9:35:56 PM
Mar 05 2005
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Derek Parnell wrote:

One aspect of D that is nice (or at least flexible ?)
is that you can write programs in ancient C style...


But you *can*. If you want to. (no flames, please)

I agree with you that this is also a strength of D. Sometimes, OOP-everything is just overkill.

With a better standard library (or perhaps a 3rd party one), it shouldn't be that hard to use D as a "native Java", either... D has more features in common with Java than what eg. C++ has, and should actually be pretty straight-forward with some docs. Like many others, I think that C++ is a more "complete" language. At least more mature, and with a lot more libraries and support ? But it's also more complex, and lacks some things from Java / C#. (like strings, garbage collection and unit tests, as Walter states) And this is where D shines. As a "simpler C++", or C/Java crossover. Buy maybe I'll get more respect for C++ after reading Matthew's book ? --anders PS. Some people make a religion out of hating OO programming, especially: http://www.geocities.com/tablizer/oopbad.htm And vice-versa... I'm finding *both* to be useful, myself. (since D supports both, this NG is not the place for a war)
Mar 05 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Anders F Björklund" <afb algonet.se> wrote in message
news:d0c4jb$fth$1 digitaldaemon.com...
 Like many others, I think that C++ is a more "complete" language.

I don't really understand why. As a *language*, what does C++ have over D? Implicit function template instantiation. It's hard to find much else.
 At least more mature, and with a lot more libraries and support ?

That, I'll concede. It certainly ought to be more mature, being over 20 years old <g>. And certainly, with all the companies doing C++ tools, there are more libraries and support.
 But it's also more complex, and lacks some things from Java / C#.
 (like strings, garbage collection and unit tests, as Walter states)

C++ is significantly deficient for the reasons you list. I'll add UTF and contracts as other areas where C++ falls short.
Mar 06 2005
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter wrote:

Like many others, I think that C++ is a more "complete" language.

I don't really understand why. As a *language*, what does C++ have over D? Implicit function template instantiation. It's hard to find much else.

D has some "simplified" versions of C++ features, like inout instead of reference params, simplified const handling (storage instead of type), etc, and I guess I'd have more examples if I had been using C++ more... And this makes C++ more "complete" in that you can do more things, but is also makes a lot harder and complex - at least at the start ? I'll let the C++ experts fill in their own pet peeves about D 1.0. (as I've said before, my own experience is with C and with Java)
But it's also more complex, and lacks some things from Java / C#.
(like strings, garbage collection and unit tests, as Walter states)

C++ is significantly deficient for the reasons you list. I'll add UTF and contracts as other areas where C++ falls short.

Currently D also falls a little short on contracts and unittests, compared to e.g. Eiffel and Java for instance, but it is definitely on the right path there! And doxygen fills up for the "missing Javadoc" Anyway, I have never really liked C++. With D, maybe I won't have to ? Although if I started a complex project today, I would probably use C++ (if C or Java wasn't enough). Just hoping that tomorrow, I can use D... --anders
Mar 06 2005
next sibling parent reply "Matthew" <admin.hat stlsoft.dot.org> writes:
"Anders F Björklund" <afb algonet.se> wrote in message
news:d0gu9k$1n20$2 digitaldaemon.com...
 Walter wrote:

Like many others, I think that C++ is a more "complete" language.

I don't really understand why. As a *language*, what does C++ have over D? Implicit function template instantiation. It's hard to find much else.


const references bool namespaces compile-time testing (none of that hideous runtime generic comparison filth) TMP macro pre-processor 'using' operators that look like operators compilers that warn proper cast operators, and the ability to fill the gaps in the spectrum with user defined types support for shims (implicit template instantiation coupled with ability to manipulate names in global/specific namespaces) lack of GC ability to produce extremely small applications (i.e. supports extremely low coupling, and allows one to dispense with C/C++ Runtime Library) etc. etc. etc. (For the record, I'm writing std.openrj right now, in 100% D, and enjoying it for the most part. But it is *not* unalloyed tra-la-la-ing in wonderland ...) Matthew
Mar 07 2005
next sibling parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Matthew wrote:

I don't really understand why. As a *language*, what does C++ have over D?



     bool

D has 'bool' now, right ? A built-in type that only holds true/false. Or did you mean boolean semantics with for instance conditionals ? I know that D has the same booleans as C99 has, but not what differs the D bool alias from the C++ bool keyword/type ? I *do* know what differs D bool from Java boolean, and that language's semantics...
     macro pre-processor
     compilers that warn

Some people thinks lacking these is a Good Thing only. (I don't, but)
     lack of GC

Unless you disable GC yourself in Phobos, that is...
     ability to produce extremely small applications (i.e. supports extremely
low coupling, and allows one to dispense 
 with C/C++ Runtime Library)

Can't you do this in D too, by dispensing with Phobos ?
     etc. etc. etc.

I'll add these too: AltiVec vector types (http://developer.apple.com/hardware/ve/model.html) inline PPC assembler (you can of course put that in separate .s files now) debugging (with name demangling and all line numbers) doxygen (without filters/hacks to make the code parse) But there is nothing stopping D from getting these, too... Except that there are only 24 hours in each day, of course. ;-) --anders
Mar 07 2005
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Matthew" <admin.hat stlsoft.dot.org> wrote in message
news:d0h20f$1r88$1 digitaldaemon.com...
 "Anders F Björklund" <afb algonet.se> wrote in message

 Walter wrote:
 As a *language*, what does C++ have over D?
 Implicit function template instantiation. It's hard to find much else.


const

Discussed in great depth elsewhere!
     references

See my response to Anders on that.
     bool

I'm not seeing it, Matthew!
     namespaces

I really see nothing in C++ namespaces that has anything over D modules. Namespaces are a failed attempt to add module like semantics to C++, and I say failed because several experts told me that exported templates were needed in order to provide "coding hygiene", i.e. prevent the names in one source file from stepping on those in another. I found that interesting because that was exactly the problem that namespace was supposed to solve.
     compile-time testing (none of that hideous runtime generic comparison

?? D has static asserts.
     TMP

??
     macro pre-processor

You can use the C preprocessor with D, if you want.
     'using'

Replaced with 'alias'.
     operators that look like operators

Sorry, but that's a bug in C++.
     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.
 and the ability to fill the gaps in the spectrum with user defined types

?? D has full UDT support.
     support for shims (implicit template instantiation coupled with

 namespaces)

Agreed.
     lack of GC

Lack of GC is a feature? How? One can program D just like you can in C, strictly using malloc/free. Nary a GC object. D does not require GC.
     ability to produce extremely small applications (i.e. supports

 with C/C++ Runtime Library)

Phobos is a part of D, just like the C/C++ runtime library is a part of C/C++. In both languages, you can stub out what you don't want, or provide some minimal alternative. Phobos is certainly not a VM that must be dragged around for the trivialest apps.
     etc. etc. etc.

? ? ?
 (For the record, I'm writing std.openrj right now, in 100% D, and enjoying

wonderland ...) I predict that once you write enough D code, you'll discover that C++ is the incomplete language <g>. Try supporting UTF in the C++ version of openrj.
Mar 07 2005
parent reply Matthias Becker <Matthias_member pathlink.com> writes:
 Walter wrote:
 As a *language*, what does C++ have over D?
 Implicit function template instantiation. It's hard to find much else.


const

Discussed in great depth elsewhere!
     references

See my response to Anders on that.
     bool

I'm not seeing it, Matthew!

Hmm... Using enum you can write your own bool.
     namespaces

I really see nothing in C++ namespaces that has anything over D modules. Namespaces are a failed attempt to add module like semantics to C++, and I say failed because several experts told me that exported templates were needed in order to provide "coding hygiene", i.e. prevent the names in one source file from stepping on those in another. I found that interesting because that was exactly the problem that namespace was supposed to solve.

The header + translation unit system is crap, right. But namespaces aren't.
     compile-time testing (none of that hideous runtime generic comparison

?? D has static asserts.
     TMP

??

Template-Meta-Programming. I never tried to do that in D, so I can't say anything usefull here.
     macro pre-processor


Matthew, do you realy want a C-like preprocessor? If D should get macros it should get powerfull Lisp-like macros!
You can use the C preprocessor with D, if you want.

     'using'

Replaced with 'alias'.
     operators that look like operators

Sorry, but that's a bug in C++.

Sorry, I don't get it? Which operator doesn't look like an operator? "in"? D has almost the same operators as C++. Or are you talking about these strange names like "opAdd"?
     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.
 and the ability to fill the gaps in the spectrum with user defined types

?? D has full UDT support.

D isn't very good at types with value semantics, while being good at types with reference semantics.
     support for shims (implicit template instantiation coupled with

 namespaces)

Agreed.
     lack of GC

Lack of GC is a feature? How? One can program D just like you can in C, strictly using malloc/free. Nary a GC object. D does not require GC.
     ability to produce extremely small applications (i.e. supports

 with C/C++ Runtime Library)

Phobos is a part of D, just like the C/C++ runtime library is a part of C/C++. In both languages, you can stub out what you don't want, or provide some minimal alternative. Phobos is certainly not a VM that must be dragged around for the trivialest apps.
     etc. etc. etc.

? ? ?
 (For the record, I'm writing std.openrj right now, in 100% D, and enjoying

wonderland ...) I predict that once you write enough D code, you'll discover that C++ is the incomplete language <g>. Try supporting UTF in the C++ version of openrj.

Mar 09 2005
next sibling parent reply pragma <pragma_member pathlink.com> writes:
[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: 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. - EricAnderton at yahoo
Mar 09 2005
parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"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: 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 ...
Mar 09 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"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.
Mar 09 2005
parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:d0o3dn$j7m$1 digitaldaemon.com...
 "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.

Of course, I recognise that. But that's completely irrelevant. C's cast performs proper conversions when casting an int to a double. That does not detract from the legion flaws of C's cast.
 We weren't talking about class reference
 conversions at the time, so I did not think to bring it up.

Fair enough. The problem with D's cast is exactly what prompted C++ to introduce its four built-in cast operators. There's nothing I can usefully add to their rationale, other than to say that C++'s template syntax and implicit instantiation makes a wonderfully powerful and extensible cast mechanism. btw, I asked B.S. whether he'd planned it that way deliberately. With customary succinctness he said "it did occur to me". I consider this to be one of his many remarkable moments of genius in designing C++, and I heartily commend you to do the same, but better, for D.
Mar 09 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message
news:d0o48n$k21$1 digitaldaemon.com...
 btw, I asked B.S. whether he'd planned it that way deliberately. With
 customary succinctness he said "it did occur to me". I consider this to
 be one of his many remarkable moments of genius in designing C++, and I
 heartily commend you to do the same, but better, for D.

Yes, B.S. did deliberately choose to use template syntax for it, and said so at the time. Just so you know!
Mar 09 2005
parent "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:d0o6ca$m4g$1 digitaldaemon.com...
 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message
 news:d0o48n$k21$1 digitaldaemon.com...
 btw, I asked B.S. whether he'd planned it that way deliberately. With
 customary succinctness he said "it did occur to me". I consider this 
 to
 be one of his many remarkable moments of genius in designing C++, and 
 I
 heartily commend you to do the same, but better, for D.

Yes, B.S. did deliberately choose to use template syntax for it, and said so at the time. Just so you know!

Ah! Then I'm the bearer of old news. Still, old's better than bad I suppose. ;)
Mar 09 2005
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
"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

 cast on your own (e.g boost::lexical_cast looks like the other C++-cast).

 the C++-Casts are more powefull. If you defenitly know that an object has

 type you want to cast to, you can use a static cast, if you aren't sure,

 use a dynamic cast. In D you allways have to use a dynamic cast, which is

 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);
Mar 09 2005
parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:d0o2qr$iif$2 digitaldaemon.com...
 "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

 cast on your own (e.g boost::lexical_cast looks like the other 
 C++-cast).

 the C++-Casts are more powefull. If you defenitly know that an object 
 has

 type you want to cast to, you can use a static cast, if you aren't 
 sure,

 use a dynamic cast. In D you allways have to use a dynamic cast, 
 which is

 more expensive.

You can do what you ask in D by first passing it through a 'void*' cast: b = cast(B)cast(void*)a;

Well, if that doesn't prove that cast() is overly coarse, I don't know what does.
 which will do the same thing as C++:

    b = static_cast<B*>(a);

This one is incontestably clearer.
Mar 09 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message
news:d0o3ln$jho$2 digitaldaemon.com...
 You can do what you ask in D by first passing it through a 'void*'
 cast:

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

Well, if that doesn't prove that cast() is overly coarse, I don't know what does.
 which will do the same thing as C++:

    b = static_cast<B*>(a);

This one is incontestably clearer.

It is? I remember when static_cast came out, I had to read the spec several times to figure out what it did. 'static' has no reliable meaning in C++. Suppose I propose: extern_cast<B*>(a); for C++. What does it do?
Mar 09 2005
next sibling parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:d0o6v7$mir$1 digitaldaemon.com...
 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message
 news:d0o3ln$jho$2 digitaldaemon.com...
 You can do what you ask in D by first passing it through a 'void*'
 cast:

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

Well, if that doesn't prove that cast() is overly coarse, I don't know what does.
 which will do the same thing as C++:

    b = static_cast<B*>(a);

This one is incontestably clearer.

It is? I remember when static_cast came out, I had to read the spec several times to figure out what it did. 'static' has no reliable meaning in C++. Suppose I propose: extern_cast<B*>(a); for C++. What does it do?

Fine. So what? Off the point. I don't care a rats about what it's called, and I have a hard time believing that you think I do. The point is that there are _different_ casts for doing _different_ things. Axiomatically, this reduces the likelihood of the execution of such operation from inadvertently doing another. Am I being unreasonable to hope that you might address my point, or simply acknowledge that you'd rather not complicate the language/compiler? I mean, come on. That double cast thing above is just bloody ridiculous. Anyone new dipping in and reading that post from the language designer is going to have their confidence factor drop to zero. Or am I wrong? Please explain
Mar 09 2005
parent Ben Hinkle <Ben_member pathlink.com> writes:
 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);




I mean, come on. That double cast thing above is just bloody ridiculous. 
Anyone new dipping in and reading that post from the language designer 
is going to have their confidence factor drop to zero. Or am I wrong? 
Please explain

Can we throw an itty-bitty template like the following into std somewhere? I'm half tempted to suggest putting it in std.c.stddef just because it's so C-like. Personally I don't think it'll get used much (Java gets along fine without one), but who knows... // compile-time cast to a class T template c_cast(T : Object) { T c_cast(void* x) { return cast(T)x; } } // example class A {} class B:A {} class C:A {} int main() { B b = new B; C c = c_cast!(C)(b); // point gun at foot... return 0; }
Mar 09 2005
prev sibling parent reply Roberto Mariottini <Roberto_member pathlink.com> writes:
In article <d0o6v7$mir$1 digitaldaemon.com>, Walter says...
I remember when static_cast came out, I had to read the spec several
times to figure out what it did. 'static' has no reliable meaning in C++.

Isn't 'static' the opposite of 'dynamic'? :-)
Suppose I propose:

    extern_cast<B*>(a);

for C++. What does it do?

The opposite of 'static'. :-) Ciao
Mar 10 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Roberto Mariottini" <Roberto_member pathlink.com> wrote in message
news:d0p053$1jav$1 digitaldaemon.com...
 In article <d0o6v7$mir$1 digitaldaemon.com>, Walter says...
I remember when static_cast came out, I had to read the spec several
times to figure out what it did. 'static' has no reliable meaning in C++.

Isn't 'static' the opposite of 'dynamic'? :-)
Suppose I propose:

    extern_cast<B*>(a);

for C++. What does it do?

The opposite of 'static'. :-)

Yup <g>. The point being that it's clear what it does only after carefully reading the documentation. The double cast way of doing static casts in D is an idiom. There are idioms in D just like there are well-known idioms in C++. I suggest that the double cast idiom will become one of those well recognized ones and it's meaning will be clear because people will be used to seeing it and using it.
Mar 10 2005
parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:d0q1vg$2m2t$1 digitaldaemon.com...
 "Roberto Mariottini" <Roberto_member pathlink.com> wrote in message
 news:d0p053$1jav$1 digitaldaemon.com...
 In article <d0o6v7$mir$1 digitaldaemon.com>, Walter says...
I remember when static_cast came out, I had to read the spec several
times to figure out what it did. 'static' has no reliable meaning in 
C++.

Isn't 'static' the opposite of 'dynamic'? :-)
Suppose I propose:

    extern_cast<B*>(a);

for C++. What does it do?

The opposite of 'static'. :-)

Yup <g>. The point being that it's clear what it does only after carefully reading the documentation. The double cast way of doing static casts in D is an idiom. There are idioms in D just like there are well-known idioms in C++. I suggest that the double cast idiom will become one of those well recognized ones and it's meaning will be clear because people will be used to seeing it and using it.

Sorry to get all unprofessional, but when I read you saying things like this I wonder whether the world is made of chocolate, and Homer's eaten out my brain. That double cast is a freakish bit of code, that will be fantastic fodder for D-etractors. I'm just stunned that you think that it's reasonable, in a language with all the intentions D makes, to propose such hacks, instead of addressing real needs within the (pre-1.0) language itself. Sure, maybe it's me. I could be cracked, but I really think not (at least in this case). I'll attempt some rationalisation: D's design is predicated on the fact that pointers are dangerous, and, despite their acknowledged power (and facilitation of efficiency) cause problems for the (un)wary in C and C++. While D permits use of pointers, goto, etc. etc. for interfacing to C and such things - a good thing, and an advantage over nannying languaJes - it should be possible to avoid them and still be able to practice D in a powerful, full-featured sophisticated way. Now I may be editorialising somewhat, but I'm pretty sure I've read those arguments from your posts over the years, albeit in fragmented form perhaps. Please correct me if this misrepresents things. Now we come to casting. There are all kinds of casting, whether they bear distinct names or have distinct language constructs or not. Integral truncation. Integral promotion. Type conversion (/subversion). OO hierarchy navigation. etc. etc. Users from other languages in which these issues have already been sensibly addressed will naturally seek to avoid the too-coarse-grained cast() operator. You've recognised that, and demonstrated a technique whereby they might do so. But what you're telling them is that, to do so, they must use pointers in a language that specifically eschews pointers. This is inconsistent, and gives the impression that the language is hacked together. If I'm wrong to draw that conclusion, I'm very interested to have it explained to me. Now, why do we have access to only a single too-coarse-grained cast()? Because you, personally, do not appreciate the purpose (or perhaps the implementation) of different cast operators. This may be because you (as I'm pretty sure you've admitted) tend not to use them. Or maybe you tend not to use them because you don't appreciate them. Chicken or egg. Impossible to tell. (Again, please correct me if I'm misrepresenting you.) I have to say that I can draw no other conclusion than that: a. you do not like/appreciate cast richness, therefore b. you don't (much?) use these casts, therefore c. you do not think they should be in D, therefore d. you have come up with a farcical cast hack, using things that are expressively avoided/avoidable in 'normal' D. And you've called it an idiom!! It's just bonkers. I put it to everyone who's managed to get to stick with the rant to this point to select which of the following is more discoverable, maintainable, amenable to automated code searching tools, indicative of considered design, attractive, etc.: b = cast(B)cast(void*)a; b = type_cast(B)(a); (Note: type_cast is just a name I conjured for the example. Naturally we'd go through a collegial process for coming up with good and sensible names for any/all specific cast operators.)
Mar 10 2005
next sibling parent reply Kris <Kris_member pathlink.com> writes:
I have to agree that the 'idiom' described did have me chuckling heartily, for
many of the reasons you describe. In particular, if this would be used often
enough to become an "idiom", then why the heck wouldn't the language clean up
the syntax?

Perhaps it should be called one of the following?

    b = castigate(B) a;

    b = castrate(B) a;

:-} It does seem jolly silly for it to remain as "cast(B) cast(void*) a" instead. Egad! In article <d0qksf$9im$1 digitaldaemon.com>, Matthew says...
"Walter" <newshound digitalmars.com> wrote in message 
news:d0q1vg$2m2t$1 digitaldaemon.com...
 "Roberto Mariottini" <Roberto_member pathlink.com> wrote in message
 news:d0p053$1jav$1 digitaldaemon.com...
 In article <d0o6v7$mir$1 digitaldaemon.com>, Walter says...
I remember when static_cast came out, I had to read the spec several
times to figure out what it did. 'static' has no reliable meaning in 
C++.

Isn't 'static' the opposite of 'dynamic'? :-)
Suppose I propose:

    extern_cast<B*>(a);

for C++. What does it do?

The opposite of 'static'. :-)

Yup <g>. The point being that it's clear what it does only after carefully reading the documentation. The double cast way of doing static casts in D is an idiom. There are idioms in D just like there are well-known idioms in C++. I suggest that the double cast idiom will become one of those well recognized ones and it's meaning will be clear because people will be used to seeing it and using it.

Sorry to get all unprofessional, but when I read you saying things like this I wonder whether the world is made of chocolate, and Homer's eaten out my brain. That double cast is a freakish bit of code, that will be fantastic fodder for D-etractors. I'm just stunned that you think that it's reasonable, in a language with all the intentions D makes, to propose such hacks, instead of addressing real needs within the (pre-1.0) language itself. Sure, maybe it's me. I could be cracked, but I really think not (at least in this case). I'll attempt some rationalisation: D's design is predicated on the fact that pointers are dangerous, and, despite their acknowledged power (and facilitation of efficiency) cause problems for the (un)wary in C and C++. While D permits use of pointers, goto, etc. etc. for interfacing to C and such things - a good thing, and an advantage over nannying languaJes - it should be possible to avoid them and still be able to practice D in a powerful, full-featured sophisticated way. Now I may be editorialising somewhat, but I'm pretty sure I've read those arguments from your posts over the years, albeit in fragmented form perhaps. Please correct me if this misrepresents things. Now we come to casting. There are all kinds of casting, whether they bear distinct names or have distinct language constructs or not. Integral truncation. Integral promotion. Type conversion (/subversion). OO hierarchy navigation. etc. etc. Users from other languages in which these issues have already been sensibly addressed will naturally seek to avoid the too-coarse-grained cast() operator. You've recognised that, and demonstrated a technique whereby they might do so. But what you're telling them is that, to do so, they must use pointers in a language that specifically eschews pointers. This is inconsistent, and gives the impression that the language is hacked together. If I'm wrong to draw that conclusion, I'm very interested to have it explained to me. Now, why do we have access to only a single too-coarse-grained cast()? Because you, personally, do not appreciate the purpose (or perhaps the implementation) of different cast operators. This may be because you (as I'm pretty sure you've admitted) tend not to use them. Or maybe you tend not to use them because you don't appreciate them. Chicken or egg. Impossible to tell. (Again, please correct me if I'm misrepresenting you.) I have to say that I can draw no other conclusion than that: a. you do not like/appreciate cast richness, therefore b. you don't (much?) use these casts, therefore c. you do not think they should be in D, therefore d. you have come up with a farcical cast hack, using things that are expressively avoided/avoidable in 'normal' D. And you've called it an idiom!! It's just bonkers. I put it to everyone who's managed to get to stick with the rant to this point to select which of the following is more discoverable, maintainable, amenable to automated code searching tools, indicative of considered design, attractive, etc.: b = cast(B)cast(void*)a; b = type_cast(B)(a); (Note: type_cast is just a name I conjured for the example. Naturally we'd go through a collegial process for coming up with good and sensible names for any/all specific cast operators.)

Mar 10 2005
parent reply pragma <pragma_member pathlink.com> writes:
In article <d0qp27$e54$1 digitaldaemon.com>, Kris says...
It does seem jolly silly for it to remain as "cast(B) cast(void*) a" instead.
Egad!

Well, having rolled my own casting operator myself, I'd like to add my $0.02 to the pot. I can easily forsee a templatized wrapper around the const-cast idiom:
 static_cast!(Foo)(bar);

Which is really the ghost of language past. Let's not do this, please. I for one would rather see the typical kinds of casts enshrined in the language itself:
 static_cast(Foo) bar;

Along with all of its friends:
 cast(Foo) bar;
 dynamic_cast(Foo) bar; // same as vanilla cast()
 static_cast(Foo) bar;
 const_cast(Foo) bar; // depending on the outcome of the 'const saga'.
 extern_cast(Foo) bar; // classname based cast rather than typeid based.

Now not having these in the language is no real loss, thanks to the (incomplete) ABI. However, use of such casts is frequent enough that adding them could only help us write cleaner (varargs come to mind) code. Also, I'll add that the template system is inadequate to make a completely water-tight cast operator, so something needs to be done one way or the other. - EricAnderton at yahoo
Mar 10 2005
parent reply Ben Hinkle <Ben_member pathlink.com> writes:
In article <d0r40c$o40$1 digitaldaemon.com>, pragma says...
In article <d0qp27$e54$1 digitaldaemon.com>, Kris says...
It does seem jolly silly for it to remain as "cast(B) cast(void*) a" instead.
Egad!

Well, having rolled my own casting operator myself, I'd like to add my $0.02 to the pot. I can easily forsee a templatized wrapper around the const-cast idiom:
 static_cast!(Foo)(bar);

Which is really the ghost of language past. Let's not do this, please. I for one would rather see the typical kinds of casts enshrined in the language itself:
 static_cast(Foo) bar;

Along with all of its friends:
 cast(Foo) bar;
 dynamic_cast(Foo) bar; // same as vanilla cast()
 static_cast(Foo) bar;
 const_cast(Foo) bar; // depending on the outcome of the 'const saga'.
 extern_cast(Foo) bar; // classname based cast rather than typeid based.

Now not having these in the language is no real loss, thanks to the (incomplete) ABI. However, use of such casts is frequent enough that adding them could only help us write cleaner (varargs come to mind) code. Also, I'll add that the template system is inadequate to make a completely water-tight cast operator, so something needs to be done one way or the other. - EricAnderton at yahoo

ack - I really hope D doesn't end up with a bazillion (or even, say, three)casting options. Casting is so rare and the performance hit of a dynamic cast vs static cast hasn't ever been a problem in my Java coding experience that it would be a pity to burden future D coder with all the esoteric casts. Why bother? Casting is evil - so why obsess over it. One benefit of the double cast is it makes it explicit what is actually happening. Say I have an int x that I want to cast to an object reference. I actually prefer cast(Object)cast(void*)x since it spells out the process of turning an int into a reference - not that I encourage that sort of thing :-)
Mar 10 2005
parent reply kris <fu bar.org> writes:
Ben Hinkle wrote:
<snip>
 ack - I really hope D doesn't end up with a bazillion (or even, say,
 three)casting options. Casting is so rare and the performance hit of a dynamic
 cast vs static cast hasn't ever been a problem in my Java coding experience
that
 it would be a pity to burden future D coder with all the esoteric casts. Why
 bother? Casting is evil - so why obsess over it.

I don't think anyone is obsessing, Ben. There's only been a couple of posts on this particular angle, compared to what must be /hundreds/ over '$' :-) I can't imagine anyone would claim that casting is the "right" way, but Walter did bring it up in terms of an 'idiom' ... for that, it needs to be applied to a certain degree (as opposed to never).
 One benefit of the double cast is it makes it explicit what is actually
 happening. Say I have an int x that I want to cast to an object reference. I
 actually prefer cast(Object)cast(void*)x since it spells out the process of
 turning an int into a reference - not that I encourage that sort of thing :-)

Again, I can't imagine you'd get an argument here. But this is not the case in question. What you're noting here is a gross violation ~ unless I misread you? Just for the record: I encourage people to avoid casting, since it tends to hide issues that the compiler might otherwise catch, and it can make maintenance and/or refactoring that much more difficult. However, if Walter expects developers will use static-casts, then that usage should be explicitly supported ~ if nothing else, it will isolate those instances from the 'gross violation' cases you identified above. I don't suppose anyone thought 'castigate' was an appropriate term? No? Oh well :-)
Mar 10 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 10 Mar 2005 21:48:56 -0800, kris wrote:

 Ben Hinkle wrote:
 <snip>
 ack - I really hope D doesn't end up with a bazillion (or even, say,
 three)casting options. Casting is so rare and the performance hit of a dynamic
 cast vs static cast hasn't ever been a problem in my Java coding experience
that
 it would be a pity to burden future D coder with all the esoteric casts. Why
 bother? Casting is evil - so why obsess over it.


But still necessary sometimes. void Foo(char[] x){}; void Foo(wchar[] x){}; Foo(cast(wchar[])"abcdef"); // Cast required else the compiles fails. -- Derek Parnell Melbourne, Australia 11/03/2005 11:06:16 PM
Mar 11 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message 
news:1l04rq800km3a.16v19z9iovqpy$.dlg 40tude.net...
 On Thu, 10 Mar 2005 21:48:56 -0800, kris wrote:

 Ben Hinkle wrote:
 <snip>
 ack - I really hope D doesn't end up with a bazillion (or even, say,
 three)casting options. Casting is so rare and the performance hit of a 
 dynamic
 cast vs static cast hasn't ever been a problem in my Java coding 
 experience that
 it would be a pity to burden future D coder with all the esoteric casts. 
 Why
 bother? Casting is evil - so why obsess over it.


But still necessary sometimes. void Foo(char[] x){}; void Foo(wchar[] x){}; Foo(cast(wchar[])"abcdef"); // Cast required else the compiles fails.

Agreed. And I argue the existing D cast does just fine with 99.9% of cast situations. I actually am curious why Walter thinks the double-cast will become an idiom. The only "legit" one that comes to mind is wanting to do a static cast on object references instead of a dynamic cast for performance.
Mar 11 2005
parent reply pragma <pragma_member pathlink.com> writes:
In article <d0s3nj$1s5q$1 digitaldaemon.com>, Ben Hinkle says...
"Derek Parnell" <derek psych.ward> wrote in message 
news:1l04rq800km3a.16v19z9iovqpy$.dlg 40tude.net...
 On Thu, 10 Mar 2005 21:48:56 -0800, kris wrote:

 Ben Hinkle wrote:
 <snip>
 ack - I really hope D doesn't end up with a bazillion (or even, say,
 three)casting options. Casting is so rare and the performance hit of a 
 dynamic
 cast vs static cast hasn't ever been a problem in my Java coding 
 experience that
 it would be a pity to burden future D coder with all the esoteric casts. 
 Why
 bother? Casting is evil - so why obsess over it.


But still necessary sometimes. void Foo(char[] x){}; void Foo(wchar[] x){}; Foo(cast(wchar[])"abcdef"); // Cast required else the compiles fails.

Agreed. And I argue the existing D cast does just fine with 99.9% of cast situations. I actually am curious why Walter thinks the double-cast will become an idiom. The only "legit" one that comes to mind is wanting to do a static cast on object references instead of a dynamic cast for performance.

Well, working with varargs is rife with casting through "void**" to get the actual argument's pointer. The suggested template in the docs helps some, but its still there, under the hood.
The only "legit" one that comes to mind is wanting to do a 
static cast on object references instead of a dynamic cast for performance. 

That's an interesting concept, but probably ill-adivsed in D (more so than in C++). It would work great class-to-class, but will fail if an interface is involved in the cast. - EricAnderton at yahoo
Mar 11 2005
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
pragma wrote:

 Well, working with varargs is rife with casting through "void**" to get the
 actual argument's pointer.  The suggested template in the docs helps some, but
 its still there, under the hood.

The suggested template is the only way that works in GDC since _argptr is not a "void*" everywhere, but a "va_list" type that *might* be one... Hopefully the void*/cast section of the D specification can be removed, in favor of std.stdarg, to stop people from writing non-portable code ? http://www.digitalmars.com/d/function.html Kinda like writing to D's string literals, which only works on Windows. --anders
Mar 11 2005
prev sibling next sibling parent Derek Parnell <derek psych.ward> writes:
On Fri, 11 Mar 2005 10:22:54 +1100, Matthew wrote:

 "Walter" <newshound digitalmars.com> wrote in message 
 news:d0q1vg$2m2t$1 digitaldaemon.com...
 "Roberto Mariottini" <Roberto_member pathlink.com> wrote in message
 news:d0p053$1jav$1 digitaldaemon.com...
 In article <d0o6v7$mir$1 digitaldaemon.com>, Walter says...
I remember when static_cast came out, I had to read the spec several
times to figure out what it did. 'static' has no reliable meaning in 
C++.

Isn't 'static' the opposite of 'dynamic'? :-)
Suppose I propose:

    extern_cast<B*>(a);

for C++. What does it do?

The opposite of 'static'. :-)

Yup <g>. The point being that it's clear what it does only after carefully reading the documentation. The double cast way of doing static casts in D is an idiom. There are idioms in D just like there are well-known idioms in C++. I suggest that the double cast idiom will become one of those well recognized ones and it's meaning will be clear because people will be used to seeing it and using it.

Sorry to get all unprofessional, but when I read you saying things like this I wonder whether the world is made of chocolate, and Homer's eaten out my brain. That double cast is a freakish bit of code, that will be fantastic fodder for D-etractors. I'm just stunned that you think that it's reasonable, in a language with all the intentions D makes, to propose such hacks, instead of addressing real needs within the (pre-1.0) language itself.

 It's just bonkers.
 
 I put it to everyone who's managed to get to stick with the rant to this 
 point to select which of the following is more discoverable, 
 maintainable, amenable to automated code searching tools, indicative of 
 considered design, attractive, etc.:
 
     b = cast(B)cast(void*)a;
 
     b = type_cast(B)(a);
 
 (Note: type_cast is just a name I conjured for the example. Naturally 
 we'd go through a collegial process for coming up with good and sensible 
 names for any/all specific cast operators.)

Matthew has a good point. The double cast idiom is just asking to be picked on as a "stupid idea" when a much more expressive one could have be implemented. -- Derek Parnell Melbourne, Australia 11/03/2005 10:57:51 PM
Mar 11 2005
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message
news:d0qksf$9im$1 digitaldaemon.com...
 Users from other languages in which these issues have already been
 sensibly addressed will naturally seek to avoid the too-coarse-grained
 cast() operator. You've recognised that, and demonstrated a technique
 whereby they might do so. But what you're telling them is that, to do
 so, they must use pointers in a language that specifically eschews
 pointers.

The cast(B)a will work perfectly fine, and avoids pointer manipulation. It'll do upcasting and downcasting for class objects in a safe manner. The cast(B)cast(void*)a is a technique for people who want to *go around* the typing rules because they "know" that 'a' can be downcast to a B without a runtime check. As such, it qualifies as a technique for more advanced programmers, and pointers are well supported in D expressly for use by more advanced programmers who understand them.
Mar 11 2005
parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:d0tobv$1999$1 digitaldaemon.com...
 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message
 news:d0qksf$9im$1 digitaldaemon.com...
 Users from other languages in which these issues have already been
 sensibly addressed will naturally seek to avoid the 
 too-coarse-grained
 cast() operator. You've recognised that, and demonstrated a technique
 whereby they might do so. But what you're telling them is that, to do
 so, they must use pointers in a language that specifically eschews
 pointers.

The cast(B)a will work perfectly fine, and avoids pointer manipulation. It'll do upcasting and downcasting for class objects in a safe manner. The cast(B)cast(void*)a is a technique for people who want to *go around* the typing rules because they "know" that 'a' can be downcast to a B without a runtime check. As such, it qualifies as a technique for more advanced programmers, and pointers are well supported in D expressly for use by more advanced programmers who understand them.

Well, I have to say I find that attitude quite depressing. I am quite sure that it will make D look like a hackers delight. You're equally sure it won't. Impasse. I can do nothing useful further, other than take the brick from my hand and not bash my head with it any further. However, you have not addressed the far less equivocal point that cast(X)cast(void*)y is manifestly less amenable to code analysis tools as static_cast(X)y
Mar 11 2005
parent "Walter" <newshound digitalmars.com> writes:
"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message
news:d0tsll$1d22$1 digitaldaemon.com...
 However, you have not addressed the far less equivocal point that

     cast(X)cast(void*)y

 is manifestly less amenable to code analysis tools as

     static_cast(X)y

If grep is the extent of it, perhaps. I think cast(void*) is eminently greppable; you'll get some false positives just like you will with grepping for static_cast. On the other hand, D is far more amenable to real code analysis tools because D is parseable at several levels without requiring a full blown compiler to do it. Even if you are using a code analysis tool that needs to do semantic analysis, it's just a lot easier to do with D than with C++. Once you have that, it isn't hard at all to look for a double cast on a class reference. If that still isn't enough, you can always write a template to do it, and grep on the template name.
Mar 11 2005
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Anders F Björklund" <afb algonet.se> wrote in message
news:d0gu9k$1n20$2 digitaldaemon.com...
 Walter wrote:
Like many others, I think that C++ is a more "complete" language.



 Implicit function template instantiation. It's hard to find much else.

D has some "simplified" versions of C++ features, like inout instead of reference params,

A C++ reference parameter gives no clue whether it is in, out, or inout. The situation is such that Microsoft went ahead and invented IDL (Interface Description Language), the sole point of which is to add that missing bit of information. IDL is irrelevant for D. Looking at how references actually work in C++, they are loaded up with special rules that make them behave as if they were storage classes rather than types. D just goes ahead and makes them what they naturally want to be. I don't see anything incomplete about it.
 simplified const handling (storage instead of type),

As has been debated here many times <g>, const as a type modifier in C++ is so semantically weak it is fairly useless. (Many disagree.) C and C++ are the only languages I've ever heard of that use const as a type modifier. Java and C# show no signs of adopting it. The C++ community has not convinced the larger programmer community that const as a type modifier has a place.
 etc, and I guess I'd have more examples if I had been using C++ more...
 And this makes C++ more "complete" in that you can do more things,
 but is also makes a lot harder and complex - at least at the start ?

I'd argue that C++ is less complete, since it relies so heavilly on STL to do things that are built in to most languages. Doing a general purpose foreach with C++ is fiendishly difficult. It's for free in D.
 I'll let the C++ experts fill in their own pet peeves about D 1.0.
 (as I've said before, my own experience is with C and with Java)

Mar 06 2005
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter wrote:

 A C++ reference parameter gives no clue whether it is in, out, or inout. The
 situation is such that Microsoft went ahead and invented IDL (Interface
 Description Language), the sole point of which is to add that missing bit of
 information. IDL is irrelevant for D.

I prefer the "in/out" parameters. Reminds me of Ada or something...
 As has been debated here many times <g>, const as a type modifier in C++ is
 so semantically weak it is fairly useless. (Many disagree.) C and C++ are
 the only languages I've ever heard of that use const as a type modifier.
 Java and C# show no signs of adopting it. The C++ community has not
 convinced the larger programmer community that const as a type modifier has
 a place.

The only place for "const" seems to be protecting read-only attribute ?
 I'd argue that C++ is less complete, since it relies so heavilly on STL to
 do things that are built in to most languages. Doing a general purpose
 foreach with C++ is fiendishly difficult. It's for free in D.

I think I'll just let you fight that one out with Matthew ;-) I never liked C++, so I went straight to Java. D changes that. --anders
Mar 07 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Anders F Björklund" <afb algonet.se> wrote in message
news:d0hu4o$2orp$1 digitaldaemon.com...
 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.
Mar 07 2005
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
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?) --anders
Mar 09 2005
parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"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??
Mar 09 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"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.
Mar 09 2005
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
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
Mar 09 2005
parent reply Ben Hinkle <Ben_member pathlink.com> writes:
In article <d0o2ge$hf5$2 digitaldaemon.com>,
=?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...
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?)

Not to put too fine a point on it but I'm not sure what you mean by "blank final" here. Java's blank final is not the same as "final requiring explicit initialization". In fact I think it's the opposite. In Java a blank final is when a class field is declared "final" that is *not* given an initializer but is provably assigned in every constructor. See http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#35962
Mar 09 2005
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Ben Hinkle wrote:

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")

Not to put too fine a point on it but I'm not sure what you mean by "blank final" here. Java's blank final is not the same as "final requiring explicit initialization". In fact I think it's the opposite. In Java a blank final is when a class field is declared "final" that is *not* given an initializer but is provably assigned in every constructor.

As usual, my code example was clear and my "explanation" sucked. Thanks. (see Matthew's const/readonly thread) --anders
Mar 09 2005
prev sibling parent "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"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.
Mar 09 2005
prev sibling next sibling parent reply "Matthew" <admin.hat stlsoft.dot.org> writes:
 simplified const handling (storage instead of type),

As has been debated here many times <g>, const as a type modifier in C++ is so semantically weak it is fairly useless. (Many disagree.)

This is hugely disingenuous. _You_ don't think const has any use. But then _you_ don't use const. Maybe they're related? I find const *enormously* useful, both for its intended uses and for the unforeseen tricks one can put it to. The absence of such is the largest common failing in other languages that I use, including C, Java, .NET *and* D, and a significant part of the reason why I don't tend to use those languages for serious development.
C and C++ are
 the only languages I've ever heard of that use const as a type modifier.
 Java and C# show no signs of adopting it. The C++ community has not
 convinced the larger programmer community that const as a type modifier has
 a place.

How can you conclude that? One might just as well surmise that the implementation complexity is what deters these other 'communities'. After all, these other languages - Java, .NET, D - are all far more allied to specific vendors, and are therefore far more likely to be swayed by what's good for the vendor rather than what's good for the programmer. That you don't recognise/acknowledge this shows that either you're trying to hoodwink us, or that you've succeeded too well in hoodwinking yourself.
 I'd argue that C++ is less complete, since it relies so heavilly on STL to
 do things that are built in to most languages. Doing a general purpose
 foreach with C++ is fiendishly difficult. It's for free in D.

As a general point, I must observe that you are far too prone these days to counter criticisms of D's feature X by saying feature Y is great. This is just stupid. Yes, D has many marvellous features. This is a big part of why I am excited about D, and why I've stuck with it these last 2.5 years. But D also has some serious flaws, omissions, and howling stinkers. The absence of some/all of const in D is a flaw. Period! The only debate is where the some/all point is drawn. To counter by saying that Java and .NET haven't followed C++ is (i) not true, and (ii) disingenuous. IIRC, Java does use final on members, so one of the *fabulous powers of const in C++* has been aped. That D has not followed this particular facet is a manifest flaw, and cannot be explained away by 'the complexity of using/implementing const'. It's nothing more than an extension of your personal uninformed (since you don't use const) prejudices. So, Walter, I say stop telling us about the great things in D. We all know and love them. No other language I know of can do slices, and the combination of slices, GC and auto is unparalleled. (FGI: Walter and I are doing an article on this "Not Your Father's Resource Management" for DDJ just as soon as I get my fingers out of all the other pies and do my half of it. The article shows how D is an optimal mix of C++'s and Java/.NET's resource management paradigms, and is superior to them all.) What's going to stop D prospering is not failure-to-recognise-its-many-significant-virtues, but all-too-ready-recognition-of-its-many-significant-flaws. Sheesh! If I went to a psychologist to get help in sorting out my many personality flaws, I wouldn't waste her time and my money in long and fatuous discussions about my many admirable traits!!!
Mar 07 2005
next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Matthew" <admin.hat stlsoft.dot.org> wrote in message
news:d0idln$97o$1 digitaldaemon.com...
 simplified const handling (storage instead of type),



 so semantically weak it is fairly useless. (Many disagree.)


Right - many disagree - and I was thinking specifically of you!
 But then _you_ don't use const. Maybe they're related?

I used to use const as a type modifier. I gave it up after becoming disenchanted with it. I use const as a storage class all the time. (The two uses are very different, although they look the same in C++. I wish to emphasize the difference, as sometimes in these threads they incorrectly get referred to interchangeably.)
 That you don't recognise/acknowledge this shows that either you're trying

 well in hoodwinking yourself.

I understand that you made a convincing argument. I respectfully suggest, however, that doesn't necessarilly mean I was convinced and am therefore trying to argue things I secretly believe to be false. I know exactly how to implement const as a type modifier. If I believed it was the right thing to do, I'd do it. Microsoft and Sun both have inhouse C++ compilers under active development, and they know how to do it, too. They've both poured incredible resources in developing C# and Java. I have no idea exactly how the decision came about not to use const as a type modifier (as distinct from const as a storage class), but you can bet your last dollar that if they felt it had high value, it'd be implemented. This is one reason why I don't think I am way out of step in my opinion on const as a type modifier.
 I'd argue that C++ is less complete, since it relies so heavilly on STL


 do things that are built in to most languages. Doing a general purpose
 foreach with C++ is fiendishly difficult. It's for free in D.


 saying feature Y is great. This is just stupid.

The thread is about whether C++ and D are "complete" languages or not, and I wrote that comment should in that context.
 The absence of some/all of const in D is a flaw. Period! The only debate

 counter
 by saying that Java and .NET haven't followed C++ is (i) not true, and

 members, so one of the *fabulous powers of const in C++* has been aped.

 is a manifest flaw, and cannot be explained away by 'the complexity of

Java's 'final' is a storage class, not a type modifier. Its use on a field does not require the constructor to have an initializer for it. In fact, it is illegal to set 'final' fields inside a constructor. The initializer for the 'final' field must appear immediately after the declaration of the field, outside of any constructor. Therefore, constructor parameters cannot influence the setting of 'final' fields. Also, if one has multiple constructors in Java, and one 'forgets' to initialize one of the fields, no diagnostic is issued. The field gets default initialized. I'd argue it is a fairly different beast in Java than in C++, since it is not aping the C++ feature of getting diagnostics from the constructor about uninitialized const fields. What Java's 'final' does share with C++ const fields is that the compiler will diagnose attempts to modify the field after it is set. Java did it right, though, as Java doesn't allow casting away of constness, or non-const references to the same field modifying it out from under you. 'final' fields in Java are solid enough that the compiler can optimize based on it, and they have meaning in multithreaded apps, which is not the case in C++. I have no issue with const and final as a storage class, I believe they are valuable and useful, and const is implemented as a storage class in D (its use could probably be profitably extended to more contexts). I don't agree with its value as a type modifier, for oft stated reasons that I will summarize as being that in legal, standard conforming C++ code the value of the presumably 'const' data can change at any moment. Const things ought to be, dagnamit, constant.
Mar 07 2005
next sibling parent reply Kris <Kris_member pathlink.com> writes:
In article <d0iiqi$emd$1 digitaldaemon.com>, Walter says...
"Matthew" <admin.hat stlsoft.dot.org> wrote in message
news:d0idln$97o$1 digitaldaemon.com...
 simplified const handling (storage instead of type),



 so semantically weak it is fairly useless. (Many disagree.)


Right - many disagree - and I was thinking specifically of you!
 But then _you_ don't use const. Maybe they're related?

I used to use const as a type modifier. I gave it up after becoming disenchanted with it. I use const as a storage class all the time. (The two uses are very different, although they look the same in C++. I wish to emphasize the difference, as sometimes in these threads they incorrectly get referred to interchangeably.)
 That you don't recognise/acknowledge this shows that either you're trying

 well in hoodwinking yourself.

I understand that you made a convincing argument. I respectfully suggest, however, that doesn't necessarilly mean I was convinced and am therefore trying to argue things I secretly believe to be false. I know exactly how to implement const as a type modifier. If I believed it was the right thing to do, I'd do it. Microsoft and Sun both have inhouse C++ compilers under active development, and they know how to do it, too. They've both poured incredible resources in developing C# and Java. I have no idea exactly how the decision came about not to use const as a type modifier (as distinct from const as a storage class), but you can bet your last dollar that if they felt it had high value, it'd be implemented. This is one reason why I don't think I am way out of step in my opinion on const as a type modifier.
 I'd argue that C++ is less complete, since it relies so heavilly on STL


 do things that are built in to most languages. Doing a general purpose
 foreach with C++ is fiendishly difficult. It's for free in D.


 saying feature Y is great. This is just stupid.

The thread is about whether C++ and D are "complete" languages or not, and I wrote that comment should in that context.
 The absence of some/all of const in D is a flaw. Period! The only debate

 counter
 by saying that Java and .NET haven't followed C++ is (i) not true, and

 members, so one of the *fabulous powers of const in C++* has been aped.

 is a manifest flaw, and cannot be explained away by 'the complexity of

Java's 'final' is a storage class, not a type modifier. Its use on a field does not require the constructor to have an initializer for it. In fact, it is illegal to set 'final' fields inside a constructor. The initializer for the 'final' field must appear immediately after the declaration of the field, outside of any constructor. Therefore, constructor parameters cannot influence the setting of 'final' fields. Also, if one has multiple constructors in Java, and one 'forgets' to initialize one of the fields, no diagnostic is issued. The field gets default initialized. I'd argue it is a fairly different beast in Java than in C++, since it is not aping the C++ feature of getting diagnostics from the constructor about uninitialized const fields. What Java's 'final' does share with C++ const fields is that the compiler will diagnose attempts to modify the field after it is set. Java did it right, though, as Java doesn't allow casting away of constness, or non-const references to the same field modifying it out from under you. 'final' fields in Java are solid enough that the compiler can optimize based on it, and they have meaning in multithreaded apps, which is not the case in C++. I have no issue with const and final as a storage class, I believe they are valuable and useful, and const is implemented as a storage class in D (its use could probably be profitably extended to more contexts). I don't agree with its value as a type modifier, for oft stated reasons that I will summarize as being that in legal, standard conforming C++ code the value of the presumably 'const' data can change at any moment. Const things ought to be, dagnamit, constant.

Very glad to hear you opinion on this. I, for one, agree 100%. If you could provide a D mechanism for making scalar and vector data "appear" to be fully constant (as in the storage class) to third-parties (think return values), then we'd have the read-only enforcement so many of us are crying out for. That could easily become a major advantage for D over other languages. In addition, the utility of a true storage-constant attribute (one that is also supported via call-by-reference ~ inout obviously does not work) then that would open up additional avenues for D.
Mar 07 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Kris" <Kris_member pathlink.com> wrote in message
news:d0ilcf$hbt$1 digitaldaemon.com...
 In article <d0iiqi$emd$1 digitaldaemon.com>, Walter says...
What Java's 'final' does share with C++ const fields is that the compiler
will diagnose attempts to modify the field after it is set. Java did it
right, though, as Java doesn't allow casting away of constness, or


references to the same field modifying it out from under you. 'final'


in Java are solid enough that the compiler can optimize based on it, and
they have meaning in multithreaded apps, which is not the case in C++.

I have no issue with const and final as a storage class, I believe they


valuable and useful, and const is implemented as a storage class in D


use could probably be profitably extended to more contexts). I don't


with its value as a type modifier, for oft stated reasons that I will
summarize as being that in legal, standard conforming C++ code the value


the presumably 'const' data can change at any moment. Const things ought


be, dagnamit, constant.

Very glad to hear you opinion on this. I, for one, agree 100%.

Good. To put it another way, anything labeled as 'const' could be burned into ROM without changing the meaning of the program. (This is also implies that const data must have initializers that can be evaluated at compile time.)
 If you could provide a D mechanism for making scalar and vector data

 be fully constant (as in the storage class) to third-parties (think return
 values), then we'd have the read-only enforcement so many of us are crying

 for. That could easily become a major advantage for D over other

 In addition, the utility of a true storage-constant attribute (one that is

 supported via call-by-reference ~ inout obviously does not work) then that

 open up additional avenues for D.

Fundamentally connected with this is the problem of aliased function parameters. Get it wrong, as C and C++ do, and you cannot build an optimizer that is competitive with FORTRAN optimizers.
Mar 07 2005
parent reply Kris <Kris_member pathlink.com> writes:
In article <d0ip9t$lmv$1 digitaldaemon.com>, Walter says...

Good. To put it another way, anything labeled as 'const' could be burned
into ROM without changing the meaning of the program. (This is also implies
that const data must have initializers that can be evaluated at compile
time.)

 If you could provide a D mechanism for making scalar and vector data

 be fully constant (as in the storage class) to third-parties (think return
 values), then we'd have the read-only enforcement so many of us are crying

 for. That could easily become a major advantage for D over other

 In addition, the utility of a true storage-constant attribute (one that is

 supported via call-by-reference ~ inout obviously does not work) then that

 open up additional avenues for D.

Fundamentally connected with this is the problem of aliased function parameters. Get it wrong, as C and C++ do, and you cannot build an optimizer that is competitive with FORTRAN optimizers.

Also agreed, 100%. It's just that we want that 'right' functionality,and preferably sooner rather than later :~)
Mar 07 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Kris" <Kris_member pathlink.com> wrote in message
news:d0ir8c$nlr$1 digitaldaemon.com...
Fundamentally connected with this is the problem of aliased function
parameters. Get it wrong, as C and C++ do, and you cannot build an


that is competitive with FORTRAN optimizers.

Also agreed, 100%. It's just that we want that 'right' functionality,and preferably sooner rather than later :~)

Realistically, it's a 2.0 issue. I've promised Norbert I'd go through the array semantics with him for that.
Mar 07 2005
parent kris <fu bar.org> writes:
OK. Appreciate you being up-front and candid about it.


Walter wrote:
 "Kris" <Kris_member pathlink.com> wrote in message
 news:d0ir8c$nlr$1 digitaldaemon.com...
 
Fundamentally connected with this is the problem of aliased function
parameters. Get it wrong, as C and C++ do, and you cannot build an


optimizer
that is competitive with FORTRAN optimizers.

Also agreed, 100%. It's just that we want that 'right' functionality,and preferably sooner rather than later :~)

Realistically, it's a 2.0 issue. I've promised Norbert I'd go through the array semantics with him for that.

Mar 08 2005
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 7 Mar 2005 13:44:43 -0800, Walter wrote:

 "Matthew" <admin.hat stlsoft.dot.org> wrote in message
 news:d0idln$97o$1 digitaldaemon.com...
 simplified const handling (storage instead of type),



 so semantically weak it is fairly useless. (Many disagree.)


Right - many disagree - and I was thinking specifically of you!
 But then _you_ don't use const. Maybe they're related?

I used to use const as a type modifier. I gave it up after becoming disenchanted with it. I use const as a storage class all the time. (The two uses are very different, although they look the same in C++. I wish to emphasize the difference, as sometimes in these threads they incorrectly get referred to interchangeably.)
 That you don't recognise/acknowledge this shows that either you're trying

 well in hoodwinking yourself.

I understand that you made a convincing argument. I respectfully suggest, however, that doesn't necessarilly mean I was convinced and am therefore trying to argue things I secretly believe to be false. I know exactly how to implement const as a type modifier. If I believed it was the right thing to do, I'd do it. Microsoft and Sun both have inhouse C++ compilers under active development, and they know how to do it, too. They've both poured incredible resources in developing C# and Java. I have no idea exactly how the decision came about not to use const as a type modifier (as distinct from const as a storage class), but you can bet your last dollar that if they felt it had high value, it'd be implemented. This is one reason why I don't think I am way out of step in my opinion on const as a type modifier.
 I'd argue that C++ is less complete, since it relies so heavilly on STL


 do things that are built in to most languages. Doing a general purpose
 foreach with C++ is fiendishly difficult. It's for free in D.


 saying feature Y is great. This is just stupid.

The thread is about whether C++ and D are "complete" languages or not, and I wrote that comment should in that context.
 The absence of some/all of const in D is a flaw. Period! The only debate

 counter
 by saying that Java and .NET haven't followed C++ is (i) not true, and

 members, so one of the *fabulous powers of const in C++* has been aped.

 is a manifest flaw, and cannot be explained away by 'the complexity of

Java's 'final' is a storage class, not a type modifier. Its use on a field does not require the constructor to have an initializer for it. In fact, it is illegal to set 'final' fields inside a constructor. The initializer for the 'final' field must appear immediately after the declaration of the field, outside of any constructor. Therefore, constructor parameters cannot influence the setting of 'final' fields. Also, if one has multiple constructors in Java, and one 'forgets' to initialize one of the fields, no diagnostic is issued. The field gets default initialized. I'd argue it is a fairly different beast in Java than in C++, since it is not aping the C++ feature of getting diagnostics from the constructor about uninitialized const fields. What Java's 'final' does share with C++ const fields is that the compiler will diagnose attempts to modify the field after it is set. Java did it right, though, as Java doesn't allow casting away of constness, or non-const references to the same field modifying it out from under you. 'final' fields in Java are solid enough that the compiler can optimize based on it, and they have meaning in multithreaded apps, which is not the case in C++. I have no issue with const and final as a storage class, I believe they are valuable and useful, and const is implemented as a storage class in D (its use could probably be profitably extended to more contexts). I don't agree with its value as a type modifier, for oft stated reasons that I will summarize as being that in legal, standard conforming C++ code the value of the presumably 'const' data can change at any moment. Const things ought to be, dagnamit, constant.

I'm getting too confused with all this 'storage class' and 'type modifier' talk. Sorry but I'm not a C++ nor a Java coder, so these terms are a bit cloudy. This is what I can understand so far from these discussions ... const "storage class": The data is defined at compile time and RAM is reserved for the information. No part of the application is allowed to modify the data during run time. const "type modifer": The data is stored by one part of the application but is not allowed to be modified by another part of the application. I can see a really good use for what I've called 'type modifier'. Passing something by reference to a routine, but not allowing that routine to modify the data passed to it. Currently, the only obvious way to do that in D is to pass a copy of the data and throw it away once the routine has returned. void Bar(char[] x) { x[4] = 'b'; } void Foo(char[] X) { X[0] = 'a'; Bar(x); } . . . char[] Y = "derek"; Foo(Y.dup); // Ignore any changes that 'Foo' might make to Y. But a nicer, more obvious, more explicit in declaring coding intentions, would be do something like ... void Foo(PRESERVE char[] X) { X[0] = 'a'; // Compiler would flag this as an error. Bar(x); // Compiler might have to pass a copy of x. } . . . char[] Y = "derek"; Foo(Y); I don't know how to implement this efficiently, but that is not the issue. The issue is that as a coder/designer, I must have the data in the passed argument to by unchanged after calling the routine. -- Derek Melbourne, Australia 8/03/2005 9:59:25 AM
Mar 07 2005
parent brad domain.invalid writes:
 const "storage class":
  The data is defined at compile time and RAM is reserved for the
 information. No part of the application is allowed to modify the data
 during run time.
 

From an embedded systems point of view, const data can also live in ROM (well, it should be able to) - many small systems do use this trick to save RAM usage. ROM also physically prevents you from modifying the variable, as such you shouldn't try to do dirty tricks to modify a const variable. I bring this up because I do embedded stuff for a living, and I don't see anything in D which precludes it from being used in small systems. Brad
Mar 07 2005
prev sibling parent reply Kris <Kris_member pathlink.com> writes:
Amen. 

It's exactly this kind of thing that has so often worn me down to the bone [and
why my sometimes inappropriate commentary joins the party; for which I do
apologize] 

I believe we should understand that D belongs to all of us. Everyone who has
contributed in one form or another (through adopted ideas, through NG posts,
through being a D evangelist, through writing supporting libraries, through
examples, tutorials, and wiki's, through providing supporting web-services such
as dsource.org and this NG, etc. etc.) *own* a piece of D. I don't think Walter
could, or would, claim that D is his own thing at this time (in fact, our
combined little bits of ownership probably amount to something rather
significant). 

As such, we kinda' owe it to ourselves to ensure the development of "our"
language is 'managed' more effectively. After all, D requires a grass-roots
approach to language adoption (in contrast to the marketing and financial clout
of a .NET approach); it's people like us who will ultimately push for adoption
of D within our own spheres of influence.


I'm noting this for three reasons: 

1) you should realize that D is /your/ language ~ not someone else's. It will
become mainstream not when D matures per se, but when each and all of us urge
our development groups to consider adopting it. Walter has never spelt this out,
but he's fully dependent upon each of us for the success of D (unless it's
perhaps just a jolly wheeze instead). 

When I see people talking about "Walter's language" it suggests either "Walter
is a shallow and hollow individual" or "I can't personally accept the
responsibility for making this better". There's probably plenty of room between,
but you get the drift? We, each of us, is expected to do the hard work of local
adoption. So we should get used to the ownership idea.

2) we deserve, and should expect more in terms of a transparent development
process. Right now, it's almost completely opaque (save for the rare and
occasional glimmer of a proactive request, such as the recent "$ or length?"
topic initiated by Walter himself). I mean, at this point, a rational and
constructive discourse over how to improve D in specific areas is the exception,
rather than the norm. Instead, what's attached below typifies the reaction. This
is surely a bad sign, and it is something that (IMO) Walter should reflect
heavily upon. 

3) Historically, there's been a lot of talk with very little action. For
example, people have often lamented over the weaknesses of the D libraries.
However, how many of you are willing to do something about changing that? We've
got to take some responsibility ourselves to change things; be a bit more
constructive and a lot more cooperative. Talk is cheap. There are perhaps one or
two dozen people who are /really/ trying to contribute to D in this particular
manner ... they can always use a bit of help! If you want good libraries for D,
write them yourselves, or better, get some momentum going with others via the
Ares project (over at dsource).

Something to think about.

- Kris


(p.s. please forgive me for hijacking your post, Matthew; but for a moment there
you sounded just like me)



In article <d0idln$97o$1 digitaldaemon.com>, Matthew says...
 simplified const handling (storage instead of type),

As has been debated here many times <g>, const as a type modifier in C++ is so semantically weak it is fairly useless. (Many disagree.)

This is hugely disingenuous. _You_ don't think const has any use. But then _you_ don't use const. Maybe they're related? I find const *enormously* useful, both for its intended uses and for the unforeseen tricks one can put it to. The absence of such is the largest common failing in other languages that I use, including C, Java, .NET *and* D, and a significant part of the reason why I don't tend to use those languages for serious development.
C and C++ are
 the only languages I've ever heard of that use const as a type modifier.
 Java and C# show no signs of adopting it. The C++ community has not
 convinced the larger programmer community that const as a type modifier has
 a place.

How can you conclude that? One might just as well surmise that the implementation complexity is what deters these other 'communities'. After all, these other languages - Java, .NET, D - are all far more allied to specific vendors, and are therefore far more likely to be swayed by what's good for the vendor rather than what's good for the programmer. That you don't recognise/acknowledge this shows that either you're trying to hoodwink us, or that you've succeeded too well in hoodwinking yourself.
 I'd argue that C++ is less complete, since it relies so heavilly on STL to
 do things that are built in to most languages. Doing a general purpose
 foreach with C++ is fiendishly difficult. It's for free in D.

As a general point, I must observe that you are far too prone these days to counter criticisms of D's feature X by saying feature Y is great. This is just stupid. Yes, D has many marvellous features. This is a big part of why I am excited about D, and why I've stuck with it these last 2.5 years. But D also has some serious flaws, omissions, and howling stinkers. The absence of some/all of const in D is a flaw. Period! The only debate is where the some/all point is drawn. To counter by saying that Java and .NET haven't followed C++ is (i) not true, and (ii) disingenuous. IIRC, Java does use final on members, so one of the *fabulous powers of const in C++* has been aped. That D has not followed this particular facet is a manifest flaw, and cannot be explained away by 'the complexity of using/implementing const'. It's nothing more than an extension of your personal uninformed (since you don't use const) prejudices. So, Walter, I say stop telling us about the great things in D. We all know and love them. No other language I know of can do slices, and the combination of slices, GC and auto is unparalleled. (FGI: Walter and I are doing an article on this "Not Your Father's Resource Management" for DDJ just as soon as I get my fingers out of all the other pies and do my half of it. The article shows how D is an optimal mix of C++'s and Java/.NET's resource management paradigms, and is superior to them all.) What's going to stop D prospering is not failure-to-recognise-its-many-significant-virtues, but all-too-ready-recognition-of-its-many-significant-flaws. Sheesh! If I went to a psychologist to get help in sorting out my many personality flaws, I wouldn't waste her time and my money in long and fatuous discussions about my many admirable traits!!!

Mar 07 2005
parent John Reimer <brk_6502 yahoo.com> writes:
Agreed, Kris.

A good, thought-provoking post.  Everybody should be considering these 
things.

Thanks,

- JJR

Kris wrote:
 Amen. 
 
 It's exactly this kind of thing that has so often worn me down to the bone [and
 why my sometimes inappropriate commentary joins the party; for which I do
 apologize] 
 
 I believe we should understand that D belongs to all of us. Everyone who has
 contributed in one form or another (through adopted ideas, through NG posts,
 through being a D evangelist, through writing supporting libraries, through
 examples, tutorials, and wiki's, through providing supporting web-services such
 as dsource.org and this NG, etc. etc.) *own* a piece of D. I don't think Walter
 could, or would, claim that D is his own thing at this time (in fact, our
 combined little bits of ownership probably amount to something rather
 significant). 
 
 As such, we kinda' owe it to ourselves to ensure the development of "our"
 language is 'managed' more effectively. After all, D requires a grass-roots
 approach to language adoption (in contrast to the marketing and financial clout
 of a .NET approach); it's people like us who will ultimately push for adoption
 of D within our own spheres of influence.
 
 
 I'm noting this for three reasons: 
 
 1) you should realize that D is /your/ language ~ not someone else's. It will
 become mainstream not when D matures per se, but when each and all of us urge
 our development groups to consider adopting it. Walter has never spelt this
out,
 but he's fully dependent upon each of us for the success of D (unless it's
 perhaps just a jolly wheeze instead). 
 
 When I see people talking about "Walter's language" it suggests either "Walter
 is a shallow and hollow individual" or "I can't personally accept the
 responsibility for making this better". There's probably plenty of room
between,
 but you get the drift? We, each of us, is expected to do the hard work of local
 adoption. So we should get used to the ownership idea.
 
 2) we deserve, and should expect more in terms of a transparent development
 process. Right now, it's almost completely opaque (save for the rare and
 occasional glimmer of a proactive request, such as the recent "$ or length?"
 topic initiated by Walter himself). I mean, at this point, a rational and
 constructive discourse over how to improve D in specific areas is the
exception,
 rather than the norm. Instead, what's attached below typifies the reaction.
This
 is surely a bad sign, and it is something that (IMO) Walter should reflect
 heavily upon. 
 
 3) Historically, there's been a lot of talk with very little action. For
 example, people have often lamented over the weaknesses of the D libraries.
 However, how many of you are willing to do something about changing that? We've
 got to take some responsibility ourselves to change things; be a bit more
 constructive and a lot more cooperative. Talk is cheap. There are perhaps one
or
 two dozen people who are /really/ trying to contribute to D in this particular
 manner ... they can always use a bit of help! If you want good libraries for D,
 write them yourselves, or better, get some momentum going with others via the
 Ares project (over at dsource).
 
 Something to think about.
 
 - Kris
 
 
 (p.s. please forgive me for hijacking your post, Matthew; but for a moment
there
 you sounded just like me)
 

Mar 08 2005
prev sibling next sibling parent reply "Rob Grainger" <nospam nospam.com> writes:
Walter,

Actually, I think you'll find that DCE invented IDL, and Microsoft just 
ported it. Actually IDL originally targetted C, so I guess
the reference issue had no impact on its design. If you look at earliest 
implementations of IUnknown, you'll notice that QueryInterface
(along with a lot of similar interfaces) uses a REFIID, which in C++ is 
defined as an IID&, in C and IID*, so the issues really predate
COM even - blame DCE RPC for these ones.

Furthermore, IDL as originally conceived was designed to allow writing 
proxy/stub implementations for Remote Procedure Calls, and
allows much more flexibility that are glossed over there - such as 
implementing custom-marshalled types, etc.

Just to clear things up.

Again, with const I absolutely disagree - placing a const on a parameter 
tells the compiler that the function called cannot modify the parameter, so 
its free to make all sort of optimisations not otherwise possible 
(especially with pointer parameters). Also, it can catch
many programmer errors at compile times (saving much more tedious runtime 
error-hunting later). Finally, I believe it makes the contract
that much more explicit. In C++, the main undermining factor comes from 
compatibility with pre-existing code (the desire for most correct C code to 
be correct C++ code) - often a severe problem in C++. In particular, many 
libraries/API's do not declare there parameters correctly, hence the need 
for const_cast, these issues shouldn't really apply to D, where they can be 
encapsulated at the interface, so I cannot see a good reason not to include 
it.

As for the for_each problem, <algorithm> provides a nice solution called, 
wait for it, for_each. Given a container..

    vector<int> v;

    // ...

    for_each(v.begin(); v.end(), functor);

Doesn't look all that complex to me...

Rob 
Mar 08 2005
parent reply "Walter" <newshound digitalmars.com> writes:
Note: in the following, I am referring to const as a type modifier, as
distinct from const as a storage class. I find const as a storage class to
be useful and desirable.


"Rob Grainger" <nospam nospam.com> wrote in message
news:d0le44$m64$1 digitaldaemon.com...
 Actually, I think you'll find that DCE invented IDL, and Microsoft just
 ported it. Actually IDL originally targetted C, so I guess
 the reference issue had no impact on its design.

But the issue of what's in, out, and inout did impact, and it's still why people need to use it.
 If you look at earliest
 implementations of IUnknown, you'll notice that QueryInterface
 (along with a lot of similar interfaces) uses a REFIID, which in C++ is
 defined as an IID&, in C and IID*, so the issues really predate
 COM even - blame DCE RPC for these ones.

 Furthermore, IDL as originally conceived was designed to allow writing
 proxy/stub implementations for Remote Procedure Calls, and
 allows much more flexibility that are glossed over there - such as
 implementing custom-marshalled types, etc.

 Just to clear things up.

Thanks.
 Again, with const I absolutely disagree - placing a const on a parameter
 tells the compiler that the function called cannot modify the parameter,

 its free to make all sort of optimisations not otherwise possible
 (especially with pointer parameters).

No, it can't. The optimizer can't make any use of const, because legal, standard conforming C++ code can modify const values. Similarly, multithreaded code cannot assume that const references remain constant. Does this happen in practice? It sure does, as I found out when adjusting the optimizer to take advantage of const. Lots of code breaks.
 Also, it can catch
 many programmer errors at compile times (saving much more tedious runtime
 error-hunting later).

That's the idea, but do such errors happen very often? Not in my experience, using it for years never found an actual bug (though it found a lot of const-correctness issues, none of them were actual bugs). The additional failure of const to provide any useful optimization opportunities kinda sealed its fate. Note that Matthew strongly disagrees with me on these points.
 Finally, I believe it makes the contract
 that much more explicit. In C++, the main undermining factor comes from
 compatibility with pre-existing code (the desire for most correct C code

 be correct C++ code) - often a severe problem in C++. In particular, many
 libraries/API's do not declare there parameters correctly, hence the need
 for const_cast, these issues shouldn't really apply to D, where they can

 encapsulated at the interface, so I cannot see a good reason not to

 it.

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.
 As for the for_each problem, <algorithm> provides a nice solution called,
 wait for it, for_each. Given a container..

     vector<int> v;

     // ...

     for_each(v.begin(); v.end(), functor);

 Doesn't look all that complex to me...

Try the following D code with C++'s std::for_each: foreach (int value; collection) { if (value == 6) return 3; } Eric Niebler has gotten much further with for_each in C++ using complex macros, but I haven't studied his work.
Mar 08 2005
parent reply "Martin M. Pedersen" <martin moeller-pedersen.dk> writes:
"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." '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. Regards, Martin
 As for the for_each problem, <algorithm> provides a nice solution called,
 wait for it, for_each. Given a container..

     vector<int> v;

     // ...

     for_each(v.begin(); v.end(), functor);

 Doesn't look all that complex to me...

Try the following D code with C++'s std::for_each: foreach (int value; collection) { if (value == 6) return 3; } Eric Niebler has gotten much further with for_each in C++ using complex macros, but I haven't studied his work.

Mar 08 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"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


 to make it const-correct, it's pretty loaded up with const keywords. I
 believe it adds a lot of visual complexity, without commensurate


 If const came with guarantees that the data would not be modified


 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

 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.)
Mar 09 2005
parent reply "Martin M. Pedersen" <martin moeller-pedersen.dk> writes:
"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
Mar 09 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"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

 and are not very conscious about it anymore. I simply do not write code

 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

 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

 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.)
Mar 09 2005
next sibling parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter wrote:

 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.

And that shows in D, too : http://www.digitalmars.com/d/interface.html
 There are no const or volatile type modifiers in D.
 To declare a C function that uses those type modifiers,
 just drop those keywords from the declaration.

Copy-on-Write also implies that the arguments are readonly by default ? But I can't think of any uses of "readonly" KW except for with char[], so maybe it can be turned into some kind of array property instead ? The last thing we want is an extra keyword to all regular parameters... So maybe it would be better to have it in the array/slice information: { size_t length; void* data; byte flags; } // or something, pseudo With one flag for "readonly", and one flag for "zero terminated" ? (for optimizing toStringz, and similar functions that need to know) Or something similarly different ? --anders
Mar 09 2005
prev sibling parent Ben Hinkle <Ben_member pathlink.com> writes:
In article <d0o2qq$iif$1 digitaldaemon.com>, Walter says...
"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

 and are not very conscious about it anymore. I simply do not write code

 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

 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.

Interesting. That's basically the Fortran approach. In Fortran, for those who don't know, things are passed by reference and it is implicit you don't mess with the inputs. When I code C++ I use const every now and just to get that little satisfaction of actually using it :-) But I don't do enough C++ to really depend on const or have it catch anything for me.
Mar 09 2005
prev sibling parent reply Matthias Becker <Matthias_member pathlink.com> writes:
 simplified const handling (storage instead of type),

As has been debated here many times <g>, const as a type modifier in C++ is so semantically weak it is fairly useless. (Many disagree.) C and C++ are the only languages I've ever heard of that use const as a type modifier. Java and C# show no signs of adopting it. The C++ community has not convinced the larger programmer community that const as a type modifier has a place.

Most languages don't have destructors. So the C++ community has not convinced the larger programmer community that destructores have a place. But are destructors bad just because of that? I know you don't think so, otherwise D wouldn't have auto classes.
 etc, and I guess I'd have more examples if I had been using C++ more...
 And this makes C++ more "complete" in that you can do more things,
 but is also makes a lot harder and complex - at least at the start ?

I'd argue that C++ is less complete, since it relies so heavilly on STL to do things that are built in to most languages.

I know a lot of languages that have built in linked lists (Lisp, SML, O'Caml, Haskell, Clean, ... to name just a few popular languages). D does not. Why?
Doing a general purpose
foreach with C++ is fiendishly difficult. It's for free in D.

OK, C++ is still not perfect. But imagine C++ with Lisp-like macros. You could do a foreach easily, without having it built in. Or imagine C++ with a Sather-like iteration model. You wouldn't need a foreach loop any more. A foreach loop isn't realy a killer-feature that no other language knows about.
Mar 10 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Matthias Becker" <Matthias_member pathlink.com> wrote in message
news:d0psuo$2gc6$1 digitaldaemon.com...
 simplified const handling (storage instead of type),

As has been debated here many times <g>, const as a type modifier in C++


so semantically weak it is fairly useless. (Many disagree.) C and C++ are
the only languages I've ever heard of that use const as a type modifier.
Java and C# show no signs of adopting it. The C++ community has not
convinced the larger programmer community that const as a type modifier


a place.

Most languages don't have destructors. So the C++ community has not

 the larger programmer community that destructores have a place. But are
 destructors bad just because of that?
 I know you don't think so, otherwise D wouldn't have auto classes.

Of course. It should be of strong interest to any language designer what other language designers do. Both Java and C# came from C++. What C++ features did they pick, what did they leave out, and most importantly, why? I believe many of the choices they made are excellent, and many are mistakes. It's important that I be able to justify the decisions for D, and if it diverges from what other C++ based language designers chose, I think the bar is at least a little higher for justifying it.
 etc, and I guess I'd have more examples if I had been using C++ more...
 And this makes C++ more "complete" in that you can do more things,
 but is also makes a lot harder and complex - at least at the start ?

I'd argue that C++ is less complete, since it relies so heavilly on STL


do things that are built in to most languages.

I know a lot of languages that have built in linked lists (Lisp, SML,

 Haskell, Clean, ... to name just a few popular languages). D does not.

Because the UDT facilities in D are good enough that it's trivial to do a linked list.
Doing a general purpose
foreach with C++ is fiendishly difficult. It's for free in D.


 do a foreach easily, without having it built in. Or imagine C++ with a
 Sather-like iteration model. You wouldn't need a foreach loop any more.
 A foreach loop isn't realy a killer-feature that no other language knows

I agree that foreach is hardly unique to D. It's not a killer feature, either. It's not, by itself, a reason for people to switch from C++ to D.
Mar 10 2005
parent Matthias Becker <Matthias_member pathlink.com> writes:
 simplified const handling (storage instead of type),

As has been debated here many times <g>, const as a type modifier in C++


so semantically weak it is fairly useless. (Many disagree.) C and C++ are
the only languages I've ever heard of that use const as a type modifier.
Java and C# show no signs of adopting it. The C++ community has not
convinced the larger programmer community that const as a type modifier


a place.

Most languages don't have destructors. So the C++ community has not

 the larger programmer community that destructores have a place. But are
 destructors bad just because of that?
 I know you don't think so, otherwise D wouldn't have auto classes.

Of course. It should be of strong interest to any language designer what other language designers do. Both Java and C# came from C++. What C++ features did they pick, what did they leave out, and most importantly, why? I believe many of the choices they made are excellent, and many are mistakes. It's important that I be able to justify the decisions for D, and if it diverges from what other C++ based language designers chose, I think the bar is at least a little higher for justifying it.

I see.
 etc, and I guess I'd have more examples if I had been using C++ more...
 And this makes C++ more "complete" in that you can do more things,
 but is also makes a lot harder and complex - at least at the start ?

I'd argue that C++ is less complete, since it relies so heavilly on STL


do things that are built in to most languages.

I know a lot of languages that have built in linked lists (Lisp, SML,

 Haskell, Clean, ... to name just a few popular languages). D does not.

Because the UDT facilities in D are good enough that it's trivial to do a linked list.

In SML a user defined type that represents a linkd list would look like this: # datatype 't MyList = EmptyList | ListNode of 't * 't MyList The type MyList parameterised with 't is eigther an EmptyList or a ListNode, which consists of an object of type 't and another list of type MyList parameterisd with 't. I think you can't beat this shortness and expressiveness in D, but SML still has a built in list type. But you are right. D isn't 'functional' enough for a built in list-type. Anyway, C++ dosn't have built-in quques, stacks, 'dictoranrys', ... but using them is almost as simple as the built-in counter-parts of other languages that have such structures built in. # stack<int> foo; # # foo.push(42); # int value = foo.top(); # foo.pop(); Could it be easier?
Mar 11 2005
prev sibling parent reply Georg Wrede <georg.wrede nospam.org> writes:
Anders F Björklund wrote:
 One aspect of D that is nice (or at least flexible ?)
 is that you can write programs in ancient C style...
 
 Without using objects, and without using exceptions,
 garbage collection and other such modern facilities :-)
 
 
 All you need to do is provide hooks for a few required
 aspects of Phobos, such as GC and assert / OutOfMemory.

I think it is absolutely necessary to have this feature as standard issue! We don't certainly _want_ folks to en masse start doing non-gc programming or ancient C style. But there are some things even I (as an example of a long time D guy) would feel uncomfortable doing with gc and stuff. (May the fears be warranted or not.) And, to the one guy at the office who fervently opposes D, one could always say you don't _have_ to use GC. This sould be documented, too. (Heh, _after_ the hairy sections in the paper manual, so women and children do not find it.)
Mar 05 2005
parent "Walter" <newshound digitalmars.com> writes:
"Georg Wrede" <georg.wrede nospam.org> wrote in message
news:4229ED47.1050405 nospam.org...
 And, to the one guy at the office who fervently opposes
 D, one could always say you don't _have_ to use GC.

That's right. You can do all the allocation with C's malloc/free. In fact, the D version of Empire is pretty much a line by line transliteration from C. The two are nearly identical.
Mar 06 2005