December 18, 2013 Re: DIP53 and DIP49 (ver2) - New definitions for qualified constructors and postblits | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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.
|
December 18, 2013 Re: DIP53 and DIP49 (ver2) - New definitions for qualified constructors and postblits | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joseph Rushton Wakeling | 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).
|
December 18, 2013 Re: DIP53 and DIP49 (ver2) - New definitions for qualified constructors and postblits | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joseph Rushton Wakeling | 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.
|
December 18, 2013 Re: DIP53 and DIP49 (ver2) - New definitions for qualified constructors and postblits | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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.
|
December 19, 2013 Re: DIP53 and DIP49 (ver2) - New definitions for qualified constructors and postblits | ||||
---|---|---|---|---|
| ||||
Attachments:
| 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 |
December 19, 2013 Re: DIP53 and DIP49 (ver2) - New definitions for qualified constructors and postblits | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr Attachments:
| 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 |
December 19, 2013 Re: DIP53 and DIP49 (ver2) - New definitions for qualified constructors and postblits | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kenji Hara | 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.
|
December 19, 2013 Re: DIP53 and DIP49 (ver2) - New definitions for qualified constructors and postblits | ||||
---|---|---|---|---|
| ||||
Posted in reply to ilya-stromberg | 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.
|
December 19, 2013 Re: DIP53 and DIP49 (ver2) - New definitions for qualified constructors and postblits | ||||
---|---|---|---|---|
| ||||
Posted in reply to ilya-stromberg | 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. |
December 19, 2013 Re: DIP53 and DIP49 (ver2) - New definitions for qualified constructors and postblits | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxim Fomin | 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
|
Copyright © 1999-2021 by the D Language Foundation