June 02, 2002
Karl Bochert <kbochert@ix.netcom.com> wrote in news:1103_1023039833@bose:

> On Sun, 2 Jun 2002 16:32:52 +0000 (UTC), Patrick Down
> <pat@codemoon.com> wrote:
>> Karl Bochert <kbochert@ix.netcom.com> wrote in news:1103_1023031499@bose:
>> 
>> > Even better would be to further blur the distinction between data and functions by not requiring the dummy m_width:
>> > 
>> >     public int width  {
>> >         // ok to omit get ??
>> >         set  {
>> >             self = value;     // two keywords !
>> >             repaint ();
>> >             }
>> >         }
>> >         ...
>> 
>> How would you access width inside the class wihout calling the function?
>> 
> 1) the absence of a get clause causes the compiler to treat
>     accesses to width just like any other variable, whether inside
>     the  class or not.  Likewise for set of course.

Yes but setting of the width value will cause a repaint.  This is appropriate when accessing width from outside the class.  However from inside the class a programmer may wish to short cut the process. Effeciency may be one reason.  You might want to be able adjust the values of width and height before doing a repaint.  If setting the value of width always calls the set function this is not possible.
June 03, 2002
On Sun, 2 Jun 2002 23:37:40 +0400, "Pavel Minayev" <evilone@omen.ru> wrote:
> "Karl Bochert" <kbochert@ix.netcom.com> wrote in message news:1103_1023039833@bose...
> 
> > 1) the absence of a get clause causes the compiler to treat
> >     accesses to width just like any other variable, whether inside
> >     the  class or not.  Likewise for set of course.
> 
> What about read-only (and write-only) properties then???
> 
Another case where one might want to use a shadow
variable. But it should not be mandatory.

> Besides, sometimes you just don't need a temporary. For example, the Width property of Button will most likely call MoveWindow to set, and GetWindowRect to get the actual position. Additional variable would be just a waste of space...
> 

1) It ought to be easy for a compiler to optimize away the storage when
a variable has both set and get clauses, neither of which access
'self'.
i.e:
   int width {
      get {
         return Get_width();
         }
      set {
         Set_width (value);
         }
       }

The line   'width = 5;' would just be coded as a call to the set function,
unless the compiler were smart enough to inline short routines.
Likewise with 'w = width ;' .


2) Besides, sometimes you just don't need a shadow variable.

    int width {
        set { self = max ( value, MAXWIDTH) ; }
         }

Do you suppose that access control could be imposed on the variable and the get and set clauses separately ??

    private int width {
        public get { return self ; }
        }

Or even overloaded ????

    private int width {
        public set { self = value;  Repaint () }
        private set { self = value; }
        }





June 03, 2002
On Sun, 2 Jun 2002 19:36:10 +0000 (UTC), Patrick Down <pat@codemoon.com> wrote:
>
> >> > Even better would be to further blur the distinction between data and functions by not requiring the dummy m_width:
> >> > 
> >> >     public int width  {
> >> >         // ok to omit get ??
> >> >         set  {
> >> >             self = value;     // two keywords !
> >> >             repaint ();
> >> >             }
> >> >         }
> >> >         ...
> >> 
> >> How would you access width inside the class wihout calling the function?
> >> 
> > 1) the absence of a get clause causes the compiler to treat
> >     accesses to width just like any other variable, whether inside
> >     the  class or not.  Likewise for set of course.
> 
> Yes but setting of the width value will cause a repaint.  This is appropriate when accessing width from outside the class.  However from inside the class a programmer may wish to short cut the process. Effeciency may be one reason.  You might want to be able adjust the values of width and height before doing a repaint.  If setting the value of width always calls the set function this is not possible.

I hadn't thought of that use of set and get.
My argument is for the set and get clauses being optional,  and
doesn't prevent using a 'shadow' variable to allow clients inside
and outside of the class to have different priviledges.

I would think a more common use would be something like:

   int width {
      set { self = max(value, MAXWIDTH)  }
      }

which is certainly more straight-forward than :

    int shadow_width;
    int width {
          set { shadow_width = max ( value, MAXWIDTH) }
          get ( return shadow_width; }
          }



June 03, 2002
Why not treat it like a spontaneously generated anonymous struct

class foo
{
  int width { }
}

that declares a struct width which consists of one member, an int, which internally to the struct is known as width.  Outsider stores to width map straight to the contained int, and outsider reads do so as well.

Now if you want to get fancy you can overload operator = (aka set)

class foo
{
  int width
  {
      void set(int v) { WidthChangedOldToNew(width,v); }  // the store to
the shadow variable is implied?
                                                               // If nothing
in here uses it, it could be optimized away.
      // the get property is automatically generated and by default it
returns the shadow variable
  }
}

The compiler automatically knows the rules for lvalues.  The only difference between this and a normal variable in the compiler is that these can't automatically be promoted to a rvalue and reads and writes go through (probably inlined) functions.  In fact I'd bar side effects inside get functions since they cause outside code to not be able to be properly optimized (it can't be sure the value didn't change during the first call so it has to call it again).  You can hope the compiler can tell the variable doesn't change, but sometimes it can't.  But this brings up the issue of const being a type modifier rather than a storage class.  If it's a type modifier, you can use it to ensure that nobody tries to modify the variable (the compiler could enforce this by making copies of params it passes elsewhere).  If it's a storage class, that prevents direct writes but doesn't prevent indirect writes (i.e. thru a pointer).  Then the user gets no guarantees and the compiler has no way to enforce anything.  But it can still guarantee correctness if it always makes a copy when sending a const variable by reference.  But what this really boils down to is that the get method should return a *value*, something for which a copy is as good as the original which indicates that copying doesn't change state.  Class objects aren't like this and usually don't get copied, which is why I think of properties as more of an anonymous struct than an anonymous class.  This is so that the calling code can take several references to the same property and optimize them together into one call to the property function followed by several uses or copies of the resulting value.  Without this guarantee, properties will be fairly expensive to call at runtime unless the properties are trivial or the caller is smart and caches the result.  But we don't want the callers to have to know whether it's an optimizable variable reference or a call to a get property function, so in order to generate the best code possible we should give the compiler the freedom to assume the value doesn't change without some intervening call to set.  That means the get function should have no side effects.  Synchronization would break that.  Maybe the compiler just has to figure out whether any side effects are present and notify the property callers whether the result is cacheable/read combinable or not so that the point of call can generate the corresponding code.  If everything gets inlined properly this should be possible.

Other kinds of structs have need of overloading assignment and conversion to rvalue also.  Not to mention other operators.

class foo
{
  int width
  {
      void set(int v) { WidthChangedOldToNew(width,v); }
      private int get(); // make width a write-only property (this is like
C++'s operator int)
  }
}

Does anyone else see the connection between operator =  and set, and operator typeconvert and get?

And anonymous structs could be constructed lots of places, like maybe while passing a parameter:

DrawWindowBorder({int left,right,top,bottom;}={0,25,0,15},colors.lightgrey);

Or would that get too confusing...

Sean

"Karl Bochert" <kbochert@ix.netcom.com> wrote in message news:1104_1023078664@bose...
> On Sun, 2 Jun 2002 19:36:10 +0000 (UTC), Patrick Down <pat@codemoon.com>
wrote:
> >
> > >> > Even better would be to further blur the distinction between data and functions by not requiring the dummy m_width:
> > >> >
> > >> >     public int width  {
> > >> >         // ok to omit get ??
> > >> >         set  {
> > >> >             self = value;     // two keywords !
> > >> >             repaint ();
> > >> >             }
> > >> >         }
> > >> >         ...
> > >>
> > >> How would you access width inside the class wihout calling the function?
> > >>
> > > 1) the absence of a get clause causes the compiler to treat
> > >     accesses to width just like any other variable, whether inside
> > >     the  class or not.  Likewise for set of course.
> >
> > Yes but setting of the width value will cause a repaint.  This is appropriate when accessing width from outside the class.  However from inside the class a programmer may wish to short cut the process. Effeciency may be one reason.  You might want to be able adjust the values of width and height before doing a repaint.  If setting the value of width always calls the set function this is not possible.
>
> I hadn't thought of that use of set and get.
> My argument is for the set and get clauses being optional,  and
> doesn't prevent using a 'shadow' variable to allow clients inside
> and outside of the class to have different priviledges.
>
> I would think a more common use would be something like:
>
>    int width {
>       set { self = max(value, MAXWIDTH)  }
>       }
>
> which is certainly more straight-forward than :
>
>     int shadow_width;
>     int width {
>           set { shadow_width = max ( value, MAXWIDTH) }
>           get ( return shadow_width; }
>           }
>
>
>


June 03, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:adcg51$2imn$1@digitaldaemon.com...
> If it seems hard to implement them in the way documented in the reference,
> then
> maybe try the C# approach?
>
>     class Button
>     {
>         private int m_width;
>         public int width
>         {
>             get
>             {
>                 return m_width;
>             }
>             set
>             {
>                 m_width = value;
>                 repaint();
>             }
>         }
>     }

I'm not too thrilled with that approach. It just seems like a lot of syntax for not much of nothing <g>.

The D approach leaves one with:

class Foo
{
    int a();
}

Foo f;
return f.a;

In other words, does it make sense to consider
    a
and
    a()
as generally equivalent, if a is a function? Note that in C, a and &a are
equivalent if a is a function.


June 04, 2002
"Walter" <walter@digitalmars.com> wrote in message news:adgp6f$2e9o$1@digitaldaemon.com...

> The D approach leaves one with:
>
> class Foo
> {
>     int a();
> }
>
> Foo f;
> return f.a;
>
> In other words, does it make sense to consider
>     a
> and
>     a()
> as generally equivalent, if a is a function? Note that in C, a and &a are
> equivalent if a is a function.

As long as it works, I don't really care much about the syntax. Yours is less "consistent", but it's shorter, and I don't know what I like more.

By the way, I hope settors are also there?



June 05, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:adhnr4$bnq$1@digitaldaemon.com...
> As long as it works, I don't really care much about the syntax.

I do <g>.

> Yours is less "consistent", but it's shorter, and I don't know
> what I like more.
> By the way, I hope settors are also there?

It's really the same issue.


June 05, 2002
Walter wrote:

> "Pavel Minayev" <evilone@omen.ru> wrote in message
> news:adhnr4$bnq$1@digitaldaemon.com...
> 
>>As long as it works, I don't really care much about the syntax.
>>
> 
> I do <g>.
> 
> 
>>Yours is less "consistent", but it's shorter, and I don't know
>>what I like more.
>>By the way, I hope settors are also there?
>>
> 
> It's really the same issue.
> 

Walter, earlier I got the impression that you were having some
difficulty implementing the properties with the syntax you had
decided on. I really liked the way you had come up with, and I
am sorry to see that it might not make it. Would it be easier
to make it work if the variables were identified with a
"property" keyword? I think it would make the code more
readable also.
i.e.

class foo
{
  property int someprop;

  void prop(int s)  //setter
  {
    someprop = s;
  }
  int prop(void)   //getter
  {
    return someprop;
  }
}

Of course this example is simple and could be replaced by simply
using a public variable. But the important part is the property
keyword. I don't know if that would make anything easier or not,
but I really hope you can include this kind of properties syntax
into D regardless of whether it uses a special keyword or not.
Just an idea...
-Jon

June 06, 2002
"Jonathan Andrew" <jon@ece.arizona.edu> wrote in message news:3CFE82EF.90305@ece.arizona.edu...
> Of course this example is simple and could be replaced by simply using a public variable. But the important part is the property keyword. I don't know if that would make anything easier or not, but I really hope you can include this kind of properties syntax into D regardless of whether it uses a special keyword or not. Just an idea...

Unfortunately, I don't see how that will resolve the particular problem with the confusion between f.a and f.a().


June 06, 2002
Walter wrote:


>>
> 
> Unfortunately, I don't see how that will resolve the particular problem with
> the confusion between f.a and f.a().
> 


Hmm, that stinks. Do you have any other alternatives or solutions that
you've been considering? I'm sure there is some kind of nice way to
pull this off.
-Jon