www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - object states

reply "Henning Pohl" <henning still-hidden.de> writes:
Imagine you want an image to keep the width of 512:

void func(Image img) {
     assert(img.width == 512);

     img.doSomething();
     assert(img.width == 512);

     while (img.somethingElse()) {
         assert(img.width == 512)

         someFunc(img);
         assert(img.width == 512);
     }
}

In theory, every call to a function can change the width of the 
image. What do you think about this: 
https://dl.dropbox.com/u/34762907/temp/prop1.html

I do know it can be implemented in D4 only.
Oct 07 2012
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 10/07/2012 11:44 AM, Henning Pohl wrote:
 Imagine you want an image to keep the width of 512:

 void func(Image img) {
 assert(img.width == 512);

 img.doSomething();
 assert(img.width == 512);

 while (img.somethingElse()) {
 assert(img.width == 512)

 someFunc(img);
 assert(img.width == 512);
 }
 }

 In theory, every call to a function can change the width of the image.
 What do you think about this:
 https://dl.dropbox.com/u/34762907/temp/prop1.html

 I do know it can be implemented in D4 only.
Sounds good. You haven't mentioned the invariant keyword, so perhaps you are not aware of that feature? http://dlang.org/class.html#Invariant http://dlang.org/dbc.html Although the docs seem to favor classes, invariant is available for structs as well. Ali -- D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
Oct 07 2012
parent reply "Henning Pohl" <henning still-hidden.de> writes:
On Sunday, 7 October 2012 at 20:18:15 UTC, Ali Çehreli wrote:
 Sounds good.
Thanks.
 You haven't mentioned the invariant keyword, so perhaps you are 
 not aware of that feature?

   http://dlang.org/class.html#Invariant

   http://dlang.org/dbc.html

 Although the docs seem to favor classes, invariant is available 
 for structs as well.

 Ali
How would you resolve the issue I wrote in my first post using invariants? You cannot add/remove checks from invariants while using the object. That's what I made different. But there are still some limits given by the language. Look at point 7 for instance. The problem about contract programming in general is you cannot use it in public library code. Distinction between logic and user input is a very important thing, we really need to improve this. You may have noticed that I did not make use of either assert or enforce. I didn't want to specify this.
Oct 07 2012
parent reply "simendsjo" <simendsjo gmail.com> writes:
On Sunday, 7 October 2012 at 20:46:09 UTC, Henning Pohl wrote:
 On Sunday, 7 October 2012 at 20:18:15 UTC, Ali Çehreli wrote:
 Sounds good.
Thanks.
 You haven't mentioned the invariant keyword, so perhaps you 
 are not aware of that feature?

  http://dlang.org/class.html#Invariant

  http://dlang.org/dbc.html

 Although the docs seem to favor classes, invariant is 
 available for structs as well.

 Ali
How would you resolve the issue I wrote in my first post using invariants? You cannot add/remove checks from invariants while using the object. That's what I made different. But there are still some limits given by the language. Look at point 7 for instance. The problem about contract programming in general is you cannot use it in public library code. Distinction between logic and user input is a very important thing, we really need to improve this. You may have noticed that I did not make use of either assert or enforce. I didn't want to specify this.
You can create a wrapper struct that includes an invariant: import std.stdio; struct Image { int width; void doSomething() { } void modifiesWidth() { --width; } } void func(Image img) { struct ImgWrapper { Image* img; this(ref Image img) { this.img = &img; } invariant() { assert(img.width == 512); } void opDispatch(string s)() { mixin("img."~s~"();"); } } auto wrapper = ImgWrapper(img); wrapper.doSomething(); wrapper.modifiesWidth(); // assertion failure } void main() { Image img = { 512 }; func(img); }
Oct 08 2012
parent "Henning Pohl" <henning still-hidden.de> writes:
On Monday, 8 October 2012 at 08:53:39 UTC, simendsjo wrote:
 You can create a wrapper struct that includes an invariant:

 import std.stdio;

 struct Image
 {
     int width;

     void doSomething()
     {
     }

     void modifiesWidth()
     {
         --width;
     }
 }

 void func(Image img)
 {
     struct ImgWrapper
     {
         Image* img;
         this(ref Image img)
         {
             this.img = &img;
         }

         invariant()
         {
             assert(img.width == 512);
         }

         void opDispatch(string s)()
         {
             mixin("img."~s~"();");
         }
     }

     auto wrapper = ImgWrapper(img);
     wrapper.doSomething();
     wrapper.modifiesWidth(); // assertion failure
 }

 void main()
 {
     Image img = { 512 };
     func(img);
 }
There is a difference between invariants and what I call states. States clear things up when you actually need to do a runtime check and when not. Invariants are always checked, because you don't care about performance in debug mode. A Number<positive> is positive already and will stay positive while you can access it. De facto you cannot change a Number<positive> to a negative number.
Oct 08 2012