July 11, 2005 Re: Round III, Brainstorm, Re: Immutable arrays for Walter and rest of us. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | "Ben Hinkle" <Ben_member@pathlink.com> wrote in message news:dadu5k$1ei$1@digitaldaemon.com... > >1) Reasonable model of "costness" > > Do what Walter suggested for 'in' plus 3 things: 1) 'out' return values 2) > 'final' local variables and 3) make violations warn and not error. I think > it > should be a warning because mixing final/non-final is roughly like passing > a > signed int to an unsigned int - something fishy is going on but we'll > assume the > user knows what they are doing until they ask for our advice. In case it > isn't > obvious an explicit out return value means the output shouldn't be > modified by > the caller (ie assign it to a final variable or an in parameter). A final > local > variable is "deep immutable". > >>2) Notation. E.g. how readonly slice will look like >> in code. Function parameters, etc. > > void foo(in char[] str); // Walter's idea > out char[] foo(); // means output is read-only > final char[] str = "blah"; // str is read-only > >>3) How to avoid "clutter". This term appears here >> not once - means that it is reasonable - so >> we need to deal with it. > > Avoids clutter by making it a warning so you don't have to go nuts with > final if > you don't want to. A variation on this is to just use the 'final' keyword and forget about marking output values. So an input parameter, local variable or field marked 'final' means "deep immutable" in Walter's sense for the lifetime of that variable. A final variable of array, pointer or reference type can be assigned new values but the contents of the array, pointer or reference (recursively) cannot change. void foo(final char[] str); // Walter's idea with 'final' instead of 'in' final char[] str = "blah"; // str contents are read-only struct Foo { final char[] str; } If one really misses const outputs a 'final' output value can be spoofed by transforming T foo(); to struct finalT{ final T x;} finalT foo(); although that would get annoying pretty quickly both to write, use and maintain. |
July 11, 2005 Re: Round III, Brainstorm, Re: Immutable arrays for Walter and rest of us. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | "Ben Hinkle" <bhinkle@mathworks.com> wrote in message news:datvsm$1e46$1@digitaldaemon.com... > > "Ben Hinkle" <Ben_member@pathlink.com> wrote in message news:dadu5k$1ei$1@digitaldaemon.com... >> >1) Reasonable model of "costness" >> >> Do what Walter suggested for 'in' plus 3 things: 1) 'out' return values >> 2) >> 'final' local variables and 3) make violations warn and not error. I >> think it >> should be a warning because mixing final/non-final is roughly like >> passing a >> signed int to an unsigned int - something fishy is going on but we'll >> assume the >> user knows what they are doing until they ask for our advice. In case it >> isn't >> obvious an explicit out return value means the output shouldn't be >> modified by >> the caller (ie assign it to a final variable or an in parameter). A final >> local >> variable is "deep immutable". >> >>>2) Notation. E.g. how readonly slice will look like >>> in code. Function parameters, etc. >> >> void foo(in char[] str); // Walter's idea >> out char[] foo(); // means output is read-only >> final char[] str = "blah"; // str is read-only >> >>>3) How to avoid "clutter". This term appears here >>> not once - means that it is reasonable - so >>> we need to deal with it. >> >> Avoids clutter by making it a warning so you don't have to go nuts with >> final if >> you don't want to. > > A variation on this is to just use the 'final' keyword and forget about > marking output values. So an input parameter, local variable or field > marked 'final' means "deep immutable" in Walter's sense for the lifetime > of that variable. A final variable of array, pointer or reference type can > be assigned new values but the contents of the array, pointer or reference > (recursively) cannot change. > void foo(final char[] str); // Walter's idea with 'final' instead of 'in' > final char[] str = "blah"; // str contents are read-only > struct Foo { final char[] str; } > > If one really misses const outputs a 'final' output value can be spoofed > by transforming > T foo(); > to > struct finalT{ final T x;} > finalT foo(); > although that would get annoying pretty quickly both to write, use and > maintain. > > Ben, am I correct thinking that your proposal void foo(final char[] str); // Walter's idea with 'final' instead of 'in' final char[] str = "blah"; // str contents are read-only struct Foo { final char[] str; } uses the same idea as in C++ void foo(const char[] str); const char[] str = "blah"; struct Foo { const char[] str; } but with different keyword? |
July 11, 2005 Re: Round III, Brainstorm, Re: Immutable arrays for Walter and rest of us. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Fedoniouk | > Ben, am I correct thinking that your proposal > > void foo(final char[] str); // Walter's idea with 'final' instead of 'in' > final char[] str = "blah"; // str contents are read-only > struct Foo { final char[] str; } > > uses the same idea as in C++ > > void foo(const char[] str); > const char[] str = "blah"; > struct Foo { const char[] str; } > > but with different keyword? not exactly - see Walter's post about 'in'. Also in C++ const is a type modifier and here final would modify a variable like in Java. For information about Java's notion of final see http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.12.4 The difference from Java's final is that in Java final means the variable doesn't change but the array or object contents can change and here it would be the reverse - the variable can change but the contents can't. Other than that it's the same as Java's final :-) |
July 11, 2005 Re: Round III, Brainstorm, Re: Immutable arrays for Walter and rest of us. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | "Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:dau6b2$1kuv$1@digitaldaemon.com... >> Ben, am I correct thinking that your proposal >> >> void foo(final char[] str); // Walter's idea with 'final' instead of 'in' >> final char[] str = "blah"; // str contents are read-only >> struct Foo { final char[] str; } >> >> uses the same idea as in C++ >> >> void foo(const char[] str); >> const char[] str = "blah"; >> struct Foo { const char[] str; } >> >> but with different keyword? > > not exactly - see Walter's post about 'in'. Also in C++ const is a type > modifier and here final would modify a variable like in Java. For > information about Java's notion of final see > http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.12.4 > The difference from Java's final is that in Java final means the variable > doesn't change but the array or object contents can change and here it > would be the reverse - the variable can change but the contents can't. > Other than that it's the same as Java's final :-) Hmm, it seems that we are speaking about the same entity but using different terms. See, in C++ declaration of const variable like const typename v; means declaration of variable of "const typename" - implicitly generated type - const version of typename with all non const members disabled ( non availble ) for use through 'v' alias. Therefore, if I understand you and Walter correctly C++: void foo(const char[] str) is exactly yours: void foo(final char[] str) and Walter's: void foo(in char[] str) Is this correct? Andrew. |
July 11, 2005 Re: Round III, Brainstorm, Re: Immutable arrays for Walter and rest of us. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Fedoniouk | > Hmm, it seems that we are speaking about the same entity but using different terms. > > See, in C++ declaration of const variable like > > const typename v; > > means declaration of variable of "const typename" - implicitly generated > type - const version > of typename with all non const members disabled ( non availble ) for use > through 'v' alias. > > Therefore, if I understand you and Walter correctly > > C++: > void foo(const char[] str) > > is exactly yours: > void foo(final char[] str) > > and Walter's: > void foo(in char[] str) > > Is this correct? Not as I read Walter's posts like http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/26096. In particular C++ const says nothing about changing the values through other references while this final/in proposal would assert that the value remains constant through all references. That's been the drum-beat of all these posts saying why D doesn't have const already. I don't understand the confusion here. In addition the final/in proposal is different than C++ const for the following example: struct A { A* ptr; } void foo(final A* ptr2) { ptr2.ptr.ptr = null; // illegal } void main() { A a; a.ptr = &a; foo(&a); } vs in C++ struct A { A* ptr; } void foo(const A* ptr2) { ptr2->ptr->ptr = 0; // legal } void main() { A a; a.ptr = &a; foo(&a); } The example is simplistic but it illustrates the meaning of recursive/deep immutability. |
July 11, 2005 Re: Round III, Brainstorm, Re: Immutable arrays for Walter and rest of us. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | "Ben Hinkle" <bhinkle@mathworks.com> wrote in message news:daubr5$1phd$1@digitaldaemon.com... >> Hmm, it seems that we are speaking about the same entity but using different terms. >> >> See, in C++ declaration of const variable like >> >> const typename v; >> >> means declaration of variable of "const typename" - implicitly generated >> type - const version >> of typename with all non const members disabled ( non availble ) for use >> through 'v' alias. >> >> Therefore, if I understand you and Walter correctly >> >> C++: >> void foo(const char[] str) >> >> is exactly yours: >> void foo(final char[] str) >> >> and Walter's: >> void foo(in char[] str) >> >> Is this correct? > > Not as I read Walter's posts like http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/26096. In particular C++ const says nothing about changing the values through other references while this final/in proposal would assert that the value remains constant through all references. That's been the drum-beat of all these posts saying why D doesn't have const already. I don't understand the confusion here. Practical "ultimate resource immutability" ( a.k.a. "Andrei's deep immutability" ) implementation is not feasible on compiler level for langages of D class (e.g. having pointers). Only on VM level it is possible to do it and at some extent only. As "D virtual machine" is a processor itself then it means that without os/hardware support implementation of this dream is not possible. I though that it was clear from the very beginning.... BTW: Do you know any solution for read-only protection of any arbitrary memory location? Highly probable that I missed something in this area recently. > > In addition the final/in proposal is different than C++ const for the > following example: > struct A { > A* ptr; > } > void foo(final A* ptr2) { > ptr2.ptr.ptr = null; // illegal > } > void main() { > A a; > a.ptr = &a; > foo(&a); > } > vs in C++ > struct A { > A* ptr; > } > void foo(const A* ptr2) { > ptr2->ptr->ptr = 0; // legal > } True. I think that C++ behavior in this case can be better as if you would change this to: struct A { A *_ptr; A* ptr() { return _ptr; } }; void foo(const A* ptr2) { ptr2->ptr()->ptr(); // error here } you will get an error: 'ptr' : cannot convert 'this' pointer from 'const struct A' to 'struct A &' or so. > void main() { > A a; > a.ptr = &a; > foo(&a); > } > The example is simplistic but it illustrates the meaning of recursive/deep > immutability. Yes it is. As I have shown in example above C++ does such deep immutability. I am using "deep immutability" term as it is described here: http://www-sop.inria.fr/everest/events/cassis05/Transp/poll.pdf page #18 |
July 11, 2005 Re: Round III, Brainstorm, Re: Immutable arrays for Walter and rest of us. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Fedoniouk | "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:daui3u$1vos$1@digitaldaemon.com... > > "Ben Hinkle" <bhinkle@mathworks.com> wrote in message news:daubr5$1phd$1@digitaldaemon.com... >>> Hmm, it seems that we are speaking about the same entity but using different terms. >>> >>> See, in C++ declaration of const variable like >>> >>> const typename v; >>> >>> means declaration of variable of "const typename" - implicitly generated >>> type - const version >>> of typename with all non const members disabled ( non availble ) for use >>> through 'v' alias. >>> >>> Therefore, if I understand you and Walter correctly >>> >>> C++: >>> void foo(const char[] str) >>> >>> is exactly yours: >>> void foo(final char[] str) >>> >>> and Walter's: >>> void foo(in char[] str) >>> >>> Is this correct? >> >> Not as I read Walter's posts like http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/26096. In particular C++ const says nothing about changing the values through other references while this final/in proposal would assert that the value remains constant through all references. That's been the drum-beat of all these posts saying why D doesn't have const already. I don't understand the confusion here. > > Practical "ultimate resource immutability" ( a.k.a. > "Andrei's deep immutability" ) implementation is not feasible on compiler > level for > langages of D class (e.g. having pointers). > Only on VM level it is possible to do it and at some extent only. As > "D virtual machine" is a processor itself then it means that without > os/hardware support implementation of this dream is not possible. > I though that it was clear from the very beginning.... > > BTW: Do you know any solution for read-only protection > of any arbitrary memory location? > Highly probable that I missed something in this area recently. As Walter's original post said deep immutability is a contract made by the programmer to the compiler (and other programmers) which the compiler can verify in simple cases similar to the cases C++ const would catch. It is independent of any VM or the existence of pointers. Are you trying to say the contract must be verfied in *all* cases? I agree it is impractical to validate all cases. I suspect that's why Walter said the compiler would only catch simple cases like assigning through an immutable pointer and such. >> >> In addition the final/in proposal is different than C++ const for the >> following example: >> struct A { >> A* ptr; >> } >> void foo(final A* ptr2) { >> ptr2.ptr.ptr = null; // illegal >> } >> void main() { >> A a; >> a.ptr = &a; >> foo(&a); >> } > >> vs in C++ >> struct A { >> A* ptr; >> } >> void foo(const A* ptr2) { >> ptr2->ptr->ptr = 0; // legal >> } > > True. I think that C++ behavior in this case can be better as if you would change this to: > > struct A { > A *_ptr; > A* ptr() { return _ptr; } > }; > > void foo(const A* ptr2) { > ptr2->ptr()->ptr(); // error here > } > > you will get an error: > 'ptr' : cannot convert 'this' pointer from 'const struct A' to 'struct A > &' or so. > >> void main() { >> A a; >> a.ptr = &a; >> foo(&a); >> } >> The example is simplistic but it illustrates the meaning of >> recursive/deep immutability. > > Yes it is. As I have shown in example above C++ does > such deep immutability. Sure - if you change the C++ example to not allow any writing then it becomes immutable. But that is different than what I originally posted and what Walter meant by deep immutable parameter. > I am using "deep immutability" term as it is described here: http://www-sop.inria.fr/everest/events/cassis05/Transp/poll.pdf page #18 I understand. Do you understand Walter's description of deep immutability from his post? The key phrase in Walter's post is "every sub-object reachable from that parameter". Perhaps we should start using the phrases "deep immutable type" and "deep immutable variable" to distinguish between the notions. |
July 11, 2005 Re: Round III, Brainstorm, Re: Immutable arrays for Walter and rest of us. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | "Ben Hinkle" <bhinkle@mathworks.com> wrote in message news:daul84$229o$1@digitaldaemon.com... > > "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:daui3u$1vos$1@digitaldaemon.com... >> >> "Ben Hinkle" <bhinkle@mathworks.com> wrote in message news:daubr5$1phd$1@digitaldaemon.com... >>>> Hmm, it seems that we are speaking about the same entity but using different terms. >>>> >>>> See, in C++ declaration of const variable like >>>> >>>> const typename v; >>>> >>>> means declaration of variable of "const typename" - implicitly >>>> generated type - const version >>>> of typename with all non const members disabled ( non availble ) for >>>> use through 'v' alias. >>>> >>>> Therefore, if I understand you and Walter correctly >>>> >>>> C++: >>>> void foo(const char[] str) >>>> >>>> is exactly yours: >>>> void foo(final char[] str) >>>> >>>> and Walter's: >>>> void foo(in char[] str) >>>> >>>> Is this correct? >>> >>> Not as I read Walter's posts like http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/26096. In particular C++ const says nothing about changing the values through other references while this final/in proposal would assert that the value remains constant through all references. That's been the drum-beat of all these posts saying why D doesn't have const already. I don't understand the confusion here. >> >> Practical "ultimate resource immutability" ( a.k.a. >> "Andrei's deep immutability" ) implementation is not feasible on compiler >> level for >> langages of D class (e.g. having pointers). >> Only on VM level it is possible to do it and at some extent only. As >> "D virtual machine" is a processor itself then it means that without >> os/hardware support implementation of this dream is not possible. >> I though that it was clear from the very beginning.... >> >> BTW: Do you know any solution for read-only protection >> of any arbitrary memory location? >> Highly probable that I missed something in this area recently. > > As Walter's original post said deep immutability is a contract made by the programmer to the compiler (and other programmers) which the compiler can verify in simple cases similar to the cases C++ const would catch. It is independent of any VM or the existence of pointers. Are you trying to say the contract must be verfied in *all* cases? I agree it is impractical to validate all cases. I suspect that's why Walter said the compiler would only catch simple cases like assigning through an immutable pointer and such. I suspect quite opposite: Walter: "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++." Ben: "Are you trying to say the contract must be verfied in *all* cases?" Of course no. This is Walter who is trying to say this as far as I understand his concerns about 'const' in C++. > >>> >>> In addition the final/in proposal is different than C++ const for the >>> following example: >>> struct A { >>> A* ptr; >>> } >>> void foo(final A* ptr2) { >>> ptr2.ptr.ptr = null; // illegal >>> } >>> void main() { >>> A a; >>> a.ptr = &a; >>> foo(&a); >>> } >> >>> vs in C++ >>> struct A { >>> A* ptr; >>> } >>> void foo(const A* ptr2) { >>> ptr2->ptr->ptr = 0; // legal >>> } >> >> True. I think that C++ behavior in this case can be better as if you would change this to: >> >> struct A { >> A *_ptr; >> A* ptr() { return _ptr; } >> }; >> >> void foo(const A* ptr2) { >> ptr2->ptr()->ptr(); // error here >> } >> >> you will get an error: >> 'ptr' : cannot convert 'this' pointer from 'const struct A' to 'struct A >> &' or so. >> >>> void main() { >>> A a; >>> a.ptr = &a; >>> foo(&a); >>> } >>> The example is simplistic but it illustrates the meaning of >>> recursive/deep immutability. >> >> Yes it is. As I have shown in example above C++ does >> such deep immutability. > > Sure - if you change the C++ example to not allow any writing then it becomes immutable. But that is different than what I originally posted and what Walter meant by deep immutable parameter. > >> I am using "deep immutability" term as it is described here: http://www-sop.inria.fr/everest/events/cassis05/Transp/poll.pdf page #18 > > I understand. Do you understand Walter's description of deep immutability from his post? The key phrase in Walter's post is "every sub-object reachable from that parameter". Perhaps we should start using the phrases "deep immutable type" and "deep immutable variable" to distinguish between the notions. > Yes, I think I understand "every sub-object reachable from that parameter". This is exactly referentional deep immutability - "using this particular reference to the object it is impossible to change state of the object and every sub-object reachable from that object" This is what C++ and Javari are doing: "The specific constraint expressed is that the abstract state of the object to which an immutable reference refers cannot be modified using that reference. The abstract state is (part of) the transitively reachable state: that is, the state of the object and all state reachable from it by following references. The type system permits explicitly excluding fields or objects from the abstract state of an object. For a statically type-safe language, the type system guarantees reference immutability." Javari also allows to: "If the language is extended with immutability downcasts, then run-time checks enforce the reference immutability constraints." by making specific changes in VM. C++ is using 'const' and Javari uses 'readonly' for marking parameters, fields and methods. http://pag.csail.mit.edu/~mernst/pubs/ref-immutability-oopsla2004-slides.pdf http://pag.csail.mit.edu/~mernst/pubs/ref-immutability-oopsla2004.pdf |
July 11, 2005 Re: Round III, Brainstorm, Re: Immutable arrays for Walter and rest of us. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Fedoniouk | On Mon, 11 Jul 2005 16:09:37 -0700, Andrew Fedoniouk <news@terrainformatica.com> wrote:
> Yes, I think I understand "every sub-object reachable from that parameter".
> This is exactly referentional deep immutability -
> "using this particular reference to the object it is impossible to change
> state of the object and every sub-object reachable from that object"
>
> This is what C++ and Javari are doing:
Doesn't this example:
struct A {
A* ptr;
}
void foo(const A* ptr2) {
ptr2->ptr->ptr = 0; // legal
}
void main() {
A a;
a.ptr = &a;
foo(&a);
}
show that C++ const does not (by default) protect sub-objects, instead a re-design (as you posted) to also use a getter is required.
Walters 'in'/'final' deep immutable idea would not require the getter (if I understand it correctly) and so is surely superior?
Regan
|
July 11, 2005 Re: Round III, Brainstorm, Re: Immutable arrays for Walter and rest of us. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | "Regan Heath" <regan@netwin.co.nz> wrote in message news:opstru1ah323k2f5@nrage.netwin.co.nz... > On Mon, 11 Jul 2005 16:09:37 -0700, Andrew Fedoniouk <news@terrainformatica.com> wrote: >> Yes, I think I understand "every sub-object reachable from that >> parameter". >> This is exactly referentional deep immutability - >> "using this particular reference to the object it is impossible to change >> state of the object and every sub-object reachable from that object" >> >> This is what C++ and Javari are doing: > > Doesn't this example: > > struct A { > A* ptr; > } > void foo(const A* ptr2) { > ptr2->ptr->ptr = 0; // legal > } > void main() { > A a; > a.ptr = &a; > foo(&a); > } > > show that C++ const does not (by default) protect sub-objects, instead a re-design (as you posted) to also use a getter is required. As far as I recall it was some rationale behind this. I'll try to find. In any case implementation of this approach will end up with marking parameters, fields and methods by 'const' or 'readonly'. This is what is being considered by Walter as "cluttering" (I personally don't think so) > > Walters 'in'/'final' deep immutable idea would not require the getter (if I understand it correctly) and so is surely superior? > > Regan |
Copyright © 1999-2021 by the D Language Foundation