October 01, 2008 Re: invariant/const class storage class | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | "Sean Kelly" wrote
> Yigal Chripun wrote:
>> Walter Bright wrote:
>>> Simen Kjaeraas wrote:
>>>> Is this really correct behavior? How then are we supposed to
>>>> initialize our
>>>> invariant objects?
>>> Currently, create them as mutable ones, then cast them to invariant.
>>
>> I understand casting as breaking the type system. shouldn't there be a
>> way to create invariant objects without the cast?
>> an invariant constructor seems a good way to solve this. any plans on
>> adding such a feature to D2?
>
> Definitely. I can't imagine that the current situation is any more than an incomplete design. After all, everything needs to be initialized.
>
>> I think it can work like this:
>>
>> class A {
>> this(params) {} // [1]
>> invariant this(params) {} // [2]
>> }
>
> I don't see any point in having a separate 'invariant' ctor, given my point about initialization above. It should be perfectly legal to simply do:
>
> class A {}
> invariant a = new A;
>
> Just as it should be legal to do:
>
> string s = "a" ~ "b";
>
> That both are illegal right now is ridiculous. Perhaps the "Polysemous Value" idea can apply here. Since the compiler can clearly detect that in both cases the value being assigned is not shared it should be perfectly acceptable to implicitly convert its type to a compatible but stronger type.
What if the constructor for A stores a mutable reference to itself somewhere? Or even a mutable reference to one of it's members? This breaks the guarantee of transitive invariance, and the author of the constructor shouldn't need to worry about that. That's why I think we do need invariant constructors.
BTW, I think you may have mistyped your string s = "a" ~ "b" example, that should be legal.
-Steve
| |||
October 01, 2008 Re: invariant/const class storage class | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer a écrit : > The different methods of making a class instance invariant basically depend on when the invariance applies. For classes where the type is declared invariant, the invariant label is enforced after the memory is acquired and initialized, and before the constructor is called. This doesn't seem to me to be a very useful construct. > Ok now I understand the compiling error. > Casting after the class is created makes the invariant label apply after the user has received the constructed class, but casting to invariant is up to the user. > > BTW, casting to invariant is the only possible way to make useful invariant heap data. One generates the data, then casts it to invariant. Usually this is done with brand-new memory so there is no chance for some separate mutable reference to be formed. The downside is that the assurance that the data is truly invariant is up to the developer. The compiler has to take your word for it. > > The proposed invariant constructors as defined in Andrei's functional document (don't have the pdf link handy, but it's on the digitalmars web site), I believe they had a section of code that you could set data, but once you started using the 'this' pointer as arguments to other functions, 'this' implicitly switched to invariant. I believe this would make invariant classes much more useful. > > There is another alternative that works today. A public static method that does this explicitly. If you make the constructor private, then you can force the caller to use the public static method. e.g.: > > class X > { > private this() {} > public static invariant(X) makeInstance() { return cast(invariant(X)) new X();} > } > > Now you can be assured that all instances of X are invariant, and you are free to assign data to members in the constructor, making X a useful construct. It's slightly better than fully custom invariance (such as with Java Strings) in that the compiler and users of the class can make more assumptions, and not as much care needs to be taken in implementing such a class. > > -Steve > Thanks for the explanations and the trick! | |||
October 01, 2008 Re: invariant/const class storage class | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote:
>
> BTW, I think you may have mistyped your string s = "a" ~ "b" example, that should be legal.
Oops, you're right. For compilation to fail, change it to:
string s = "a".dup ~ "b";
Sean
| |||
October 02, 2008 Re: invariant/const class storage class | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Yigal Chripun | On Wed, 01 Oct 2008 16:23:32 +0200, Yigal Chripun <yigal100@gmail.com> wrote: > Andrei Alexandrescu wrote: >> Yigal Chripun wrote: >>> Walter Bright wrote: >>>> Simen Kjaeraas wrote: >>>>> Is this really correct behavior? How then are we supposed to >>>>> initialize our >>>>> invariant objects? >>>> Currently, create them as mutable ones, then cast them to invariant. >>> >>> I understand casting as breaking the type system. shouldn't there be a >>> way to create invariant objects without the cast? >>> an invariant constructor seems a good way to solve this. any plans on >>> adding such a feature to D2? >> >> There are plans. >> >>> I think it can work like this: >>> >>> class A { >>> this(params) {} // [1] >>> invariant this(params) {} // [2] >>> } >>> >>> // create a mutable object - will use type [1] c-tors. >>> auto a = new A(params); >>> >>> // create an invariant object - will use type [2] c-tors. >>> invariant a = new A(params); >>> >>> // create a const object - will use type [1] or [2] c-tors. >>> const a = new A(params); >>> >>> in the const case, if there are two c-tors which only differ by >>> invariant-ness of the c-tor using either will create ambiguity and >>> therefore should be a compile-time error. >> >> Way, way, way more complicated than this. >> >> Andrei > > May I ask what are the complications? "Mortis Portalis Tackulatum - and he's still breathing"... -- Simen | |||
October 02, 2008 Re: invariant/const class storage class | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | Simen Kjaeraas wrote:
> On Wed, 01 Oct 2008 16:23:32 +0200, Yigal Chripun <yigal100@gmail.com> wrote:
>
>> Andrei Alexandrescu wrote:
>>> Yigal Chripun wrote:
>>>> Walter Bright wrote:
>>>>> Simen Kjaeraas wrote:
>>>>>> Is this really correct behavior? How then are we supposed to
>>>>>> initialize our
>>>>>> invariant objects?
>>>>> Currently, create them as mutable ones, then cast them to invariant.
>>>>
>>>> I understand casting as breaking the type system. shouldn't there be a
>>>> way to create invariant objects without the cast?
>>>> an invariant constructor seems a good way to solve this. any plans on
>>>> adding such a feature to D2?
>>>
>>> There are plans.
>>>
>>>> I think it can work like this:
>>>>
>>>> class A {
>>>> this(params) {} // [1]
>>>> invariant this(params) {} // [2]
>>>> }
>>>>
>>>> // create a mutable object - will use type [1] c-tors.
>>>> auto a = new A(params);
>>>>
>>>> // create an invariant object - will use type [2] c-tors.
>>>> invariant a = new A(params);
>>>>
>>>> // create a const object - will use type [1] or [2] c-tors.
>>>> const a = new A(params);
>>>>
>>>> in the const case, if there are two c-tors which only differ by
>>>> invariant-ness of the c-tor using either will create ambiguity and
>>>> therefore should be a compile-time error.
>>>
>>> Way, way, way more complicated than this.
>>>
>>> Andrei
>>
>> May I ask what are the complications?
>
> "Mortis Portalis Tackulatum - and he's still breathing"...
Tackulatum? Was that tacitum?
Andrei
| |||
October 02, 2008 Re: invariant/const class storage class | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thu, 02 Oct 2008 03:46:00 +0200, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > Simen Kjaeraas wrote: >> On Wed, 01 Oct 2008 16:23:32 +0200, Yigal Chripun <yigal100@gmail.com> wrote: >> >>> Andrei Alexandrescu wrote: >>>> Yigal Chripun wrote: >>>>> Walter Bright wrote: >>>>>> Simen Kjaeraas wrote: >>>>>>> Is this really correct behavior? How then are we supposed to >>>>>>> initialize our >>>>>>> invariant objects? >>>>>> Currently, create them as mutable ones, then cast them to invariant. >>>>> >>>>> I understand casting as breaking the type system. shouldn't there be a >>>>> way to create invariant objects without the cast? >>>>> an invariant constructor seems a good way to solve this. any plans on >>>>> adding such a feature to D2? >>>> >>>> There are plans. >>>> >>>>> I think it can work like this: >>>>> >>>>> class A { >>>>> this(params) {} // [1] >>>>> invariant this(params) {} // [2] >>>>> } >>>>> >>>>> // create a mutable object - will use type [1] c-tors. >>>>> auto a = new A(params); >>>>> >>>>> // create an invariant object - will use type [2] c-tors. >>>>> invariant a = new A(params); >>>>> >>>>> // create a const object - will use type [1] or [2] c-tors. >>>>> const a = new A(params); >>>>> >>>>> in the const case, if there are two c-tors which only differ by >>>>> invariant-ness of the c-tor using either will create ambiguity and >>>>> therefore should be a compile-time error. >>>> >>>> Way, way, way more complicated than this. >>>> >>>> Andrei >>> >>> May I ask what are the complications? >> "Mortis Portalis Tackulatum - and he's still breathing"... > > Tackulatum? Was that tacitum? > > Andrei > From Terry Pratchett's 'Pyramids'. Doctor: "Fairly straightforward. A case of mortis portalis tackulatum with complications." Chidder: "What's that mean?" Doctor: "In laymen's terms, he's as dead as a doornail." Chidder: "What are the complications?" Doctor: "He's still breathing." -- Simen | |||
October 02, 2008 Re: invariant/const class storage class | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | Simen Kjaeraas wrote:
> On Thu, 02 Oct 2008 03:46:00 +0200, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>
>> Simen Kjaeraas wrote:
>>> On Wed, 01 Oct 2008 16:23:32 +0200, Yigal Chripun <yigal100@gmail.com> wrote:
>>>
>>>> Andrei Alexandrescu wrote:
>>>>> Yigal Chripun wrote:
>>>>>> Walter Bright wrote:
>>>>>>> Simen Kjaeraas wrote:
>>>>>>>> Is this really correct behavior? How then are we supposed to
>>>>>>>> initialize our
>>>>>>>> invariant objects?
>>>>>>> Currently, create them as mutable ones, then cast them to invariant.
>>>>>>
>>>>>> I understand casting as breaking the type system. shouldn't there be a
>>>>>> way to create invariant objects without the cast?
>>>>>> an invariant constructor seems a good way to solve this. any plans on
>>>>>> adding such a feature to D2?
>>>>>
>>>>> There are plans.
>>>>>
>>>>>> I think it can work like this:
>>>>>>
>>>>>> class A {
>>>>>> this(params) {} // [1]
>>>>>> invariant this(params) {} // [2]
>>>>>> }
>>>>>>
>>>>>> // create a mutable object - will use type [1] c-tors.
>>>>>> auto a = new A(params);
>>>>>>
>>>>>> // create an invariant object - will use type [2] c-tors.
>>>>>> invariant a = new A(params);
>>>>>>
>>>>>> // create a const object - will use type [1] or [2] c-tors.
>>>>>> const a = new A(params);
>>>>>>
>>>>>> in the const case, if there are two c-tors which only differ by
>>>>>> invariant-ness of the c-tor using either will create ambiguity and
>>>>>> therefore should be a compile-time error.
>>>>>
>>>>> Way, way, way more complicated than this.
>>>>>
>>>>> Andrei
>>>>
>>>> May I ask what are the complications?
>>> "Mortis Portalis Tackulatum - and he's still breathing"...
>>
>> Tackulatum? Was that tacitum?
>>
>> Andrei
>>
>
> From Terry Pratchett's 'Pyramids'.
>
> Doctor: "Fairly straightforward. A case of mortis portalis tackulatum with complications."
> Chidder: "What's that mean?"
> Doctor: "In laymen's terms, he's as dead as a doornail."
> Chidder: "What are the complications?"
> Doctor: "He's still breathing."
Heh. Funny, but what's the link?
Andrei
| |||
October 02, 2008 Re: invariant/const class storage class | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thu, 02 Oct 2008 03:54:02 +0200, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > Simen Kjaeraas wrote: >> On Thu, 02 Oct 2008 03:46:00 +0200, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: >> >>> Simen Kjaeraas wrote: >>>> On Wed, 01 Oct 2008 16:23:32 +0200, Yigal Chripun <yigal100@gmail.com> wrote: >>>> >>>>> Andrei Alexandrescu wrote: >>>>>> Yigal Chripun wrote: >>>>>>> Walter Bright wrote: >>>>>>>> Simen Kjaeraas wrote: >>>>>>>>> Is this really correct behavior? How then are we supposed to >>>>>>>>> initialize our >>>>>>>>> invariant objects? >>>>>>>> Currently, create them as mutable ones, then cast them to invariant. >>>>>>> >>>>>>> I understand casting as breaking the type system. shouldn't there be a >>>>>>> way to create invariant objects without the cast? >>>>>>> an invariant constructor seems a good way to solve this. any plans on >>>>>>> adding such a feature to D2? >>>>>> >>>>>> There are plans. >>>>>> >>>>>>> I think it can work like this: >>>>>>> >>>>>>> class A { >>>>>>> this(params) {} // [1] >>>>>>> invariant this(params) {} // [2] >>>>>>> } >>>>>>> >>>>>>> // create a mutable object - will use type [1] c-tors. >>>>>>> auto a = new A(params); >>>>>>> >>>>>>> // create an invariant object - will use type [2] c-tors. >>>>>>> invariant a = new A(params); >>>>>>> >>>>>>> // create a const object - will use type [1] or [2] c-tors. >>>>>>> const a = new A(params); >>>>>>> >>>>>>> in the const case, if there are two c-tors which only differ by >>>>>>> invariant-ness of the c-tor using either will create ambiguity and >>>>>>> therefore should be a compile-time error. >>>>>> >>>>>> Way, way, way more complicated than this. >>>>>> >>>>>> Andrei >>>>> >>>>> May I ask what are the complications? >>>> "Mortis Portalis Tackulatum - and he's still breathing"... >>> >>> Tackulatum? Was that tacitum? >>> >>> Andrei >>> >> From Terry Pratchett's 'Pyramids'. >> Doctor: "Fairly straightforward. A case of mortis portalis tackulatum with complications." >> Chidder: "What's that mean?" >> Doctor: "In laymen's terms, he's as dead as a doornail." >> Chidder: "What are the complications?" >> Doctor: "He's still breathing." > > Heh. Funny, but what's the link? > > Andrei Uhm, nothing really. Just this managed to slip past my nonsense filter at 4 in the morning. -- Simen | |||
October 02, 2008 Re: invariant/const class storage class | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | Simen Kjaeraas wrote:
> On Thu, 02 Oct 2008 03:54:02 +0200, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>
>> Simen Kjaeraas wrote:
>>> On Thu, 02 Oct 2008 03:46:00 +0200, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>>
>>>> Simen Kjaeraas wrote:
>>>>> On Wed, 01 Oct 2008 16:23:32 +0200, Yigal Chripun <yigal100@gmail.com> wrote:
>>>>>
>>>>>> Andrei Alexandrescu wrote:
>>>>>>> Yigal Chripun wrote:
>>>>>>>> Walter Bright wrote:
>>>>>>>>> Simen Kjaeraas wrote:
>>>>>>>>>> Is this really correct behavior? How then are we supposed to
>>>>>>>>>> initialize our
>>>>>>>>>> invariant objects?
>>>>>>>>> Currently, create them as mutable ones, then cast them to invariant.
>>>>>>>>
>>>>>>>> I understand casting as breaking the type system. shouldn't there be a
>>>>>>>> way to create invariant objects without the cast?
>>>>>>>> an invariant constructor seems a good way to solve this. any plans on
>>>>>>>> adding such a feature to D2?
>>>>>>>
>>>>>>> There are plans.
>>>>>>>
>>>>>>>> I think it can work like this:
>>>>>>>>
>>>>>>>> class A {
>>>>>>>> this(params) {} // [1]
>>>>>>>> invariant this(params) {} // [2]
>>>>>>>> }
>>>>>>>>
>>>>>>>> // create a mutable object - will use type [1] c-tors.
>>>>>>>> auto a = new A(params);
>>>>>>>>
>>>>>>>> // create an invariant object - will use type [2] c-tors.
>>>>>>>> invariant a = new A(params);
>>>>>>>>
>>>>>>>> // create a const object - will use type [1] or [2] c-tors.
>>>>>>>> const a = new A(params);
>>>>>>>>
>>>>>>>> in the const case, if there are two c-tors which only differ by
>>>>>>>> invariant-ness of the c-tor using either will create ambiguity and
>>>>>>>> therefore should be a compile-time error.
>>>>>>>
>>>>>>> Way, way, way more complicated than this.
>>>>>>>
>>>>>>> Andrei
>>>>>>
>>>>>> May I ask what are the complications?
>>>>> "Mortis Portalis Tackulatum - and he's still breathing"...
>>>>
>>>> Tackulatum? Was that tacitum?
>>>>
>>>> Andrei
>>>>
>>> From Terry Pratchett's 'Pyramids'.
>>> Doctor: "Fairly straightforward. A case of mortis portalis tackulatum with complications."
>>> Chidder: "What's that mean?"
>>> Doctor: "In laymen's terms, he's as dead as a doornail."
>>> Chidder: "What are the complications?"
>>> Doctor: "He's still breathing."
>>
>> Heh. Funny, but what's the link?
>>
>> Andrei
>
> Uhm, nothing really. Just this managed to slip past my nonsense filter at 4 in the morning.
I kept on thinking of connections const/invariant -> rigor mortis.
Andrei
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply