digitalmars.D - Immutable arrays for Walter and rest of us.
- Andrew Fedoniouk (65/65) Jun 29 2005 I would like to discuss one of my previous ideas again
- Victor Nakoryakov (6/6) Jun 30 2005 Yep, good idea. But you're not the first, and I think not the last who
- Regan Heath (7/72) Jun 30 2005 Not a bad idea. I prefer the solution I've mentioned a few times already...
- Kramer (5/107) Jun 30 2005 And since it has been suggested so many times and IMO a very worth while
- Brad Beveridge (7/21) Jun 30 2005 I like it and I agree 100%. I don't happen to like # as the token to
- Andrew Fedoniouk (10/30) Jun 30 2005 In fact immutable arrays are 80% or so of use
- Brad Beveridge (9/51) Jun 30 2005 I could see possible problems with templates using !
- Brad Beveridge (10/20) Jun 30 2005 Do you think that class/struct types should also be able to be
- Andrew Fedoniouk (11/30) Jun 30 2005 If it is needed anyone can create mutable/immutable state
- AJG (10/75) Jun 30 2005 Just wanted to put in my vote for this suggested feature. Whatever the a...
- Vathix (20/31) Jun 30 2005 I don't like it. Not just the syntax. I think immutable is so common tha...
-
Brad Beveridge
(7/14)
Jun 30 2005
- Vathix (3/5) Jun 30 2005 No, but I'm willing to compromise.
- Walter (5/5) Jun 30 2005 What is the difference between that and C++'s const as a type modifier?
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (10/16) Jun 30 2005 Or the other proposal, "readonly", seeing as how const is overloaded...
- AJG (12/18) Jun 30 2005 I agree, but I don't think it's a bad thing at all. The more the merrier...
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (4/5) Jun 30 2005 "length", for arrays. As in this "remove":
- AJG (10/15) Jun 30 2005 Awesome, thanks. I use length a lot, so $ is great.
- Regan Heath (8/27) Jun 30 2005 And pull it off, so to speak (you're decrementing the length, or trying ...
- Trevor Parscal (17/20) Jul 05 2005 Personally, I think using # is way more descriptive than $... $ looks
- AJG (10/28) Jul 05 2005 You have my vote. I agree wholeheartedly.
- Regan Heath (6/31) Jul 05 2005 I dont mind $, that said, I don't mind # either.
- Regan Heath (43/48) Jun 30 2005 Nothing, which is why I prefer the idea I've been bandying (sp?) around ...
- Andrew Fedoniouk (26/75) Jun 30 2005 Regan,
- Regan Heath (16/102) Jun 30 2005 The runtime or the compile time one? (you seem not to realise I am talki...
- Andrew Fedoniouk (12/119) Jun 30 2005 The question is: where this bit is located?
- Regan Heath (6/49) Jun 30 2005 If that is what is required, yes.
- Andrew Fedoniouk (16/67) Jul 01 2005 So -release will have sizeof(void*) == 32
- Regan Heath (10/50) Jul 01 2005 Yes.
- Regan Heath (40/98) Jul 01 2005 I recently forgot my 'other' option for runtime 'readonly' checking of
- Andrew Fedoniouk (13/18) Jun 30 2005 typename # * is eqiuvalent of
- Walter (34/36) Jul 01 2005 I've been discussing this issue with Andrei (of Modern C++ Design fame)....
- Regan Heath (8/10) Jul 01 2005 By function local do you mean "a" or "b" below?
- AJG (3/13) Jul 01 2005 I think he means "b". As opposed to parameter in variables, like "a".
- Regan Heath (17/34) Jul 01 2005 If he does, then why can't all 'in' parameters be immutable. 'in' is the...
- AJG (10/21) Jul 01 2005 This would be fantastic, IMHO. It makes perfect sense, and we get the be...
- Kevin Bealer (11/25) Jul 01 2005 This sounds great. In this scenario, can I store the in object (or its ...
- Walter (10/18) Jul 01 2005 sub
- Sean Kelly (22/37) Jul 01 2005 I think in this case a copy would need to be made. ie.
- Carlos Santander (7/20) Jul 01 2005 I think that's similar to what Pascal does, and that's something I agree...
- Walter (3/5) Jul 02 2005 With the 'in' compromise, it doesn't address return values.
- Dave (43/63) Jul 02 2005 One other thought - Make it so that an "explicit in" makes a copy as it ...
- Dave (16/44) Jul 04 2005 I guess I don't understand why this is a problem because there has alway...
I would like to discuss one of my previous ideas again as it seems it was lost in the fire. I think below is the best compromise we can get. In fact as more I am looking on it as more I am sure that it not even compromise - it is "well done immutables". Idea is to extend typesystem with a new type: immutable (const, readonly) array and pointer. Proposed notation of immutable array type is as: Proposed notation of immutable pointer is as: Immutable array as a type has exactly the same set of properties and methods as array except of mutators: opIndexAssign and int length(int newlength) char[] s1; is1 = s1; // ok. s1 = is1; // compile time (CT) err. Examples: s1[0] = 'a'; // ok is1[0] = 'a'; // CT err. s1.length = 1; // ok is1.length = 1; // CT err. -------------------------------- String and array literals are immutable by definition: char[] s1 = "Hello world"; // CT err. Sidenote: In C++, by historical reasons, string literals have type char* and not const char* which is imho bad and needs to be changed. ------------------------------ This approach will give us readonlyness without major changes in language notation and architecture. This approach is free from C++ "const syntactical madness" where const is used for three different things and looks ugly sometimes. Clear differentiation of built-in reference types (array and struct) onto mutable and immutable versions will increase "fullness" of D's balanced type system. The thing is that char[] is from one side is atomic type and it is pretty natural to human to interpret it as just lets say atomic int. But at the same time it is a reference to some possibly shared data. This is why arrays and pointers shall exist in two forms. consumer has no rights to change it as it will damage integrity state of the owner. ------------------------------------------- Possible variations of immutable type notation I've considered: 2) typename$[] 3) typename [] 4) typename[] const - not good as it conflicts with C++ cases visually. of notation though. Ideas anyone? -------------------------------------------- I think it makes sense to add opSliceConst to the list of overloadable operators. -------------------------------------------- Having readonlyness interpreted and implemented this way will finally reconcile const and no-const camps. I hope. Andrew.
Jun 29 2005
Yep, good idea. But you're not the first, and I think not the last who suggest some solution for constness. To me suggestion seems to be ignored. -- Victor (aka nail) Nakoryakov nail-mail<at>mail<dot>ru Krasnoznamensk, Moscow, Russia
Jun 30 2005
Not a bad idea. I prefer the solution I've mentioned a few times already. I just hope Walter gives us some indication of what he's thinking at some stage. (hint, hint) Regan On Wed, 29 Jun 2005 23:06:12 -0700, Andrew Fedoniouk <news terrainformatica.com> wrote:I would like to discuss one of my previous ideas again as it seems it was lost in the fire. I think below is the best compromise we can get. In fact as more I am looking on it as more I am sure that it not even compromise - it is "well done immutables". Idea is to extend typesystem with a new type: immutable (const, readonly) array and pointer. Proposed notation of immutable array type is as: Proposed notation of immutable pointer is as: Immutable array as a type has exactly the same set of properties and methods as array except of mutators: opIndexAssign and int length(int newlength) char[] s1; is1 = s1; // ok. s1 = is1; // compile time (CT) err. Examples: s1[0] = 'a'; // ok is1[0] = 'a'; // CT err. s1.length = 1; // ok is1.length = 1; // CT err. -------------------------------- String and array literals are immutable by definition: char[] s1 = "Hello world"; // CT err. Sidenote: In C++, by historical reasons, string literals have type char* and not const char* which is imho bad and needs to be changed. ------------------------------ This approach will give us readonlyness without major changes in language notation and architecture. This approach is free from C++ "const syntactical madness" where const is used for three different things and looks ugly sometimes. Clear differentiation of built-in reference types (array and struct) onto mutable and immutable versions will increase "fullness" of D's balanced type system. The thing is that char[] is from one side is atomic type and it is pretty natural to human to interpret it as just lets say atomic int. But at the same time it is a reference to some possibly shared data. This is why arrays and pointers shall exist in two forms. consumer has no rights to change it as it will damage integrity state of the owner. ------------------------------------------- Possible variations of immutable type notation I've considered: 2) typename$[] 3) typename [] 4) typename[] const - not good as it conflicts with C++ cases visually. of notation though. Ideas anyone? -------------------------------------------- I think it makes sense to add opSliceConst to the list of overloadable operators. -------------------------------------------- Having readonlyness interpreted and implemented this way will finally reconcile const and no-const camps. I hope. Andrew.
Jun 30 2005
And since it has been suggested so many times and IMO a very worth while idea/feature, if Walter does not want to add it, then we need some practices/idioms for D on how to simulate it. -Kramer In article <opss6iqfje23k2f5 nrage.netwin.co.nz>, Regan Heath says...Not a bad idea. I prefer the solution I've mentioned a few times already. I just hope Walter gives us some indication of what he's thinking at some stage. (hint, hint) Regan On Wed, 29 Jun 2005 23:06:12 -0700, Andrew Fedoniouk <news terrainformatica.com> wrote:I would like to discuss one of my previous ideas again as it seems it was lost in the fire. I think below is the best compromise we can get. In fact as more I am looking on it as more I am sure that it not even compromise - it is "well done immutables". Idea is to extend typesystem with a new type: immutable (const, readonly) array and pointer. Proposed notation of immutable array type is as: Proposed notation of immutable pointer is as: Immutable array as a type has exactly the same set of properties and methods as array except of mutators: opIndexAssign and int length(int newlength) char[] s1; is1 = s1; // ok. s1 = is1; // compile time (CT) err. Examples: s1[0] = 'a'; // ok is1[0] = 'a'; // CT err. s1.length = 1; // ok is1.length = 1; // CT err. -------------------------------- String and array literals are immutable by definition: char[] s1 = "Hello world"; // CT err. Sidenote: In C++, by historical reasons, string literals have type char* and not const char* which is imho bad and needs to be changed. ------------------------------ This approach will give us readonlyness without major changes in language notation and architecture. This approach is free from C++ "const syntactical madness" where const is used for three different things and looks ugly sometimes. Clear differentiation of built-in reference types (array and struct) onto mutable and immutable versions will increase "fullness" of D's balanced type system. The thing is that char[] is from one side is atomic type and it is pretty natural to human to interpret it as just lets say atomic int. But at the same time it is a reference to some possibly shared data. This is why arrays and pointers shall exist in two forms. consumer has no rights to change it as it will damage integrity state of the owner. ------------------------------------------- Possible variations of immutable type notation I've considered: 2) typename$[] 3) typename [] 4) typename[] const - not good as it conflicts with C++ cases visually. of notation though. Ideas anyone? -------------------------------------------- I think it makes sense to add opSliceConst to the list of overloadable operators. -------------------------------------------- Having readonlyness interpreted and implemented this way will finally reconcile const and no-const camps. I hope. Andrew.
Jun 30 2005
Andrew Fedoniouk wrote:of notation though. Ideas anyone? -------------------------------------------- I think it makes sense to add opSliceConst to the list of overloadable operators. -------------------------------------------- Having readonlyness interpreted and implemented this way will finally reconcile const and no-const camps. I hope. Andrew.signify immutability though. I've never been opposed to longish names, so my vote would be for "immutable" as a decorator. immutable char[] is1; char[] s1; Brad
Jun 30 2005
"Brad Beveridge" <brad somewhere.net> wrote in message news:da13eo$1ao3$2 digitaldaemon.com...Andrew Fedoniouk wrote:In fact immutable arrays are 80% or so of use cases of arrays in average code. So motivation is to make 'immutable' flag as shorter as possible. What about this: char![] Ideally, default char[] should be immutable and char![] should be mutable. Andrew.of notation though. Ideas anyone? -------------------------------------------- I think it makes sense to add opSliceConst to the list of overloadable operators. -------------------------------------------- Having readonlyness interpreted and implemented this way will finally reconcile const and no-const camps. I hope. Andrew.signify immutability though. I've never been opposed to longish names, so my vote would be for "immutable" as a decorator. immutable char[] is1; char[] s1;
Jun 30 2005
Andrew Fedoniouk wrote:"Brad Beveridge" <brad somewhere.net> wrote in message news:da13eo$1ao3$2 digitaldaemon.com...I could see possible problems with templates using ! I agree that having a short flag is probably a good idea, but I would personally value absolute clarity over conciseness. Some other choices for "immutable" http://thesaurus.reference.com/search?q=immutable I like "fixed", "stable", "firm" and "solid" in that order. Of course, step 1 is getting Walter to agree that we need _something_ BradAndrew Fedoniouk wrote:In fact immutable arrays are 80% or so of use cases of arrays in average code. So motivation is to make 'immutable' flag as shorter as possible. What about this: char![] Ideally, default char[] should be immutable and char![] should be mutable. Andrew.of notation though. Ideas anyone? -------------------------------------------- I think it makes sense to add opSliceConst to the list of overloadable operators. -------------------------------------------- Having readonlyness interpreted and implemented this way will finally reconcile const and no-const camps. I hope. Andrew.signify immutability though. I've never been opposed to longish names, so my vote would be for "immutable" as a decorator. immutable char[] is1; char[] s1;
Jun 30 2005
Andrew Fedoniouk wrote:I would like to discuss one of my previous ideas again as it seems it was lost in the fire. I think below is the best compromise we can get. In fact as more I am looking on it as more I am sure that it not even compromise - it is "well done immutables". Idea is to extend typesystem with a new type: immutable (const, readonly) array and pointer.Do you think that class/struct types should also be able to be immutable? Or does that open a can of worms that is too large? I think that perhaps they should be allowed to be decorated with "immutable", but I am not certain of the rules that should go along with it - ie, what members can be called etc. I don't really care about this, but it is good to be consistant. Of course, it will probably be a miracle if Walter gives us a straight answer on your original proposal even :) Brad
Jun 30 2005
"Brad Beveridge" <brad somewhere.net> wrote in message news:da1534$1cik$1 digitaldaemon.com...Andrew Fedoniouk wrote:If it is needed anyone can create mutable/immutable state variable for his/her own class. Or create mutable versions of it. This approach was used in mango. A bit overkill, IMO, but works. behavior of basic types.I would like to discuss one of my previous ideas again as it seems it was lost in the fire. I think below is the best compromise we can get. In fact as more I am looking on it as more I am sure that it not even compromise - it is "well done immutables". Idea is to extend typesystem with a new type: immutable (const, readonly) array and pointer.Do you think that class/struct types should also be able to be immutable? Or does that open a can of worms that is too large? I think that perhaps they should be allowed to be decorated with "immutable", but I am not certain of the rules that should go along with it - ie, what members can be called etc.I don't really care about this, but it is good to be consistant. Of course, it will probably be a miracle if Walter gives us a straight answer on your original proposal even :)Hope dies last. And I think we are almost at position to start "Sic transit gloria mundi..."
Jun 30 2005
Just wanted to put in my vote for this suggested feature. Whatever the actual need this. It's up to Walter now, I guess. Cheers, --AJG. PS: Using hackish class-wrappers for this kind of thing is _way_ too much trouble and it not worth it IMHO. We need language/compiler level support. In article <da024r$65o$1 digitaldaemon.com>, Andrew Fedoniouk says...I would like to discuss one of my previous ideas again as it seems it was lost in the fire. I think below is the best compromise we can get. In fact as more I am looking on it as more I am sure that it not even compromise - it is "well done immutables". Idea is to extend typesystem with a new type: immutable (const, readonly) array and pointer. Proposed notation of immutable array type is as: Proposed notation of immutable pointer is as: Immutable array as a type has exactly the same set of properties and methods as array except of mutators: opIndexAssign and int length(int newlength) char[] s1; is1 = s1; // ok. s1 = is1; // compile time (CT) err. Examples: s1[0] = 'a'; // ok is1[0] = 'a'; // CT err. s1.length = 1; // ok is1.length = 1; // CT err. -------------------------------- String and array literals are immutable by definition: char[] s1 = "Hello world"; // CT err. Sidenote: In C++, by historical reasons, string literals have type char* and not const char* which is imho bad and needs to be changed. ------------------------------ This approach will give us readonlyness without major changes in language notation and architecture. This approach is free from C++ "const syntactical madness" where const is used for three different things and looks ugly sometimes. Clear differentiation of built-in reference types (array and struct) onto mutable and immutable versions will increase "fullness" of D's balanced type system. The thing is that char[] is from one side is atomic type and it is pretty natural to human to interpret it as just lets say atomic int. But at the same time it is a reference to some possibly shared data. This is why arrays and pointers shall exist in two forms. consumer has no rights to change it as it will damage integrity state of the owner. ------------------------------------------- Possible variations of immutable type notation I've considered: 2) typename$[] 3) typename [] 4) typename[] const - not good as it conflicts with C++ cases visually. of notation though. Ideas anyone? -------------------------------------------- I think it makes sense to add opSliceConst to the list of overloadable operators. -------------------------------------------- Having readonlyness interpreted and implemented this way will finally reconcile const and no-const camps. I hope. Andrew.======================= I sync, therefore I am.
Jun 30 2005
On Thu, 30 Jun 2005 02:06:12 -0400, Andrew Fedoniouk <news terrainformatica.com> wrote:I would like to discuss one of my previous ideas again as it seems it was lost in the fire. I think below is the best compromise we can get. In fact as more I am looking on it as more I am sure that it not even compromise - it is "well done immutables". Idea is to extend typesystem with a new type: immutable (const, readonly) array and pointer. Proposed notation of immutable array type is as: Proposed notation of immutable pointer is as:I don't like it. Not just the syntax. I think immutable is so common that it should be the default. Right now we have to enforce it ourselves using COW. I don't have much of a problem with it but it seems many others do. What if arrays and pointers were immutable by default? The only way to make something mutable is to use a mutable keyword. I think it would be much more productive and sounds a lot more relaxing than specifying immutable. There would have to be a way to force something that is immutable to be mutable (?). Perhaps using cast(mutable char[]) for char[]. Here is an example: char[] foo = "hi"; // Good, immutable. mutable char[] bar = new char[30]; char[] baz = bar; // Mutable to immutable. mutable char[] bat = "hey"; // ERROR, string literal is immutable. mutable char[] qux = cast(mutable char[])bar; // Force immutable to mutable. Not recommended. It would break a lot of existing code, but I believe supporting the current style could still be supported using -deprecated. - Chris
Jun 30 2005
Vathix wrote:On Thu, 30 Jun 2005 02:06:12 -0400, Andrew Fedoniouk <news terrainformatica.com> wrote:<snip>I don't like it. Not just the syntax. I think immutable is so common that it should be the default. Right now we have to enforce it ourselves using COW. I don't have much of a problem with it but it seems many others do.<snip>- ChrisWould you still fall into the category of "we need _something_ to protect immutable data"? I think I might start a voting thread to see who need/want this feeture :) Brad
Jun 30 2005
On Thu, 30 Jun 2005 13:40:26 -0400, Brad Beveridge <brad somewhere.net> wrote:Would you still fall into the category of "we need _something_ to protect immutable data"?No, but I'm willing to compromise.
Jun 30 2005
What is the difference between that and C++'s const as a type modifier? C++: typename const * Proposal:
Jun 30 2005
Walter wrote:What is the difference between that and C++'s const as a type modifier? C++: typename const * Proposal:Or the other proposal, "readonly", seeing as how const is overloaded... (or the newly proposed variant thereof, which seems to be "immutable") BTW; Another note: There was an old suggestion (I think) that an explicit "in" would mean readonly for the array contents too, and not just for the array pointer. But it's a bit "unclear" for declarations, I think ? "in typename *" --anders
Jun 30 2005
Hi,Or the other proposal, "readonly", seeing as how const is overloaded... (or the newly proposed variant thereof, which seems to be "immutable")I agree, but I don't think it's a bad thing at all. The more the merrier, I say. Oh, and what is [$]? I've never seen that one before...Another note: There was an old suggestion (I think) that an explicit "in" would mean readonly for the array contents too, and not just for the array pointer.I like this a lot. This is the way it should be, IMHO, by default at all times; at least the explicit "in" would give us the option to enforce it. I can't decide which one I like better, the explicit in or immutability; either one would be a great improvement. I guess both would be even better? Cheers, --AJG. ======================= I sync, therefore I am.
Jun 30 2005
AJG wrote:Oh, and what is [$]? I've never seen that one before..."length", for arrays. As in this "remove": array = array[0 .. i-1] ~ array[i+1 .. $]; --anders
Jun 30 2005
Awesome, thanks. I use length a lot, so $ is great. Anybody have any concerns about this usage?: // Easy way to get last element. int lastItem = someArray[--$]; Cheers, --AJG. In article <da1q3p$26jr$1 digitaldaemon.com>, =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...AJG wrote:======================== if (!sin) throw rock[0];Oh, and what is [$]? I've never seen that one before..."length", for arrays. As in this "remove": array = array[0 .. i-1] ~ array[i+1 .. $]; --anders
Jun 30 2005
On Fri, 1 Jul 2005 02:46:41 +0000 (UTC), AJG <AJG_member pathlink.com> wrote:Awesome, thanks. I use length a lot, so $ is great. Anybody have any concerns about this usage?: // Easy way to get last element. int lastItem = someArray[--$];And pull it off, so to speak (you're decrementing the length, or trying to). Does that work? AFAIK you cannot say "--someArray.length" as length is a property i.e not an lvalue I write someArray[$-1] to get the last element. ReganCheers, --AJG. In article <da1q3p$26jr$1 digitaldaemon.com>, =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...AJG wrote:======================== if (!sin) throw rock[0];Oh, and what is [$]? I've never seen that one before..."length", for arrays. As in this "remove": array = array[0 .. i-1] ~ array[i+1 .. $]; --anders
Jun 30 2005
I write someArray[$-1] to get the last element.varaible, but honestly, cold fusion is crap, so I just ignore it... should give you the last 5 elements of the array. Also, I have another idea. using "..." should mean, to the end. so list[4 ...] means, from 4 on. so... means, the last 5 :) Just an idea. Won't break existing code. -- Thanks, Trevor Parscal www.trevorparscal.com trevorparscal hotmail.com
Jul 05 2005
Hi, In article <daf0km$umn$1 digitaldaemon.com>, Trevor Parscal says...You have my vote. I agree wholeheartedly.I write someArray[$-1] to get the last element.varaible, but honestly, cold fusion is crap, so I just ignore it... should give you the last 5 elements of the array.Also, I have another idea. using "..." should mean, to the end. so list[4 ...] means, from 4 on. so... means, the last 5 :) Just an idea. Won't break existing code.I also like this idea. To make it simpler we could just use .. and leave one (or both) of the ends blank. So that: array[.. b] == array[0 .. b]; Just thinking out loud. --AJG.-- Thanks, Trevor Parscal www.trevorparscal.com trevorparscal hotmail.com
Jul 05 2005
On Wed, 6 Jul 2005 01:05:17 +0000 (UTC), AJG <AJG_member pathlink.com> wrote:In article <daf0km$umn$1 digitaldaemon.com>, Trevor Parscal says...You have my vote. I agree wholeheartedly.I write someArray[$-1] to get the last element.varaible, but honestly, cold fusion is crap, so I just ignore it... meaning... should give you the last 5 elements of the array.This idea has been proposed before, along with many others. Do a search, you'll see what I mean. ReganAlso, I have another idea. using "..." should mean, to the end. so list[4 ...] means, from 4 on. so... means, the last 5 :) Just an idea. Won't break existing code.I also like this idea. To make it simpler we could just use .. and leave one (or both) of the ends blank. So that: array[.. b] == array[0 .. b]; Just thinking out loud.
Jul 05 2005
On Thu, 30 Jun 2005 11:19:38 -0700, Walter <newshound digitalmars.com> wrote:What is the difference between that and C++'s const as a type modifier? C++: typename const * Proposal:Nothing, which is why I prefer the idea I've been bandying (sp?) around here for the past month. Please read carefully this is _not_ the same thing. A readonly compile time, and perhaps also runtime (disabled for -release) readonly bit flag for all variables. Initialised to 'false'. Set to 'true' in the presence of "readonly" as a type modifier. Set to 'true' when passed as an 'in' parameter. Compiler errors on all operations that mutate a readonly flagged variable. Example usage: class Foo { char[] data; readonly char[] get() { return data; } } void foo(inout char[] data) { data[0] = 'a'; } Foo f = new Foo(); char[] p = f.get(); p[0] = 'a'; //error cannot mutate readonly foo(p); //error passing readonly as mutable void foo(char[] data) { data[0] = 'a'; } //error cannot mutate readonly IMPORTANT: this does not create a seperate distinct type, "readonly char[]" is not a different type to "char[]" it's the same type with it's readonly flag set to 'true'. The reason this is important is that it stops this situation... char[] s; ..s used as temp var here.. readonly char[] p = f.get(); s = p; //error s is not readonly Which is just plain irritating. People typically solve the above by casting the readonly away. Not good. In the above 's's readonly flag is set on assignment, it becomes readonly. The readonly flag would be set to false when passed as 'out', or on assignment to a rhs which has readonly=false (including null). A runtime flag is required for cases like: char[] p = test ? some_string : f.get(); p[1] = 'd'; //is 'p' readonly if some_string isn't? where the compiler cannot tell at compile time. The runtime flag would be present in every single variable, disabled by -release and/or it's own compile time flag (perhaps disabled by default like -unittest) Regan
Jun 30 2005
Regan, Readonly flag is technicaly difficult and inefficient to implement. Any access to the pointer(sic!) and array shall check first this flag in runtime. Second problem is that you need to store somewhere this bit. Where? Proposed solution is just static (compile time) test. Moving conditions which can be checked in compile to runtime is generally not a good idea - non-efficient and difficult to verify in full. To be short, in runtime you may get following: <quote> Ariane 5 Rocket Disaster The Ariane 5 Rocket was made by the European Space Agency. In simple terms Navigational software was used from the Ariane 4 in the more powerful Ariane 5. The computer was programmed with a safety feature which aborted the mission and caused the rocket to self destruct if it went off course. Due to an error in the navigation calculations, however, the Arian 5 self destructed - even though it was on course to its planned destination. Investigators later discovered that the cause of the Ariane 5 disaster was attributed to calculations based on the Ariane 4 dimensions and power. </quote> If it is possible to verify conditions in CT you'd better do it there. PS: Ariane software is written in ADA, afaik. Andrew. "Regan Heath" <regan netwin.co.nz> wrote in message news:opss7fh6dr23k2f5 nrage.netwin.co.nz...On Thu, 30 Jun 2005 11:19:38 -0700, Walter <newshound digitalmars.com> wrote:What is the difference between that and C++'s const as a type modifier? C++: typename const * Proposal:Nothing, which is why I prefer the idea I've been bandying (sp?) around here for the past month. Please read carefully this is _not_ the same thing. A readonly compile time, and perhaps also runtime (disabled for -release) readonly bit flag for all variables. Initialised to 'false'. Set to 'true' in the presence of "readonly" as a type modifier. Set to 'true' when passed as an 'in' parameter. Compiler errors on all operations that mutate a readonly flagged variable. Example usage: class Foo { char[] data; readonly char[] get() { return data; } } void foo(inout char[] data) { data[0] = 'a'; } Foo f = new Foo(); char[] p = f.get(); p[0] = 'a'; //error cannot mutate readonly foo(p); //error passing readonly as mutable void foo(char[] data) { data[0] = 'a'; } //error cannot mutate readonly IMPORTANT: this does not create a seperate distinct type, "readonly char[]" is not a different type to "char[]" it's the same type with it's readonly flag set to 'true'. The reason this is important is that it stops this situation... char[] s; ..s used as temp var here.. readonly char[] p = f.get(); s = p; //error s is not readonly Which is just plain irritating. People typically solve the above by casting the readonly away. Not good. In the above 's's readonly flag is set on assignment, it becomes readonly. The readonly flag would be set to false when passed as 'out', or on assignment to a rhs which has readonly=false (including null). A runtime flag is required for cases like: char[] p = test ? some_string : f.get(); p[1] = 'd'; //is 'p' readonly if some_string isn't? where the compiler cannot tell at compile time. The runtime flag would be present in every single variable, disabled y -release and/or it's own compile time flag (perhaps disabled by default like -unittest) Regan
Jun 30 2005
On Thu, 30 Jun 2005 19:52:53 -0700, Andrew Fedoniouk <news terrainformatica.com> wrote:Readonly flag is technicaly difficult and inefficient to implement.The runtime or the compile time one? (you seem not to realise I am talking about *both*)Any access to the pointer(sic!) and array shall check first this flag in runtime.Yes. When you enable the runtime DBC feature you'll get this, just like array bounds checks.Second problem is that you need to store somewhere this bit. Where?1 bit in every single variable.Proposed solution is just static (compile time) test.Mine is first a compile time suggestion, followed by a runtime one (as it's been shown that some cases exist where compile time check is impossible)Moving conditions which can be checked in compile to runtime is generally not a good idea - non-efficient and difficult to verify in full.Like I said above, my primary suggestion is a compile time one, it has been shown not all cases can be verified at compile time, as such a runtime solution is required.To be short, in runtime you may get following:<snip> I can't see how this is even relevant. ReganAndrew. "Regan Heath" <regan netwin.co.nz> wrote in message news:opss7fh6dr23k2f5 nrage.netwin.co.nz...On Thu, 30 Jun 2005 11:19:38 -0700, Walter <newshound digitalmars.com> wrote:What is the difference between that and C++'s const as a type modifier? C++: typename const * Proposal:Nothing, which is why I prefer the idea I've been bandying (sp?) around here for the past month. Please read carefully this is _not_ the same thing. A readonly compile time, and perhaps also runtime (disabled for -release) readonly bit flag for all variables. Initialised to 'false'. Set to 'true' in the presence of "readonly" as a type modifier. Set to 'true' when passed as an 'in' parameter. Compiler errors on all operations that mutate a readonly flagged variable. Example usage: class Foo { char[] data; readonly char[] get() { return data; } } void foo(inout char[] data) { data[0] = 'a'; } Foo f = new Foo(); char[] p = f.get(); p[0] = 'a'; //error cannot mutate readonly foo(p); //error passing readonly as mutable void foo(char[] data) { data[0] = 'a'; } //error cannot mutate readonly IMPORTANT: this does not create a seperate distinct type, "readonly char[]" is not a different type to "char[]" it's the same type with it's readonly flag set to 'true'. The reason this is important is that it stops this situation... char[] s; ..s used as temp var here.. readonly char[] p = f.get(); s = p; //error s is not readonly Which is just plain irritating. People typically solve the above by casting the readonly away. Not good. In the above 's's readonly flag is set on assignment, it becomes readonly. The readonly flag would be set to false when passed as 'out', or on assignment to a rhs which has readonly=false (including null). A runtime flag is required for cases like: char[] p = test ? some_string : f.get(); p[1] = 'd'; //is 'p' readonly if some_string isn't? where the compiler cannot tell at compile time. The runtime flag would be present in every single variable, disabled y -release and/or it's own compile time flag (perhaps disabled by default like -unittest) Regan
Jun 30 2005
"Regan Heath" <regan netwin.co.nz> wrote in message news:opss7xxlgs23k2f5 nrage.netwin.co.nz...On Thu, 30 Jun 2005 19:52:53 -0700, Andrew Fedoniouk <news terrainformatica.com> wrote:The question is: where this bit is located? array variable is 32bit ptr (64bit) and 32bit (64bit) length. pointer variable is 32bit (64bit). So where is the place for it? In additional machine word which will be assosiated with each variable?Readonly flag is technicaly difficult and inefficient to implement.The runtime or the compile time one? (you seem not to realise I am talking about *both*)Any access to the pointer(sic!) and array shall check first this flag in runtime.Yes. When you enable the runtime DBC feature you'll get this, just like array bounds checks.Second problem is that you need to store somewhere this bit. Where?1 bit in every single variable.Universal solution is to have opAssign, etc. So extreme cases can be handled by declaring your own structures/classes. Having hidden bit (if it is possible at all) for only arrays and pointers is little bit unnatural, imho.Proposed solution is just static (compile time) test.Mine is first a compile time suggestion, followed by a runtime one (as it's been shown that some cases exist where compile time check is impossible)Moving conditions which can be checked in compile to runtime is generally not a good idea - non-efficient and difficult to verify in full.Like I said above, my primary suggestion is a compile time one, it has been shown not all cases can be verified at compile time, as such a runtime solution is required.To be short, in runtime you may get following:<snip> I can't see how this is even relevant. ReganAndrew. "Regan Heath" <regan netwin.co.nz> wrote in message news:opss7fh6dr23k2f5 nrage.netwin.co.nz...On Thu, 30 Jun 2005 11:19:38 -0700, Walter <newshound digitalmars.com> wrote:What is the difference between that and C++'s const as a type modifier? C++: typename const * Proposal:Nothing, which is why I prefer the idea I've been bandying (sp?) around here for the past month. Please read carefully this is _not_ the same thing. A readonly compile time, and perhaps also runtime (disabled or -release) readonly bit flag for all variables. Initialised to 'false'. Set to 'true' in the presence of "readonly" as a type modifier. Set to 'true' when passed as an 'in' parameter. Compiler errors on all operations that mutate a readonly flagged variable. Example usage: class Foo { char[] data; readonly char[] get() { return data; } } void foo(inout char[] data) { data[0] = 'a'; } Foo f = new Foo(); char[] p = f.get(); p[0] = 'a'; //error cannot mutate readonly foo(p); //error passing readonly as mutable void foo(char[] data) { data[0] = 'a'; } //error cannot mutate readonly IMPORTANT: this does not create a seperate distinct type, "readonly char[]" is not a different type to "char[]" it's the same type with it's readonly flag set to 'true'. The reason this is important is that it stops this situation... char[] s; ..s used as temp var here.. readonly char[] p = f.get(); s = p; //error s is not readonly Which is just plain irritating. People typically solve the above by casting the readonly away. Not good. In the above 's's readonly flag is set on assignment, it becomes readonly. The readonly flag would be set to false when passed as 'out', or on assignment to a rhs which has readonly=false (including null). A runtime flag is required for cases like: char[] p = test ? some_string : f.get(); p[1] = 'd'; //is 'p' readonly if some_string isn't? where the compiler cannot tell at compile time. The runtime flag would be present in every single variable, disabled y -release and/or it's own compile time flag (perhaps disabled by default like -unittest) Regan
Jun 30 2005
On Thu, 30 Jun 2005 23:10:00 -0700, Andrew Fedoniouk <news terrainformatica.com> wrote:"Regan Heath" <regan netwin.co.nz> wrote in message news:opss7xxlgs23k2f5 nrage.netwin.co.nz...If that is what is required, yes.On Thu, 30 Jun 2005 19:52:53 -0700, Andrew Fedoniouk <news terrainformatica.com> wrote:The question is: where this bit is located? array variable is 32bit ptr (64bit) and 32bit (64bit) length. pointer variable is 32bit (64bit). So where is the place for it? In additional machine word which will be assosiated with each variable?Readonly flag is technicaly difficult and inefficient to implement.The runtime or the compile time one? (you seem not to realise I am talking about *both*)Any access to the pointer(sic!) and array shall check first this flag in runtime.Yes. When you enable the runtime DBC feature you'll get this, just like array bounds checks.Second problem is that you need to store somewhere this bit. Where?1 bit in every single variable.That doesn't give us immutable char[].Universal solution is to have opAssign, etc.Proposed solution is just static (compile time) test.Mine is first a compile time suggestion, followed by a runtime one (as it's been shown that some cases exist where compile time check is impossible)Moving conditions which can be checked in compile to runtime is generally not a good idea - non-efficient and difficult to verify in full.Like I said above, my primary suggestion is a compile time one, it has been shown not all cases can be verified at compile time, as such a runtime solution is required.So extreme cases can be handled by declaring your own structures/classes. Having hidden bit (if it is possible at all) for only arrays and pointers is little bit unnatural, imho.Not just arrays and pointers, everything, even UDT's. Regan
Jun 30 2005
"Regan Heath" <regan netwin.co.nz> wrote in message news:opss714rpw23k2f5 nrage.netwin.co.nz...On Thu, 30 Jun 2005 23:10:00 -0700, Andrew Fedoniouk <news terrainformatica.com> wrote:So -release will have sizeof(void*) == 32 and otherwise sizeof(void*) == 64. Do you *really* think this is a solution?"Regan Heath" <regan netwin.co.nz> wrote in message news:opss7xxlgs23k2f5 nrage.netwin.co.nz...If that is what is required, yes.On Thu, 30 Jun 2005 19:52:53 -0700, Andrew Fedoniouk <news terrainformatica.com> wrote:The question is: where this bit is located? array variable is 32bit ptr (64bit) and 32bit (64bit) length. pointer variable is 32bit (64bit). So where is the place for it? In additional machine word which will be assosiated with each variable?Readonly flag is technicaly difficult and inefficient to implement.The runtime or the compile time one? (you seem not to realise I am talking about *both*)Any access to the pointer(sic!) and array shall check first this flag in runtime.Yes. When you enable the runtime DBC feature you'll get this, just like array bounds checks.Second problem is that you need to store somewhere this bit. Where?1 bit in every single variable.It will give you an option: struct chars { private char[] data; bit mutableBit; void opAssign(chars rightSide) { if(!mutableBit) throw new WellKnownAndExpectedExceptionAndNotAnError; ... } }That doesn't give us immutable char[].Universal solution is to have opAssign, etc.Proposed solution is just static (compile time) test.Mine is first a compile time suggestion, followed by a runtime one (as it's been shown that some cases exist where compile time check is impossible)Moving conditions which can be checked in compile to runtime is generally not a good idea - non-efficient and difficult to verify in full.Like I said above, my primary suggestion is a compile time one, it has been shown not all cases can be verified at compile time, as such a runtime solution is required.So extreme cases can be handled by declaring your own structures/classes. Having hidden bit (if it is possible at all) for only arrays and pointers is little bit unnatural, imho.Not just arrays and pointers, everything, even UDT's. Regan
Jul 01 2005
On Fri, 1 Jul 2005 00:35:38 -0700, Andrew Fedoniouk <news terrainformatica.com> wrote:Yes. Almost all cases are handled at *compile* time, there are very few cases which cannot be handled at compile time. As such the runtime solution is a very small piece of the overall solution. It's optional, can be disabled by a switch, and would *only* be used during the design stage just like the other DBC features.So -release will have sizeof(void*) == 32 and otherwise sizeof(void*) == 64. Do you *really* think this is a solution?If that is what is required, yes.1 bit in every single variable.The question is: where this bit is located? array variable is 32bit ptr (64bit) and 32bit (64bit) length. pointer variable is 32bit (64bit). So where is the place for it? In additional machine word which will be assosiated with each variable?D does not need a string class. ReganIt will give you an option: struct chars { private char[] data; bit mutableBit; void opAssign(chars rightSide) { if(!mutableBit) throw new WellKnownAndExpectedExceptionAndNotAnError; ... } }That doesn't give us immutable char[].Universal solution is to have opAssign, etc.Proposed solution is just static (compile time) test.Mine is first a compile time suggestion, followed by a runtime one (as it's been shown that some cases exist where compile time check is impossible)Moving conditions which can be checked in compile to runtime is generally not a good idea - non-efficient and difficult to verify in full.Like I said above, my primary suggestion is a compile time one, it has been shown not all cases can be verified at compile time, as such a runtime solution is required.
Jul 01 2005
I recently forgot my 'other' option for runtime 'readonly' checking of "in" parameters, this solution uses in/out contracts, eg. import std.stdio; import std.string; import std.c.stdlib; void main() { char[] a = "regan"; foo(a); } void* cmp = null; void foo(char[] string) in { cmp = realloc(cmp,string.sizeof); memcpy(cmp,&string,string.sizeof); } out { assert(memcmp(cmp,&string,string.sizeof) == 0); } body { //this causes the assert, remove it, no assert. string.length = 20; } As you can see it simply makes a duplicate of the 'in' parameter then compares the parameter with the duplicate upon completion of the function. This is better than a readonly flag in every object as it saves memory overall. It is worse in that it doesn't tell you exactly where it was modified, just that it was modified somewhere in that function. This idea doesn't necessarily help us with "const" labelled returns eg. class Foo { private char[] data; const char[] get() { return data[0..5]; } } char[] p = f.get(); char[] s = b ? p : "foo"; //where b is determined at runtime. s[0] = 'a'; However a copy could be setup when f.get() returned and checked when 'p' went out of scope. This sounds difficult ot implement to me however. Regan On Fri, 01 Jul 2005 19:46:23 +1200, Regan Heath <regan netwin.co.nz> wrote:On Fri, 1 Jul 2005 00:35:38 -0700, Andrew Fedoniouk <news terrainformatica.com> wrote:Yes. Almost all cases are handled at *compile* time, there are very few cases which cannot be handled at compile time. As such the runtime solution is a very small piece of the overall solution. It's optional, can be disabled by a switch, and would *only* be used during the design stage just like the other DBC features.So -release will have sizeof(void*) == 32 and otherwise sizeof(void*) == 64. Do you *really* think this is a solution?If that is what is required, yes.1 bit in every single variable.The question is: where this bit is located? array variable is 32bit ptr (64bit) and 32bit (64bit) length. pointer variable is 32bit (64bit). So where is the place for it? In additional machine word which will be assosiated with each variable?D does not need a string class. ReganIt will give you an option: struct chars { private char[] data; bit mutableBit; void opAssign(chars rightSide) { if(!mutableBit) throw new WellKnownAndExpectedExceptionAndNotAnError; ... } }That doesn't give us immutable char[].Universal solution is to have opAssign, etc.Proposed solution is just static (compile time) test.Mine is first a compile time suggestion, followed by a runtime one (as it's been shown that some cases exist where compile time check is impossible)Moving conditions which can be checked in compile to runtime is generally not a good idea - non-efficient and difficult to verify in full.Like I said above, my primary suggestion is a compile time one, it has been shown not all cases can be verified at compile time, as such a runtime solution is required.
Jul 01 2005
"Walter" <newshound digitalmars.com> wrote in message news:da1d5u$1kdf$1 digitaldaemon.com...What is the difference between that and C++'s const as a type modifier? C++: typename const * Proposal:C++'s const typename * -or- typename const * It is a 'mutable pointer to immutable data.' I think that proposed singular form But again it is a personal matter. Andrew.
Jun 30 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da024r$65o$1 digitaldaemon.com...I would like to discuss one of my previous ideas again as it seems it was lost in the fire.I've been discussing this issue with Andrei (of Modern C++ Design fame). He points out that there are numerous different "const" semantics, each having their uses and disadvantages. He suggests that all should be supported in one way or another, and I agree that that would have some advantages. One of my (several) dislikes with "const" is that most (90% ?) of a function's parameters are likely to be "const". So one winds up with the C++ aesthetically ugly consequence of "const" here, there, everywhere. And you can't use it casually here and there, once you start down the road of making a few functions have "const" parameters, you've got to do it throughout the program. So perhaps one could turn that inside out, and make "const" the default for function parameters. If the parameter was to be changed, it'd be explicitly marked as "mutable" or some such. But that runs into another problem. Function local variables, on the other hand, one would want to be "mutable" by default. There's also the issue that "const" already exists as a variable storage class. So far, I haven't thought of anything that makes consistent sense, and doesn't look like an ugly hack. One thing I have thought of is a compromise. Change the semantics of explicitly "in" parameters to be what Andrei calls "deep immutable". Deep immutable parameters would have unchanging values for the scope of that parameter, and also every sub-object reachable by that parameter would also be unchangeable. The values wouldn't change even by another reference or another thread. (This is quite unlike C++ "const".) "in" would be a promise by the programmer, and could not be guaranteed by the compiler - but - the optimizer can take advantage of this promise to generate perhaps significantly better code. (With C++ "const", values can change at any momen t by another reference or another thread, making optimizations based on "const" impossible.) C++ "const" is enforced by the compiler, but is useless semantic information. "in" is not enforced by the compiler beyond the trivial, but is useful semantic information.
Jul 01 2005
On Fri, 1 Jul 2005 01:34:31 -0700, Walter <newshound digitalmars.com> wrote:But that runs into another problem. Function local variables, on the other hand, one would want to be "mutable" by default.By function local do you mean "a" or "b" below? void foo(char[] a) { char[] b; } Regan
Jul 01 2005
I think he means "b". As opposed to parameter in variables, like "a". --AJG. In article <opss8aohii23k2f5 nrage.netwin.co.nz>, Regan Heath says...On Fri, 1 Jul 2005 01:34:31 -0700, Walter <newshound digitalmars.com> wrote:But that runs into another problem. Function local variables, on the other hand, one would want to be "mutable" by default.By function local do you mean "a" or "b" below? void foo(char[] a) { char[] b; } Regan
Jul 01 2005
If he does, then why can't all 'in' parameters be immutable. 'in' is the default parameter type, so all variables would be immutable by default. No 'const' (or whatever keyword is used) everywhere. I've always thought 'in' was part of the function contract stating "I only need read access to this", this change would actually enforce that. If a mutable copy was required then: void foo(char[] a) { char[] b = a.dup; } would work. It could even be optimised by the compiler. I imagine the compiler is already making a dup of the variable which is passed (as it does for value types), this would make a second one, it could optimise one of those duplicates away. Regan On Fri, 1 Jul 2005 13:20:18 +0000 (UTC), AJG <AJG_member pathlink.com> wrote:I think he means "b". As opposed to parameter in variables, like "a". --AJG. In article <opss8aohii23k2f5 nrage.netwin.co.nz>, Regan Heath says...On Fri, 1 Jul 2005 01:34:31 -0700, Walter <newshound digitalmars.com> wrote:But that runs into another problem. Function local variables, on the other hand, one would want to be "mutable" by default.By function local do you mean "a" or "b" below? void foo(char[] a) { char[] b; } Regan
Jul 01 2005
Hi,One of my (several) dislikes with "const" is that most (90% ?) of a function's parameters are likely to be "const". So one winds up with the C++ aesthetically ugly consequence of "const" here, there, everywhere. And you can't use it casually here and there, once you start down the road of making a few functions have "const" parameters, you've got to do it throughout the program.Very true.One thing I have thought of is a compromise. Change the semantics of explicitly "in" parameters to be what Andrei calls "deep immutable". Deep immutable parameters would have unchanging values for the scope of that parameter, and also every sub-object reachable by that parameter would also be unchangeable.This would be fantastic, IMHO. It makes perfect sense, and we get the best of both worlds. [a] Immutable variables exactly where we need them; and [b] the simple aesthetic syntax. This should have always been the default, and it definitely gets my vote by far. Cheers, --AJG. ======================= I sync, therefore I am.
Jul 01 2005
In article <da2v7t$b9b$1 digitaldaemon.com>, Walter says...One thing I have thought of is a compromise. Change the semantics of explicitly "in" parameters to be what Andrei calls "deep immutable". Deep immutable parameters would have unchanging values for the scope of that parameter, and also every sub-object reachable by that parameter would also be unchangeable. The values wouldn't change even by another reference or another thread. (This is quite unlike C++ "const".) "in" would be a promise by the programmer, and could not be guaranteed by the compiler - but - the optimizer can take advantage of this promise to generate perhaps significantly better code. (With C++ "const", values can change at any momen t by another reference or another thread, making optimizations based on "const" impossible.)This sounds great. In this scenario, can I store the in object (or its sub objects) to a local variable? If so it would be immutable too I would guess, but is there a special syntax? (Or is slicing, etc forbidden in these cases?) :void foo(in int[] x) :{ : int[] middle1 = x[1..$-1]; // is middle implicitely immutable? : in int[] middle2 = x[1..$-1]; // explicitly marked as immutable? : middle[0] = middle1[1]; // this should fail to compile right? :}C++ "const" is enforced by the compiler, but is useless semantic information. "in" is not enforced by the compiler beyond the trivial, but is useful semantic information.Kevin
Jul 01 2005
"Kevin Bealer" <Kevin_member pathlink.com> wrote in message news:da3ppb$1h97$1 digitaldaemon.com...This sounds great. In this scenario, can I store the in object (or itssubobjects) to a local variable? If so it would be immutable too I wouldguess,but is there a special syntax? (Or is slicing, etc forbidden in thesecases?):void foo(in int[] x) :{ : int[] middle1 = x[1..$-1]; // is middle implicitely immutable?I don't see how to make that work right. The only thing I can think of is to allow middle1 to modify x, but that such modification would be undefined behavior. Not so hot.: in int[] middle2 = x[1..$-1]; // explicitly marked as immutable?There I hate using 'in' as a storage class. It's confusing with 'const'.: middle[0] = middle1[1]; // this should fail to compile right?Yes. That's one case the compiler should pick up.
Jul 01 2005
In article <da3ug1$1n4l$1 digitaldaemon.com>, Walter says..."Kevin Bealer" <Kevin_member pathlink.com> wrote in message news:da3ppb$1h97$1 digitaldaemon.com...I think in this case a copy would need to be made. ie. int[] middle1 = x[1..$-1].dup; This is no different than when a programmer wants to modify a const parameter in C++. I'm not sure that there's a good way to enforce this in the compiler, though it might be nice if there were a way to verify that a parameter is unchanged via DBC. Perhaps something like this? void fn( in int[] x ) in { preserve int[] p = x.dup; } out { assert( x == p ); } or perhaps: void fn( in int[] x ) int[] p; in { p = x.dup; } .. SeanThis sounds great. In this scenario, can I store the in object (or itssubobjects) to a local variable? If so it would be immutable too I wouldguess,but is there a special syntax? (Or is slicing, etc forbidden in thesecases?):void foo(in int[] x) :{ : int[] middle1 = x[1..$-1]; // is middle implicitely immutable?I don't see how to make that work right. The only thing I can think of is to allow middle1 to modify x, but that such modification would be undefined behavior. Not so hot.
Jul 01 2005
Walter escribió:One thing I have thought of is a compromise. Change the semantics of explicitly "in" parameters to be what Andrei calls "deep immutable". Deep immutable parameters would have unchanging values for the scope of that parameter, and also every sub-object reachable by that parameter would also be unchangeable. The values wouldn't change even by another reference or another thread. (This is quite unlike C++ "const".) "in" would be a promise by the programmer, and could not be guaranteed by the compiler - but - the optimizer can take advantage of this promise to generate perhaps significantly better code. (With C++ "const", values can change at any momen t by another reference or another thread, making optimizations based on "const" impossible.)I think that's similar to what Pascal does, and that's something I agree with. One point that isn't addressed yet (I think) is returning something: can it be modified? What happens if it's modified? etc. -- Carlos Santander Bernal
Jul 01 2005
"Carlos Santander" <csantander619 gmail.com> wrote in message news:da4e0i$27v9$1 digitaldaemon.com...One point that isn't addressed yet (I think) is returning something: can it be modified? What happens if it's modified? etc.With the 'in' compromise, it doesn't address return values.
Jul 02 2005
"Walter" <newshound digitalmars.com> wrote in message news:da2v7t$b9b$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da024r$65o$1 digitaldaemon.com...One other thought - Make it so that an "explicit in" makes a copy as it does now, and the default (non-specified) param. storage class is "deep immutable". Pointer params would act the same as they do now regardless, and functions with extern(...) would be exempt as well. If pointers were taken out of the picture, why couldn't the compiler catch cases like below? class C { ... } void foo(C c, int[] arr) { // Errors c = new C; c.i = 10; int* z = &c.i; bar(c); C x = c; arr = new int[20]; arr[10] = 10; arr[] = 0; int[] b = arr; int[] b4 = arr[0..10]; int* y = &a[5]; // Ok int[] b2 = arr.dup; int[] b3 = arr[]; int[] b5 = arr[0..10].dup; int* p = cast(int*)&a[6]; void* v = cast(void*)&a[6]; *(cast(int*)v) = 700; baz(c); } void bar(inout C x) { ... } void baz(C x) { ... } In all those cases either the param is directly an lvalue /or/ the address of the param is directly taken, or the same for a member of an aggregate. The spec. would explicitly say "the compiler is responsible for checking /only/ for cases where "either the param (or one of it's aggragate members) is directly assigned to, the address of the param (or one of its aggragate members) is directly taken or the param (or an aggregate member) is directly passed into a function via an out or inout parameter. All other cases are undefined."I would like to discuss one of my previous ideas again as it seems it was lost in the fire.So far, I haven't thought of anything that makes consistent sense, and doesn't look like an ugly hack. One thing I have thought of is a compromise. Change the semantics of explicitly "in" parameters to be what Andrei calls "deep immutable". Deep immutable parameters would have unchanging values for the scope of that parameter, and also every sub-object reachable by that parameter would also be unchangeable. The values wouldn't change even by another reference or another thread. (This is quite unlike C++ "const".) "in" would be a promise by the programmer, and could not be guaranteed by the compiler - but - the optimizer can take advantage of this promise to generate perhaps significantly better code. (With C++ "const", values can change at any momen t by another reference or another thread, making optimizations based on "const" impossible.)
Jul 02 2005
"Walter" <newshound digitalmars.com> wrote in message news:da2v7t$b9b$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da024r$65o$1 digitaldaemon.com...I guess I don't understand why this is a problem because there has always been a 'seperation' and distinction between locals and params to me. I realize there is a union of scope inside the function and they share many of the same syntax and semantic rules as variables, but I've always considered them two seperate and distinct groups of vars. I think most non-newbie programmers realize this and recognize that any params passed by reference also 'live' outside of the function. Why do you think a typical programmer would be completely put off by the idea that an 'implicit in' param couldn't be modified, while by default a local variable could (especially if the compiler would constantly reinforce the idea that "hey - D's default params are different" by reporting trivial-case errors)? Thanks, - DaveI would like to discuss one of my previous ideas again as it seems it was lost in the fire.I've been discussing this issue with Andrei (of Modern C++ Design fame). He points out that there are numerous different "const" semantics, each having their uses and disadvantages. He suggests that all should be supported in one way or another, and I agree that that would have some advantages. One of my (several) dislikes with "const" is that most (90% ?) of a function's parameters are likely to be "const". So one winds up with the C++ aesthetically ugly consequence of "const" here, there, everywhere. And you can't use it casually here and there, once you start down the road of making a few functions have "const" parameters, you've got to do it throughout the program. So perhaps one could turn that inside out, and make "const" the default for function parameters. If the parameter was to be changed, it'd be explicitly marked as "mutable" or some such. But that runs into another problem. Function local variables, on the other hand, one would want to be "mutable" by default. There's also the issue that "const" already exists as a variable storage class.
Jul 04 2005