www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DIP53 and DIP49 (ver2) - New definitions for qualified constructors

reply "Kenji Hara" <k.hara.pg gmail.com> writes:
http://wiki.dlang.org/DIP53
Redesign currently implemented qualified constructor concept.

http://wiki.dlang.org/DIP49
Improved points from version 1:
- Swap meanings of 'this(this) inout' and 'this(this) const'
- Inout postblit now covers all cheap (== not rebind 
indirections) copies between same qualifiers

Kenji Hara
Dec 17 2013
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/17/13 7:42 PM, Kenji Hara wrote:
 http://wiki.dlang.org/DIP53
 Redesign currently implemented qualified constructor concept.

 http://wiki.dlang.org/DIP49
 Improved points from version 1:
 - Swap meanings of 'this(this) inout' and 'this(this) const'
 - Inout postblit now covers all cheap (== not rebind indirections)
 copies between same qualifiers

 Kenji Hara
Fantastic. I started to read DIP49 earlier today and it really rings well. I'll read the updated one. Andrei
Dec 17 2013
prev sibling next sibling parent reply "QAston" <qaston gmail.com> writes:
On Wednesday, 18 December 2013 at 03:42:46 UTC, Kenji Hara wrote:
 http://wiki.dlang.org/DIP53
 Redesign currently implemented qualified constructor concept.

 http://wiki.dlang.org/DIP49
 Improved points from version 1:
 - Swap meanings of 'this(this) inout' and 'this(this) const'
 - Inout postblit now covers all cheap (== not rebind 
 indirections) copies between same qualifiers

 Kenji Hara
This is awesome, maybe I'll be able to use immutable in my code, thanks to this and your bugfixes (opAssign)! One suggestion though - maybe unique would be better than const for unique postblit/constructor, I think static confusion is an important lesson from the past.
Dec 18 2013
parent reply "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Wednesday, 18 December 2013 at 11:10:10 UTC, QAston wrote:
 On Wednesday, 18 December 2013 at 03:42:46 UTC, Kenji Hara 
 wrote:
 http://wiki.dlang.org/DIP53
 Redesign currently implemented qualified constructor concept.

 http://wiki.dlang.org/DIP49
 Improved points from version 1:
 - Swap meanings of 'this(this) inout' and 'this(this) const'
 - Inout postblit now covers all cheap (== not rebind 
 indirections) copies between same qualifiers

 Kenji Hara
This is awesome, maybe I'll be able to use immutable in my code, thanks to this and your bugfixes (opAssign)! One suggestion though - maybe unique would be better than const for unique postblit/constructor, I think static confusion is an important lesson from the past.
I agree, ` unique` attribute looks more clear. BTW, we can use `unique` keyword for unique postblit/constructor. Also, we can use this keyword for unique storage class of variables and related issues.
Dec 18 2013
parent reply Kenji Hara <k.hara.pg gmail.com> writes:
I think adding new keyword/attribute just for readability is overkill.

Kenji Hara


2013/12/18 ilya-stromberg <ilya-stromberg-2009 yandex.ru>

 On Wednesday, 18 December 2013 at 11:10:10 UTC, QAston wrote:

 On Wednesday, 18 December 2013 at 03:42:46 UTC, Kenji Hara wrote:

 http://wiki.dlang.org/DIP53
 Redesign currently implemented qualified constructor concept.

 http://wiki.dlang.org/DIP49
 Improved points from version 1:
 - Swap meanings of 'this(this) inout' and 'this(this) const'
 - Inout postblit now covers all cheap (== not rebind indirections)
 copies between same qualifiers

 Kenji Hara
This is awesome, maybe I'll be able to use immutable in my code, thanks to this and your bugfixes (opAssign)! One suggestion though - maybe unique would be better than const for unique postblit/constructor, I think static confusion is an important lesson from the past.
I agree, ` unique` attribute looks more clear. BTW, we can use `unique` keyword for unique postblit/constructor. Also, we can use this keyword for unique storage class of variables and related issues.
Dec 18 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Kenji Hara:

 I think adding new keyword/attribute just for readability is 
 overkill.
Making the code more explicit and easy to understand, using the right words, is rather important. So I like unique, that can probably be re-uses for another purpose. What's worse than having many keywords is having them with multiple meanings. Otherwise are you willing to explain again and again to future people in D.learn that specific "const" doesn't really mean const, it really means... and so on :-) Bye, bearophile
Dec 18 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Wednesday, 18 December 2013 at 15:29:44 UTC, bearophile wrote:
 Kenji Hara:

 I think adding new keyword/attribute just for readability is 
 overkill.
Making the code more explicit and easy to understand, using the right words, is rather important. So I like unique, that can probably be re-uses for another purpose. What's worse than having many keywords is having them with multiple meanings. Otherwise are you willing to explain again and again to future people in D.learn that specific "const" doesn't really mean const, it really means... and so on :-) Bye, bearophile
Which additional meaning will const qualifier have?
Dec 18 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/18/2013 04:47 PM, Maxim Fomin wrote:
 On Wednesday, 18 December 2013 at 15:29:44 UTC, bearophile wrote:
 Kenji Hara:

 I think adding new keyword/attribute just for readability is overkill.
Making the code more explicit and easy to understand, using the right words, is rather important. So I like unique, that can probably be re-uses for another purpose. What's worse than having many keywords is having them with multiple meanings. Otherwise are you willing to explain again and again to future people in D.learn that specific "const" doesn't really mean const, it really means... and so on :-) Bye, bearophile
Which additional meaning will const qualifier have?
It will be used to annotate a postblit that requires all fields with indirections to be re-initialized with freshly allocated data instead of a postblit that is used during copying of a const object. (There will be no way to define such a const postblit, because the DIP assumes this to be useless.)
Dec 18 2013
parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 18/12/13 16:59, Timon Gehr wrote:
 It will be used to annotate a postblit that requires all fields with
 indirections to be re-initialized with freshly allocated data instead of a
 postblit that is used during copying of a const object. (There will be no way
to
 define such a const postblit, because the DIP assumes this to be useless.)
Not sure I see the difference here with the existing different cases of const attached to a variable vs. const attached to a method. The meanings are subtly different but the analogy is helpful.
Dec 18 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/18/2013 05:05 PM, Joseph Rushton Wakeling wrote:
 On 18/12/13 16:59, Timon Gehr wrote:
 It will be used to annotate a postblit that requires all fields with
 indirections to be re-initialized with freshly allocated data instead
 of a
 postblit that is used during copying of a const object. (There will be
 no way to
 define such a const postblit, because the DIP assumes this to be
 useless.)
Not sure I see the difference here with the existing different cases of const attached to a variable vs. const attached to a method. The meanings are subtly different but the analogy is helpful.
Well, 'const' attached to a method is simply the notation used for attaching 'const' to the implicit 'this' parameter.
Dec 18 2013
next sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 18/12/13 18:20, Timon Gehr wrote:
 Well, 'const' attached to a method is simply the notation used for attaching
 'const' to the implicit 'this' parameter.
Sure, but if you see a method: struct Foo { const int bar() { ... } } ... the instinctive interpretation of that is "This is a method that returns a const int." You soon learn your mistake, but once you have, the mental association between one form of const and the other makes sense, even if you don't appreciate the subtlety of the fact that it's referring to the implicit "this" parameter. I suggest attaching const, immutable, etc. to constructors is similarly helpful by analogy, even if it strictly speaking means using the same keyword for two different things.
Dec 18 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 12/18/2013 06:33 PM, Joseph Rushton Wakeling wrote:
 On 18/12/13 18:20, Timon Gehr wrote:
 Well, 'const' attached to a method is simply the notation used for
 attaching
 'const' to the implicit 'this' parameter.
Sure, but if you see a method: struct Foo { const int bar() { ... } } ... the instinctive interpretation of that is "This is a method that returns a const int." You soon learn your mistake, but once you have, the mental association between one form of const and the other makes sense, even if you don't appreciate the subtlety of the fact that it's referring to the implicit "this" parameter. I suggest attaching const, immutable, etc. to constructors is similarly helpful by analogy, even if it strictly speaking means using the same keyword for two different things.
Something that would be closer to what is happening here would be to make the 'const' annotation on a method denote purity.
Dec 18 2013
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Dec 18, 2013 at 06:33:37PM +0100, Joseph Rushton Wakeling wrote:
 On 18/12/13 18:20, Timon Gehr wrote:
Well, 'const' attached to a method is simply the notation used for
attaching 'const' to the implicit 'this' parameter.
Sure, but if you see a method: struct Foo { const int bar() { ... } } ... the instinctive interpretation of that is "This is a method that returns a const int." You soon learn your mistake, but once you have, the mental association between one form of const and the other makes sense, even if you don't appreciate the subtlety of the fact that it's referring to the implicit "this" parameter.
[...] For this reason, it is better to write 'const' on the right side of the function name than on the left: struct Foo { // Now it's clear(er) that 'const' refers to const(this) // rather than const(int). int bar() const { ... } } And also to always write `const(int)` rather than the potentially ambiguous `const int`. It may feel unnecessarily verbose at first, until you have to distinguish between: const(int)[] func(); const(int[]) func(); int[] func() const; const(int)[] func() const; const(int[]) func() const; then you begin to appreciate the notation. :) T -- Almost all proofs have bugs, but almost all theorems are true. -- Paul Pedersen
Dec 18 2013
prev sibling next sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 18/12/13 19:40, H. S. Teoh wrote:
 For this reason, it is better to write 'const' on the right side of the
 function name than on the left
Yes, and it's exactly the practice I follow, although Ddoc replaces it on the left-hand side ... :-)
 And also to always write `const(int)` rather than the potentially
 ambiguous `const int`. It may feel unnecessarily verbose at first, until
 you have to distinguish between:

 	const(int)[] func();
 	const(int[]) func();
 	int[] func() const;
 	const(int)[] func() const;
 	const(int[]) func() const;

 then you begin to appreciate the notation. :)
Well, quite :-) I'm not complaining about the issues here, I'm suggesting that inventing an extra keyword for the cases discussed in these DIPs is not necessary, because the analogy and connection with existing use of const/immutable is valuable.
Dec 18 2013
next sibling parent reply "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Wednesday, 18 December 2013 at 19:10:07 UTC, Joseph Rushton 
Wakeling wrote:
 Well, quite :-)  I'm not complaining about the issues here, I'm 
 suggesting that inventing an extra keyword for the cases 
 discussed in these DIPs is not necessary, because the analogy 
 and connection with existing use of const/immutable is valuable.
Sorry if I miss something, but I don't understand this analogy. `const` means that original type can be `mutable` or `immutable`, so both `mutable` and `immutable` types can be implicitly converted to the `const` type. If I understand DIP correctly, unique postblit/constructor returns `unique` type that can be implicitly converted to the all of `mutable`, `immutable` and `const` types. So, this behavior is the opposite of current `const` behavior. So, where is analogy here? BTW, it looks like the DIP mix `const` and `unique` semantic. It's different things, but they are in the same section.
Dec 18 2013
next sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 18/12/13 21:11, ilya-stromberg wrote:
 Sorry if I miss something, but I don't understand this analogy.

 `const` means that original type can be `mutable` or `immutable`, so both
 `mutable` and `immutable` types can be implicitly converted to the `const`
type.

 If I understand DIP correctly, unique postblit/constructor returns `unique`
type
 that can be implicitly converted to the all of `mutable`, `immutable` and
 `const` types. So, this behavior is the opposite of current `const` behavior.

 So, where is analogy here?
Well, as far as I understand it (happy to be corrected if wrong), the point of this DIP is to offer a way to _easily_ create immutable and const instances of objects (which as I recall from the last time I tried to do it, is a real PITA). So, you have your regular mutable constructor -- 'this' with no qualifications -- which can be used to construct mutable instances. You have this(...) immutable, which can be used to construct immutable instances. And you have this(...) const (aka "unique"), which can be used to construct both immutable and mutable instances. It seems to me that this is a very natural relation to the existing interpretation of mutable, immutable and const variables by the language, and e.g. the way that immutable, mutable and const function parameters are addressed.
Dec 18 2013
next sibling parent reply "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Wednesday, 18 December 2013 at 21:11:10 UTC, Joseph Rushton 
Wakeling wrote:
 On 18/12/13 21:11, ilya-stromberg wrote:
 Sorry if I miss something, but I don't understand this analogy.

 `const` means that original type can be `mutable` or 
 `immutable`, so both
 `mutable` and `immutable` types can be implicitly converted to 
 the `const` type.

 If I understand DIP correctly, unique postblit/constructor 
 returns `unique` type
 that can be implicitly converted to the all of `mutable`, 
 `immutable` and
 `const` types. So, this behavior is the opposite of current 
 `const` behavior.

 So, where is analogy here?
Well, as far as I understand it (happy to be corrected if wrong), the point of this DIP is to offer a way to _easily_ create immutable and const instances of objects (which as I recall from the last time I tried to do it, is a real PITA). So, you have your regular mutable constructor -- 'this' with no qualifications -- which can be used to construct mutable instances. You have this(...) immutable, which can be used to construct immutable instances. And you have this(...) const (aka "unique"), which can be used to construct both immutable and mutable instances. It seems to me that this is a very natural relation to the existing interpretation of mutable, immutable and const variables by the language, and e.g. the way that immutable, mutable and const function parameters are addressed.
I understood your position, but it's bad analogy because we can have both `const` and `unique` postblits/constructors (at least in theory). I want to say that compiler can implicitly convert `mutable` and `immutable` types to the `const` type, but we can add `const` postblit/constructor for better control this cast (of course, only if we decide that it's really need). In other hand, `unique` postblit/constructor creates `unique` type that can be implicitly convert to the `mutable` and `immutable` types. It's different things. So, theoretically we can have both `const` and `unique` postblits/constructors. We shouldn't mix 2 different semantics. I think the main problem with this DIP is `unique` postblit/constructor because we don't know what exactly means `unique`. Maybe we should write another DIP with this description or don't implement `unique` postblit/constructor (for now, I hope).
Dec 18 2013
parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 18/12/13 22:53, ilya-stromberg wrote:
 I understood your position, but it's bad analogy because we can have both
 `const` and `unique` postblits/constructors (at least in theory).

 I want to say that compiler can implicitly convert `mutable` and `immutable`
 types to the `const` type, but we can add `const` postblit/constructor for
 better control this cast (of course, only if we decide that it's really need).
I understand yours too, but isn't this a case where the theory gives us more than we need? That is, we can already get a const instance using the currently-proposed const constructor, with no downside that I can see. I don't particularly want to second-guess the future, but it seems to me like having distinct const and unique constructors would probably just lead to a confusing situation where either people over-specify (e.g. writing both const-specific and unique constructor where just unique would do, with risk of code duplication, extra maintenance burden, etc.) or where people assume that an object doesn't support something they want (e.g. "I can't instantiate a const instance because it doesn't have a const-specific constructor ..."). Unless there's a good application of a specifically const-specific postblit/constructor, it seems to me that the conflation in the DIP is helpful, because it simplifies the process of writing, understanding and using code at the cost of something which probably wouldn't be practically very useful.
Dec 19 2013
parent reply "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Thursday, 19 December 2013 at 09:52:15 UTC, Joseph Rushton 
Wakeling wrote:
 Unless there's a good application of a specifically 
 const-specific postblit/constructor, it seems to me that the 
 conflation in the DIP is helpful, because it simplifies the 
 process of writing, understanding and using code at the cost of 
 something which probably wouldn't be practically very useful.
Yes, I think that REAL const-specific postblit/constructor can be useful, for example, for advanced dynamic typing. For example, we can have reference-counting policy for some data object (for example, for manual memory management). So, we should create smart pointer with simple well-known rules: increase reference count if we create new smart pointer, decrease reference count if we destroy old smart pointer and destroy data object if reference count is equal zero. Now assume that you need multithread support (it's also well-known problem). So, you must use synchronization (mutex and/or atomic operations) for every data object access because because another thread can modify data object. Now assume that we have REAL const-specific postblit/constructor support. In this case we can separate `mutable` and `const` reference counts. If `mutable` reference count is equal 0 we can access data object witout any synchronization because nobody can't change data object (and it will be definetly faster because mutex and/or atomic operations is very slow). So, REAL const-specific postblit/constructor can be really useful for advanced dynamic typing and optimization. Am I right? Another question: for example, we will decide that we want to have REAL const-specific postblit/constructor support after 5-10 years (who knows what happens with D in future?). What should we do in this case: introduce new `realconst` keyword only for REAL const-specific postblit/constructor? Would you like to be responsible for this decision?
Dec 20 2013
parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 20/12/13 10:10, ilya-stromberg wrote:
 Would you like to be responsible for this decision?
I hope it's clear that what I'm trying to do is understand your reasoning, because you have ideas and knowledge that are different from mine.
Dec 20 2013
parent "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Friday, 20 December 2013 at 09:18:07 UTC, Joseph Rushton 
Wakeling wrote:
 On 20/12/13 10:10, ilya-stromberg wrote:
 Would you like to be responsible for this decision?
I hope it's clear that what I'm trying to do is understand your reasoning, because you have ideas and knowledge that are different from mine.
Yes, I know. The main question was: "is this example with advanced dynamic typing good enough and do you agree that REAL const-specific postblit/constructor can be useful?".
Dec 20 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/18/2013 10:11 PM, Joseph Rushton Wakeling wrote:
 And you have this(...) const (aka "unique"), which can be used to
 construct both immutable and mutable instances.

 It seems to me that this is a very natural relation to the existing
 interpretation of mutable, immutable and const variables by the
 language, and e.g. the way that immutable, mutable and const function
 parameters are addressed.
The natural interpretation of a const constructor is that it constructs a const object directly. Such a constructor could eg. initialize a field declared with a mutable type using some external const reference. void foo(const(int[]) a){ // ... struct S{ int[] a; this()const{ this.a=a; } } // ... } The DIP argues that such a construct is not particularly useful and hence eliminates it for the purpose of using the syntax for a _different_ concept. There is no way to implement the above constructor using the new semantics.
Dec 18 2013
next sibling parent "Francesco Cattoglio" <francesco.cattoglio gmail.com> writes:
On Wednesday, 18 December 2013 at 22:26:32 UTC, Timon Gehr wrote:
 The natural interpretation of a const constructor is that it 
 constructs a const object directly. Such a constructor could 
 eg. initialize a field declared with a mutable type using some 
 external const reference.

 void foo(const(int[]) a){
     // ...
     struct S{
         int[] a;
         this()const{
             this.a=a;
         }
     }
     // ...
 }

 The DIP argues that such a construct is not particularly useful 
 and hence eliminates it for the purpose of using the syntax for 
 a _different_ concept. There is no way to implement the above 
 constructor using the new semantics.
Just my 2 cents: I have to agree. The const can be confusing and making it so that a different concept cannot be implemented really looks like a bad idea.
Dec 18 2013
prev sibling parent reply Kenji Hara <k.hara.pg gmail.com> writes:
2013/12/19 Timon Gehr <timon.gehr gmx.ch>

 The natural interpretation of a const constructor is that it constructs a
 const object directly. Such a constructor could eg. initialize a field
 declared with a mutable type using some external const reference.

 void foo(const(int[]) a){
     // ...
     struct S{
         int[] a;
         this()const{
             this.a=a;
         }
     }
     // ...
 }

 The DIP argues that such a construct is not particularly useful
Yes, that's one of the start point of my thoughts.
 and hence eliminates it for the purpose of using the syntax for a
 _different_ concept. There is no way to implement the above constructor
 using the new semantics.
No, that's not merely syntactic choice. The 'const' constructor/postblit is a natural conclusion derived from the semantic meaning. I tweaked descriptions in DIP to express it more clearly. Kenji Hara
Dec 18 2013
parent reply "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Thursday, 19 December 2013 at 01:38:07 UTC, Kenji Hara wrote:
 No, that's not merely syntactic choice. The 'const' 
 constructor/postblit is
 a natural conclusion derived from the semantic meaning.

 I tweaked descriptions in DIP to express it more clearly.
I disagree. It's the `unique` postblit/constructor becaouse it creates object that can be implicitly converted to the all of `mutable`, `immutable` and `const` types. What should we do if we decide that we need REAL `const` postblit/constructor? I mean postblit/constructor that creates only `const` object that can't be implicitly converted to the `mutable` or `immutable`. About possible rationale: see Timon Gehr's example above. Additional example: I want to log all my type casts (for example, for debug purposes). So, I can implement `const` postblit/constructor and use it for every cast from `mutable` and `immutable` to `const`. So, please don't assume that nobody needs REAL `const` postblit/constructor. We can use `unique` keyword for your idea and, theoretically, we can create `unique` storage class for variables that can be implicitly converted to the all of `mutable`, `immutable` and `const` types. BTW, it looks like it's quite easy to implement `unique` storage class only for local scope (only for function body). For example: immutable(int)[] foo() { //it's unique variable because I created it unique arr = new unique int[2]; //I can change unique variable because only I have reference for it arr[0] = 10; arr[1] = 20; //unique variable can be implicitly converted to the immutable variable return arr; } So, `unique` storage class allows to avoid unsafe `cast(immutable)` cast. It's often use case, see also `std.exception.assumeUnique`. So, I think it will be great to have reserved `unique` keyword for `unique` storage class.
Dec 18 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Thursday, 19 December 2013 at 07:31:28 UTC, ilya-stromberg 
wrote:
 What should we do if we decide that we need REAL `const` 
 postblit/constructor? I mean postblit/constructor that creates 
 only `const` object that can't be implicitly converted to the 
 `mutable` or `immutable`.
D is not C/C++. Objects are either mutable or immutable. Sometimes you can view any of them through const. There are no const objects per se.
 BTW, it looks like it's quite easy to implement `unique` 
 storage class only for local scope (only for function body). 
 For example:

 immutable(int)[] foo()
 {
    //it's unique variable because I created it
    unique arr = new unique int[2];

    //I can change unique variable because only I have reference 
 for it
    arr[0] = 10;
    arr[1] = 20;

    //unique variable can be implicitly converted to the 
 immutable variable
    return arr;
 }

 So, `unique` storage class allows to avoid unsafe 
 `cast(immutable)` cast. It's often use case, see also 
 `std.exception.assumeUnique`. So, I think it will be great to 
 have reserved `unique` keyword for `unique` storage class.
Current implementation can be characterized by complete absence of sane escape analysis. import std.stdio; import core.memory; class A { int *ptr; ~this() { (*ptr)++; } } pure foo() { A a = new A; int* ptr = new int; a.ptr = ptr; a = null; return ptr; } void main() { immutable int* ptr = foo(); writeln(*ptr); // it is 0 GC.collect(); writeln(*ptr); // it is 1 now } Your proposal suffers from same issue. Although idea of unique can be worthy, without escape analysis it is another hole.
Dec 19 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Maxim Fomin:

 Your proposal suffers from same issue. Although idea of unique 
 can be worthy, without escape analysis it is another hole.
This seems the next important area of design/implementation work to do on D :-) Bye, bearophile
Dec 19 2013
prev sibling next sibling parent reply "Francesco Cattoglio" <francesco.cattoglio gmail.com> writes:
On Thursday, 19 December 2013 at 11:22:59 UTC, Maxim Fomin wrote:
 void main()
 {
    immutable int* ptr = foo();
    writeln(*ptr); // it is 0
    GC.collect();
    writeln(*ptr); // it is 1 now
 }

 Your proposal suffers from same issue. Although idea of unique 
 can be worthy, without escape analysis it is another hole.
Wow... that looks really unsettling. But as far as I can tell, you are declaring an immutable pointer, and the pointer itself never changes. After all, this looks correct. Or am I missing something from the language specifics?
Dec 19 2013
parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Thursday, 19 December 2013 at 12:49:55 UTC, Francesco 
Cattoglio wrote:
 On Thursday, 19 December 2013 at 11:22:59 UTC, Maxim Fomin 
 wrote:
 void main()
 {
   immutable int* ptr = foo();
   writeln(*ptr); // it is 0
   GC.collect();
   writeln(*ptr); // it is 1 now
 }

 Your proposal suffers from same issue. Although idea of unique 
 can be worthy, without escape analysis it is another hole.
Wow... that looks really unsettling. But as far as I can tell, you are declaring an immutable pointer, and the pointer itself never changes. After all, this looks correct. Or am I missing something from the language specifics?
Actually it is fully immutable, which means that both pointer and pointee are fixed. This is not the case and that's why it is a hole.
Dec 19 2013
prev sibling parent "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Thursday, 19 December 2013 at 11:22:59 UTC, Maxim Fomin wrote:
 On Thursday, 19 December 2013 at 07:31:28 UTC, ilya-stromberg 
 wrote:
 What should we do if we decide that we need REAL `const` 
 postblit/constructor? I mean postblit/constructor that creates 
 only `const` object that can't be implicitly converted to the 
 `mutable` or `immutable`.
D is not C/C++. Objects are either mutable or immutable. Sometimes you can view any of them through const. There are no const objects per se.
Yes, I know. The `const` type means that I don't know at compile time real object type: it can be `mutable` or `immutable` type. I can use `const` postblit/constructor to mark object. It lets me know the real object type at the run time and provide additional optimisations. So, it's a kind of dynamic typing. See also example here: http://forum.dlang.org/thread/oijzbufgajagkonenmxp forum.dlang.org?page=5#post-pakelxyollnwvewuxajo:40forum.dlang.org
Dec 20 2013
prev sibling parent reply Kenji Hara <k.hara.pg gmail.com> writes:
2013/12/19 Joseph Rushton Wakeling <joseph.wakeling webdrake.net>

 And you have this(...) const (aka "unique"), which can be used to
 construct both immutable and mutable instances.

 It seems to me that this is a very natural relation to the existing
 interpretation of mutable, immutable and const variables by the language,
 and e.g. the way that immutable, mutable and const function parameters are
 addressed.
That's right. When 'const' constructor/postblit is called, the constructing object qualifier is either mutable or immutable, even if it is not visible inside const constructor/postblit. ---- I tweaked the descriptions in DIPs, about Const Constructor/Postblit concept. - I mostly removed words "unique constructor" and "unique postblit", because they would just increase reader's confusion. DIPs can describe intrinsic concepts without these words. - I added following sections in DIPs: Why 'const' postblit will called to copy arbitrary qualified object? http://wiki.dlang.org/DIP49#Why_.27const.27_postblit_will_called_to_copy_arbitrary_qualified_object.3F Why 'const' constructor will be called to create arbitrary qualified object? http://wiki.dlang.org/DIP53#Why_.27const.27_constructor_will_be_called_to_create_arbitrary_qualified_object.3F There's no violation against the widely known "const method" concept. Kenji Hara
Dec 18 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/19/2013 02:27 AM, Kenji Hara wrote:
 2013/12/19 Joseph Rushton Wakeling <joseph.wakeling webdrake.net
 <mailto:joseph.wakeling webdrake.net>>

     And you have this(...) const (aka "unique"), which can be used to
     construct both immutable and mutable instances.

     It seems to me that this is a very natural relation to the existing
     interpretation of mutable, immutable and const variables by the
     language, and e.g. the way that immutable, mutable and const
     function parameters are addressed.


 That's right. When 'const' constructor/postblit is called, the
 constructing object qualifier is either mutable or immutable, even if it
 is not visible inside const constructor/postblit.
 ...
That is how to treat a 'wildcard', and not a supertype. The semantics of the new const constructor are the same as for the existing inout constructor.
 ----

 I tweaked the descriptions in DIPs, about Const Constructor/Postblit
 concept.

 - I mostly removed words "unique constructor" and "unique postblit",
 because they would just increase reader's confusion.
    DIPs can describe intrinsic concepts without these words.

 - I added following sections in DIPs:

    Why 'const' postblit will called to copy arbitrary qualified object?
 http://wiki.dlang.org/DIP49#Why_.27const.27_postblit_will_called_to_copy_arbitrary_qualified_object.3F

    Why 'const' constructor will be called to create arbitrary qualified
 object?
 http://wiki.dlang.org/DIP53#Why_.27const.27_constructor_will_be_called_to_create_arbitrary_qualified_object.3F

    There's no violation against the widely known "const method" concept.

 Kenji Hara
Well, a constructor can be thought of as yielding a result. A const method returning 'this' cannot return an 'immutable' object. I do understand your rationale. What I am saying is that the DIP adds a wildcard meaning to 'const' that was not previously there, and I consider this to be more of a weakness than a strength.
Dec 19 2013
parent reply Kenji Hara <k.hara.pg gmail.com> writes:
2013/12/19 Timon Gehr <timon.gehr gmx.ch>
 Well, a constructor can be thought of as yielding a result. A const method
 returning 'this' cannot return an 'immutable' object.
Constructor has no return value in semantic level.
 I do understand your rationale. What I am saying is that the DIP adds a
 wildcard meaning to 'const' that was not previously there, and I consider
 this to be more of a weakness than a strength.
What is the weakness? As far as I can see, there is no *logical* failure. Indeed I can agree that the described concept in the DIP may be hard to understand, but it would be enough easy compared with the currently implemented thing. Kenji Hara
Dec 19 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/19/2013 02:58 PM, Kenji Hara wrote:
 2013/12/19 Timon Gehr <timon.gehr gmx.ch <mailto:timon.gehr gmx.ch>>

     Well, a constructor can be thought of as yielding a result. A const
     method returning 'this' cannot return an 'immutable' object.


 Constructor has no return value in semantic level.
Conceptually speaking, a struct constructor declaration immediately gives you a callable with the corresponding return type. struct S{ this(int x)immutable{ } } immutable(S) construct(int x){ return S(x); }
     I do understand your rationale. What I am saying is that the DIP
     adds a wildcard meaning to 'const' that was not previously there,
     and I consider this to be more of a weakness than a strength.


 What is the weakness? As far as I can see, there is no *logical* failure.

 Indeed I can agree that the described concept in the DIP may be hard to
 understand, but it would be enough easy compared with the currently
 implemented thing.

 Kenji Hara
I think it is easy to understand. I just think that the 'const' qualifier is not descriptive.
Dec 19 2013
parent reply Kenji Hara <k.hara.pg gmail.com> writes:
2013/12/20 Timon Gehr <timon.gehr gmx.ch>

 On 12/19/2013 02:58 PM, Kenji Hara wrote:

 2013/12/19 Timon Gehr <timon.gehr gmx.ch <mailto:timon.gehr gmx.ch>>


     Well, a constructor can be thought of as yielding a result. A const
     method returning 'this' cannot return an 'immutable' object.


 Constructor has no return value in semantic level.
Conceptually speaking, a struct constructor declaration immediately gives you a callable with the corresponding return type. struct S{ this(int x)immutable{ } } immutable(S) construct(int x){ return S(x); }
It's not necessary concept. I do understand your rationale. What I am saying is that the DIP
     adds a wildcard meaning to 'const' that was not previously there,
     and I consider this to be more of a weakness than a strength.


 What is the weakness? As far as I can see, there is no *logical* failure.

 Indeed I can agree that the described concept in the DIP may be hard to
 understand, but it would be enough easy compared with the currently
 implemented thing.

 Kenji Hara
I think it is easy to understand. I just think that the 'const' qualifier is not descriptive.
I think it is necessary small learning cost, to keep language semantics simple. Kenji Hara
Dec 19 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Kenji Hara:

 I think it is necessary small learning cost, to keep language 
 semantics simple.
The semantics of the language is not simpler using "const", it's the same semantic complexity. But it's a little less clear for the person that reads the code. Bye, bearophile
Dec 19 2013
prev sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 19 December 2013 at 15:32:33 UTC, Kenji Hara wrote:
 I think it is necessary small learning cost, to keep language 
 semantics
 simple.

 Kenji Hara
If that is an extra learning cost, doesn't it make the semantic more complex, almost by definition ? I'm also against adding a new meaning to const, especially when its current meaning can make sense.
Dec 19 2013
next sibling parent Kenji Hara <k.hara.pg gmail.com> writes:
2013/12/20 deadalnix <deadalnix gmail.com>

 On Thursday, 19 December 2013 at 15:32:33 UTC, Kenji Hara wrote:

 I think it is necessary small learning cost, to keep language semantics
 simple.

 Kenji Hara
If that is an extra learning cost, doesn't it make the semantic more complex, almost by definition ?
I say it is small but *necessary* cost. It's not extra cost. I'm also against adding a new meaning to const, especially when its current
 meaning can make sense.
These DIPs does not add a new meaning to 'const' as the type qualifier and method qualifier. They binds new meanings to "this(this) const" and this(...) const". You need to learn added meaning, so it's not free, but I'd also say it's enough trivial. Kenji Hara
Dec 19 2013
prev sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 20/12/13 01:41, deadalnix wrote:
 If that is an extra learning cost, doesn't it make the semantic more complex,
 almost by definition ?
Compared to ... ? As far as I can see, it's learning a small extra meaning of 'const' in a context where it's quite intuitive, versus introducing an extra keyword which is used _only_ in this context and which is not entirely intuitive. I'd have said the second would be more complex and more likely to lead to practical misunderstanding.
Dec 19 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Joseph Rushton Wakeling:

 As far as I can see, it's learning a small extra meaning of 
 'const' in a context where it's quite intuitive, versus 
 introducing an extra keyword which is used _only_ in this 
 context and which is not entirely intuitive.
A new keyword is a flag that you have found something different. It makes it simpler to learn.
 I'd have said the second would be more complex and more likely 
 to lead to practical misunderstanding.
Giving different names to different ideas makes them less complex :-) (We are bikeshedding a little.) Bye, bearophile
Dec 20 2013
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 12/20/13, bearophile <bearophileHUGS lycos.com> wrote:
 A new keyword is a flag that you have found something different.
 It makes it simpler to learn.
It also steals a valid symbol name. E.g. there's tons of C code that uses the symbol name "body", but I can't use this symbol because it's used in DBC. It's a keyword that's used in literally just one feature, and it's annoying. Plus DBC code just looks ugly to me (at least with asserts in the actual body I can add diagnostic messages), so I don't see how "body" has made DBC better.
Dec 20 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 It also steals a valid symbol name.
Someone has suggested to prefix it with a .
 E.g. there's tons of C code that
 uses the symbol name "body", but I can't use this symbol 
 because it's
 used in DBC. It's a keyword that's used in literally just one 
 feature, and it's annoying.
In the case discussed here I think the unique will find another usage.
 Plus DBC code just looks ugly to me (at least with
 asserts in the actual body I can add diagnostic messages), so I 
 don't see how "body" has made DBC better.
"body" seems not needed in DBC, I suggested to remove it. But the little failure with body is not the same situation as the one discussed here. Bye, bearophile
Dec 20 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/20/2013 10:13 AM, Andrej Mitrovic wrote:
 On 12/20/13, bearophile <bearophileHUGS lycos.com> wrote:
 A new keyword is a flag that you have found something different.
 It makes it simpler to learn.
It also steals a valid symbol name. E.g. there's tons of C code that uses the symbol name "body", but I can't use this symbol because it's used in DBC. It's a keyword that's used in literally just one feature, and it's annoying. Plus DBC code just looks ugly to me (at least with asserts in the actual body I can add diagnostic messages), so I don't see how "body" has made DBC better.
We could get rid of the keyword easily without changing the syntax of contracts.
Dec 20 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 12/20/2013 12:32 PM, Timon Gehr wrote:
 On 12/20/2013 10:13 AM, Andrej Mitrovic wrote:
 On 12/20/13, bearophile <bearophileHUGS lycos.com> wrote:
 A new keyword is a flag that you have found something different.
 It makes it simpler to learn.
It also steals a valid symbol name. E.g. there's tons of C code that uses the symbol name "body", but I can't use this symbol because it's used in DBC. It's a keyword that's used in literally just one feature, and it's annoying. Plus DBC code just looks ugly to me (at least with asserts in the actual body I can add diagnostic messages), so I don't see how "body" has made DBC better.
We could get rid of the keyword easily without changing the syntax of contracts.
(But then it would be possible to get into funny situations like struct body{...} class C{ abstract void foo()in{...}out{...} body b; // syntax error })
Dec 20 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 12/20/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 at least with
 asserts in the actual body I can add diagnostic messages)
Sorry that was wrong, "in" can be used for that of course. But I don't see the benefit of in blocks.
Dec 20 2013
prev sibling next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 20/12/13 09:42, bearophile wrote:
 A new keyword is a flag that you have found something different. It makes it
 simpler to learn.

 [... ]

 Giving different names to different ideas makes them less complex :-)
Seems to me there's something of a sweet spot to be found between minimizing the total number of keywords in use, adequately expressing the diversity of ideas, and taking advantage of overlapping (not identical) concepts to simplify language usability. But ...
 (We are bikeshedding a little.)
... yes :-) So I'll bow out here.
Dec 20 2013
prev sibling parent "QAston" <qaston gmail.com> writes:
On Friday, 20 December 2013 at 08:42:29 UTC, bearophile wrote:
 (We are bikeshedding a little.)
A lot actually, I just hope this gets implemented, whatever keyword will be used.
Dec 20 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/20/2013 08:43 AM, Joseph Rushton Wakeling wrote:
 On 20/12/13 01:41, deadalnix wrote:
 If that is an extra learning cost, doesn't it make the semantic more
 complex,
 almost by definition ?
Compared to ... ? As far as I can see, it's learning a small extra meaning of 'const' in a context where it's quite intuitive, ...
It is not only adding an extra meaning of const, but also removing an old one in some specific context. Why is the following 'intuitive'? const(int*) g = ...; struct S{ int* a, b; this(immutable(int)* a, immutable(int)* b)immutable{ this.a=a; // ok this.b=b; // ok } this(const(int)* a, const(int)* b)const{ this.a=a; // error this.b=b; // error } // if we want to initialize a and b with pointers // with different qualifiers, we can do the following this(inout(int)* a, inout(int)* b)inout{ this.a=a; // ok this.b=b; // ok } // but in general, initializing a field with a // 'const' reference is not fair game in such // a constructor this(inout(int)* a)inout{ this.a=a; this.b=g; // error } } Why is it 'intuitive' that in this context 'inout' is not a wildcard for the other type qualifiers? struct S{ int* a, b; this(inout(int)* a, inout(int)* b)inout{ this.a=a; this.b=b; } // no go: // this(const(int)* a, const(int)* b)const{this.a=a; this.b=b; } } // ... // but: int* a = ...; immutable(int)* b=...; auto s = S(a,b); // ok! static assert(is(typeof(s)==const(S))); The DIP breaks some existing, perfectly valid code without any clear way to fix it. const(int)* foo(...){ ... } class C{ int* a; this()const{ a = foo(...); // error } } Again, what is so 'intuitive' about this?
Dec 20 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 12/20/2013 03:04 PM, Timon Gehr wrote:
 The DIP breaks some existing, perfectly valid code without any clear way
 to fix it.

 const(int)* foo(...){ ... }

 class C{
      int* a;
      this()const{
          a = foo(...); // error
      }
 }
The actual workaround will be: class C{ int* a; private this(inout(int)* foo_result)inout{ a = foo_result; } } const(C) constructC(){ return new C(foo(...)); } // or 'new const(C)' ? If so, how to add a const constructor // without breaking the workaround?
Dec 20 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/18/2013 08:09 PM, Joseph Rushton Wakeling wrote:
 On 18/12/13 19:40, H. S. Teoh wrote:
 For this reason, it is better to write 'const' on the right side of the
 function name than on the left
Yes, and it's exactly the practice I follow, although Ddoc replaces it on the left-hand side ... :-)
 And also to always write `const(int)` rather than the potentially
 ambiguous `const int`. It may feel unnecessarily verbose at first, until
 you have to distinguish between:

     const(int)[] func();
     const(int[]) func();
     int[] func() const;
     const(int)[] func() const;
     const(int[]) func() const;

 then you begin to appreciate the notation. :)
Well, quite :-) I'm not complaining about the issues here, I'm suggesting that inventing an extra keyword for the cases discussed in these DIPs is not necessary, because the analogy and connection with existing use of const/immutable is valuable.
There is no such analogy or connection.
Dec 18 2013
parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 18/12/13 21:16, Timon Gehr wrote:
 On 12/18/2013 08:09 PM, Joseph Rushton Wakeling wrote:
 Well, quite :-)  I'm not complaining about the issues here, I'm
 suggesting that inventing an extra keyword for the cases discussed in
 these DIPs is not necessary, because the analogy and connection with
 existing use of const/immutable is valuable.
There is no such analogy or connection.
See my earlier response to Ilya. If I've interpreted things wrongly, do let me know, but I don't see how you can say there is not a useful overlap between the meaning placed on these qualifiers in this DIP and the meaning placed on them in other circumstances in the language.
Dec 18 2013
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Dec 18, 2013 at 08:09:54PM +0100, Joseph Rushton Wakeling wrote:
 On 18/12/13 19:40, H. S. Teoh wrote:
For this reason, it is better to write 'const' on the right side of
the function name than on the left
Yes, and it's exactly the practice I follow, although Ddoc replaces it on the left-hand side ... :-)
I know, and IMO this deserves a bug in bugzilla. The idea behind Ddoc is very good, but there are quite a few areas in the current implementation that leaves one disappointed, and this is one of them. (I know I'm opening a can of worms here, since a good number of people prefer writing function modifiers on the left, but I feel strongly enough about this to bring it up. :P)
And also to always write `const(int)` rather than the potentially
ambiguous `const int`. It may feel unnecessarily verbose at first,
until you have to distinguish between:

	const(int)[] func();
	const(int[]) func();
	int[] func() const;
	const(int)[] func() const;
	const(int[]) func() const;

then you begin to appreciate the notation. :)
Well, quite :-) I'm not complaining about the issues here, I'm suggesting that inventing an extra keyword for the cases discussed in these DIPs is not necessary, because the analogy and connection with existing use of const/immutable is valuable.
Yes. T -- Windows: the ultimate triumph of marketing over technology. -- Adrian von Bidder
Dec 18 2013
prev sibling parent "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Wednesday, 18 December 2013 at 15:20:39 UTC, Kenji Hara wrote:
 I think adding new keyword/attribute just for readability is 
 overkill.

 Kenji Hara
We can use `unique` keyword as unique storage class of variables in future if we decide that this feature can be useful. It's not my idea, see `std.exception.assumeUnique`: "Checking for uniqueness during compilation is possible in certain cases (see the unique and lent keywords in the ArchJava language), but complicates the language considerably.". We already have reserved `macro` keyword for AST macros, so add one more reserved keyword for possible language improvement is not so terrible. But, of course, it's only my IMHO.
Dec 18 2013
prev sibling next sibling parent "Joseph Rushton Wakeling" <joseph.wakeling webdrake.net> writes:
On Wednesday, 18 December 2013 at 03:42:46 UTC, Kenji Hara wrote:
 http://wiki.dlang.org/DIP53
 Redesign currently implemented qualified constructor concept.
Thank you very much -- this is going to be really useful.
Dec 18 2013
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.ca> writes:
On 2013-12-18 03:42:38 +0000, "Kenji Hara" <k.hara.pg gmail.com> said:

 http://wiki.dlang.org/DIP49
 Improved points from version 1:
 - Swap meanings of 'this(this) inout' and 'this(this) const'
 - Inout postblit now covers all cheap (== not rebind indirections) 
 copies between same qualifiers
I can't help but notice that if you want class-typed members to be assignable in a "this(this) immutable" context you'll need to add tail-constness for classes in the language. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Dec 19 2013
parent reply Kenji Hara <k.hara.pg gmail.com> writes:
2013/12/20 Michel Fortin <michel.fortin michelf.ca>

 On 2013-12-18 03:42:38 +0000, "Kenji Hara" <k.hara.pg gmail.com> said:

  http://wiki.dlang.org/DIP49
 Improved points from version 1:
 - Swap meanings of 'this(this) inout' and 'this(this) const'
 - Inout postblit now covers all cheap (== not rebind indirections) copies
 between same qualifiers
I can't help but notice that if you want class-typed members to be assignable in a "this(this) immutable" context you'll need to add tail-constness for classes in the language.
Sorry I can't understand what you saying. DIP49 does not touch class reference semantics. It's not a purpose of DIP49. Kenji Hara
Dec 19 2013
parent reply Michel Fortin <michel.fortin michelf.ca> writes:
On 2013-12-20 01:31:03 +0000, Kenji Hara <k.hara.pg gmail.com> said:

 
 2013/12/20 Michel Fortin <michel.fortin michelf.ca>
 
 On 2013-12-18 03:42:38 +0000, "Kenji Hara" <k.hara.pg gmail.com> said:
 
 http://wiki.dlang.org/DIP49
 Improved points from version 1:
 - Swap meanings of 'this(this) inout' and 'this(this) const'
 - Inout postblit now covers all cheap (== not rebind indirections) copies
 between same qualifiers
 
I can't help but notice that if you want class-typed members to be assignable in a "this(this) immutable" context you'll need to add tail-constness for classes in the language.
Sorry I can't understand what you saying. DIP49 does not touch class reference semantics. It's not a purpose of DIP49.
But what if your struct has a class-typed member: struct A { Object o; int* a; this(this) { a = new int; o = new Object; } this(this) immutable { a = new immutable(int); o = new immutable(Object); // will that work? } } On the second postblit, the type of "a" has to be "immutable(int)*" to allow you to assign something else to the pointer while not being able to affect what's at the other end of the indirection. So then, what is the type of "o"? Again, you need to be able to assign the variable while not affecting what is at the other end of the indirection. You need a tail-immutable object reference, which doesn't exist. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Dec 19 2013
next sibling parent Michel Fortin <michel.fortin michelf.ca> writes:
On 2013-12-20 02:07:32 +0000, Michel Fortin <michel.fortin michelf.ca> said:

 But what if your struct has a class-typed member:
 
 	struct A {
 		Object o;
 		int* a;
 
 		this(this) {
 			a = new int;
 			o = new Object;
 		}
 
 		this(this) immutable {
 			a = new immutable(int);
 			o = new immutable(Object); // will that work?
 		}
 	}
 
 On the second postblit, the type of "a" has to be "immutable(int)*" to 
 allow you to assign something else to the pointer while not being able 
 to affect what's at the other end of the indirection.
 
 So then, what is the type of "o"? Again, you need to be able to assign 
 the variable while not affecting what is at the other end of the 
 indirection. You need a tail-immutable object reference, which doesn't 
 exist.
I just want to add that this is not a criticism of the DIP in any way. I'm simply pointing out that it'll just make more visible an already embarrassing omission in the language. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Dec 19 2013
prev sibling parent Kenji Hara <k.hara.pg gmail.com> writes:
2013/12/20 Michel Fortin <michel.fortin michelf.ca>

 But what if your struct has a class-typed member:

         struct A {
                 Object o;
                 int* a;

                 this(this) {
                         a = new int;
                         o = new Object;
                 }

                 this(this) immutable {
                         a = new immutable(int);
                         o = new immutable(Object); // will that work?
                 }
         }

 On the second postblit, the type of "a" has to be "immutable(int)*" to
 allow you to assign something else to the pointer while not being able to
 affect what's at the other end of the indirection.

 So then, what is the type of "o"? Again, you need to be able to assign the
 variable while not affecting what is at the other end of the indirection.
 You need a tail-immutable object reference, which doesn't exist.
That's already resolved "design issue" from 2.064, by fixing issue 9665. http://d.puremagic.com/issues/show_bug.cgi?id=9665 Inside constructor, first occured field assignment is automatically handled as the field initializing. struct A { Object o; int* a; this(int) immutable { a = new immutable(int); // is exactly same as: immutable int* a = new immutable(int); o = new immutable(Object); // is exactly same as: immutable(Object) o = new immutable(Object); } Inside postblit, the same rule should be applied. this(this) immutable { a = new immutable(int); // is exactly same as: immutable int* a = new immutable(int); o = new immutable(Object); // is exactly same as: immutable(Object) o = new immutable(Object); } Unfortunately postblit case does not work. I can say it's definitely a compiler bug. http://d.puremagic.com/issues/show_bug.cgi?id=11292 However, I'm purposely delaying to fix the bug, because of DIP49. Kenji Hara
Dec 19 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/18/2013 04:42 AM, Kenji Hara wrote:
 http://wiki.dlang.org/DIP53
 Redesign currently implemented qualified constructor concept.
 ...
Roughly speaking, this DIP just removes a language feature and changes the syntax of another feature to something less descriptive. I think implementing this is a net loss.
 http://wiki.dlang.org/DIP49
 Improved points from version 1:
 - Swap meanings of 'this(this) inout' and 'this(this) const'
 - Inout postblit now covers all cheap (== not rebind indirections)
 copies between same qualifiers

 Kenji Hara
What about just mentioning the qualifiers of source and target of the copy explicitly? this(this){ ... } // mutable source, mutable target this(immutable this){ ... } // immutable source mutable target this(const this)immutable{ ... } // const source, immutable target this(const this)const{ ... } // const source, const target // ... this(inout this)inout{ ... } // source and target have the same qualifier // ... this(this)inout{ ... } // mutable source, arbitrary target // ... this(const this)inout{ ... } // const source, arbitrary target Whenever source and target are (potentially) incompatible, the postblit ensures that all fields with incompatible types in source and target are reinitialized. Only unique expressions convert to 'inout' anyway, hence the last signature above would correspond to unique postblit in the current proposal. This would be more explicit, strictly more expressive and require less special casing in the compiler implementation.
Dec 20 2013
next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
Just watched this presentation : 
http://www.infoq.com/presentations/functional-pros-cons

Skip to minute 28 to understand what we are discussing here about 
the magical unique.
Dec 20 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 12/21/2013 03:57 AM, deadalnix wrote:
 Just watched this presentation :
 http://www.infoq.com/presentations/functional-pros-cons

 Skip to minute 28 to understand what we are discussing here about the
 magical unique.
At minute 28 he starts discussing Monads using Dart-like syntax.
Dec 21 2013
prev sibling parent "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Friday, 20 December 2013 at 22:40:16 UTC, Timon Gehr wrote:
 http://wiki.dlang.org/DIP49
 Improved points from version 1:
 - Swap meanings of 'this(this) inout' and 'this(this) const'
 - Inout postblit now covers all cheap (== not rebind 
 indirections)
 copies between same qualifiers

 Kenji Hara
What about just mentioning the qualifiers of source and target of the copy explicitly? this(this){ ... } // mutable source, mutable target this(immutable this){ ... } // immutable source mutable target this(const this)immutable{ ... } // const source, immutable target this(const this)const{ ... } // const source, const target // ... this(inout this)inout{ ... } // source and target have the same qualifier // ... this(this)inout{ ... } // mutable source, arbitrary target // ... this(const this)inout{ ... } // const source, arbitrary target Whenever source and target are (potentially) incompatible, the postblit ensures that all fields with incompatible types in source and target are reinitialized. Only unique expressions convert to 'inout' anyway, hence the last signature above would correspond to unique postblit in the current proposal. This would be more explicit, strictly more expressive and require less special casing in the compiler implementation.
I agree, it will be the most powerful solution. And we should use the same rules for constructor behavior. Also, we have strange rules in DIP 53:
 If mutable constructor is defined, if immutable constructor is 
 not defined, it will be used for const object construction.
 If immutable constructor is defined, if mutable constructor is 
 not defined, it will be used for const object construction.
What happens if we have both mutable and immutable constructors?
Dec 21 2013