digitalmars.D - DIP53 and DIP49 (ver2) - New definitions for qualified constructors
- Kenji Hara (8/8) Dec 17 2013 http://wiki.dlang.org/DIP53
- Andrei Alexandrescu (4/12) Dec 17 2013 Fantastic. I started to read DIP49 earlier today and it really rings
- QAston (6/14) Dec 18 2013 This is awesome, maybe I'll be able to use immutable in my code,
- ilya-stromberg (5/22) Dec 18 2013 I agree, `@unique` attribute looks more clear.
- Kenji Hara (3/29) Dec 18 2013 I think adding new keyword/attribute just for readability is overkill.
- bearophile (10/12) Dec 18 2013 Making the code more explicit and easy to understand, using the
- Maxim Fomin (2/14) Dec 18 2013 Which additional meaning will const qualifier have?
- Timon Gehr (6/23) Dec 18 2013 It will be used to annotate a postblit that requires all fields with
- Joseph Rushton Wakeling (4/8) Dec 18 2013 Not sure I see the difference here with the existing different cases of ...
- Timon Gehr (3/14) Dec 18 2013 Well, 'const' attached to a method is simply the notation used for
- Joseph Rushton Wakeling (14/16) Dec 18 2013 Sure, but if you see a method:
- Timon Gehr (3/20) Dec 18 2013 Something that would be closer to what is happening here would be to
- H. S. Teoh (22/38) Dec 18 2013 [...]
- Joseph Rushton Wakeling (7/18) Dec 18 2013 Yes, and it's exactly the practice I follow, although Ddoc replaces it o...
- ilya-stromberg (13/17) Dec 18 2013 Sorry if I miss something, but I don't understand this analogy.
- Joseph Rushton Wakeling (12/19) Dec 18 2013 Well, as far as I understand it (happy to be corrected if wrong), the po...
- ilya-stromberg (19/50) Dec 18 2013 I understood your position, but it's bad analogy because we can
- Joseph Rushton Wakeling (15/20) Dec 19 2013 I understand yours too, but isn't this a case where the theory gives us ...
- ilya-stromberg (28/33) Dec 20 2013 Yes, I think that REAL const-specific postblit/constructor can be
- Joseph Rushton Wakeling (3/4) Dec 20 2013 I hope it's clear that what I'm trying to do is understand your reasonin...
- ilya-stromberg (5/10) Dec 20 2013 Yes, I know. The main question was: "is this example with
- Timon Gehr (18/24) Dec 18 2013 The natural interpretation of a const constructor is that it constructs
- Francesco Cattoglio (4/22) Dec 18 2013 Just my 2 cents: I have to agree. The const can be confusing and
- Kenji Hara (6/23) Dec 18 2013 No, that's not merely syntactic choice. The 'const' constructor/postblit...
- ilya-stromberg (36/40) Dec 18 2013 I disagree. It's the `unique` postblit/constructor becaouse it
- Maxim Fomin (34/57) Dec 19 2013 D is not C/C++. Objects are either mutable or immutable.
- bearophile (5/7) Dec 19 2013 This seems the next important area of design/implementation work
- Francesco Cattoglio (5/14) Dec 19 2013 Wow... that looks really unsettling.
- Maxim Fomin (5/22) Dec 19 2013 Actually it is fully immutable, which means that both pointer and
- ilya-stromberg (8/17) Dec 20 2013 Yes, I know. The `const` type means that I don't know at compile
- Kenji Hara (18/24) Dec 18 2013 That's right. When 'const' constructor/postblit is called, the construct...
- Timon Gehr (9/35) Dec 19 2013 That is how to treat a 'wildcard', and not a supertype. The semantics of...
- Kenji Hara (7/12) Dec 19 2013 What is the weakness? As far as I can see, there is no *logical* failure...
- Timon Gehr (7/19) Dec 19 2013 Conceptually speaking, a struct constructor declaration immediately
- Kenji Hara (6/35) Dec 19 2013 It's not necessary concept.
- bearophile (6/8) Dec 19 2013 The semantics of the language is not simpler using "const", it's
- deadalnix (5/9) Dec 19 2013 If that is an extra learning cost, doesn't it make the semantic
- Kenji Hara (9/18) Dec 19 2013 I say it is small but *necessary* cost. It's not extra cost.
- Joseph Rushton Wakeling (7/9) Dec 19 2013 Compared to ... ?
- bearophile (8/14) Dec 20 2013 A new keyword is a flag that you have found something different.
- Andrej Mitrovic (7/9) Dec 20 2013 It also steals a valid symbol name. E.g. there's tons of C code that
- bearophile (9/18) Dec 20 2013 In the case discussed here I think the @unique will find another
- Timon Gehr (3/12) Dec 20 2013 We could get rid of the keyword easily without changing the syntax of
- Timon Gehr (7/21) Dec 20 2013 (But then it would be possible to get into funny situations like
- Andrej Mitrovic (3/5) Dec 20 2013 Sorry that was wrong, "in" can be used for that of course. But I don't
- Joseph Rushton Wakeling (6/11) Dec 20 2013 Seems to me there's something of a sweet spot to be found between minimi...
- QAston (3/4) Dec 20 2013 A lot actually, I just hope this gets implemented, whatever
- Timon Gehr (55/62) Dec 20 2013 It is not only adding an extra meaning of const, but also removing an
- Timon Gehr (11/20) Dec 20 2013 The actual workaround will be:
- Timon Gehr (2/22) Dec 18 2013 There is no such analogy or connection.
- Joseph Rushton Wakeling (5/11) Dec 18 2013 See my earlier response to Ilya. If I've interpreted things wrongly, do...
- H. S. Teoh (11/33) Dec 18 2013 I know, and IMO this deserves a bug in bugzilla. The idea behind Ddoc is
- ilya-stromberg (10/13) Dec 18 2013 We can use `unique` keyword as unique storage class of variables
- Joseph Rushton Wakeling (2/4) Dec 18 2013 Thank you very much -- this is going to be really useful.
- Michel Fortin (8/13) Dec 19 2013 I can't help but notice that if you want class-typed members to be
- Kenji Hara (4/14) Dec 19 2013 Sorry I can't understand what you saying. DIP49 does not touch class
- Michel Fortin (25/44) Dec 19 2013 But what if your struct has a class-typed member:
- Michel Fortin (8/33) Dec 19 2013 I just want to add that this is not a criticism of the DIP in any way.
- Kenji Hara (26/45) Dec 19 2013 That's already resolved "design issue" from 2.064, by fixing issue 9665.
- Timon Gehr (23/32) Dec 20 2013 Roughly speaking, this DIP just removes a language feature and changes
- deadalnix (4/4) Dec 20 2013 Just watched this presentation :
- Timon Gehr (2/6) Dec 21 2013 At minute 28 he starts discussing Monads using Dart-like syntax.
- ilya-stromberg (5/39) Dec 21 2013 I agree, it will be the most powerful solution. And we should use
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
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 HaraFantastic. I started to read DIP49 earlier today and it really rings well. I'll read the updated one. Andrei
Dec 17 2013
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 HaraThis 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
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: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.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 HaraThis 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
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: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.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 HaraThis 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
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
On Wednesday, 18 December 2013 at 15:29:44 UTC, bearophile wrote:Kenji Hara:Which additional meaning will const qualifier have?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
On 12/18/2013 04:47 PM, Maxim Fomin wrote:On Wednesday, 18 December 2013 at 15:29:44 UTC, bearophile 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.)Kenji Hara:Which additional meaning will const qualifier have?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
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
On 12/18/2013 05:05 PM, Joseph Rushton Wakeling wrote:On 18/12/13 16:59, Timon Gehr wrote:Well, 'const' attached to a method is simply the notation used for attaching 'const' to the implicit 'this' parameter.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
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
On 12/18/2013 06:33 PM, Joseph Rushton Wakeling wrote:On 18/12/13 18:20, Timon Gehr wrote:Something that would be closer to what is happening here would be to make the 'const' annotation on a method denote purity.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
On Wed, Dec 18, 2013 at 06:33:37PM +0100, Joseph Rushton Wakeling wrote:On 18/12/13 18:20, Timon Gehr wrote:[...] 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 PedersenWell, '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.
Dec 18 2013
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 leftYes, 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
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
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
On Wednesday, 18 December 2013 at 21:11:10 UTC, Joseph Rushton Wakeling wrote:On 18/12/13 21:11, 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). 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).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
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
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
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
On Friday, 20 December 2013 at 09:18:07 UTC, Joseph Rushton Wakeling wrote:On 20/12/13 10:10, ilya-stromberg wrote: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?".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
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
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
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 usefulYes, 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
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
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
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
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
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: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.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
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: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.orgWhat 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.
Dec 20 2013
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
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 HaraWell, 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
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
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 HaraI think it is easy to understand. I just think that the 'const' qualifier is not descriptive.
Dec 19 2013
2013/12/20 Timon Gehr <timon.gehr gmx.ch>On 12/19/2013 02:58 PM, Kenji Hara wrote:It's not necessary concept. I do understand your rationale. What I am saying is that the DIP2013/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 think it is necessary small learning cost, to keep language semantics simple. Kenji Haraadds 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 HaraI think it is easy to understand. I just think that the 'const' qualifier is not descriptive.
Dec 19 2013
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
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 HaraIf 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
2013/12/20 deadalnix <deadalnix gmail.com>On Thursday, 19 December 2013 at 15:32:33 UTC, Kenji Hara wrote: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 currentI think it is necessary small learning cost, to keep language semantics simple. Kenji HaraIf that is an extra learning cost, doesn't it make the semantic more complex, almost by definition ?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
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
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
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
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
On 12/20/2013 10:13 AM, Andrej Mitrovic wrote:On 12/20/13, bearophile <bearophileHUGS lycos.com> wrote:We could get rid of the keyword easily without changing the syntax of contracts.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
On 12/20/2013 12:32 PM, Timon Gehr wrote:On 12/20/2013 10:13 AM, Andrej Mitrovic wrote:(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 })On 12/20/13, bearophile <bearophileHUGS lycos.com> wrote:We could get rid of the keyword easily without changing the syntax of contracts.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
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
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
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
On 12/20/2013 08:43 AM, Joseph Rushton Wakeling wrote:On 20/12/13 01:41, deadalnix wrote: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?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, ...
Dec 20 2013
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
On 12/18/2013 08:09 PM, Joseph Rushton Wakeling wrote:On 18/12/13 19:40, H. S. Teoh wrote:There is no such analogy or connection.For this reason, it is better to write 'const' on the right side of the function name than on the leftYes, 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
On 18/12/13 21:16, Timon Gehr wrote:On 12/18/2013 08:09 PM, Joseph Rushton Wakeling wrote: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.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
On Wed, Dec 18, 2013 at 08:09:54PM +0100, Joseph Rushton Wakeling wrote:On 18/12/13 19:40, H. S. Teoh wrote: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)For this reason, it is better to write 'const' on the right side of the function name than on the leftYes, and it's exactly the practice I follow, although Ddoc replaces it on the left-hand side ... :-)Yes. T -- Windows: the ultimate triumph of marketing over technology. -- Adrian von BidderAnd 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
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 HaraWe 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
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
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 qualifiersI 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
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/DIP49Sorry I can't understand what you saying. DIP49 does not touch class reference semantics. It's not a purpose of DIP49. Kenji HaraImproved 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 qualifiersI 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.
Dec 19 2013
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>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.caOn 2013-12-18 03:42:38 +0000, "Kenji Hara" <k.hara.pg gmail.com> said: http://wiki.dlang.org/DIP49Sorry I can't understand what you saying. DIP49 does not touch class reference semantics. It's not a purpose of 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 qualifiersI 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.
Dec 19 2013
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
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
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 HaraWhat 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
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
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
On Friday, 20 December 2013 at 22:40:16 UTC, Timon Gehr wrote: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: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 HaraWhat 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.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