www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Do we really need const?

reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Bruce Adams wrote:
 charles Wrote:

 Const is a god awful abomination that no language has gotten right, 
 the sooner its gotten rid of the better.  No one I work with has 




 As a seasoned C++ programmer I and my colleagues regularly use the
 c++ flavour of const with no problems. It may not be the best 
 solution in the world but it works. I always found it a reasonably
 intuitive bit of syntactic sugar. That's not to say that we can't do
 better in D. I'd recommend reading Scott Meyers effective C++ books
 for a start. And perhaps we should review the deliberations that went
 into developing the C++ const system. 

 By the way, what languages other than C++ have some kind of const
 mechanism? They've got to be worth a review too.

That's a very good point. *Are* there any others? Pascal seems to have some form of it (http://www.gnu-pascal.de/gpc/const.html). Any Pascal devotees out there care to comment? I managed to avoid ever learning Pascal. Anyway, if one asserts that const is a critical feature for "enterprise code", yet there exist a large body of "enterprise code" written in languages that don't have const, then we have a contradiction. It can't be all that critical if lots of successful software projects get written without it. There's of course Java. Lots of enterprise software is written in Java, and yet Java does not have const. There is without a doubt some diagnostic benefit to const, but if it were such a great win overall wouldn't everybody be doing it? Is it really worth the pain of having to create two versions of every function, and two flavors of every iterator, etc.? I guess I've gotten used to it in C++ and certainly bought into the const-correctness mantra. When I see C++ code that doesn't use const correctly my kneejerk reaction is always "sheesh -- amateur". But I've never really taken a step back to try to seriously evaluate the cost-benefit tradeoff. It seems from the discussion here the past week, there is no real multithreading benefit to be had from const/invariant. 'Pure' is where it's at for that. So maybe we're just better off without the complexities of const. I've certainly gotten used to the lack of const in Python, so why not in a C++-ish language? --bb
Sep 16 2007
next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Bill Baxter wrote:
 It seems from the discussion here the past week, there is no real 
 multithreading benefit to be had from const/invariant.  'Pure' is where 
 it's at for that.  So maybe we're just better off without the 
 complexities of const.

I'm thinking the same way. There are clear benefits to 'pure', with both multi-threading and optimisation, and it's conceptually simple and easy to explain to a newbie. But 'const' seems to be a horrible morass, complicated to explain, complicated to code, and with very little benefit. At the very least, it's clear that 'const' has cost the D community a huge amount of discussion bandwidth and mental space, with very little of use to show for it. We may be caught in a productivity trap.
Sep 17 2007
parent Bruce Adams <tortoise_74 yeah.who.co.uk> writes:
Don Clugston Wrote:

 Bill Baxter wrote:
 It seems from the discussion here the past week, there is no real 
 multithreading benefit to be had from const/invariant.  'Pure' is where 
 it's at for that.  So maybe we're just better off without the 
 complexities of const.

I'm thinking the same way. There are clear benefits to 'pure', with both multi-threading and optimisation, and it's conceptually simple and easy to explain to a newbie. But 'const' seems to be a horrible morass, complicated to explain, complicated to code, and with very little benefit. At the very least, it's clear that 'const' has cost the D community a huge amount of discussion bandwidth and mental space, with very little of use to show for it. We may be caught in a productivity trap.

From what I've seen here. Talking in this group all day long doesn't seem to affect productivity that badly. ;)
Sep 17 2007
prev sibling next sibling parent Bruce Adams <tortoise_74 yeah.who.co.uk> writes:
Bill Baxter Wrote:

 Bruce Adams wrote:
  > charles Wrote:
  >
  >> Const is a god awful abomination that no language has gotten right, 
  >> the sooner its gotten rid of the better.  No one I work with has 
 ever >> had a situation where const actually paid off.
  >>
 
 As a seasoned C++ programmer I and my colleagues regularly use the
 c++ flavour of const with no problems. It may not be the best 
 solution in the world but it works. I always found it a reasonably
 intuitive bit of syntactic sugar. That's not to say that we can't do
 better in D. I'd recommend reading Scott Meyers effective C++ books
 for a start. And perhaps we should review the deliberations that went
 into developing the C++ const system. 

 By the way, what languages other than C++ have some kind of const

That's a very good point. *Are* there any others? Pascal seems to have some form of it (http://www.gnu-pascal.de/gpc/const.html). Any Pascal devotees out there care to comment? I managed to avoid ever learning Pascal. Anyway, if one asserts that const is a critical feature for "enterprise code", yet there exist a large body of "enterprise code" written in languages that don't have const, then we have a contradiction. It can't be all that critical if lots of successful software projects get written without it. There's of course Java. Lots of enterprise software is written in Java, and yet Java does not have const. There is without a doubt some diagnostic benefit to const, but if it were such a great win overall wouldn't everybody be doing it? Is it really worth the pain of having to create two versions of every function, and two flavors of every iterator, etc.? I guess I've gotten used to it in C++ and certainly bought into the const-correctness mantra. When I see C++ code that doesn't use const correctly my kneejerk reaction is always "sheesh -- amateur". But I've never really taken a step back to try to seriously evaluate the cost-benefit tradeoff. It seems from the discussion here the past week, there is no real multithreading benefit to be had from const/invariant. 'Pure' is where it's at for that. So maybe we're just better off without the complexities of const. I've certainly gotten used to the lack of const in Python, so why not in a C++-ish language? --bb

Arguing that something isn't useful because you can live without it is not sound. I can live without a dish-washer but I'd rather not have to do the washing up myself. Similarly the GIT people seem perfectly happy to write all their code in C, and from my brief glance at their code base its quite neat. Its a case of working smarter versus working harder. That said, its better to wait and deliberate and get a good const system rather than live with something that's not up to par. I can't really comment on pascal myself. I did do some modula-2 many years ago, which I consider to be 2 steps on from pascal in Wirths evolution (pascal, modula 1,2,3 then oberon). I think const is just used for variables assigned once and ideally at compile time when the expression permits it. Regards, Bruce.
Sep 17 2007
prev sibling next sibling parent reply Matti Niemenmaa <see_signature for.real.address> writes:
Bill Baxter wrote:
 There's of course Java.  Lots of enterprise software is written in Java,
 and yet Java does not have const.

Java has a limited form of const in final, which allows for both compile-time constants and variables which can only be assigned to once. See the "variables" and "fields" sections here: http://renaud.waldura.com/doc/java/final-keyword.shtml -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
Sep 17 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Matti Niemenmaa wrote:
 Bill Baxter wrote:
 There's of course Java.  Lots of enterprise software is written in Java,
 and yet Java does not have const.

Java has a limited form of const in final, which allows for both compile-time constants and variables which can only be assigned to once. See the "variables" and "fields" sections here: http://renaud.waldura.com/doc/java/final-keyword.shtml

Yes, a lot of languages seem to have that form of const, which is more or less like const is in D1.x. That doesn't seem to be the problematic kind. --bb
Sep 17 2007
next sibling parent reply Regan Heath <regan netmail.co.nz> writes:
Bill Baxter wrote:
 Matti Niemenmaa wrote:
 Bill Baxter wrote:
 There's of course Java.  Lots of enterprise software is written in Java,
 and yet Java does not have const.

Java has a limited form of const in final, which allows for both compile-time constants and variables which can only be assigned to once. See the "variables" and "fields" sections here: http://renaud.waldura.com/doc/java/final-keyword.shtml

Yes, a lot of languages seem to have that form of const, which is more or less like const is in D1.x. That doesn't seem to be the problematic kind.

Java also has invariant strings which is another form of const, one that makes multithreading easier. It seems that there are at least 4 forms of const: 1. invariant data 2. invariant variables 3. logical const 4. transitive const Forms #1 and #2 should combine well with 'pure' I imagine. Regan
Sep 17 2007
parent Regan Heath <regan netmail.co.nz> writes:
Regan Heath wrote:
 2. invariant variables

This was badly named, I really mean "invariant references/pointers". Some might call this an extension of #1 (invariant data) Regan
Sep 17 2007
prev sibling parent reply Matti Niemenmaa <see_signature for.real.address> writes:
Bill Baxter wrote:
 Matti Niemenmaa wrote:
 Java has a limited form of const in final, which allows for both 
 compile-time constants and variables which can only be assigned to once.
 
 See the "variables" and "fields" sections here: 
 http://renaud.waldura.com/doc/java/final-keyword.shtml

Yes, a lot of languages seem to have that form of const, which is more or less like const is in D1.x. That doesn't seem to be the problematic kind.

No. But it's more than D1.x's const, in that it can be used other than just for compile time constants. -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
Sep 17 2007
parent reply Regan Heath <regan netmail.co.nz> writes:
Matti Niemenmaa wrote:
 Bill Baxter wrote:
 Matti Niemenmaa wrote:
 Java has a limited form of const in final, which allows for both 
 compile-time constants and variables which can only be assigned to once.

 See the "variables" and "fields" sections here: 
 http://renaud.waldura.com/doc/java/final-keyword.shtml

less like const is in D1.x. That doesn't seem to be the problematic kind.

No. But it's more than D1.x's const, in that it can be used other than just for compile time constants.

It's like D2.0's 'final' then. Regan
Sep 17 2007
parent Matti Niemenmaa <see_signature for.real.address> writes:
Regan Heath wrote:
 Matti Niemenmaa wrote:
 Bill Baxter wrote:
 Matti Niemenmaa wrote:
 Java has a limited form of const in final, which allows for both 
 compile-time constants and variables which can only be assigned to 
 once.
 
 See the "variables" and "fields" sections here: 
 http://renaud.waldura.com/doc/java/final-keyword.shtml

less like const is in D1.x. That doesn't seem to be the problematic kind.

No. But it's more than D1.x's const, in that it can be used other than just for compile time constants.

It's like D2.0's 'final' then.

Yep. -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
Sep 17 2007
prev sibling next sibling parent Lionello Lunesu <lio lunesu.remove.com> writes:
Just a quick note to say that I also have never missed "const" in D and 
am reluctant to start with D 2.0 because of the added complexity. Walter 
has said himself that while porting Phobos to 2.0, he has not 
encountered, let alone fixed, a single bug. For me, 
const/final/invariant is just not worth it.

I like const conceptually, but then there are many similar concepts that 
are nice and const is just one of them.

D should opt for a more general red code / green code mechanism, as 
explained by Scott Meyers in the next video:

http://video.google.com/videoplay?docid=-4728145737208991310

Pure/not-pure, throw/no-throw, const/not-const, 
threadsafe/not-threadsafe etc. are all similar and I would love to see 
one solution for all these red/green restrictions.

L.

PS. I'm playing around with the idea to add keywords after a function 
declaration to add labels to the function. The compiler should then only 
accept calls to functions with at least the labels of the caller:

void bar() throw;
void foo() { bar(); }//ERROR, bar can throw
void foo2() throw { bar(); } //OK
void foo3() throw { bar() throw; } //OK ("cast")

Or something to that effect. Possible using "!" to negate (!throw). I 
have not thought this through more than what's written here and have no 
idea what it would imply for the grammar.
Sep 17 2007
prev sibling next sibling parent reply Jan Claeys <usenet janc.be> writes:
Op Mon, 17 Sep 2007 15:36:35 +0900
schreef Bill Baxter <dnewsgroup billbaxter.com>:

 I've certainly gotten used to the lack of const in Python

Python has immutable objects (e.g. strings & tuples). :) -- JanC
Sep 17 2007
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Jan Claeys wrote:
 Op Mon, 17 Sep 2007 15:36:35 +0900
 schreef Bill Baxter <dnewsgroup billbaxter.com>:
 
 I've certainly gotten used to the lack of const in Python

Python has immutable objects (e.g. strings & tuples). :)

Yeh I'm really thinking more about the type of const that appears in front of parameters to functions, and forces you to write all your member functions twice in C++. Whatever you call that form. #3 & #4 from Regan's list. :-) --bb
Sep 17 2007
prev sibling next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Jan Claeys wrote:
 Op Mon, 17 Sep 2007 15:36:35 +0900
 schreef Bill Baxter <dnewsgroup billbaxter.com>:
 
 I've certainly gotten used to the lack of const in Python

Python has immutable objects (e.g. strings & tuples). :)

A lot of Python users also seem to be quite unhappy about the gil. Python in its current form appears to be unsuitable for writing parallel code.
Sep 17 2007
parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Jan Claeys wrote:
 Op Mon, 17 Sep 2007 23:00:33 -0700
 schreef Walter Bright <newshound1 digitalmars.com>:
 Python in its current form appears to be unsuitable for writing
 parallel code.

There are lots of (sometimes massively) parallel python applications around; some of them were named in the recent discussions. As an example, the EVE Online servers & clients work as one large distributed parallel application (there is one shared "state").

To be fair, that's parallelism via stackless which is just cooperative multithreading. As far as I understand it, if you ignore the overhead of context switching and locks, code written against stackless and using Python threads will run at the same speed irrespective of how many hardware threads you have. Neither one, AFAIK, can actually execute multiple threads of Python code simultaneously. That said, stackless is still the bee's knees if you're on a uniprocessor machine. The ability to have hundreds of thousands of super lightweight threads with almost no overhead, *and* the ability to just pickle a thread and re-start it on another machine? And people wonder why the EVE guys get so excited by it :P -- Daniel
Sep 22 2007
prev sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Jan Claeys wrote:
 Op Mon, 17 Sep 2007 15:36:35 +0900
 schreef Bill Baxter <dnewsgroup billbaxter.com>:
 
 I've certainly gotten used to the lack of const in Python

Python has immutable objects (e.g. strings & tuples). :)

Actually I remembered one time when lack of const did bite me in Python. I was translating some Matlab code I wrote to Python/NumPy (http://www.scipy.org/). In Matlab all calls are call-by-value, and all assignments are assign-by-value (both use COW under the covers to make performance reasonable). In Python they're call-by-reference and assign-by-reference for most anything more complicated than an 'int'. The matrix class I was using in the Python code definitely fell into the by-reference category. After I got the port basically working there were quite a few bugs that turned out to be a result of functions I translated from Matlab modifying their arguments. If Python had const, I don't think I would have had those problems. On the other hand, the NumPy matrix class itself has a read-only flag. If I were porting to Python again I'd probably try to write a decorator to use during debugging that sets that readonly flag before entering the function and unsets it on return. --bb
Sep 22 2007
prev sibling next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message 
news:fcl79k$18vu$1 digitalmars.com...

 It seems from the discussion here the past week, there is no real 
 multithreading benefit to be had from const/invariant.  'Pure' is where 
 it's at for that.  So maybe we're just better off without the complexities 
 of const.  I've certainly gotten used to the lack of const in Python, so 
 why not in a C++-ish language?

I start to wonder how much of the "of COURSE we need const!" thinking comes from "if all you have is a hammer, everything starts looking like a nail." That is, I wonder how many people think we absolutely need const because they're so used to using it in C and C++. Never having learned a const-correct language (started with various BASICs, then on to very rudimentary C++, then D, and also a bit of Java and C#), I simply don't see the overwhelming need. Sure, there are a very few cases where const could be useful in my code for efficiency's sake, but I've never felt like I was missing any expressive power. Furthermore, I have been bitten exactly once by something that theoretically could have been prevented by const. It took me two minutes in the debugger to track down the problem. I'd say that those two minutes were a much better tradeoff than the god-knows-how-long it'd take to write const and non-const overloads of who-knows-how-many functions.
Sep 17 2007
next sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
Jarrett Billingsley wrote:
 "Bill Baxter" <dnewsgroup billbaxter.com> wrote in message 
 news:fcl79k$18vu$1 digitalmars.com...
 
 It seems from the discussion here the past week, there is no real 
 multithreading benefit to be had from const/invariant.  'Pure' is where 
 it's at for that.  So maybe we're just better off without the complexities 
 of const.  I've certainly gotten used to the lack of const in Python, so 
 why not in a C++-ish language?

I start to wonder how much of the "of COURSE we need const!" thinking comes from "if all you have is a hammer, everything starts looking like a nail." That is, I wonder how many people think we absolutely need const because they're so used to using it in C and C++.

I think it would be a comfort to have it for function signatures, but I've only been affected by it once -- with getopt on C. (And getopt is an ugly, horrible thing. _Why_ does it modify the command line arguments?) Other than that, D2 invariant and final seem useful. D2 const is good for basic things, but seems to scale poorly.
 Never having learned a const-correct language (started with various BASICs, 
 then on to very rudimentary C++, then D, and also a bit of Java and C#), I 
 simply don't see the overwhelming need.  Sure, there are a very few cases 
 where const could be useful in my code for efficiency's sake, but I've never 
 felt like I was missing any expressive power.  Furthermore, I have been 
 bitten exactly once by something that theoretically could have been 
 prevented by const.  It took me two minutes in the debugger to track down 
 the problem.  I'd say that those two minutes were a much better tradeoff 
 than the god-knows-how-long it'd take to write const and non-const overloads 
 of who-knows-how-many functions. 

Most of the time, you shouldn't need to write those overloads. Either the function can be const, in which case you can use it with mutable data anyway, or it can't, in which case you can't write a const overload for it. At least in an ideal system.
Sep 17 2007
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Christopher Wright wrote:
 Most of the time, you shouldn't need to write those overloads. Either 
 the function can be const, in which case you can use it with mutable 
 data anyway, or it can't, in which case you can't write a const overload 
 for it. At least in an ideal system.

The reason that C++ member functions are written twice, const and non-const, are to transmit the const to the return type: const T foo(const S); T foo(S); Nothing more.
Sep 17 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Walter Bright wrote:
 Christopher Wright wrote:
 Most of the time, you shouldn't need to write those overloads. Either 
 the function can be const, in which case you can use it with mutable 
 data anyway, or it can't, in which case you can't write a const 
 overload for it. At least in an ideal system.

The reason that C++ member functions are written twice, const and non-const, are to transmit the const to the return type: const T foo(const S); T foo(S); Nothing more.

There's also the practice of writing all iterators twice. One tail const, one tail mutable. --bb
Sep 17 2007
prev sibling next sibling parent Robert Fraser <fraserofthenight gmail.com> writes:
Jarrett Billingsley Wrote:

 "Bill Baxter" <dnewsgroup billbaxter.com> wrote in message 
 news:fcl79k$18vu$1 digitalmars.com...
 
 It seems from the discussion here the past week, there is no real 
 multithreading benefit to be had from const/invariant.  'Pure' is where 
 it's at for that.  So maybe we're just better off without the complexities 
 of const.  I've certainly gotten used to the lack of const in Python, so 
 why not in a C++-ish language?

I start to wonder how much of the "of COURSE we need const!" thinking comes from "if all you have is a hammer, everything starts looking like a nail." That is, I wonder how many people think we absolutely need const because they're so used to using it in C and C++. Never having learned a const-correct language (started with various BASICs, then on to very rudimentary C++, then D, and also a bit of Java and C#), I simply don't see the overwhelming need. Sure, there are a very few cases where const could be useful in my code for efficiency's sake, but I've never felt like I was missing any expressive power. Furthermore, I have been bitten exactly once by something that theoretically could have been prevented by const. It took me two minutes in the debugger to track down the problem. I'd say that those two minutes were a much better tradeoff than the god-knows-how-long it'd take to write const and non-const overloads of who-knows-how-many functions.

You put it a lot better than I did. High-five!
Sep 17 2007
prev sibling next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Jarrett Billingsley wrote:
 "Bill Baxter" <dnewsgroup billbaxter.com> wrote in message 
 news:fcl79k$18vu$1 digitalmars.com...
 
 It seems from the discussion here the past week, there is no real 
 multithreading benefit to be had from const/invariant.  'Pure' is where 
 it's at for that.  


I was a little over-zealous in my condemnation here. I should have said just "const" not "const/invariant". --bb
Sep 18 2007
prev sibling next sibling parent reply "Janice Caron" <caron800 googlemail.com> writes:
On 9/17/07, Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 "Bill Baxter" <dnewsgroup billbaxter.com> wrote in message
 news:fcl79k$18vu$1 digitalmars.com...

 It seems from the discussion here the past week, there is no real
 multithreading benefit to be had from const/invariant.  'Pure' is where
 it's at for that.  So maybe we're just better off without the complexities
 of const.  I've certainly gotten used to the lack of const in Python, so
 why not in a C++-ish language?

I start to wonder how much of the "of COURSE we need const!" thinking comes from "if all you have is a hammer, everything starts looking like a nail." That is, I wonder how many people think we absolutely need const because they're so used to using it in C and C++. Never having learned a const-correct language (started with various BASICs, then on to very rudimentary C++, then D, and also a bit of Java and C#), I simply don't see the overwhelming need. Sure, there are a very few cases where const could be useful in my code for efficiency's sake, but I've never felt like I was missing any expressive power. Furthermore, I have been bitten exactly once by something that theoretically could have been prevented by const. It took me two minutes in the debugger to track down the problem. I'd say that those two minutes were a much better tradeoff than the god-knows-how-long it'd take to write const and non-const overloads of who-knows-how-many functions.

Let me share some real world experience about using const versus not using const. Today, I found myself writing a small standalone project in D, for my own personal use. I wrote a function that took a ubtye[] as it's parameter. It occured to me that the function didn't actually modify the array, so (since I have D2.0) I could have declared the parameter const. I considered it, and then I thought: "Nah... let's not bother. Too much effort". BUT... When working on a big project, it's a different story. A couple of years back, I was team leader in a C++ project with half a dozen other developers. It was a multithreaded application. So I wrote this bunch of classes which had to be called in a certain way or it wouldn't compile - because data had to be shared between server instances and so forth. Well, a couple of the developers figured out the right thing to do all by themselves, and that was great. Of the others, about three tried the "obvious", discovered that it wouldn't compile because of const-correctness, and came to me asking why not. I explained that there was good reason for the constness, that it was thread-safety issue, and then I told them the correct, "authorised" way of doing things, and then they went off and did the right thing. So in this case, const forced everyone to get it right. Well - almost everyone. (There's always /one/!) One team member tried the "obvious", discovered that it wouldn't compile, and then, instead of asking me why not, figured out a workaround to make it compile using pointers. (If C++ had had intransitive const, the compiler would have prevented this, but it doesn't so he got away with it). Then ... weeks later ... we found that the server randomly fell over after several hours of problem-free up-time. The symptoms were random memory corruption. It took us about a month to find and fix the problem! Care to guess what the problem turned out to be? Yes, it was that errant team member's workaround for const-correctness that ended up causing multiple threads to (rarely) become thread-unsafe. (Moral: If your code won't compile when you try to call a co-worker's function, don't hack up a workaround - instead, ask them if you're calling it right!) So what I conclude from this is: (1) For a small project, you can ignore const. Just because the language has it, doesn't mean you have to use it. (2) For a large project, it's essential. And moreover, it needs to be transitive by default. I don't have a problem with const being transitive by default. I think it's a good idea. I do, however, have a problem with there being *no way to specify* mutable pointer to const pointer to mutable data. We've listed enough use cases to know that sometimes that's exactly what you need. It shouldn't be the default, but it should be /possible/. But ... on the other hand ... we /can/ cast away const, and even though it's "undefined", there is some indication that you can get away with it if you know what you're doing (in terms of thread-safety), so maybe it's not as big a problem as some of us imagine. Anyway, there's my story and my conclusions. Hope it helps. If not, hope it kept you amused. :-)
Sep 19 2007
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Janice Caron" wrote
 (If C++ had had intransitive const, the compiler would have prevented
 this, but it doesn't so he got away with it).

Something tells me that this friend of yours would have done the same thing in D. Is there a warning if you cast away const? If not, there should be. Otherwise, D wouldn't have helped you in this case either...
 I don't have a problem with const being transitive by default. I think
 it's a good idea. I do, however, have a problem with there being *no
 way to specify* mutable pointer to const pointer to mutable data.
 We've listed enough use cases to know that sometimes that's exactly
 what you need. It shouldn't be the default, but it should be
 /possible/.

 But ... on the other hand ... we /can/ cast away const, and even
 though it's "undefined", there is some indication that you can get
 away with it if you know what you're doing (in terms of
 thread-safety), so maybe it's not as big a problem as some of us
 imagine.

Then why be SO adamant about const being transitive! (i.e. Walter's view, not yours). If the 'accepted' practice is to cast away const if you want to have intransitive const, then transitive const is equally meaningless. The more I think about this issue, the more I think that I can probably live with transitive only const. I don't think it's such a bad thing as it simply makes you think differently when designing classes. As I believe intransitive const is a subset of transitive const, it's almost implementable with transitive-only, but I think I'll probably stay away from it. -Steve
Sep 19 2007
prev sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Janice Caron Wrote:

 On 9/17/07, Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 "Bill Baxter" <dnewsgroup billbaxter.com> wrote in message
 news:fcl79k$18vu$1 digitalmars.com...

 It seems from the discussion here the past week, there is no real
 multithreading benefit to be had from const/invariant.  'Pure' is where
 it's at for that.  So maybe we're just better off without the complexities
 of const.  I've certainly gotten used to the lack of const in Python, so
 why not in a C++-ish language?

I start to wonder how much of the "of COURSE we need const!" thinking comes from "if all you have is a hammer, everything starts looking like a nail." That is, I wonder how many people think we absolutely need const because they're so used to using it in C and C++. Never having learned a const-correct language (started with various BASICs, then on to very rudimentary C++, then D, and also a bit of Java and C#), I simply don't see the overwhelming need. Sure, there are a very few cases where const could be useful in my code for efficiency's sake, but I've never felt like I was missing any expressive power. Furthermore, I have been bitten exactly once by something that theoretically could have been prevented by const. It took me two minutes in the debugger to track down the problem. I'd say that those two minutes were a much better tradeoff than the god-knows-how-long it'd take to write const and non-const overloads of who-knows-how-many functions.

Let me share some real world experience about using const versus not using const. Today, I found myself writing a small standalone project in D, for my own personal use. I wrote a function that took a ubtye[] as it's parameter. It occured to me that the function didn't actually modify the array, so (since I have D2.0) I could have declared the parameter const. I considered it, and then I thought: "Nah... let's not bother. Too much effort". BUT... When working on a big project, it's a different story. A couple of years back, I was team leader in a C++ project with half a dozen other developers. It was a multithreaded application. So I wrote this bunch of classes which had to be called in a certain way or it wouldn't compile - because data had to be shared between server instances and so forth. Well, a couple of the developers figured out the right thing to do all by themselves, and that was great. Of the others, about three tried the "obvious", discovered that it wouldn't compile because of const-correctness, and came to me asking why not. I explained that there was good reason for the constness, that it was thread-safety issue, and then I told them the correct, "authorised" way of doing things, and then they went off and did the right thing. So in this case, const forced everyone to get it right. Well - almost everyone. (There's always /one/!) One team member tried the "obvious", discovered that it wouldn't compile, and then, instead of asking me why not, figured out a workaround to make it compile using pointers. (If C++ had had intransitive const, the compiler would have prevented this, but it doesn't so he got away with it). Then ... weeks later ... we found that the server randomly fell over after several hours of problem-free up-time. The symptoms were random memory corruption. It took us about a month to find and fix the problem! Care to guess what the problem turned out to be? Yes, it was that errant team member's workaround for const-correctness that ended up causing multiple threads to (rarely) become thread-unsafe. (Moral: If your code won't compile when you try to call a co-worker's function, don't hack up a workaround - instead, ask them if you're calling it right!) So what I conclude from this is: (1) For a small project, you can ignore const. Just because the language has it, doesn't mean you have to use it. (2) For a large project, it's essential. And moreover, it needs to be transitive by default.

But wait... if there wasn't any const in the first place, the guy wouldn't have needed to hack up that workaround... I'm sensing a different moral here... ;-P
 
 I don't have a problem with const being transitive by default. I think
 it's a good idea. I do, however, have a problem with there being *no
 way to specify* mutable pointer to const pointer to mutable data.
 We've listed enough use cases to know that sometimes that's exactly
 what you need. It shouldn't be the default, but it should be
 /possible/.
 
 But ... on the other hand ... we /can/ cast away const, and even
 though it's "undefined", there is some indication that you can get
 away with it if you know what you're doing (in terms of
 thread-safety), so maybe it's not as big a problem as some of us
 imagine.
 
 Anyway, there's my story and my conclusions. Hope it helps. If not,
 hope it kept you amused. :-)

Sep 19 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Robert Fraser wrote:
 Janice Caron Wrote:
 
 On 9/17/07, Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 "Bill Baxter" <dnewsgroup billbaxter.com> wrote in message
 news:fcl79k$18vu$1 digitalmars.com...

 It seems from the discussion here the past week, there is no real
 multithreading benefit to be had from const/invariant.  'Pure' is where
 it's at for that.  So maybe we're just better off without the complexities
 of const.  I've certainly gotten used to the lack of const in Python, so
 why not in a C++-ish language?

from "if all you have is a hammer, everything starts looking like a nail." That is, I wonder how many people think we absolutely need const because they're so used to using it in C and C++. Never having learned a const-correct language (started with various BASICs, then on to very rudimentary C++, then D, and also a bit of Java and C#), I simply don't see the overwhelming need. Sure, there are a very few cases where const could be useful in my code for efficiency's sake, but I've never felt like I was missing any expressive power. Furthermore, I have been bitten exactly once by something that theoretically could have been prevented by const. It took me two minutes in the debugger to track down the problem. I'd say that those two minutes were a much better tradeoff than the god-knows-how-long it'd take to write const and non-const overloads of who-knows-how-many functions.

using const. Today, I found myself writing a small standalone project in D, for my own personal use. I wrote a function that took a ubtye[] as it's parameter. It occured to me that the function didn't actually modify the array, so (since I have D2.0) I could have declared the parameter const. I considered it, and then I thought: "Nah... let's not bother. Too much effort". BUT... When working on a big project, it's a different story. A couple of years back, I was team leader in a C++ project with half a dozen other developers. It was a multithreaded application. So I wrote this bunch of classes which had to be called in a certain way or it wouldn't compile - because data had to be shared between server instances and so forth. Well, a couple of the developers figured out the right thing to do all by themselves, and that was great. Of the others, about three tried the "obvious", discovered that it wouldn't compile because of const-correctness, and came to me asking why not. I explained that there was good reason for the constness, that it was thread-safety issue, and then I told them the correct, "authorised" way of doing things, and then they went off and did the right thing. So in this case, const forced everyone to get it right. Well - almost everyone. (There's always /one/!) One team member tried the "obvious", discovered that it wouldn't compile, and then, instead of asking me why not, figured out a workaround to make it compile using pointers. (If C++ had had intransitive const, the compiler would have prevented this, but it doesn't so he got away with it). Then ... weeks later ... we found that the server randomly fell over after several hours of problem-free up-time. The symptoms were random memory corruption. It took us about a month to find and fix the problem! Care to guess what the problem turned out to be? Yes, it was that errant team member's workaround for const-correctness that ended up causing multiple threads to (rarely) become thread-unsafe. (Moral: If your code won't compile when you try to call a co-worker's function, don't hack up a workaround - instead, ask them if you're calling it right!) So what I conclude from this is: (1) For a small project, you can ignore const. Just because the language has it, doesn't mean you have to use it. (2) For a large project, it's essential. And moreover, it needs to be transitive by default.

But wait... if there wasn't any const in the first place, the guy wouldn't have needed to hack up that workaround... I'm sensing a different moral here... ;-P

First, I'm not convinced that cluebie wouldn't have just casted away const to work around D's transitivity. Second, along the same lines as Robert's reply, if you created a library for which in your words "the obvious way" was not the right way to use it, and three developers had to ask you how it works, then it sounds like you may not have documented your cleverness sufficiently. Maybe if you hadn't been thinking compiler errors from constness would save you, then you would have either designed it so that it just worked "the obvious way" or at least documented it more thoroughly. Or was it documented clearly and people just ignored the documentation? That can certainly happen, too. --bb
Sep 19 2007
prev sibling next sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On 9/19/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 Something tells me that this friend of yours would have done the same thing
 in D.  Is there a warning if you cast away const?  If not, there should be.

 Otherwise, D wouldn't have helped you in this case either...

Difficult to say. Everyone hesitates before typing "const_cast"! Even when it's legitimate, it feels a bit naughty. Trouble is, the "const_cast" keyword is not compulsory. With C++ is that it isn't immediately obvious that a cast like "(void *)p" is casting away const, but that's what everyone types, because it's quicker than than the safe alternative "static_cast<void *>(p)". That's why I'm hoping Walter will arrange it so that D's "cast(T)" will refuse to cast away constness without a special syntax.
Sep 19 2007
prev sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On 9/19/07, Robert Fraser <fraserofthenight gmail.com> wrote:
 But wait... if there wasn't any const in the first place, the guy wouldn't
have needed to hack up that workaround...

Oh dear. I hope I'm not being misunderstood again. const forced the rest of the team (apart from this one guy) to get it right. That meant the project ended up relatively bug free. This one guy was the exception that proves the rule!
Sep 19 2007
prev sibling next sibling parent Jan Claeys <usenet janc.be> writes:
Op Mon, 17 Sep 2007 23:00:33 -0700
schreef Walter Bright <newshound1 digitalmars.com>:

 A lot of Python users also seem to be quite unhappy about the gil.

Actually, only some Python implementation have the GIL (CPython & Stackless), most don't have it (Jython, IronPython, PyPy, etc.). Of course CPython is probably used more than all others combined...
 Python in its current form appears to be unsuitable for writing
 parallel code.

There are lots of (sometimes massively) parallel python applications around; some of them were named in the recent discussions. As an example, the EVE Online servers & clients work as one large distributed parallel application (there is one shared "state"). The complaints seem to be more about how people have to write parallel code, but trying to port Java/C++ code/idioms word for word into Python (obviously) doesn't work very well. AFAIK most CPython parallel programming uses one of two techniques: 1. Non-Python modules (e.g. those written in C, C++ or D) can (temporarily) release the GIL if they make sure they don't access/change data shared with other threads during that period. 2. Multiple processes + some form of IPC (machine-local or distributed over a cluster) -- JanC
Sep 22 2007
prev sibling next sibling parent Jan Claeys <usenet janc.be> writes:
Op Sun, 23 Sep 2007 16:16:03 +1000
schreef Daniel Keep <daniel.keep.lists gmail.com>:

 Jan Claeys wrote:
 There are lots of (sometimes massively) parallel python applications
 around; some of them were named in the recent discussions.  As an
 example, the EVE Online servers & clients work as one large
 distributed parallel application (there is one shared "state").

To be fair, that's parallelism via stackless which is just cooperative multithreading. As far as I understand it, if you ignore the overhead of context switching and locks, code written against stackless and using Python threads will run at the same speed irrespective of how many hardware threads you have. Neither one, AFAIK, can actually execute multiple threads of Python code simultaneously.

Not multiple threads of pure python code, but modules written in C++ (which I think they use at least in the client, and most likely also server-side) can use multiple simultaneous threads. And multiple processes + IPC are no problem for pure python code.
 That said, stackless is still the bee's knees if you're on a
 uniprocessor machine.  The ability to have hundreds of thousands of
 super lightweight threads with almost no overhead, *and* the ability
 to just pickle a thread and re-start it on another machine?

They run it on a cluster of several multiprocessor machines, not even counting the tens of thousands of PCs of their customers (the players of the game) that have to share (part of) the state of the game. <http://myeve.eve-online.com/devblog.asp?a=blog&bid=303> tells about their early 2006 hardware (70 dual-cpu IBM LS20 Opteron blades :) ). On 2007-09-03 they had more than 35000 people logged in into the same game: <http://www.gamershell.com/news/41371.html>. -- JanC
Sep 24 2007
prev sibling parent Jan Claeys <usenet janc.be> writes:
Op Sun, 23 Sep 2007 15:48:08 +0900
schreef Bill Baxter <dnewsgroup billbaxter.com>:

 Actually I remembered one time when lack of const did bite me in
 Python. I was translating some Matlab code I wrote to Python/NumPy 
 (http://www.scipy.org/).

 In Matlab all calls are call-by-value, and all assignments are 
 assign-by-value (both use COW under the covers to make performance 
 reasonable).  In Python they're call-by-reference and 
 assign-by-reference for most anything more complicated than an 'int'. 
 The matrix class I was using in the Python code definitely fell into
 the by-reference category.

Never do a word-by-word translation... :) Both mutable & immutable objects are passed as "objects" in python (the technical details of how that happens, e.g. using pointers, is merely an implementation detail, but it's obviously very close to what happens with call-by-reference in other languages) and it's only at the time of assignment that behaviour between them differs. It's the same outside of a function/method and has nothing to do with the different methods of parameter passing in other languages.
 If Python had const, I don't think I would have had those problems.

Well, Python has something 'const'-like, only it's linked to the object's type, and not defined by the way it's called. ;) And if you want to "call by value", there is always the 'copy' module: <http://docs.python.org/lib/module-copy.html> (Could be used in a decorator too...) -- JanC
Sep 24 2007