View mode: basic / threaded / horizontal-split · Log in · Help
June 02, 2002
Re: final time
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
Re: final time
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
Re: final time
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
Re: final time
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
Re: final time
"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
Re: final time
"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
Re: final time
"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
Re: final time
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
Re: final time
"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
Re: final time
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
1 2 3
Top | Discussion index | About this forum | D home