digitalmars.D - Round II, Re: Immutable arrays for Walter and rest of us.
- Andrew Fedoniouk (68/116) Jul 01 2005 I think that "deep immutables" ((C) Andrei Alexandrescu, I guess)
- Ben Hinkle (23/83) Jul 01 2005 How would this cover the following case that Walter's proposal covers:
- Andrew Fedoniouk (42/143) Jul 01 2005 in/inout/out describes mechanism of passing parameters - by ref or by va...
- Walter (10/28) Jul 02 2005 It's
- Ben Hinkle (8/41) Jul 02 2005 Personally I'm also surprised people are so paranoid in D about possible...
- Andrew Fedoniouk (25/70) Jul 02 2005 "Java and C# don't have const"
- Stefan Zobel (11/36) Jul 02 2005 Hi Andrew,
- Andrew Fedoniouk (13/69) Jul 04 2005 (Sorry, missed your message initially)
- Ben Hinkle (15/89) Jul 02 2005 Currently D's final is more limited than Java's but I have always assume...
- Andrew Fedoniouk (44/145) Jul 02 2005 Yes, Java::final is not a C::const (it cannot protect references).
- Walter (8/16) Jul 02 2005 The COW rule for when to .dup is:
- Andrew Fedoniouk (18/36) Jul 02 2005 In real projects and in real life this *not sure* is almost always.
- Walter (14/52) Jul 03 2005 the
- Andrew Fedoniouk (31/90) Jul 03 2005 Absolutely true. This is why e.g. string literals
- Walter (9/67) Jul 03 2005 It is an error in C++ to do that, though it is allowed by some compilers...
- Andrew Fedoniouk (11/93) Jul 03 2005 Delphi:
- Andrew Fedoniouk (11/44) Jul 02 2005 "This is why I am often flummoxed why it is given such weight in C++."
- Andrew Fedoniouk (4/4) Jul 02 2005 One more:
- Walter (9/13) Jul 02 2005 Java only has top level const (final). Any data referred to by a final
- Andrew Fedoniouk (4/19) Jul 02 2005 Mea culpa. Was too optimistic about Java/C# .
- Walter (8/13) Jul 02 2005 Yet the value can change anyway. Another reference can change it, and
- Andrew Fedoniouk (33/50) Jul 02 2005 Right!
- Walter (17/35) Jul 03 2005 In following COW principles, you do not need to dup the slice when retur...
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (23/32) Jul 03 2005 No offense, but didn't you design the language and string handling ? :-)
- Stefan Zobel (7/14) Jul 03 2005 For what it's worth, that String isn't immutable in Java/C# sense, is it...
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (15/18) Jul 03 2005 This goes for most implementations of toString(), I guess ?
- Andrew Fedoniouk (16/33) Jul 03 2005 Exactly!
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (20/25) Jul 03 2005 The only problem being that in/out just affects the pointer/array ref,
- Stefan Zobel (24/42) Jul 03 2005 Yep, exactly.
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (10/27) Jul 03 2005 I simply meant that even when you *do* have "const char[]" (or similar),
- Stefan Zobel (6/33) Jul 04 2005 Ok, point taken. It's a COW string intended to be used as such.
- Walter (13/45) Jul 03 2005 strings.
- Sean Kelly (10/28) Jul 03 2005 To me, C++ 'const' just a means of indicating, in code, that a value is ...
- AJG (60/72) Jul 02 2005 I can't fathom that the compiler can't make use of the fact that you are...
- Andrew Fedoniouk (40/131) Jul 03 2005 Thanks, AJG, excellent statement.
- Walter (24/30) Jul 03 2005 The
- AJG (21/47) Jul 03 2005 Hm... that's an interesting situation. Ok, say pointers are not consider...
- Walter (24/73) Jul 03 2005 be
- Andrew Fedoniouk (27/58) Jul 03 2005 Walter, it is enough for me to know that
- Dave (16/85) Jul 03 2005 The whole problem is, with the C++ rules, the optimizations cannot even ...
- Andrew Fedoniouk (29/131) Jul 03 2005 Again I am willing to write to functions which provided
- Dave (49/85) Jul 03 2005 I understand - I think we're all looking for some way to implement
- Andrew Fedoniouk (26/125) Jul 03 2005 '"const" storage modifier is not going to happen,...'
- Walter (29/53) Jul 03 2005 codegenerator
- Andrew Fedoniouk (30/97) Jul 03 2005 True.
- Walter (7/19) Jul 04 2005 I will argue that you cannot tell that - especially if you are looking f...
- Andrew Fedoniouk (21/47) Jul 04 2005 const helps me to do not do bugs. To change what is not
- Unknown W. Brackets (14/48) Jul 04 2005 Well, now, I have a question. What does this say:
- Sean Kelly (3/21) Jul 03 2005 Why do I suddenly feel like we're moving towards defining 'restrict' in ...
- Dave (4/31) Jul 03 2005 Take a peek in the archives on that subject - I don't think you need to ...
- Nick (17/20) Jul 03 2005 That is true, but also in fact completly irrelevant. I think you might h...
- Walter (16/36) Jul 03 2005 have
- Regan Heath (33/75) Jul 03 2005 This is the same point I've tried to make in the past. To me 'in' is par...
- Dave (15/48) Jul 03 2005 It is equally probable that another thread could step on obj within the
- Ben Hinkle (6/59) Jul 03 2005 You're right - the threading model shouldn't enter into it. I'm liking
- Dave (22/86) Jul 03 2005 I think Walter's idea is a great idea and a good compromise!
- Andrew Fedoniouk (27/117) Jul 03 2005 1) How in will solve this:
- Walter (15/55) Jul 03 2005 It won't, but then again, I don't see that the .dup is necessary there, ...
- Ben Hinkle (3/15) Jul 03 2005 Perhaps dstyle.html should say functions with a leading 'to' should not
- Walter (3/6) Jul 03 2005 That's a good idea. There are also the 'is' prefix functions.
- Andrew Fedoniouk (11/17) Jul 03 2005 I beleive that next will be a proposal to use 'c' as a first
- Ben Hinkle (11/32) Jul 03 2005 Nothing is preventing someone from writing
- Andrew Fedoniouk (7/45) Jul 03 2005 Ben, am I propsing to abuse naming conventions? No.
- Victor Nakoryakov (10/14) Jul 04 2005 Emmmm... All speaking russian use english for variables/methods/classes
- Andrew Fedoniouk (16/92) Jul 03 2005 Walter, imagine that you know nothing about internals
- Walter (4/5) Jul 03 2005 I'm afraid not. Take a look at the STL source code :-( Go into
- Andrew Fedoniouk (15/91) Jul 03 2005 1 ) There are situations when you just cannot use different names.
"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 think that "deep immutables" ((C) Andrei Alexandrescu, I guess) are ideal but too deep to be considered as a solution for practical (read fast) compiler. L-value analysis in this case might be a) cyclic (not sure but highly suspect this) and b) too complex - depth of trees. ----------------------------- I would like to emphasize my proposal again: First of all: D already has mechanism to force (to implement) deep immutability. class Immutable { public int prop() { ... } [private] int prop(int v) { assert(false); } SomeObject propO() { return ([this is immutable])? new Immutable(): new Mutable(); } } As you can see mutating properties/methods can be disabled at compile time ( private accessor ) and/or at runtime ( assert-throw ) Main logical/design conflict is: there is no such (available to developer) mechanism for arrays and pointers. They are 'naked' - always mutable. Main idea of my proposal is in defining new array and pointer types: immutable array and immutable pointer. Let's say that D array type internally declared as primitive "[ ]" (T) { private T *_ptr; private uint _length; T * ptr() { return _ptr; } private void ptr(T *) { } // ptr is not an L-value. uint length() { return _length; } uint length(uint nl) { resize(); return _length; } void opIndexAssign(int index, T v) { _ptr[ index ] = v; } void opAssign(struct "[ ]" (T) r) { _ptr = r._ptr; _length = r._length; } } { private uint _length; uint length() { return _length; } private uint length(uint nl) { resize(); return _length; } // no such op available private void opIndexAssign(int index, T v); // no such op available private void opAssign(struct "[ ]" (T) r); // no such op available // but this one is here - immutable <- immutable : r._length; } } Having it you'll close the only one "immutability hole" left in D. Again, structs and classes already have a protection layer availbale - you can always create a protecting perimeter for your classes/structs: public property-methods and just methods of any needed depth. You can return from functions mutable or immutable struct and class instances using various policies. perfect) - *all* D types will have an option to be immutable. Andrew.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
How would this cover the following case that Walter's proposal covers: class A { int x; } void foo(in A obj){ int y = obj.x; // do whatever you want... assert( obj.x == y ); } void main() { A obj = new A; foo(obj); // says it doesn't change obj } Is it practical to force A to implement some immutability just because foo doesn't change its inputs? I'm not saying Walter's proposal is prefect. It's very strong for foo to say no other thread or reference will change obj since it has no control over what other threads are doing. I would be taking pretty much blind leap of faith when declaring an object reference as 'in' and saying that no other thread is stepping on that object during the call lifetime.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.I think that "deep immutables" ((C) Andrei Alexandrescu, I guess) are ideal but too deep to be considered as a solution for practical (read fast) compiler. L-value analysis in this case might be a) cyclic (not sure but highly suspect this) and b) too complex - depth of trees. ----------------------------- I would like to emphasize my proposal again: First of all: D already has mechanism to force (to implement) deep immutability. class Immutable { public int prop() { ... } [private] int prop(int v) { assert(false); } SomeObject propO() { return ([this is immutable])? new Immutable(): new Mutable(); } } As you can see mutating properties/methods can be disabled at compile time ( private accessor ) and/or at runtime ( assert-throw )Main logical/design conflict is: there is no such (available to developer) mechanism for arrays and pointers. They are 'naked' - always mutable. Main idea of my proposal is in defining new array and pointer types: immutable array and immutable pointer.Let's say that D array type internally declared as[snip]The complexity of the implementation is one thing - another is the impact of introducing a new array type (and pointer type) on existing and future user code.Having it you'll close the only one "immutability hole" left in D. Again, structs and classes already have a protection layer availbale - you can always create a protecting perimeter for your classes/structs: public property-methods and just methods of any needed depth. You can return from functions mutable or immutable struct and class instances using various policies. perfect) - *all* D types will have an option to be immutable. Andrew.
Jul 01 2005
"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:da4afr$24jc$1 digitaldaemon.com...in/inout/out describes mechanism of passing parameters - by ref or by value. foo( in char[] str ) means that value of str will not be changed after return from function. But it does not disallow you to change the value of str is pointing to. This makes perfect sense for me. and as by definition of immutable array content pointed by str.ptr will not be changed. all have usable sense as do foo( in char[] str ) foo( inout char[] str ) foo( out char[] str ) Please don't change this. in is not a const in any sense. 'in' does not allow you to have immutable arrays as properties - and this is imho most valueable thing. allow you and compiler to distinguish cases: foo( char[] str ) thus to build more optimal code structure. With just 'in' it is impossible. Remeber duscussed problem with stream.scanf parameters?How would this cover the following case that Walter's proposal covers: class A { int x; } void foo(in A obj){ int y = obj.x; // do whatever you want... assert( obj.x == y ); } void main() { A obj = new A; foo(obj); // says it doesn't change obj } Is it practical to force A to implement some immutability just because foo doesn't change its inputs? I'm not saying Walter's proposal is prefect. It's very strong for foo to say no other thread or reference will change obj since it has no control over what other threads are doing. I would be taking pretty much blind leap of faith when declaring an object reference as 'in' and saying that no other thread is stepping on that object during the call lifetime.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.I think that "deep immutables" ((C) Andrei Alexandrescu, I guess) are ideal but too deep to be considered as a solution for practical (read fast) compiler. L-value analysis in this case might be a) cyclic (not sure but highly suspect this) and b) too complex - depth of trees. ----------------------------- I would like to emphasize my proposal again: First of all: D already has mechanism to force (to implement) deep immutability. class Immutable { public int prop() { ... } [private] int prop(int v) { assert(false); } SomeObject propO() { return ([this is immutable])? new Immutable(): new Mutable(); } } As you can see mutating properties/methods can be disabled at compile time ( private accessor ) and/or at runtime ( assert-throw )Pretty much as '+ =' and '+='Main logical/design conflict is: there is no such (available to developer) mechanism for arrays and pointers. They are 'naked' - always mutable. Main idea of my proposal is in defining new array and pointer types: immutable array and immutable pointer.Existing code will not be impacted heavily. It depends of what static array will be. significantly simplify life and make D clear. Now it is just sequence of "why's" - why it allowed here and not there. First step - to make it compileable is 15 minutes - exactly the same amount of time it took me to replace all inner classes with static inner classes.Let's say that D array type internally declared as[snip]simple.The complexity of the implementation is one thing - another is the impact of introducing a new array type (and pointer type) on existing and future user code.Having it you'll close the only one "immutability hole" left in D. Again, structs and classes already have a protection layer availbale - you can always create a protecting perimeter for your classes/structs: public property-methods and just methods of any needed depth. You can return from functions mutable or immutable struct and class instances using various policies. (almost perfect) - *all* D types will have an option to be immutable. Andrew.
Jul 01 2005
"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:da4afr$24jc$1 digitaldaemon.com...How would this cover the following case that Walter's proposal covers: class A { int x; } void foo(in A obj){ int y = obj.x; // do whatever you want... assert( obj.x == y ); } void main() { A obj = new A; foo(obj); // says it doesn't change obj } Is it practical to force A to implement some immutability just because foo doesn't change its inputs? I'm not saying Walter's proposal is prefect.It'svery strong for foo to say no other thread or reference will change obj since it has no control over what other threads are doing. I would betakingpretty much blind leap of faith when declaring an object reference as 'in' and saying that no other thread is stepping on that object during the call lifetime.You're right. I have misgivings about it for that reason. On the other hand, look at C++ "const". Nothing about "const" says that some other thread or reference cannot change the value out from under you at any moment. Furthermore, it can be cast away and modified anyway. The semantic value of C++ "const" is essentially zip. This is why I am often flummoxed why it is given such weight in C++.
Jul 02 2005
"Walter" <newshound digitalmars.com> wrote in message news:da6k71$11rs$1 digitaldaemon.com..."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:da4afr$24jc$1 digitaldaemon.com...Personally I'm also surprised people are so paranoid in D about possible COW violations. What's the phrase from Spiderman ... "with great power comes great responsibility" :-) Granted in Java people IMO overcompensate by dup'ing too often so I hope D users don't go that route.How would this cover the following case that Walter's proposal covers: class A { int x; } void foo(in A obj){ int y = obj.x; // do whatever you want... assert( obj.x == y ); } void main() { A obj = new A; foo(obj); // says it doesn't change obj } Is it practical to force A to implement some immutability just because foo doesn't change its inputs? I'm not saying Walter's proposal is prefect.It'svery strong for foo to say no other thread or reference will change obj since it has no control over what other threads are doing. I would betakingpretty much blind leap of faith when declaring an object reference as 'in' and saying that no other thread is stepping on that object during the call lifetime.You're right. I have misgivings about it for that reason. On the other hand, look at C++ "const". Nothing about "const" says that some other thread or reference cannot change the value out from under you at any moment. Furthermore, it can be cast away and modified anyway. The semantic value of C++ "const" is essentially zip. This is why I am often flummoxed why it is given such weight in C++.
Jul 02 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da7fo5$bje$1 digitaldaemon.com..."Walter" <newshound digitalmars.com> wrote in message news:da6k71$11rs$1 digitaldaemon.com...Umm... Java has 'final' keyword. You define an entity once and cannot change it or derive from it later. More specifically: a final class cannot be subclassed, a final method cannot be overridden and a final variable cannot change from its initialized value. Function parameters can also be declared as final. in declaration of function parameters. is protecting also references. E.g. you cannot say "hello"[0] = 'b'; And more regarding strings in these systems: Java/.NET String "package" consist of 1) String class (immutable) and 2) StringBuffer (mutable) class Literal strings there are instances of String class which is immutable, sic! I would like to highlight this again: In modern programming systems string implementation is a bundle of friendly value classes (immutable) and buffer (mutable) classes. D currently has only StringBuffer (sort of)."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:da4afr$24jc$1 digitaldaemon.com...Personally I'm also surprised people are so paranoid in D about possible COW violations. What's the phrase from Spiderman ... "with great power comes great responsibility" :-) Granted in Java people IMO overcompensate by dup'ing too often so I hope D users don't go that route.How would this cover the following case that Walter's proposal covers: class A { int x; } void foo(in A obj){ int y = obj.x; // do whatever you want... assert( obj.x == y ); } void main() { A obj = new A; foo(obj); // says it doesn't change obj } Is it practical to force A to implement some immutability just because foo doesn't change its inputs? I'm not saying Walter's proposal is prefect.It'svery strong for foo to say no other thread or reference will change obj since it has no control over what other threads are doing. I would betakingpretty much blind leap of faith when declaring an object reference as 'in' and saying that no other thread is stepping on that object during the call lifetime.You're right. I have misgivings about it for that reason. On the other hand, look at C++ "const". Nothing about "const" says that some other thread or reference cannot change the value out from under you at any moment. Furthermore, it can be cast away and modified anyway. The semantic value of C++ "const" is essentially zip. This is why I am often flummoxed why it is given such weight in C++.
Jul 02 2005
In article <da7i52$cv9$1 digitaldaemon.com>, Andrew Fedoniouk says..."Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da7fo5$bje$1 digitaldaemon.com... Umm... Java has 'final' keyword. You define an entity once and cannot change it or derive from it later. More specifically: a final class cannot be subclassed, a final method cannot be overridden and a final variable cannot change from its initialized value. Function parameters can also be declared as final. in declaration of function parameters. is protecting also references. E.g. you cannot say "hello"[0] = 'b'; And more regarding strings in these systems: Java/.NET String "package" consist of 1) String class (immutable) and 2) StringBuffer (mutable) class Literal strings there are instances of String class which is immutable, sic! I would like to highlight this again: In modern programming systems string implementation is a bundle of friendly value classes (immutable) and buffer (mutable) classes. D currently has only StringBuffer (sort of).Hi Andrew, hhm, I agree with most of your points here. You once said in this discussion that it is impossible to implement something like Java String in D. Apart from D string literals (char[]), I fail to see why. Could you please explain? Kind regards, Stefan (Of course, I think, we all agree that unnecessary dup'ing is undesirable, but that doesn't render it "impossible").
Jul 02 2005
"Stefan Zobel" <Stefan_member pathlink.com> wrote in message news:da7jlk$dtk$1 digitaldaemon.com...In article <da7i52$cv9$1 digitaldaemon.com>, Andrew Fedoniouk says...(Sorry, missed your message initially) Strictly speaking it is possible to define String in D with exact set of methods and behavior as Java string. Mea culpa - I was not exact in terms. I mean it is almost impossible to use such String effectively. System and OS functions demands char* which you cannot get from String by its specification. Powerfull mechanism of slices is also lost here. Yes, as you mentioned, you can dup on each opSlice call but this is not a practical option. Again beg my pardon. Andrew."Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da7fo5$bje$1 digitaldaemon.com... Umm... Java has 'final' keyword. You define an entity once and cannot change it or derive from it later. More specifically: a final class cannot be subclassed, a final method cannot be overridden and a final variable cannot change from its initialized value. Function parameters can also be declared as final. and in declaration of function parameters. is protecting also references. E.g. you cannot say "hello"[0] = 'b'; And more regarding strings in these systems: Java/.NET String "package" consist of 1) String class (immutable) and 2) StringBuffer (mutable) class Literal strings there are instances of String class which is immutable, sic! I would like to highlight this again: In modern programming systems string implementation is a bundle of friendly value classes (immutable) and buffer (mutable) classes. D currently has only StringBuffer (sort of).Hi Andrew, hhm, I agree with most of your points here. You once said in this discussion that it is impossible to implement something like Java String in D. Apart from D string literals (char[]), I fail to see why. Could you please explain? Kind regards, Stefan (Of course, I think, we all agree that unnecessary dup'ing is undesirable, but that doesn't render it "impossible").
Jul 04 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7i52$cv9$1 digitaldaemon.com..."Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da7fo5$bje$1 digitaldaemon.com...Currently D's final is more limited than Java's but I have always assumed D's final will eventually match Java's. It still isn't the same as C++'s const, though."Walter" <newshound digitalmars.com> wrote in message news:da6k71$11rs$1 digitaldaemon.com...Umm... Java has 'final' keyword. You define an entity once and cannot change it or derive from it later. More specifically: a final class cannot be subclassed, a final method cannot be overridden and a final variable cannot change from its initialized value. Function parameters can also be declared as final."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:da4afr$24jc$1 digitaldaemon.com...Personally I'm also surprised people are so paranoid in D about possible COW violations. What's the phrase from Spiderman ... "with great power comes great responsibility" :-) Granted in Java people IMO overcompensate by dup'ing too often so I hope D users don't go that route.How would this cover the following case that Walter's proposal covers: class A { int x; } void foo(in A obj){ int y = obj.x; // do whatever you want... assert( obj.x == y ); } void main() { A obj = new A; foo(obj); // says it doesn't change obj } Is it practical to force A to implement some immutability just because foo doesn't change its inputs? I'm not saying Walter's proposal is prefect.It'svery strong for foo to say no other thread or reference will change obj since it has no control over what other threads are doing. I would betakingpretty much blind leap of faith when declaring an object reference as 'in' and saying that no other thread is stepping on that object during the call lifetime.You're right. I have misgivings about it for that reason. On the other hand, look at C++ "const". Nothing about "const" says that some other thread or reference cannot change the value out from under you at any moment. Furthermore, it can be cast away and modified anyway. The semantic value of C++ "const" is essentially zip. This is why I am often flummoxed why it is given such weight in C++.and in declaration of function parameters. say "hello"[0] = 'b';Sure, but this, too, isn't const. D has getters and setters so one can make you mean by "is protecting also references". The example you give is of a as far as I know. How does one make a non-string reference const?And more regarding strings in these systems: Java/.NET String "package" consist of 1) String class (immutable) and 2) StringBuffer (mutable) class Literal strings there are instances of String class which is immutable, sic!It's also probably the most common use of const in C++. To me that isn't enough reason to introduce const, though.I would like to highlight this again: In modern programming systems string implementation is a bundle of friendly value classes (immutable) and buffer (mutable) classes. D currently has only StringBuffer (sort of).Why bother with multiple types/classes when D already spanks the competition with one? We should keep things as simple as possible.
Jul 02 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da7mmr$fjl$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7i52$cv9$1 digitaldaemon.com...Yes, Java::final is not a C::const (it cannot protect references). Java::final is exactly D::const now except of Java::final can be used in function parameters declaration and D's counterpart - cannot. I have no idea of what D::final means. It is defined as a keyword but have no meaning so far, AFAIK. (correct me.)"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da7fo5$bje$1 digitaldaemon.com...Currently D's final is more limited than Java's but I have always assumed D's final will eventually match Java's. It still isn't the same as C++'s const, though."Walter" <newshound digitalmars.com> wrote in message news:da6k71$11rs$1 digitaldaemon.com...Umm... Java has 'final' keyword. You define an entity once and cannot change it or derive from it later. More specifically: a final class cannot be subclassed, a final method cannot be overridden and a final variable cannot change from its initialized value. Function parameters can also be declared as final."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:da4afr$24jc$1 digitaldaemon.com...Personally I'm also surprised people are so paranoid in D about possible COW violations. What's the phrase from Spiderman ... "with great power comes great responsibility" :-) Granted in Java people IMO overcompensate by dup'ing too often so I hope D users don't go that route.How would this cover the following case that Walter's proposal covers: class A { int x; } void foo(in A obj){ int y = obj.x; // do whatever you want... assert( obj.x == y ); } void main() { A obj = new A; foo(obj); // says it doesn't change obj } Is it practical to force A to implement some immutability just because foo doesn't change its inputs? I'm not saying Walter's proposal is prefect.It'svery strong for foo to say no other thread or reference will change obj since it has no control over what other threads are doing. I would betakingpretty much blind leap of faith when declaring an object reference as 'in' and saying that no other thread is stepping on that object during the call lifetime.You're right. I have misgivings about it for that reason. On the other hand, look at C++ "const". Nothing about "const" says that some other thread or reference cannot change the value out from under you at any moment. Furthermore, it can be cast away and modified anyway. The semantic value of C++ "const" is essentially zip. This is why I am often flummoxed why it is given such weight in C++.( http://en.wikipedia.org/wiki/Const_correctness ) too. Neither do Java. But they do have immutable strings, you are right higlighting this.and in declaration of function parameters. say "hello"[0] = 'b';Sure, but this, too, isn't const. D has getters and setters so one can what you mean by "is protecting also references". The example you give is keyword as far as I know. How does one make a non-string reference const?std.openrj.d: class Record { Field[] fields() { return m_fields.dup; } } Do you like this dup? class Field { final char[] name() { return m_name; } } Pay attention that std.openrj is an attempt to create OOP, reusable, effective and robust library module in D. Lack of constness is seen in each class of it.And more regarding strings in these systems: Java/.NET String "package" consist of 1) String class (immutable) and 2) StringBuffer (mutable) class Literal strings there are instances of String class which is immutable, sic!It's also probably the most common use of const in C++. To me that isn't enough reason to introduce const, though.Agreed in principle, but "simple as possible" does not mean "sancta simplicitas", right? "I'll give you my slice and don't forget to dup it as it is not yours." This does not work in serious programming as slice creation happens in one place and its consuming in galaxy far far away and code of three developers happens in between. It is EXTREMELY difficult to debug. I know. It happened to me once in Harmonia and I wasted almost three days to catch it. Sigh... And I was designing it by myself - not even in team... Andrew.I would like to highlight this again: In modern programming systems string implementation is a bundle of friendly value classes (immutable) and buffer (mutable) classes. D currently has only StringBuffer (sort of).Why bother with multiple types/classes when D already spanks the competition with one? We should keep things as simple as possible.
Jul 02 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7s6r$jcd$1 digitaldaemon.com..."I'll give you my slice and don't forget to dup it as it is not yours." This does not work in serious programming as slice creation happens in one place and its consuming in galaxy far far away and code of three developers happens in between. It is EXTREMELY difficult to debug. I know. It happened to me once in Harmonia and I wasted almost three days to catch it. Sigh... And I was designing it by myself - not even in team...The COW rule for when to .dup is: When you're going to change the data, and you're not *sure* you're the sole handle to it. I don't see why the need is there for m_fields.dup in openrj.d. Preemptively duping something by the provider is the wrong approach to COW. Duping should be done by the consumer of it, and then only if the consumer modifies it.
Jul 02 2005
"Walter" <newshound digitalmars.com> wrote in message news:da7u7k$kkh$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7s6r$jcd$1 digitaldaemon.com...In real projects and in real life this *not sure* is almost always."I'll give you my slice and don't forget to dup it as it is not yours." This does not work in serious programming as slice creation happens in one place and its consuming in galaxy far far away and code of three developers happens in between. It is EXTREMELY difficult to debug. I know. It happened to me once in Harmonia and I wasted almost three days to catch it. Sigh... And I was designing it by myself - not even in team...The COW rule for when to .dup is: When you're going to change the data, and you're not *sure* you're the sole handle to it.I don't see why the need is there for m_fields.dup in openrj.d. Preemptively duping something by the provider is the wrong approach to COW. Duping should be done by the consumer of it, and then only if the consumer modifies it.I know this theory. The whole team are C++ programmers. They get used to const. And you know.... this is really a "code culture" thing - respect of developers who are working with you and using your code. const - it is mine - don't touch it. no const - it is yours. And C++ compiler helps us a lot here to prevent stupid mistakes. All most respectfull C++ guys are unified in 'const is good'' http://artima.com/intv/const.html Shall I tell my team that const is wrong because: "it is useless for optimizing"? I'll never will do that, sorry. pointers are so effective but dangerous. without const they are dangerous in order of magnitude. The same apply to D slices. Andrew.
Jul 02 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da818n$md2$1 digitaldaemon.com..."Walter" <newshound digitalmars.com> wrote in message news:da7u7k$kkh$1 digitaldaemon.com...the"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7s6r$jcd$1 digitaldaemon.com..."I'll give you my slice and don't forget to dup it as it is not yours." This does not work in serious programming as slice creation happens in one place and its consuming in galaxy far far away and code of three developers happens in between. It is EXTREMELY difficult to debug. I know. It happened to me once in Harmonia and I wasted almost three days to catch it. Sigh... And I was designing it by myself - not even in team...The COW rule for when to .dup is: When you're going to change the data, and you're not *sure* you'reTrue, but it's also true that most of the time, one doesn't care because one has no need to modify the data.sole handle to it.In real projects and in real life this *not sure* is almost always.it.I don't see why the need is there for m_fields.dup in openrj.d. Preemptively duping something by the provider is the wrong approach to COW. Duping should be done by the consumer of it, and then only if the consumer modifiesI know this theory. The whole team are C++ programmers. They get used to const. And you know.... this is really a "code culture" thing - respect of developers who are working with you and using your code. const - it is mine - don't touch it. no const - it is yours. And C++ compiler helps us a lot here to prevent stupid mistakes. All most respectfull C++ guys are unified in 'const is good'' http://artima.com/intv/const.html Shall I tell my team that const is wrong because: "it is useless for optimizing"? I'll never will do that, sorry.C++ const benefits are greater than zero, even though it is useless to the optimizer as it gives no meaningful semantic information.pointers are so effective but dangerous. without const they are dangerous in order of magnitude. The same apply to D slices.I find it curious that many features of C++ have leaked out into other languages, but not const. I agree with you that C++ has a culture of "const is good". I'd like to find something better, something that works (i.e. that gives useful semantic information). I also am not understanding how const would help with COW mistakes.
Jul 03 2005
"Walter" <newshound digitalmars.com> wrote in message news:da888e$rhs$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da818n$md2$1 digitaldaemon.com...Absolutely true. This is why e.g. string literals shall have type const char[] and not just a char[] by default. This is stupid design mistake in C++: "hello"[0] = 0; will compile and run on one machines and will not on others."Walter" <newshound digitalmars.com> wrote in message news:da7u7k$kkh$1 digitaldaemon.com...the"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7s6r$jcd$1 digitaldaemon.com..."I'll give you my slice and don't forget to dup it as it is not yours." This does not work in serious programming as slice creation happens in one place and its consuming in galaxy far far away and code of three developers happens in between. It is EXTREMELY difficult to debug. I know. It happened to me once in Harmonia and I wasted almost three days to catch it. Sigh... And I was designing it by myself - not even in team...The COW rule for when to .dup is: When you're going to change the data, and you're not *sure* you'reTrue, but it's also true that most of the time, one doesn't care because one has no need to modify the data.sole handle to it.In real projects and in real life this *not sure* is almost always.Walter, need of const appears together with raw pointers. It is critical to have pointers (slices included) together with const. If some language takes ++ from C but not pointers then it does not need const so much. There is no language in active use which has raw pointers and has no concept of pointers to const data. Even C. It had no const from the very beginning. But C99 (year of 1999, sic) has it. const is simply a type designator: const typename* and typename* *are* different types - with different behavior. Combining them in one entity as you did in D design is exactly the same as having only one int type without unsigned counterpart.it.I don't see why the need is there for m_fields.dup in openrj.d. Preemptively duping something by the provider is the wrong approach to COW. Duping should be done by the consumer of it, and then only if the consumer modifiesI know this theory. The whole team are C++ programmers. They get used to const. And you know.... this is really a "code culture" thing - respect of developers who are working with you and using your code. const - it is mine - don't touch it. no const - it is yours. And C++ compiler helps us a lot here to prevent stupid mistakes. All most respectfull C++ guys are unified in 'const is good'' http://artima.com/intv/const.html Shall I tell my team that const is wrong because: "it is useless for optimizing"? I'll never will do that, sorry.C++ const benefits are greater than zero, even though it is useless to the optimizer as it gives no meaningful semantic information.pointers are so effective but dangerous. without const they are dangerous in order of magnitude. The same apply to D slices.I find it curious that many features of C++ have leaked out into other languages, but not const.I agree with you that C++ has a culture of "const is good". I'd like to find something better, something that works (i.e. that gives useful semantic information). I also am not understanding how const would help with COW mistakes.What are the "COW mistakes"? I don't understand this exactly.... Anyway.... void toLower(in char[] str) char[] toLower(in const char[] str) Having them both is a matter of optimization. First does transformation in place, second allocates new string. Do these two together make sense? Definitely, yes.
Jul 03 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da97g2$1l30$1 digitaldaemon.com..."Walter" <newshound digitalmars.com> wrote in message news:da888e$rhs$1 digitaldaemon.com...It is an error in C++ to do that, though it is allowed by some compilers for backwards compatibility. In C++, string literals are const char*."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da818n$md2$1 digitaldaemon.com...Absolutely true. This is why e.g. string literals shall have type const char[] and not just a char[] by default. This is stupid design mistake in C++: "hello"[0] = 0; will compile and run on one machines and will not on others."Walter" <newshound digitalmars.com> wrote in message news:da7u7k$kkh$1 digitaldaemon.com...the"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7s6r$jcd$1 digitaldaemon.com..."I'll give you my slice and don't forget to dup it as it is not yours." This does not work in serious programming as slice creation happens in one place and its consuming in galaxy far far away and code of three developers happens in between. It is EXTREMELY difficult to debug. I know. It happened to me once in Harmonia and I wasted almost three days to catch it. Sigh... And I was designing it by myself - not even in team...The COW rule for when to .dup is: When you're going to change the data, and you're not *sure* you'reTrue, but it's also true that most of the time, one doesn't care because one has no need to modify the data.sole handle to it.In real projects and in real life this *not sure* is almost always.Walter, need of const appears together with raw pointers. It is critical to have pointers (slices included) together with const. If some language takes ++ from C but not pointers then it does not need const so much. There is no language in active use which has raw pointers and has no concept of pointers to const data.I don't know of any language that even allows raw pointers other than C, C++ and D!A COW mistake would be, for example, modifying a reference when you aren't sure you're the owner of it.I agree with you that C++ has a culture of "const is good". I'd like to find something better, something that works (i.e. that gives useful semantic information). I also am not understanding how const would help with COW mistakes.What are the "COW mistakes"? I don't understand this exactly....Anyway.... void toLower(in char[] str) char[] toLower(in const char[] str) Having them both is a matter of optimization. First does transformation in place, second allocates new string. Do these two together make sense? Definitely, yes.See my comments on this example in another post here.
Jul 03 2005
"Walter" <newshound digitalmars.com> wrote in message news:da9dc2$1r5s$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da97g2$1l30$1 digitaldaemon.com...Delphi: function CopyStr(const aSourceString : string; aStart, aLength : Integer) : string;"Walter" <newshound digitalmars.com> wrote in message news:da888e$rhs$1 digitaldaemon.com...It is an error in C++ to do that, though it is allowed by some compilers for backwards compatibility. In C++, string literals are const char*."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da818n$md2$1 digitaldaemon.com...Absolutely true. This is why e.g. string literals shall have type const char[] and not just a char[] by default. This is stupid design mistake in C++: "hello"[0] = 0; will compile and run on one machines and will not on others."Walter" <newshound digitalmars.com> wrote in message news:da7u7k$kkh$1 digitaldaemon.com...the"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7s6r$jcd$1 digitaldaemon.com..."I'll give you my slice and don't forget to dup it as it is not yours." This does not work in serious programming as slice creation happens in one place and its consuming in galaxy far far away and code of three developers happens in between. It is EXTREMELY difficult to debug. I know. It happened to me once in Harmonia and I wasted almost three days to catch it. Sigh... And I was designing it by myself - not even in team...The COW rule for when to .dup is: When you're going to change the data, and you're not *sure* you'reTrue, but it's also true that most of the time, one doesn't care because one has no need to modify the data.sole handle to it.In real projects and in real life this *not sure* is almost always.Walter, need of const appears together with raw pointers. It is critical to have pointers (slices included) together with const. If some language takes ++ from C but not pointers then it does not need const so much. There is no language in active use which has raw pointers and has no concept of pointers to const data.I don't know of any language that even allows raw pointers other than C, C++ and D!See, I even don't know about these errors as I am using void foo(const char[] s) { s[0] = 0; // here compiler rises an error - warnig me.... } Is it bad?A COW mistake would be, for example, modifying a reference when you aren't sure you're the owner of it.I agree with you that C++ has a culture of "const is good". I'd like to find something better, something that works (i.e. that gives useful semantic information). I also am not understanding how const would help with COW mistakes.What are the "COW mistakes"? I don't understand this exactly....Anyway.... void toLower(in char[] str) char[] toLower(in const char[] str) Having them both is a matter of optimization. First does transformation in place, second allocates new string. Do these two together make sense? Definitely, yes.See my comments on this example in another post here.
Jul 03 2005
"Walter" <newshound digitalmars.com> wrote in message news:da6k71$11rs$1 digitaldaemon.com..."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:da4afr$24jc$1 digitaldaemon.com..."This is why I am often flummoxed why it is given such weight in C++." Walter, consider 'const' as just any other access specifier: private, public, protected, etc. "const" has pretty much the same usability weight as these. const is not a physical protection. And never was. It is logical declaration of intention: I am not going to change this parameter or value it is refereing, so, compiler, please, warn me if I'll do this accidentally.How would this cover the following case that Walter's proposal covers: class A { int x; } void foo(in A obj){ int y = obj.x; // do whatever you want... assert( obj.x == y ); } void main() { A obj = new A; foo(obj); // says it doesn't change obj } Is it practical to force A to implement some immutability just because foo doesn't change its inputs? I'm not saying Walter's proposal is prefect.It'svery strong for foo to say no other thread or reference will change obj since it has no control over what other threads are doing. I would betakingpretty much blind leap of faith when declaring an object reference as 'in' and saying that no other thread is stepping on that object during the call lifetime.You're right. I have misgivings about it for that reason. On the other hand, look at C++ "const". Nothing about "const" says that some other thread or reference cannot change the value out from under you at any moment. Furthermore, it can be cast away and modified anyway. The semantic value of C++ "const" is essentially zip. This is why I am often flummoxed why it is given such weight in C++.
Jul 02 2005
One more: has concept of const (parameters and references) and these are the most popular languages so far.
Jul 02 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7jil$dsm$1 digitaldaemon.com...One more: has concept of const (parameters and references) and these are the most popular languages so far.Java only has top level const (final). Any data referred to by a final reference can be changed through that reference (or any other reference to the same object). About the only value it has other than simple constant folding (as pointed out by Matthew) is that any uninitialized finals must be initialized exactly once in the constructors. As far as preventing a function from modifying the fields of a 'final' reference parameter, it is useless.
Jul 02 2005
"Walter" <newshound digitalmars.com> wrote in message news:da7t1t$jth$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7jil$dsm$1 digitaldaemon.com...Working horses C, C++, Delphi still there though.One more: has concept of const (parameters and references) and these are the most popular languages so far.Java only has top level const (final). Any data referred to by a final reference can be changed through that reference (or any other reference to the same object). About the only value it has other than simple constant folding (as pointed out by Matthew) is that any uninitialized finals must be initialized exactly once in the constructors. As far as preventing a function from modifying the fields of a 'final' reference parameter, it is useless.
Jul 02 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7j26$dkb$1 digitaldaemon.com...const is not a physical protection. And never was. It is logical declaration of intention: I am not going to change this parameter or value it is refereing, so, compiler, please, warn me if I'll do this accidentally.Yet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct". The C++ const is *completely useless* to the compiler optimizer for that reason. A const thing that instead, is a guarantee that the underlying values won't change, is actually useful. An optimizer can do a lot with it.
Jul 02 2005
"Walter" <newshound digitalmars.com> wrote in message news:da7pp5$i06$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7j26$dkb$1 digitaldaemon.com...Right! Let's throw out private, protected, etc. As they are: (here goes citation of your statement above) Who the hell started this 'canard' (hoax, fr.) that const is for compiler optimization? const is a basic of DbC. It is a contrct. Not more not less. const references allows to mininimize needless memory allocations in design. This is true. And this is how 'const' helps optimization. Best optimizer is you and me - not a compiler. Table at bottom of http://www.terrainformatica.com/htmlayout/ It is not about const but const was a significant part of it.const is not a physical protection. And never was. It is logical declaration of intention: I am not going to change this parameter or value it is refereing, so, compiler, please, warn me if I'll do this accidentally.Yet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct". The C++ const is *completely useless* to the compiler optimizer for that reason.A const thing that instead, is a guarantee that the underlying values won't change, is actually useful. An optimizer can do a lot with it.ooohh... could you first provide me an option to *declare* e.g. slice as immutable thus I'll be able to return it from function without duping it? *That* would be optimization. Walter, again, what language are you going to substitute by D? What is the main target? C/C++? If yes then they have const references. and very desireable with slices - they are extremely useful and are making D so attractive (among other good and useful features). Again, in my opinion 1) const references - const arrays and pointers 2) opAssign/dtors in structures are the *only* things left in D not-implemented from C++ feature set. If they will be there you and anyone can honestly say "D is next letter after C and C++" as it allows you to do *everything* that you can in C++ and it has much more "well done" features - true next step. Andrew.
Jul 02 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7ulp$kub$1 digitaldaemon.com...ooohh... could you first provide me an option to *declare* e.g. slice as immutable thus I'll be able to return it from function without duping it? *That* would be optimization.In following COW principles, you do not need to dup the slice when returning it. The producer of the value doesn't need to dup it, the *consumer* does, and only if the *consumer* modifies it. Taking a slice of an array does not modify it in any way, so no dup is required. So I am not understanding why const or immutable is needed for D strings. I've written a number of string processing programs in D (including a macro text processor, and the silly program that transforms newsgroup postings into the "archive" pages), and didn't have any difficulty with D strings. They went together with much less effort and far fewer bugs than their C++ counterparts.Walter, again, what language are you going to substitute by D? What is the main target? C/C++? If yes then they have const references. and very desireable with slices - they are extremely useful and are making D so attractive (among other good and useful features). Again, in my opinion 1) const references - const arrays and pointers 2) opAssign/dtors in structures are the *only* things left in D not-implemented from C++ feature set. If they will be there you and anyone can honestly say "D is next letter after C and C++" as it allows you to do *everything* that you can in C++ and it has much more "well done" features - true next step.Unfortunately, there are several other "must haves" various people want D to have. I do understand the desire for const. But there are many different ways to approach the problem, and I'm not willing to just duplicate the C++ const with all its weaknesses and problems. There's got to be a better way.
Jul 03 2005
Walter wrote:So I am not understanding why const or immutable is needed for D strings. I've written a number of string processing programs in D (including a macro text processor, and the silly program that transforms newsgroup postings into the "archive" pages), and didn't have any difficulty with D strings. They went together with much less effort and far fewer bugs than their C++ counterparts.No offense, but didn't you design the language and string handling ? :-) I've written several segfaults by changing "readonly" literals, and gotten some strange results by setting hash string keys without duping them first (and then later changing the value of the string, that is...) I also think it's pretty easy to "mess up" when using any array slices. It would be great if there were some "extra mechanism" enforcing CoW.I do understand the desire for const. But there are many different ways to approach the problem, and I'm not willing to just duplicate the C++ const with all its weaknesses and problems. There's got to be a better way.It would nice to come up with an approach that would: a) default local strings/arrays to read-write b) default external parameters to read-only "in"/"out" doesn't really work, since it only affects the array pointer/length and not the actually characters. Maybe something like "char[out] string", but that looks a little like a variable... Anyway, I wouldn't want to see "const" (or "readonly", "immutable") all over the place either - better to have a "readwrite" or "mutable" keyword for the (few?) cases when you *do* want to modify the contents ? I guess it's the D Gentlemen's Agreement, while keeping on searching. (it's easy enough* to implement java.lang.String and StringBuffer in D, but I'm still hoping there is some compromise between "C" and "Java") --anders * PS. Here's one such hack (mostly for the discussion really) http://www.algonet.se/~afb/d/dcaf/html/class_string.html http://www.algonet.se/~afb/d/dcaf/html/class_string_buffer.html
Jul 03 2005
In article <da8but$t3j$1 digitaldaemon.com>, =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...I guess it's the D Gentlemen's Agreement, while keeping on searching. (it's easy enough* to implement java.lang.String and StringBuffer in D, but I'm still hoping there is some compromise between "C" and "Java") --anders * PS. Here's one such hack (mostly for the discussion really) http://www.algonet.se/~afb/d/dcaf/html/class_string.html http://www.algonet.se/~afb/d/dcaf/html/class_string_buffer.htmlEvery time you hand out a char[], you give the caller a reference to your internal member. Should be a "return str.dup;" :-( Best regards, Stefan
Jul 03 2005
Stefan Zobel wrote:Every time you hand out a char[], you give the caller a reference to your internal member. Should be a "return str.dup;" :-(This goes for most implementations of toString(), I guess ? This actually would be the key issue we are debating here... The char[] that is given out *is* read-only, there's just no way of indicating that - except for the Gentlemen's Agreement. And, no, it should NOT be a dup (as my "StringBuffer" did do that). It's _supposed_ to return a reference to the (immutable) contents. And you could still peek and poke it by casting to char* and changing the memory inside, but that's besides the point here. I don't think that D needs a string class, but "something else" ? I like the current strings, it's just that they are (or: could be) a little dangerous - just like a raw char* in C could be, I guess. But for C/C++ there is "const" - D needs something similar, but better. --anders
Jul 03 2005
"Anders F Björklund" <afb algonet.se> wrote in message news:da8ivk$12cm$1 digitaldaemon.com...Stefan Zobel wrote:Exactly! You can theoretically reproduce String (immutable string value) which will be *completely useles and inneffective*. What is the point to have String which you cannot use e.g. here: FILE * fopen([const] char* path, [const] char* flags); ?Every time you hand out a char[], you give the caller a reference to your internal member. Should be a "return str.dup;" :-(This goes for most implementations of toString(), I guess ? This actually would be the key issue we are debating here... The char[] that is given out *is* read-only, there's just no way of indicating that - except for the Gentlemen's Agreement.And, no, it should NOT be a dup (as my "StringBuffer" did do that). It's _supposed_ to return a reference to the (immutable) contents. And you could still peek and poke it by casting to char* and changing the memory inside, but that's besides the point here. I don't think that D needs a string class, but "something else" ? I like the current strings, it's just that they are (or: could be) a little dangerous - just like a raw char* in C could be, I guess.Agreed, String as a class is not needed in D. But String as an entity consist of two things: and string manipulation buffer (array): char[]. And this *duo* is the must for success.But for C/C++ there is "const" - D needs something similar, but better.D already has better part - in, inout, out. These combined with const *is* better from notational point of view than in current C/C++.
Jul 03 2005
Andrew Fedoniouk wrote:The only problem being that in/out just affects the pointer/array ref, where it works fine already, but not the actual contents of the array... In some ways, that is similar to how passing an object reference to a function allows it to change internal state of the object passed. But the difference is of course that the object is changed through methods while the array passed could be modified "behind your back". So we still need some "mutable" attribute to give to strings/arrays, and something like "char[out] string" might work - but is rather ugly ? and would rather have both "mutable char[]" (as well as "static if"...) Assuming here that C++-style "const" is the default for a parameter, and that it would be more useful to have a keyword for the opposite. But I think that it's a _very_ good chance that this ends up like the booleans, with some syntax approaching the real thing but not enforced. How it is *supposed* to work is pretty clear from the Copy-on-Write ? It's just that there is not too much "checking" from the D compiler... For me it's not really a show-stopper, just a(nother) small annoyance. The string handling in D still rocks when compared to what old C had. --andersBut for C/C++ there is "const" - D needs something similar, but better.D already has better part - in, inout, out. These combined with const *is* better from notational point of view than in current C/C++.
Jul 03 2005
In article <da8ivk$12cm$1 digitaldaemon.com>, =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...Stefan Zobel wrote:Yep, exactly.Every time you hand out a char[], you give the caller a reference to your internal member. Should be a "return str.dup;" :-(This goes for most implementations of toString(), I guess ? This actually would be the key issue we are debating here...The char[] that is given out *is* read-only, there's just no way of indicating that - except for the Gentlemen's Agreement.I understand the "philosophical" point here. I was just pointing out that, technically (current D), it is not.And, no, it should NOT be a dup (as my "StringBuffer" did do that). It's _supposed_ to return a reference to the (immutable) contents.Hhm, "_supposed_". Not sure, if I can follow you here, but that may be because english is not my mother tongue (also didn't take a look at StringBuffer). The fact remains, that (to be really immutable) it must be a dup in D as it is right now.And you could still peek and poke it by casting to char* and changing the memory inside, but that's besides the point here.void main () { String mutableString = new String("immutable!"); writefln(mutableString); char[] ref = mutableString.toString(); ref[9] = '?'; writefln(mutableString); } No "peeking and poking" here, just a realistic use case. But I'm convinced you know that. So, presumably I simply didn't get your point?I don't think that D needs a string class, but "something else" ? I like the current strings, it's just that they are (or: could be) a little dangerous - just like a raw char* in C could be, I guess. But for C/C++ there is "const" - D needs something similar, but better. --andersAgreed, we wouldn't need a string class (could save on all that duping) if we had a way to declare const/immutable/... references in D. Just wanted to remark that String.d isn't immutable, nothing more. No offense intended :) Kind regards, Stefan
Jul 03 2005
Stefan Zobel wrote:I simply meant that even when you *do* have "const char[]" (or similar), you can still (implicitly?) cast it to a pointer in D and change away... Then again, introducing such a new thing would probably be accompanied by "const char*" too, which any "const char[]" would return for .ptr ?And you could still peek and poke it by casting to char* and changing the memory inside, but that's besides the point here.void main () { String mutableString = new String("immutable!"); writefln(mutableString); char[] ref = mutableString.toString(); ref[9] = '?'; writefln(mutableString); } No "peeking and poking" here, just a realistic use case. But I'm convinced you know that. So, presumably I simply didn't get your point?Agreed, we wouldn't need a string class (could save on all that duping) if we had a way to declare const/immutable/... references in D. Just wanted to remark that String.d isn't immutable, nothing more. No offense intended :)As pointed out by others, could take toString out - making it useless. And this is not only "toString", but also toCodePoints and opSlice - and probably most other similar member functions returing arrays... ? They are all read-only and "protected" by the Copy-on-Write convention. --anders
Jul 03 2005
In article <daali1$5mn$1 digitaldaemon.com>, =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...Stefan Zobel wrote:Ok, point taken. It's a COW string intended to be used as such. Thanks for the clarification. Best regards, StefanI simply meant that even when you *do* have "const char[]" (or similar), you can still (implicitly?) cast it to a pointer in D and change away... Then again, introducing such a new thing would probably be accompanied by "const char*" too, which any "const char[]" would return for .ptr ?And you could still peek and poke it by casting to char* and changing the memory inside, but that's besides the point here.void main () { String mutableString = new String("immutable!"); writefln(mutableString); char[] ref = mutableString.toString(); ref[9] = '?'; writefln(mutableString); } No "peeking and poking" here, just a realistic use case. But I'm convinced you know that. So, presumably I simply didn't get your point?Agreed, we wouldn't need a string class (could save on all that duping) if we had a way to declare const/immutable/... references in D. Just wanted to remark that String.d isn't immutable, nothing more. No offense intended :)As pointed out by others, could take toString out - making it useless. And this is not only "toString", but also toCodePoints and opSlice - and probably most other similar member functions returing arrays... ? They are all read-only and "protected" by the Copy-on-Write convention. --anders
Jul 04 2005
"Anders F Björklund" <afb algonet.se> wrote in message news:da8but$t3j$1 digitaldaemon.com...Walter wrote:strings.So I am not understanding why const or immutable is needed for DmacroI've written a number of string processing programs in D (including astrings.text processor, and the silly program that transforms newsgroup postings into the "archive" pages), and didn't have any difficulty with DC++They went together with much less effort and far fewer bugs than theirYup (with some help from others like Jan Knepper and Arcane Jill), but it did go through a few iterations.counterparts.No offense, but didn't you design the language and string handling ? :-)I've written several segfaults by changing "readonly" literals, and gotten some strange results by setting hash string keys without duping them first (and then later changing the value of the string, that is...) I also think it's pretty easy to "mess up" when using any array slices.There is a mindset to COW that takes some getting used to.It would be great if there were some "extra mechanism" enforcing CoW.I agree, but I am not convinced that "const" is it.toI do understand the desire for const. But there are many different waysconstapproach the problem, and I'm not willing to just duplicate the C++Yes.with all its weaknesses and problems. There's got to be a better way.It would nice to come up with an approach that would: a) default local strings/arrays to read-write b) default external parameters to read-only "in"/"out" doesn't really work, since it only affects the array pointer/length and not the actually characters. Maybe something like "char[out] string", but that looks a little like a variable... Anyway, I wouldn't want to see "const" (or "readonly", "immutable") all over the place either - better to have a "readwrite" or "mutable" keyword for the (few?) cases when you *do* want to modify the contents ?I guess it's the D Gentlemen's Agreement, while keeping on searching. (it's easy enough* to implement java.lang.String and StringBuffer in D, but I'm still hoping there is some compromise between "C" and "Java") --anders * PS. Here's one such hack (mostly for the discussion really) http://www.algonet.se/~afb/d/dcaf/html/class_string.html http://www.algonet.se/~afb/d/dcaf/html/class_string_buffer.html
Jul 03 2005
In article <da89e7$s7m$1 digitaldaemon.com>, Walter says..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da7ulp$kub$1 digitaldaemon.com...To me, C++ 'const' just a means of indicating, in code, that a value is not intended to be modifiable. So if I have a string property in a class, I can return a const reference my internal copy and be somewhat assurred that the client will have to make a conscious attempt if he wants to modify the data. This is really only useful for strings IMO in D, as they can be expensive to copy and there's no way to restrict their functionality. But I'm not sure it's worth adding a language feature just to help idiot-proof string use.ooohh... could you first provide me an option to *declare* e.g. slice as immutable thus I'll be able to return it from function without duping it? *That* would be optimization.In following COW principles, you do not need to dup the slice when returning it. The producer of the value doesn't need to dup it, the *consumer* does, and only if the *consumer* modifies it. Taking a slice of an array does not modify it in any way, so no dup is required. So I am not understanding why const or immutable is needed for D strings. I've written a number of string processing programs in D (including a macro text processor, and the silly program that transforms newsgroup postings into the "archive" pages), and didn't have any difficulty with D strings. They went together with much less effort and far fewer bugs than their C++ counterparts.I do understand the desire for const. But there are many different ways to approach the problem, and I'm not willing to just duplicate the C++ const with all its weaknesses and problems. There's got to be a better way.I agree. Hopefully, something will present itself. Sean
Jul 03 2005
Hi Walter,I can't fathom that the compiler can't make use of the fact that you are telling it: "The following function body will not modify [variable] at all, ever."? Surely this is useful information that can be made into some kind of optimization, specially when ignoring the dangers of threading: I simply don't see why threads even have to come into the picture. You could take a soldering iron and hack memory directly and the runtime won't be able to protect against that. But does it matter? I don't think that's the point of const. It is not a guarantee by the _compiler_ that the value will remain constant. It is a guarantee by the _programmer_ that his function body will not touch the variable. Of course, the compiler (or lexer), should make sure to prevent the programmer from violating his contract via syntax.const is not a physical protection. And never was. It is logical declaration of intention: I am not going to change this parameter or value it is refereing, so, compiler, please, warn me if I'll do this accidentally.Yet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct". The C++ const is *completely useless* to the compiler optimizer for that reason.A const thing that instead, is a guarantee that the underlying values won't change, is actually useful. An optimizer can do a lot with it.But wouldn't such a thing (a runtime-enforced const) cause big performance problems? It would mean the runtime would have to deal with race conditions and thread synchronization for every single const variable and object in memory. That seems awfully slow to me; a gratuitous use of locks and mutexes. If so, this makes for an interesting catch-22. If you implement it, you can optimize, but you get the performance penalty. If you don't implement it, there's no performance penalty, but you can't optimize either. I say forget about the runtime-const. Stick with semantic (compile-time) const, and try to make use of that info to optimize. Forget about threading too, which should make it easier. If the programmer wants to make sure some variable won't change via some other thread, then he should: [a] simply not use it in that thread; or [b] make the function that uses it on that thread take a const; or [c] lock and synchronize it himself individually. As far as references go, you should not (syntactically) be able to make a non-const reference to a const. That should guarantee correctness within the function body. Examples: Pretty simple, if you ask me. You could make "in" = "const" (syntactically) in that sense, which should have always been the default. Or you could do: - No modifier: e.g. func(int a) : This means make a (mutable, independent) copy of the caller's variable. Use dup for arrays, etc. - IN modifier: e.g. func(in int a) : This means const as defined above. Cheers, --AJG.
Jul 02 2005
"AJG" <AJG_member pathlink.com> wrote in message news:da7vvd$lm6$1 digitaldaemon.com...Hi Walter,Thanks, AJG, excellent statement. Except final :) in, inout and out in function parameters defines direction. This quite different from const and let's don't mix it. See, declaration: void toLower(in char[] str) means that toLower function will not change length of the str but allowed to change its content. Reasonable? Yes. Next step, this declaration: char[] toLower(in const char[] str) means that: 1) this toLower will not change str. nor length nor its content. 2) It returns mutable array and caller is free to use it in the way it wants - it may own it, store it, whatever. These two functions will peacefuly coexist in phobos as they have different signatures. Developer can do *optimal* choice. Signature: const char[] getDir(in const char[] path) means: getDir will not do anything with path - will just return const slice. Signature: void splitPath(in const char[] path, out const char[] dir, out const char[] filename, out const char[] ext) Means it will not touch path and will return constant slices representing path parts. Signature: void splitPath(in const char[] path, out char[] dir, out char[] filename, out char[] ext) Means it will not touch path and will return arrays - copies of path parts - caller is free to own them. Anyone brave here to tell me (us with AJG :) that all this above have nothing common with optimization?I can't fathom that the compiler can't make use of the fact that you are telling it: "The following function body will not modify [variable] at all, ever."? Surely this is useful information that can be made into some kind of optimization, specially when ignoring the dangers of threading: I simply don't see why threads even have to come into the picture. You could take a soldering iron and hack memory directly and the runtime won't be able to protect against that. But does it matter? I don't think that's the point of const. It is not a guarantee by the _compiler_ that the value will remain constant. It is a guarantee by the _programmer_ that his function body will not touch the variable. Of course, the compiler (or lexer), should make sure to prevent the programmer from violating his contract via syntax.const is not a physical protection. And never was. It is logical declaration of intention: I am not going to change this parameter or value it is refereing, so, compiler, please, warn me if I'll do this accidentally.Yet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct". The C++ const is *completely useless* to the compiler optimizer for that reason.A const thing that instead, is a guarantee that the underlying values won't change, is actually useful. An optimizer can do a lot with it.But wouldn't such a thing (a runtime-enforced const) cause big performance problems? It would mean the runtime would have to deal with race conditions and thread synchronization for every single const variable and object in memory. That seems awfully slow to me; a gratuitous use of locks and mutexes. If so, this makes for an interesting catch-22. If you implement it, you can optimize, but you get the performance penalty. If you don't implement it, there's no performance penalty, but you can't optimize either. I say forget about the runtime-const. Stick with semantic (compile-time) const, and try to make use of that info to optimize. Forget about threading too, which should make it easier. If the programmer wants to make sure some variable won't change via some other thread, then he should: [a] simply not use it in that thread; or [b] make the function that uses it on that thread take a const; or [c] lock and synchronize it himself individually. As far as references go, you should not (syntactically) be able to make a non-const reference to a const. That should guarantee correctness within the function body. Examples: Pretty simple, if you ask me. You could make "in" = "const" (syntactically) in that sense, which should have always been the default. Or you could do: - No modifier: e.g. func(int a) : This means make a (mutable, independent) copy of the caller's variable. Use dup for arrays, etc. - IN modifier: e.g. func(in int a) : This means const as defined above.
Jul 03 2005
"AJG" <AJG_member pathlink.com> wrote in message news:da7vvd$lm6$1 digitaldaemon.com...TheYet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct".reason.C++ const is *completely useless* to the compiler optimizer for thatI can't fathom that the compiler can't make use of the fact that you aretellingit: "The following function body will not modify [variable] at all,ever."? Consider the following C++ function: int foo(const int *p, int *q) { int i = *p; *q = 3; return *p; } At the return statement, could we replace *p with i, thereby saving ourselves a dereference operation? After all, p points to "const" data, right? Wrong. Consider calling foo() this way: int a[3]; ... foo(a, a); Since p and q now hold the same value, *q = 3; will change the contents of what p points to. This code is perfectly legal C++, and is "const-correct". It happens often enough in real code, too, as I discovered when trying to implement this optimization.
Jul 03 2005
In article <da88rb$ruj$1 digitaldaemon.com>, Walter says..."AJG" <AJG_member pathlink.com> wrote in message news:da7vvd$lm6$1 digitaldaemon.com...TheYet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct".reason.C++ const is *completely useless* to the compiler optimizer for thatI can't fathom that the compiler can't make use of the fact that you aretellingit: "The following function body will not modify [variable] at all,ever."? Consider the following C++ function: int foo(const int *p, int *q) { int i = *p; *q = 3; return *p; }int a[3]; ... foo(a, a);Hm... that's an interesting situation. Ok, say pointers are not considered, because they are inherently unsafe anyway. Let's take only regular in/out/inout variables. Could the same trick be done simply with these?This code is perfectly legal C++, and is "const-correct". It happens often enough in real code, too, as I discovered when trying to implement this optimization.It's possible that such code, although legal, is simply bad code that can't be protected against. The function documentation should state which variables shouldn't be the same. I think it's simply undefined behaviour. I dunno if all optimization should be off simply because of the occasinal badly coded, documented and used function. It's kind of like modifying the iterating array inside a foreach - perfectly valid too, but that's going to be ugly (perhaps that should be made illegal too, btw). Or for example, sending the same variable to multiple parameters of a string-manipulation (str*) function. Consider this: // char *str = "Some text"; // str = strcat(str, str); --------------------------- Once again, what if pointers are not considered, would this make things easier? If you take out pointers, couldn't the compiler detect if you were sending the same variable to multiple differently-accessable parameters? Cheers, --AJG.
Jul 03 2005
"AJG" <AJG_member pathlink.com> wrote in message news:da8vgt$1bos$1 digitaldaemon.com...In article <da88rb$ruj$1 digitaldaemon.com>, Walter says...be"AJG" <AJG_member pathlink.com> wrote in message news:da7vvd$lm6$1 digitaldaemon.com...Yet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot"const-correct".relied on to be constant, even if your program is 100%areThereason.C++ const is *completely useless* to the compiler optimizer for thatI can't fathom that the compiler can't make use of the fact that youconsidered,tellingit: "The following function body will not modify [variable] at all,ever."? Consider the following C++ function: int foo(const int *p, int *q) { int i = *p; *q = 3; return *p; }int a[3]; ... foo(a, a);Hm... that's an interesting situation. Ok, say pointers are notbecause they are inherently unsafe anyway. Let's take only regularin/out/inoutvariables. Could the same trick be done simply with these?With simple value variables, no. But that isn't interesting, as there isn't much of any point to "const" value variables as function parameters. With reference parameters, yes, it can happen in the same way.oftenThis code is perfectly legal C++, and is "const-correct". It happenscan't beenough in real code, too, as I discovered when trying to implement this optimization.It's possible that such code, although legal, is simply bad code thatprotected against. The function documentation should state which variables shouldn't be the same. I think it's simply undefined behaviour. I dunno if all optimization should be off simply because of the occasinalbadlycoded, documented and used function. It's kind of like modifying the iterating array inside a foreach -perfectlyvalid too, but that's going to be ugly (perhaps that should be madeillegal too,btw). Or for example, sending the same variable to multiple parameters ofastring-manipulation (str*) function. Consider this: // char *str = "Some text"; // str = strcat(str, str); --------------------------- Once again, what if pointers are not considered, would this make thingseasier?If you take out pointers, couldn't the compiler detect if you were sendingthesame variable to multiple differently-accessable parameters?The compiler cannot detect it in the general case, as a function may receive a non-const reference to the same data by an arbitrarilly complex path. What you're suggesting is different from C++ "const" - you're suggesting that const actually mean "constant". This is definitely more interesting that C++ const, but then there's the problem of undefined behavior and trying to detect it.
Jul 03 2005
Hi Walter,I know I'm pushing it here, but can't the compiler follow that arbitrarily complex path (excluding pointers)?Once again, what if pointers are not considered, would this make thingseasier?If you take out pointers, couldn't the compiler detect if you were sendingthesame variable to multiple differently-accessable parameters?The compiler cannot detect it in the general case, as a function may receive a non-const reference to the same data by an arbitrarilly complex path.What you're suggesting is different from C++ "const" - you're suggesting that const actually mean "constant". This is definitely more interesting that C++ const, but then there's the problem of undefined behavior and trying to detect it.Hm... perhaps. Ok, first let me see if I understand your point: You say: C++ const, which is semantic only, is useless for optimizations. You say: Implementing C++ const in D would be equally useless re: optimizations. I say: const should be _always_ about semantics ("correctness"), and _if possible_ provide optimizations. You say: That is not good enough, we need correctness and optimization. Is that correct? So, if you can solve the arbitrarily complex path problem, you get the both of both worlds, right? I dunno if this is possible, just thinking out loud. If not syntactically, could it be done via whole-program static analysis? Thanks, --AJG.
Jul 03 2005
"AJG" <AJG_member pathlink.com> wrote in message news:da9ig8$1vpg$1 digitaldaemon.com...sendingOnce again, what if pointers are not considered, would this make thingseasier?If you take out pointers, couldn't the compiler detect if you werereceivethesame variable to multiple differently-accessable parameters?The compiler cannot detect it in the general case, as a function mayIf it could, the program could be executed at compile time rather than run time <g>.a non-const reference to the same data by an arbitrarilly complex path.I know I'm pushing it here, but can't the compiler follow that arbitrarily complex path (excluding pointers)?optimizations.What you're suggesting is different from C++ "const" - you're suggesting that const actually mean "constant". This is definitely more interesting that C++ const, but then there's the problem of undefined behavior and trying to detect it.Hm... perhaps. Ok, first let me see if I understand your point: You say: C++ const, which is semantic only, is useless for optimizations. You say: Implementing C++ const in D would be equally useless re:I say: const should be _always_ about semantics ("correctness"), and _if possible_ provide optimizations. You say: That is not good enough, we need correctness and optimization. Is that correct?From correctness comes the optimizations. C++ doesn't implement correctness, as my example showed.If not syntactically, could it be done via whole-program static analysis?No.
Jul 03 2005
"Walter" <newshound digitalmars.com> wrote in message news:da88rb$ruj$1 digitaldaemon.com..."AJG" <AJG_member pathlink.com> wrote in message news:da7vvd$lm6$1 digitaldaemon.com...Walter, it is enough for me to know that int foo(const int *p, int *q) { int i = *p; *q = 3; .... 200 lines of code return *p; } will not change *p. I am not asking for optimization here. Optimization happened before - when I wrote this fucntion declaration using const parameters. I understand that you focused on optimiziation as compiler and codegenerator writer. This is perfectly good and thank you for that. But const is a matter of language design and not about optimization. Well not exactly as if I will write both: int foo(const int *p, int *q) int foo(int *p, int *q) then I will make an act of optimization on the design level. Again: from the point of optimization 'public', 'private' attributes are almost worthless. But despite of that they are in the language. const is the same - it is a contract. Any argument that you can *intentionally* break constness are true. The same apply to visibility attributes. Andrew.TheYet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct".reason.C++ const is *completely useless* to the compiler optimizer for thatI can't fathom that the compiler can't make use of the fact that you aretellingit: "The following function body will not modify [variable] at all,ever."? Consider the following C++ function: int foo(const int *p, int *q) { int i = *p; *q = 3; return *p; } At the return statement, could we replace *p with i, thereby saving ourselves a dereference operation? After all, p points to "const" data, right? Wrong. Consider calling foo() this way: int a[3]; ... foo(a, a); Since p and q now hold the same value, *q = 3; will change the contents of what p points to. This code is perfectly legal C++, and is "const-correct". It happens often enough in real code, too, as I discovered when trying to implement this optimization.
Jul 03 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da93ap$1g54$1 digitaldaemon.com..."Walter" <newshound digitalmars.com> wrote in message news:da88rb$ruj$1 digitaldaemon.com...The whole problem is, with the C++ rules, the optimizations cannot even be done by the code generator - you may think you've optimized something with const, but in reality the code generator cannot make use of it because of how const is implimented in C++ and the compiler cannot figure out 100% for certain what is being done with referenced data."AJG" <AJG_member pathlink.com> wrote in message news:da7vvd$lm6$1 digitaldaemon.com...Walter, it is enough for me to know that int foo(const int *p, int *q) { int i = *p; *q = 3; .... 200 lines of code return *p; } will not change *p. I am not asking for optimization here. Optimization happened before - when I wrote this fucntion declaration using const parameters.TheYet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct".reason.C++ const is *completely useless* to the compiler optimizer for thatI can't fathom that the compiler can't make use of the fact that you aretellingit: "The following function body will not modify [variable] at all,ever."? Consider the following C++ function: int foo(const int *p, int *q) { int i = *p; *q = 3; return *p; } At the return statement, could we replace *p with i, thereby saving ourselves a dereference operation? After all, p points to "const" data, right? Wrong. Consider calling foo() this way: int a[3]; ... foo(a, a); Since p and q now hold the same value, *q = 3; will change the contents of what p points to. This code is perfectly legal C++, and is "const-correct". It happens often enough in real code, too, as I discovered when trying to implement this optimization.I understand that you focused on optimiziation as compiler and codegenerator writer. This is perfectly good and thank you for that.What I think Walter has in mind with his "explicit in" proposal for D is "constness" while still allowing for the optimizations that C++ can't do, or at least can't do without making the compiler much more complicated.But const is a matter of language design and not about optimization. Well not exactly as if I will write both: int foo(const int *p, int *q) int foo(int *p, int *q) then I will make an act of optimization on the design level. Again: from the point of optimization 'public', 'private' attributes are almost worthless.'private' and 'package' data members may have some optimizations applied because of the protection attribute scope rules. private and package methods can't be virtual, so there are some optimizations having to do with inlining and the vtable that can be (and are) done by the compiler, because 'private' or 'package' guarantees that those are not virtual methods.But despite of that they are in the language. const is the same - it is a contract. Any argument that you can *intentionally* break constness are true. The same apply to visibility attributes. Andrew.
Jul 03 2005
"Dave" <Dave_member pathlink.com> wrote in message news:da95on$1jff$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da93ap$1g54$1 digitaldaemon.com...Again I am willing to write to functions which provided together will give an optimal choice: void toUpper( in char[] strbuf ) // inplace char[] toUpper( in const char[] str ) // return brand new. I am free to chose optimal function for particular case. And while implementing it compiler will not allow me to change *accidentally* value of str. This is *deterministic* optimization. codegenerator *may* do optimization. And may not. const is not about codegenerator optimiziation. Dot. Forget about it."Walter" <newshound digitalmars.com> wrote in message news:da88rb$ruj$1 digitaldaemon.com...The whole problem is, with the C++ rules, the optimizations cannot even be done by the code generator - you may think you've optimized something with const, but in reality the code generator cannot make use of it because of how const is implimented in C++ and the compiler cannot figure out 100% for certain what is being done with referenced data."AJG" <AJG_member pathlink.com> wrote in message news:da7vvd$lm6$1 digitaldaemon.com...Walter, it is enough for me to know that int foo(const int *p, int *q) { int i = *p; *q = 3; .... 200 lines of code return *p; } will not change *p. I am not asking for optimization here. Optimization happened before - when I wrote this fucntion declaration using const parameters.TheYet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct".reason.C++ const is *completely useless* to the compiler optimizer for thatI can't fathom that the compiler can't make use of the fact that you aretellingit: "The following function body will not modify [variable] at all,ever."? Consider the following C++ function: int foo(const int *p, int *q) { int i = *p; *q = 3; return *p; } At the return statement, could we replace *p with i, thereby saving ourselves a dereference operation? After all, p points to "const" data, right? Wrong. Consider calling foo() this way: int a[3]; ... foo(a, a); Since p and q now hold the same value, *q = 3; will change the contents of what p points to. This code is perfectly legal C++, and is "const-correct". It happens often enough in real code, too, as I discovered when trying to implement this optimization.I think that you a wrong here as following: import std.stdio; class One { package int foo() { return 1; } } class Two: One { override package int foo() { return 2; } } int main() { Two t = new Two; return t.foo(); } compiles just fine.I understand that you focused on optimiziation as compiler and codegenerator writer. This is perfectly good and thank you for that.What I think Walter has in mind with his "explicit in" proposal for D is "constness" while still allowing for the optimizations that C++ can't do, or at least can't do without making the compiler much more complicated.But const is a matter of language design and not about optimization. Well not exactly as if I will write both: int foo(const int *p, int *q) int foo(int *p, int *q) then I will make an act of optimization on the design level. Again: from the point of optimization 'public', 'private' attributes are almost worthless.'private' and 'package' data members may have some optimizations applied because of the protection attribute scope rules. private and package methods can't be virtual, so there are some optimizations having to do with inlining and the vtable that can be (and are) done by the compiler, because 'private' or 'package' guarantees that those are not virtual methods.But despite of that they are in the language. const is the same - it is a contract. Any argument that you can *intentionally* break constness are true. The same apply to visibility attributes. Andrew.
Jul 03 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da9g47$1tfc$1 digitaldaemon.com..."Dave" <Dave_member pathlink.com> wrote in message news:da95on$1jff$1 digitaldaemon.com...I understand - I think we're all looking for some way to implement "constness" in a way that is better, for at least the majority of cases, than how C++ does it. From Walter's earlier post, it appears that overloading based on some type of "const" storage modifier is not going to happen, so I'll take what I can get in this regard, especially if it helps compiler implementors do their job better because then I get better tools. Walter wants D's "constness" to be taken as a semantic guarantee of some value, and I agree with him on that, because then it's of more value to both the compiler and someone debugging code (const the way it is in C++ can actually hide bugs). I also agree with the notion that C++ constness is a mess and that is one of the major reasons why I want D to succeed, so I don't have to deal with that as it is. I take it you basically want C++ constness in D - I just have to disagree with that because that's one of the things I think needs to be done better.The whole problem is, with the C++ rules, the optimizations cannot even be done by the code generator - you may think you've optimized something with const, but in reality the code generator cannot make use of it because of how const is implimented in C++ and the compiler cannot figure out 100% for certain what is being done with referenced data.Again I am willing to write to functions which provided together will give an optimal choice: void toUpper( in char[] strbuf ) // inplace char[] toUpper( in const char[] str ) // return brand new.I am free to chose optimal function for particular case. And while implementing it compiler will not allow me to change *accidentally* value of str.Try this: 1 1 vs. this: 2 1 ;--- import std.stdio; class One { version(_package) package int foo() { return 1; } else public int foo() { return 1; } } class Two: One { version(_package) override package int foo() { return 2; } else override public int foo() { return 2; } } void main() { Two t = new Two; writefln((cast(One)t).foo()); One o = new One; writefln("%d\n",(cast(One)o).foo()); }private and package methods can't be virtual, so there are some optimizations having to do with inlining and the vtable that can be (and are) done by the compiler, because 'private' or 'package' guarantees that those are not virtual methods.I think that you a wrong here as following: import std.stdio; class One { package int foo() { return 1; } } class Two: One { override package int foo() { return 2; } } int main() { Two t = new Two; return t.foo(); } compiles just fine.
Jul 03 2005
"Dave" <Dave_member pathlink.com> wrote in message news:da9jup$21h4$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da9g47$1tfc$1 digitaldaemon.com...'"const" storage modifier is not going to happen,...' Then page http://www.digitalmars.com/d/comparison.html needs to be updated by features which are impossible to implement in D in principle. Just for the sake of truth."Dave" <Dave_member pathlink.com> wrote in message news:da95on$1jff$1 digitaldaemon.com...I understand - I think we're all looking for some way to implement "constness" in a way that is better, for at least the majority of cases, than how C++ does it. From Walter's earlier post, it appears that overloading based on some type of "const" storage modifier is not going to happen, so I'll take what I can get in this regard, especially if it helps compiler implementors do their job better because then I get better tools.The whole problem is, with the C++ rules, the optimizations cannot even be done by the code generator - you may think you've optimized something with const, but in reality the code generator cannot make use of it because of how const is implimented in C++ and the compiler cannot figure out 100% for certain what is being done with referenced data.Again I am willing to write to functions which provided together will give an optimal choice: void toUpper( in char[] strbuf ) // inplace char[] toUpper( in const char[] str ) // return brand new.Walter wants D's "constness" to be taken as a semantic guarantee of some value, and I agree with him on that, because then it's of more value to both the compiler and someone debugging code (const the way it is in C++ can actually hide bugs). I also agree with the notion that C++ constness is a mess and that is one of the major reasons why I want D to succeed, so I don't have to deal with that as it is. I take it you basically want C++ constness in D - I just have to disagree with that because that's one of the things I think needs to be done better.The ultimate const protection can be done only on hardware level (I mean without compromises) which is not the case for D. About stylistic: I will repeat again: the best way (near ideal) is to be able to say something like this: type[def] string: char[] { private opIndexAssign(...) // disabled public string opSlice() // returns immutable slice.... ... etc... } It is more universal but significantly more complex. But I am pretty sure it is a future - to be able to fine tune type redefinitions of primitives. For a while I propose to introduceNice! Just perfect! And those people are telling me that const hides possible errors? :-)))I am free to chose optimal function for particular case. And while implementing it compiler will not allow me to change *accidentally* value of str.Try this: 1 1 vs. this: 2 1 ;--- import std.stdio; class One { version(_package) package int foo() { return 1; } else public int foo() { return 1; } } class Two: One { version(_package) override package int foo() { return 2; } else override public int foo() { return 2; } } void main() { Two t = new Two; writefln((cast(One)t).foo()); One o = new One; writefln("%d\n",(cast(One)o).foo()); }private and package methods can't be virtual, so there are some optimizations having to do with inlining and the vtable that can be (and are) done by the compiler, because 'private' or 'package' guarantees that those are not virtual methods.I think that you a wrong here as following: import std.stdio; class One { package int foo() { return 1; } } class Two: One { override package int foo() { return 2; } } int main() { Two t = new Two; return t.foo(); } compiles just fine.
Jul 03 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da93ap$1g54$1 digitaldaemon.com...Walter, it is enough for me to know that int foo(const int *p, int *q) { int i = *p; *q = 3; .... 200 lines of code return *p; } will not change *p. I am not asking for optimization here. Optimization happened before - when I wrote this fucntion declaration using const parameters. I understand that you focused on optimiziation as compiler andcodegeneratorwriter. This is perfectly good and thank you for that.The optimization issue is a symptom of the problem with const, not the problem itself. The inability to make *any* use of const for the compiler to learn something about the program is, to me anyway, indicative that the semantic value of const is not there. Optimizers work by being able to prove certain properties of code to be true. At a higher level, being able to prove certain things about a program is important for all kinds of code analysis tools, like verifiers, etc. Being able to prove something about a program is also useful for the programmer, as knowing something that must be true about a piece of code is the first step to debugging it. C++ const doesn't enable proving anything about the const reference. The optimizer can't prove the values won't change, and *neither can the programmer* rely on it. If I see a const reference in C++ code, I don't know if it really is constant or not. As a programmer looking at someone else's code, it offers no value.But const is a matter of language design and not about optimization. Well not exactly as if I will write both: int foo(const int *p, int *q) int foo(int *p, int *q) then I will make an act of optimization on the design level. Again: from the point of optimization 'public', 'private' attributes are almost worthless. But despite of that they are in the language. const is the same - it is a contract. Any argument that you can *intentionally* break constness are true. The same apply to visibility attributes.My point (with the example given) is you are NOT breaking const. The code is legal, supported and is const-correct. It's not like const_cast, which is known to be an escape from const, can be grepped for, and can be warned about. There is no commonly accepted C++ convention that says such code is bad form, undefined, etc. And yes, these things do appear in real, working, production code, as I found out when attempting to use const in the optimizer. The only way "const" can be constant in C++ is if you follow an informal convention for your own code that is not enforced by the compiler or the language or by any third party whose code you might wish to use. You cannot assume that const is constant..
Jul 03 2005
"Walter" <newshound digitalmars.com> wrote in message news:da99a9$1n0q$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da93ap$1g54$1 digitaldaemon.com...True. Except of the last statement: "As a programmer looking at someone else's code, it offers no value." When I am looking on: char[] toStringz(const char[] s) I can tell that: 1) function designed to do not change 's' 2) body of the function passed through compiler - it not contains stupid mistakes inside. Currently I am looking on char* toStringz(char[] s) and trying to guess - what a hell it is doing with my 's'? And finally I can see there memcpy from my friend - C runtime which I know declared as memcpy(void* dst, const void* src, size_t sz)... Could you please do the same? Without it DbC is not full in D.Walter, it is enough for me to know that int foo(const int *p, int *q) { int i = *p; *q = 3; .... 200 lines of code return *p; } will not change *p. I am not asking for optimization here. Optimization happened before - when I wrote this fucntion declaration using const parameters. I understand that you focused on optimiziation as compiler andcodegeneratorwriter. This is perfectly good and thank you for that.The optimization issue is a symptom of the problem with const, not the problem itself. The inability to make *any* use of const for the compiler to learn something about the program is, to me anyway, indicative that the semantic value of const is not there. Optimizers work by being able to prove certain properties of code to be true. At a higher level, being able to prove certain things about a program is important for all kinds of code analysis tools, like verifiers, etc. Being able to prove something about a program is also useful for the programmer, as knowing something that must be true about a piece of code is the first step to debugging it. C++ const doesn't enable proving anything about the const reference. The optimizer can't prove the values won't change, and *neither can the programmer* rely on it. If I see a const reference in C++ code, I don't know if it really is constant or not. As a programmer looking at someone else's code, it offers no value.Exactly! And this is huge. If *you* will write: int foo(const char[] s) then I will trust you - Walter made as much as possible to ensure that foo is not changing s. So I don't need to waste my time digging inside *each* string function in Phobos. Ben propose to use 'to' for that... Is it better or what? Will you also implement "if function name starts from 'to' then ..."? Trying to optimize everything is good but close to "Road to hell is paved by good wishes". Andrew.But const is a matter of language design and not about optimization. Well not exactly as if I will write both: int foo(const int *p, int *q) int foo(int *p, int *q) then I will make an act of optimization on the design level. Again: from the point of optimization 'public', 'private' attributes are almost worthless. But despite of that they are in the language. const is the same - it is a contract. Any argument that you can *intentionally* break constness are true. The same apply to visibility attributes.My point (with the example given) is you are NOT breaking const. The code is legal, supported and is const-correct. It's not like const_cast, which is known to be an escape from const, can be grepped for, and can be warned about. There is no commonly accepted C++ convention that says such code is bad form, undefined, etc. And yes, these things do appear in real, working, production code, as I found out when attempting to use const in the optimizer. The only way "const" can be constant in C++ is if you follow an informal convention for your own code that is not enforced by the compiler or the language or by any third party whose code you might wish to use. You cannot assume that const is constant..
Jul 03 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da9sbs$29to$1 digitaldaemon.com...True. Except of the last statement: "As a programmer looking at someone else's code, it offers no value." When I am looking on: char[] toStringz(const char[] s) I can tell that: 1) function designed to do not change 's' 2) body of the function passed through compiler - it not contains stupid mistakes inside.I will argue that you cannot tell that - especially if you are looking for bugs. The language offers no guarantees about const, so when you're going bug hunting, const is not helpful.Currently I am looking on char* toStringz(char[] s) and trying to guess - what a hell it is doing with my 's'?I understand it can be helpful there, but I don't think it is as helpful as you do. I think there's a better way here somewhere, if we can find it.
Jul 04 2005
"Walter" <newshound digitalmars.com> wrote in message news:dach1f$1u8t$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da9sbs$29to$1 digitaldaemon.com...const helps me to do not do bugs. To change what is not designed to be changed. From the very beginning - at planning level. Hunting is a different story. But again such simple (well, from external look) preventive method can narrow the bug field a lot. DbC methods in D are good, but if code designer will not cover all conditions carefully then they at least meaningless if not worse...True. Except of the last statement: "As a programmer looking at someone else's code, it offers no value." When I am looking on: char[] toStringz(const char[] s) I can tell that: 1) function designed to do not change 's' 2) body of the function passed through compiler - it not contains stupid mistakes inside.I will argue that you cannot tell that - especially if you are looking for bugs. The language offers no guarantees about const, so when you're going bug hunting, const is not helpful.Yep, so far I can see three methods only. Hope somebody will add more. First is straightforward reproduction of const in C++ with all bells and whistles. Second is already defined in "Round III. Brainstrom...." (Explicit contsness, variant I) Third one I've already mentioned somewhere here and going to formalize today also. I like explicit contsness variants as more I would say D-ish (grammatically pure) and easily implementable - read reliable. But again it is my personal opinion only - means can be not perfect. Andrew.Currently I am looking on char* toStringz(char[] s) and trying to guess - what a hell it is doing with my 's'?I understand it can be helpful there, but I don't think it is as helpful as you do. I think there's a better way here somewhere, if we can find it.
Jul 04 2005
Well, now, I have a question. What does this say: char* toStringz(in char[] s) As compared to: char* toStringz(char[] s) Or: char* toStringz(inout char[] s) Since the in is explicitly specified (even if it is implicit) you can easily tell that the argument is meant not to modify the data pointed to. If it says inout, then you can assume it returns and modifies the string. It may not mean that it CAN'T change s, but there's only so much you can get out of stupid programmers. In some cases, it's just a simple matter of knowing what you're doing. -[Unknown]"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da9sbs$29to$1 digitaldaemon.com...True. Except of the last statement: "As a programmer looking at someone else's code, it offers no value." When I am looking on: char[] toStringz(const char[] s) I can tell that: 1) function designed to do not change 's' 2) body of the function passed through compiler - it not contains stupid mistakes inside.I will argue that you cannot tell that - especially if you are looking for bugs. The language offers no guarantees about const, so when you're going bug hunting, const is not helpful.Currently I am looking on char* toStringz(char[] s) and trying to guess - what a hell it is doing with my 's'?I understand it can be helpful there, but I don't think it is as helpful as you do. I think there's a better way here somewhere, if we can find it.
Jul 04 2005
In article <da88rb$ruj$1 digitaldaemon.com>, Walter says...Consider the following C++ function: int foo(const int *p, int *q) { int i = *p; *q = 3; return *p; } At the return statement, could we replace *p with i, thereby saving ourselves a dereference operation? After all, p points to "const" data, right? Wrong. Consider calling foo() this way: int a[3]; ... foo(a, a); Since p and q now hold the same value, *q = 3; will change the contents of what p points to. This code is perfectly legal C++, and is "const-correct". It happens often enough in real code, too, as I discovered when trying to implement this optimization.Why do I suddenly feel like we're moving towards defining 'restrict' in D? :) Sean
Jul 03 2005
In article <da9716$1knv$1 digitaldaemon.com>, Sean Kelly says...In article <da88rb$ruj$1 digitaldaemon.com>, Walter says...Take a peek in the archives on that subject - I don't think you need to worry about that <g> - DaveConsider the following C++ function: int foo(const int *p, int *q) { int i = *p; *q = 3; return *p; } At the return statement, could we replace *p with i, thereby saving ourselves a dereference operation? After all, p points to "const" data, right? Wrong. Consider calling foo() this way: int a[3]; ... foo(a, a); Since p and q now hold the same value, *q = 3; will change the contents of what p points to. This code is perfectly legal C++, and is "const-correct". It happens often enough in real code, too, as I discovered when trying to implement this optimization.Why do I suddenly feel like we're moving towards defining 'restrict' in D? :) Sean
Jul 03 2005
In article <da7pp5$i06$1 digitaldaemon.com>, Walter says...Yet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct".That is true, but also in fact completly irrelevant. I think you might have misunderstood the intention of the const keyword in C++. It's not meant to be, and has never been meant to be, a guarantee to the internals of the function that "this value will not change". It's not supposed to protect the INSIDE of the function from the outside world, but quite the opposite. It's a guarantee (or contract, if you will) with the code OUTSIDE the function (ie. the caller) that "THIS function will never change this value." What happens in other threads and other references has no relevance to this contract. Also, your example with foo(a,a) is ok, since when you (the caller) send 'a' as the second (non-const) parameter, the function is 'allowed' to change it. Thus the function has not broken the contract. I am not arguing for or against const in D here. My experience with it in C++ has been pretty much the same as yours, and so I am not really convinced of it's usefulness. But your argument really attacks a use of 'const' that was never intended, and thus is not a very good argument. Nick
Jul 03 2005
"Nick" <Nick_member pathlink.com> wrote in message news:da9dfv$1r9p$1 digitaldaemon.com...In article <da7pp5$i06$1 digitaldaemon.com>, Walter says...haveYet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct".That is true, but also in fact completly irrelevant. I think you mightmisunderstood the intention of the const keyword in C++. It's not meant tobe,and has never been meant to be, a guarantee to the internals of thefunctionthat "this value will not change". It's not supposed to protect the INSIDEofthe function from the outside world, but quite the opposite. It's aguarantee(or contract, if you will) with the code OUTSIDE the function (ie. thecaller)that "THIS function will never change this value." What happens in otherthreadsand other references has no relevance to this contract. Also, your examplewithfoo(a,a) is ok, since when you (the caller) send 'a' as the second(non-const)parameter, the function is 'allowed' to change it. Thus the function hasnotbroken the contract. I am not arguing for or against const in D here. My experience with it inC++has been pretty much the same as yours, and so I am not really convincedof it'susefulness. But your argument really attacks a use of 'const' that wasneverintended, and thus is not a very good argument.You do make a good point.
Jul 03 2005
On Sun, 3 Jul 2005 15:05:20 -0700, Walter <newshound digitalmars.com> wrote:"Nick" <Nick_member pathlink.com> wrote in message news:da9dfv$1r9p$1 digitaldaemon.com...This is the same point I've tried to make in the past. To me 'in' is part of the function contract stating I will only 'read' this parameter. I had a DBC style idea for detecting modification to 'in' parameters, it went: 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; } The compiler could concievably insert these checks itself. Of course, this only detects changes to the variable itself be it a reference, pointer, int etc. It does not address the other desire, to protect the data referenced by the variable. ReganIn article <da7pp5$i06$1 digitaldaemon.com>, Walter says...haveYet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct".That is true, but also in fact completly irrelevant. I think you mightmisunderstood the intention of the const keyword in C++. It's not meant tobe,and has never been meant to be, a guarantee to the internals of thefunctionthat "this value will not change". It's not supposed to protect the INSIDEofthe function from the outside world, but quite the opposite. It's aguarantee(or contract, if you will) with the code OUTSIDE the function (ie. thecaller)that "THIS function will never change this value." What happens in otherthreadsand other references has no relevance to this contract. Also, your examplewithfoo(a,a) is ok, since when you (the caller) send 'a' as the second(non-const)parameter, the function is 'allowed' to change it. Thus the function hasnotbroken the contract. I am not arguing for or against const in D here. My experience with it inC++has been pretty much the same as yours, and so I am not really convincedof it'susefulness. But your argument really attacks a use of 'const' that wasneverintended, and thus is not a very good argument.You do make a good point.
Jul 03 2005
"Walter" <newshound digitalmars.com> wrote in message news:da6k71$11rs$1 digitaldaemon.com..."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:da4afr$24jc$1 digitaldaemon.com...It is equally probable that another thread could step on obj within the foo() call lifetime as it is now, regardless of any optimizations that the "in" proposal allows, so I don't think that concern should be a show stopper. Either way the results are the same - sporadically incorrect results, and either way it is going to be a bear to debug and proper synchronization by the /user/ of obj and foo() will be the way to fix the problem - same as any other multi-threading issue. I see no problem with just removing the part of the proposal that promises that no other /thread/ will change obj. because I don't think that is practical in any sense at the language implementaton level for a language with the goals of D (D doesn't offer or promise auto-synchronization in any other case, does it?). - DaveHow would this cover the following case that Walter's proposal covers: class A { int x; } void foo(in A obj){ int y = obj.x; // do whatever you want... assert( obj.x == y ); } void main() { A obj = new A; foo(obj); // says it doesn't change obj } Is it practical to force A to implement some immutability just because foo doesn't change its inputs? I'm not saying Walter's proposal is prefect.It'svery strong for foo to say no other thread or reference will change obj since it has no control over what other threads are doing. I would betakingpretty much blind leap of faith when declaring an object reference as 'in' and saying that no other thread is stepping on that object during the call lifetime.You're right. I have misgivings about it for that reason. On the other hand, look at C++ "const". Nothing about "const" says that some other thread or reference cannot change the value out from under you at any moment. Furthermore, it can be cast away and modified anyway. The semantic value of C++ "const" is essentially zip. This is why I am often flummoxed why it is given such weight in C++.
Jul 03 2005
"Dave" <Dave_member pathlink.com> wrote in message news:da8nqk$161t$1 digitaldaemon.com..."Walter" <newshound digitalmars.com> wrote in message news:da6k71$11rs$1 digitaldaemon.com...You're right - the threading model shouldn't enter into it. I'm liking Walter's suggestion more now. Earlier I thought it was too strong a condition but now I can see, for example, lots of places in phobos where 'in' can be used."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:da4afr$24jc$1 digitaldaemon.com...It is equally probable that another thread could step on obj within the foo() call lifetime as it is now, regardless of any optimizations that the "in" proposal allows, so I don't think that concern should be a show stopper. Either way the results are the same - sporadically incorrect results, and either way it is going to be a bear to debug and proper synchronization by the /user/ of obj and foo() will be the way to fix the problem - same as any other multi-threading issue. I see no problem with just removing the part of the proposal that promises that no other /thread/ will change obj. because I don't think that is practical in any sense at the language implementaton level for a language with the goals of D (D doesn't offer or promise auto-synchronization in any other case, does it?). - DaveHow would this cover the following case that Walter's proposal covers: class A { int x; } void foo(in A obj){ int y = obj.x; // do whatever you want... assert( obj.x == y ); } void main() { A obj = new A; foo(obj); // says it doesn't change obj } Is it practical to force A to implement some immutability just because foo doesn't change its inputs? I'm not saying Walter's proposal is prefect.It'svery strong for foo to say no other thread or reference will change obj since it has no control over what other threads are doing. I would betakingpretty much blind leap of faith when declaring an object reference as 'in' and saying that no other thread is stepping on that object during the call lifetime.You're right. I have misgivings about it for that reason. On the other hand, look at C++ "const". Nothing about "const" says that some other thread or reference cannot change the value out from under you at any moment. Furthermore, it can be cast away and modified anyway. The semantic value of C++ "const" is essentially zip. This is why I am often flummoxed why it is given such weight in C++.
Jul 03 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da8qa5$17op$1 digitaldaemon.com..."Dave" <Dave_member pathlink.com> wrote in message news:da8nqk$161t$1 digitaldaemon.com...I think Walter's idea is a great idea and a good compromise! Truth be told, I actually think the following would be the best: [none]/in/out/inout - [none] and 'in' would follow the new proposal with regard to 'immutable', and /all/ would allow the new opimizations that I think Walter has in mind. The exceptions would be pointer params. and functions declared extern or exported, which would simply operate as they do now, where the expectation is that they are treated differently anyway. volatile/volatile in/volatile out/volatile inout - 'volatile', 'volatile in', 'volatile out' and 'volatile inout' params. would basically operate exactly as they do now. Just like other statements in any other scope, a "volatile" param. would mean "inhibit optimizations on the variable that may effect memory reads/writes". Not even a new keyword.. The whole justification for these new defaults is because the cases where "volatile" would have to be used for the code to operate correctly are a small minority, so shouldn't the default go with what benefits the great majority of cases? Also, the same justification goes for making the default [none] and 'in' operate the same way w.r.t. the new proposal - majority of cases rules. Another big plus would be not having to litter code with 'in' (like C++ code is littered with 'const')."Walter" <newshound digitalmars.com> wrote in message news:da6k71$11rs$1 digitaldaemon.com...You're right - the threading model shouldn't enter into it. I'm liking Walter's suggestion more now. Earlier I thought it was too strong a condition but now I can see, for example, lots of places in phobos where 'in' can be used."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:da4afr$24jc$1 digitaldaemon.com...It is equally probable that another thread could step on obj within the foo() call lifetime as it is now, regardless of any optimizations that the "in" proposal allows, so I don't think that concern should be a show stopper. Either way the results are the same - sporadically incorrect results, and either way it is going to be a bear to debug and proper synchronization by the /user/ of obj and foo() will be the way to fix the problem - same as any other multi-threading issue. I see no problem with just removing the part of the proposal that promises that no other /thread/ will change obj. because I don't think that is practical in any sense at the language implementaton level for a language with the goals of D (D doesn't offer or promise auto-synchronization in any other case, does it?). - DaveHow would this cover the following case that Walter's proposal covers: class A { int x; } void foo(in A obj){ int y = obj.x; // do whatever you want... assert( obj.x == y ); } void main() { A obj = new A; foo(obj); // says it doesn't change obj } Is it practical to force A to implement some immutability just because foo doesn't change its inputs? I'm not saying Walter's proposal is prefect.It'svery strong for foo to say no other thread or reference will change obj since it has no control over what other threads are doing. I would betakingpretty much blind leap of faith when declaring an object reference as 'in' and saying that no other thread is stepping on that object during the call lifetime.You're right. I have misgivings about it for that reason. On the other hand, look at C++ "const". Nothing about "const" says that some other thread or reference cannot change the value out from under you at any moment. Furthermore, it can be cast away and modified anyway. The semantic value of C++ "const" is essentially zip. This is why I am often flummoxed why it is given such weight in C++.
Jul 03 2005
"Dave" <Dave_member pathlink.com> wrote in message news:da931u$1fto$1 digitaldaemon.com..."Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da8qa5$17op$1 digitaldaemon.com...1) How in will solve this: class Record { Field[] fields() { return m_fields.dup; // this is not needed, isn't it? // but it must be here in current D. } } 2) 'In' does not allow to distinguish cases: void toUpper(in char[] str_in_place); char[] toUpper(in const char[] str); and select optimal implementation."Dave" <Dave_member pathlink.com> wrote in message news:da8nqk$161t$1 digitaldaemon.com...I think Walter's idea is a great idea and a good compromise! Truth be told, I actually think the following would be the best: [none]/in/out/inout - [none] and 'in' would follow the new proposal with regard to 'immutable', and /all/ would allow the new opimizations that I think Walter has in mind. The exceptions would be pointer params. and functions declared extern or exported, which would simply operate as they do now, where the expectation is that they are treated differently anyway."Walter" <newshound digitalmars.com> wrote in message news:da6k71$11rs$1 digitaldaemon.com...You're right - the threading model shouldn't enter into it. I'm liking Walter's suggestion more now. Earlier I thought it was too strong a condition but now I can see, for example, lots of places in phobos where 'in' can be used."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:da4afr$24jc$1 digitaldaemon.com...It is equally probable that another thread could step on obj within the foo() call lifetime as it is now, regardless of any optimizations that the "in" proposal allows, so I don't think that concern should be a show stopper. Either way the results are the same - sporadically incorrect results, and either way it is going to be a bear to debug and proper synchronization by the /user/ of obj and foo() will be the way to fix the problem - same as any other multi-threading issue. I see no problem with just removing the part of the proposal that promises that no other /thread/ will change obj. because I don't think that is practical in any sense at the language implementaton level for a language with the goals of D (D doesn't offer or promise auto-synchronization in any other case, does it?). - DaveHow would this cover the following case that Walter's proposal covers: class A { int x; } void foo(in A obj){ int y = obj.x; // do whatever you want... assert( obj.x == y ); } void main() { A obj = new A; foo(obj); // says it doesn't change obj } Is it practical to force A to implement some immutability just because foo doesn't change its inputs? I'm not saying Walter's proposal is prefect.It'svery strong for foo to say no other thread or reference will change obj since it has no control over what other threads are doing. I would betakingpretty much blind leap of faith when declaring an object reference as 'in' and saying that no other thread is stepping on that object during the call lifetime.You're right. I have misgivings about it for that reason. On the other hand, look at C++ "const". Nothing about "const" says that some other thread or reference cannot change the value out from under you at any moment. Furthermore, it can be cast away and modified anyway. The semantic value of C++ "const" is essentially zip. This is why I am often flummoxed why it is given such weight in C++.volatile/volatile in/volatile out/volatile inout - 'volatile', 'volatile in', 'volatile out' and 'volatile inout' params. would basically operate exactly as they do now. Just like other statements in any other scope, a "volatile" param. would mean "inhibit optimizations on the variable that may effect memory reads/writes". Not even a new keyword.. The whole justification for these new defaults is because the cases where "volatile" would have to be used for the code to operate correctly are a small minority, so shouldn't the default go with what benefits the great majority of cases? Also, the same justification goes for making the default [none] and 'in' operate the same way w.r.t. the new proposal - majority of cases rules. Another big plus would be not having to litter code with 'in' (like C++ code is littered with 'const')."littered with 'const'".... well, it depends.... If European will see Stone Garden in Japan he will find it littered by stones. For me personally code which is not using const looks non-prefessional and written by young hacker in 'fire-n-forget' mode. Non maintainable, non reliable, non optimized. Someone can tell that: private int something1 public int something2 is littered with private and public. Does it *really* mean that it is littered? Andrew.
Jul 03 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da95gq$1j4t$1 digitaldaemon.com...1) How in will solve this: class Record { Field[] fields() { return m_fields.dup; // this is not needed, isn't it? // but it must be here in current D. } }It won't, but then again, I don't see that the .dup is necessary there, as fields() is a producer of a value, not a consumer.2) 'In' does not allow to distinguish cases: void toUpper(in char[] str_in_place); char[] toUpper(in const char[] str); and select optimal implementation.That's correct, there would be no overloading based on const-ness. I know this is commonplace in C++, but frankly I think it's poor design. A function overloaded on const implicitly has significantly different behavior, and so should have a different name.wherevolatile/volatile in/volatile out/volatile inout - 'volatile', 'volatile in', 'volatile out' and 'volatile inout' params. would basically operate exactly as they do now. Just like other statements in any other scope, a "volatile" param. would mean "inhibit optimizations on the variable that may effect memory reads/writes". Not even a new keyword.. The whole justification for these new defaults is because the casesThe idea is that the most common case should be the default. Would you agree that for the vast majority of function parameters, they are read only? That mutable ones are relatively rare? If so, then it makes sense to have the uncommon ones need the extra syntax. As for myself, since most parameters in C++ code are const, the const everywhere tends to visually clutter up the code, obscuring the other stuff."volatile" would have to be used for the code to operate correctly are a small minority, so shouldn't the default go with what benefits the great majority of cases? Also, the same justification goes for making the default [none] and 'in' operate the same way w.r.t. the new proposal - majority of cases rules. Another big plus would be not having to litter code with 'in' (like C++ code is littered with 'const')."littered with 'const'".... well, it depends.... If European will see Stone Garden in Japan he will find it littered by stones. For me personally code which is not using const looks non-prefessional and written by young hacker in 'fire-n-forget' mode. Non maintainable, non reliable, non optimized. Someone can tell that: private int something1 public int something2 is littered with private and public. Does it *really* mean that it is littered?
Jul 03 2005
Perhaps dstyle.html should say functions with a leading 'to' should not modify their inputs. There are several toFoo functions in phobos and it would be nice to keep that style consistent.2) 'In' does not allow to distinguish cases: void toUpper(in char[] str_in_place); char[] toUpper(in const char[] str); and select optimal implementation.That's correct, there would be no overloading based on const-ness. I know this is commonplace in C++, but frankly I think it's poor design. A function overloaded on const implicitly has significantly different behavior, and so should have a different name.
Jul 03 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da9b6j$1ouo$1 digitaldaemon.com...Perhaps dstyle.html should say functions with a leading 'to' should not modify their inputs. There are several toFoo functions in phobos and it would be nice to keep that style consistent.That's a good idea. There are also the 'is' prefix functions.
Jul 03 2005
"Walter" <newshound digitalmars.com> wrote in message news:da9dc2$1r5s$2 digitaldaemon.com..."Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da9b6j$1ouo$1 digitaldaemon.com...I beleive that next will be a proposal to use 'c' as a first char of parameter name and all this will end up with Polish Notation and the like... Poor man type system to be short. Gentlemen, array and immutable slice are two *distinct* types with their own set of operations. The same for pointers - immutable pointer cannot be dereferenced to l-value. And please don't cover holes in type system by inventing naming conventions. This is not honest. Andrew.Perhaps dstyle.html should say functions with a leading 'to' should not modify their inputs. There are several toFoo functions in phobos and it would be nice to keep that style consistent.That's a good idea. There are also the 'is' prefix functions.
Jul 03 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da9k9n$2201$1 digitaldaemon.com..."Walter" <newshound digitalmars.com> wrote in message news:da9dc2$1r5s$2 digitaldaemon.com...Nothing is preventing someone from writing void upper(char[] str); char[] toUpper(char[] str); I see no reason to abuse the already-established conventions with the "to" prefix. Multiple versions of toUpper might seem natural to you and your team but it isn't "typical" D code. Even if all your proposals were accepted I would still argue a function named toUpper should not modify its input. That isn't saying your general point is wrong - just that the example you gave using the name "toUpper" isn't one that should be encouraged."Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da9b6j$1ouo$1 digitaldaemon.com...I beleive that next will be a proposal to use 'c' as a first char of parameter name and all this will end up with Polish Notation and the like... Poor man type system to be short. Gentlemen, array and immutable slice are two *distinct* types with their own set of operations. The same for pointers - immutable pointer cannot be dereferenced to l-value. And please don't cover holes in type system by inventing naming conventions. This is not honest. Andrew.Perhaps dstyle.html should say functions with a leading 'to' should not modify their inputs. There are several toFoo functions in phobos and it would be nice to keep that style consistent.That's a good idea. There are also the 'is' prefix functions.
Jul 03 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da9lak$23de$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da9k9n$2201$1 digitaldaemon.com...Ben, am I propsing to abuse naming conventions? No. 'to' works in some places and for someone - fine. But how this related to const? OT: this 'to' in Russian is one letter and sometimes looks funny combined with camelCase."Walter" <newshound digitalmars.com> wrote in message news:da9dc2$1r5s$2 digitaldaemon.com...Nothing is preventing someone from writing void upper(char[] str); char[] toUpper(char[] str); I see no reason to abuse the already-established conventions with the "to" prefix. Multiple versions of toUpper might seem natural to you and your team but it isn't "typical" D code. Even if all your proposals were accepted I would still argue a function named toUpper should not modify its input. That isn't saying your general point is wrong - just that the example you gave using the name "toUpper" isn't one that should be encouraged."Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:da9b6j$1ouo$1 digitaldaemon.com...I beleive that next will be a proposal to use 'c' as a first char of parameter name and all this will end up with Polish Notation and the like... Poor man type system to be short. Gentlemen, array and immutable slice are two *distinct* types with their own set of operations. The same for pointers - immutable pointer cannot be dereferenced to l-value. And please don't cover holes in type system by inventing naming conventions. This is not honest. Andrew.Perhaps dstyle.html should say functions with a leading 'to' should not modify their inputs. There are several toFoo functions in phobos and it would be nice to keep that style consistent.That's a good idea. There are also the 'is' prefix functions.
Jul 03 2005
Andrew Fedoniouk wrote:OT: this 'to' in Russian is one letter and sometimes looks funny combined with camelCase.Emmmm... All speaking russian use english for variables/methods/classes as well as in comments. So this is no matter how such things are translated to native language, you will never find constructions ala stroka kStroke(); :) -- Victor (aka nail) Nakoryakov nail-mail<at>mail<dot>ru Krasnoznamensk, Moscow, Russia
Jul 04 2005
"Walter" <newshound digitalmars.com> wrote in message news:da99t5$1net$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da95gq$1j4t$1 digitaldaemon.com...Walter, imagine that you know nothing about internals of this function: char* toStringz(char[] string) what you can tell about it? And if you'll see char[] toStringz(const char[] string) isn't it better? You don't need documentation or its source code in most cases.1) How in will solve this: class Record { Field[] fields() { return m_fields.dup; // this is not needed, isn't it? // but it must be here in current D. } }It won't, but then again, I don't see that the .dup is necessary there, as fields() is a producer of a value, not a consumer.2) 'In' does not allow to distinguish cases: void toUpper(in char[] str_in_place); char[] toUpper(in const char[] str); and select optimal implementation.That's correct, there would be no overloading based on const-ness. I know this is commonplace in C++, but frankly I think it's poor design. A function overloaded on const implicitly has significantly different behavior, and so should have a different name.wherevolatile/volatile in/volatile out/volatile inout - 'volatile', 'volatile in', 'volatile out' and 'volatile inout' params. would basically operate exactly as they do now. Just like other statements in any other scope, a "volatile" param. would mean "inhibit optimizations on the variable that may effect memory reads/writes". Not even a new keyword.. The whole justification for these new defaults is because the casesThe idea is that the most common case should be the default. Would you agree that for the vast majority of function parameters, they are read only? That mutable ones are relatively rare? If so, then it makes sense to have the uncommon ones need the extra syntax."volatile" would have to be used for the code to operate correctly are a small minority, so shouldn't the default go with what benefits the great majority of cases? Also, the same justification goes for making the default [none] and 'in' operate the same way w.r.t. the new proposal - majority of cases rules. Another big plus would be not having to litter code with 'in' (like C++ code is littered with 'const')."littered with 'const'".... well, it depends.... If European will see Stone Garden in Japan he will find it littered by stones. For me personally code which is not using const looks non-prefessional and written by young hacker in 'fire-n-forget' mode. Non maintainable, non reliable, non optimized. Someone can tell that: private int something1 public int something2 is littered with private and public. Does it *really* mean that it is littered?As for myself, since most parameters in C++ code are const, the const everywhere tends to visually clutter up the code, obscuring the other stuff.most cases are strings I believe. So do alias const char[] string; alias char[] string_buffer; and use this strings. Word 'string' has same number of characters as 'char[]'. And forget about clutter.
Jul 03 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da9jf7$210d$1 digitaldaemon.com...most cases are strings I believe. So doI'm afraid not. Take a look at the STL source code :-( Go into \dm\stlport\stlport\stl and do a grep for "const".
Jul 03 2005
"Walter" <newshound digitalmars.com> wrote in message news:da99t5$1net$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:da95gq$1j4t$1 digitaldaemon.com...1 ) There are situations when you just cannot use different names. E.g. template specializations. 2) "overloaded on const implicitly has significantly different behavior" This apply also to all cases of function overloading. E.g. foo(int i) and foo(char[] s) might have a significantly different behavior, isn't it? 3) "should have a different name" - someone will consider D as language forcing "name pollution" then. Following this statement all toString() shall be rewritten as toStringFromXXX( XXX x );1) How in will solve this: class Record { Field[] fields() { return m_fields.dup; // this is not needed, isn't it? // but it must be here in current D. } }It won't, but then again, I don't see that the .dup is necessary there, as fields() is a producer of a value, not a consumer.2) 'In' does not allow to distinguish cases: void toUpper(in char[] str_in_place); char[] toUpper(in const char[] str); and select optimal implementation.That's correct, there would be no overloading based on const-ness. I know this is commonplace in C++, but frankly I think it's poor design. A function overloaded on const implicitly has significantly different behavior, and so should have a different name.Yep, as I meantioned above: alias const char[] string; will help.wherevolatile/volatile in/volatile out/volatile inout - 'volatile', 'volatile in', 'volatile out' and 'volatile inout' params. would basically operate exactly as they do now. Just like other statements in any other scope, a "volatile" param. would mean "inhibit optimizations on the variable that may effect memory reads/writes". Not even a new keyword.. The whole justification for these new defaults is because the casesThe idea is that the most common case should be the default. Would you agree that for the vast majority of function parameters, they are read only? That mutable ones are relatively rare? If so, then it makes sense to have the uncommon ones need the extra syntax. As for myself, since most parameters in C++ code are const, the const everywhere tends to visually clutter up the code, obscuring the other stuff."volatile" would have to be used for the code to operate correctly are a small minority, so shouldn't the default go with what benefits the great majority of cases? Also, the same justification goes for making the default [none] and 'in' operate the same way w.r.t. the new proposal - majority of cases rules. Another big plus would be not having to litter code with 'in' (like C++ code is littered with 'const')."littered with 'const'".... well, it depends.... If European will see Stone Garden in Japan he will find it littered by stones. For me personally code which is not using const looks non-prefessional and written by young hacker in 'fire-n-forget' mode. Non maintainable, non reliable, non optimized. Someone can tell that: private int something1 public int something2 is littered with private and public. Does it *really* mean that it is littered?
Jul 03 2005