View mode: basic / threaded / horizontal-split · Log in · Help
June 13, 2005
Re: Way to make properties
Let me revise my initial example.  Consider a class 'Foo' with a property 'bar' of type 
int, set'able with either an int or char[] value.  Okay, then, simple yes?  Assume its a 
public property, through-and-through.  Now then.  Current D implementation of properties:

# public class Foo {
#   public int bar () { return p_bar; }
#
#   public int bar (int    x) { return p_bar = x;        }
#   public int bar (char[] x) { return p_bar = toInt(x); }
#
#   private int p_bar;
# }

My proposal (currently... it fluxes, I'll admit) changes this to something like:

# public class Foo {
#   public property bar : int {
#     public set (int    x) { _value = x; }
#     public set (char[] x) { _value = toInt(x); }
#   }
# }

The gettor is the default gettor, simply returning bar._value.  To make a property 
read-only, just don't define any settors.  So a read-only property looks like this:

# public property foo : int {/+read only+/}

Or this, maybe:

# public property foo : int ;

Also note that the 'set' has no return-type.  It isn't a function/method at all, but a 
wrapper around the assignment.  The return-type is always the type of the property, and 
the return value is always the final contents of the _value variable, which would be 
compiler-generated along the same lines as _arguments and _argptr currently are.  As for 
gettors, they are locked into the type of the property, and use an out parameter.  So, the 
default gettor above would look like this, if it were coded out:

# public get (out int x) { x = _value; }

Why use a parameter?  Well one might presumably do this:

# public class Foo {
#   public property bar : int {
#     public set (int    x) { _value = x; }
#     public set (char[] x) { _value = toInt(x); }
#
#     protected get (out char[] x) { x = std.string.toString(_value); }
#   }
# }

Which would only have meaning in cases like:

# public class Child : Foo {
#   public void someMethod () {
#     char[] str = bar;
#   }
# }

Where the expected type is obvious.  Or if this is two much complexity for the compiler, 
then two other options are available.  An explicit get-invokation for special gettors, so 
that the above becomes:

# char[] str;
# bar.get(str);

Or just disallow alternatively-typed gettors entirely, and make the syntax of the gettor 
into just:

# [protection] 'get' '{' code '}'

Okay, I will hush now.  I'm really just typing my thoughts as they come to me, anyhow. 
Its something that I would like, but if it really isn't a true improvement, then so be it. 
 D isn't C#, nor do I want it to be.  :)

-- Chris Sauls
June 14, 2005
Re: Way to make properties
Maxime Larose wrote:
> I don't understand why you all seem intent on making the language so
> verbose. Wouldn't the following be a lot clearer and less error-prone:
> 
> class A {
>   property int houseNumber;
> }
> 
> With the compiler generating the get and set methods?
<snip top of upside-down reply>

How would this be different from a normal field?

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on 
the 'group where everyone may benefit.
June 14, 2005
Re: Way to make properties
Chris Sauls wrote:
<snip>
> Also note that the 'set' has no return-type.  It isn't a function/method 
> at all, but a wrapper around the assignment.  The return-type is always 
> the type of the property, and the return value is always the final 
> contents of the _value variable,
<snip>

Why not make it return the return value of the gettor?  It would make 
sense.  See also

http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/10199

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on 
the 'group where everyone may benefit.
June 14, 2005
Re: Way to make properties
"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message
news:d8m7bp$m5o$1@digitaldaemon.com...
> Maxime Larose wrote:
> > I don't understand why you all seem intent on making the language so
> > verbose. Wouldn't the following be a lot clearer and less error-prone:
> >
> > class A {
> >   property int houseNumber;
> > }
> >
> > With the compiler generating the get and set methods?
> <snip top of upside-down reply>
>
> How would this be different from a normal field?
>

A setter and getter would be generated for the property. It could obviously
be inlined later by the compiler, but the indirection would remain there.
Later on, it would be possible to manually specify a getter and/or setter if
the need arose, and clients would pick it up without changing a line of
code.

Don't take this bad, but your question suggests you do not know/realise why
getters and setters are used in the first place. Why would one do this:
class A {
 private int number;
 public int getNumber { return number; }
 public void setNumber(int n) { number = n; }
}
...
instanceOfA.setNumber(6);
... = instanceOfA.getNumber();


If it's a 100% equivalent to this:
class A {
 public int number;
}
instanceOfA.number = 6;
... = instanceOfA.number;

???


The reason is that these forms are not equivalent, at least conceptually.
The fact that 'number' is a member variable of class A is an implementation
detail, and maybe later on in the program lifecycle the implementation
detail will change. E.g., for efficiency 'number' could become lazily
calculated, or it could be writen to and read from a DB, etc.

Thus, setters and getters shield clients from the implementation details.
If/when 'number''s implementation change, not a single line of code has to
be changed on the clients. (It may have to be recompiled though, if the
compiler optimised away the function call.) Now, to be honest, this whole
idiom is a bit silly because in actual facts 99.9% of the time, the getter
will simply return the member variable and the setter will set it. In the
oft-chance that the implementation is changed later on, making the variable
private and recompiling will flag all instances of clients using the
variable directly and it is then quite easy to fix. Actually, unless a whole
lot implementation details change, which I've never seen personnally, it is
probably more time efficient not to bother with setters and getters and
later fix the compilation error if the variable is made private.

However, an advantage of setters/getters is it allows one to treat variables
more or less the same way across the board (setA/getA everywhere) and
read-only variables are implemented by simply not coding a setter. In other
words it is consistent, i.e. you don't end up with class A being defined as:
class A
{
 public int number;      // can set and get
 private char[] street;  // read-only
 public char[] getStreet();
}
... instanceOfA.number ... // to access number
... instanceOfA.street; // invalid
.. instanceOfA.getStreet();   // to access street

which would make the program look messy. Another compelling reason to use
setter and getters is that by convention, in certain languages at least (C
and C++), the interface of a class is defined in terms of methods, not
exposed public variables.

However, there is absolutely no reasons why a language would not help
programmers in this regard and give some syntaxing sugar for it, as it is
one of the most used idiom. Being built in the language, programmers of that
language become accustomed to it and do not hesitate to change publicly
exposed variables!

So, coming back to my suggestion, the following code would tell the compiler
to implement the idiom:
Definition:
class A {
  property int houseNumber;
}

In clients:
instanceOfA.setHouseNumber(6);
... = instanceOfA.getHouseNumber();
// or even more simply:
// would be translated to use the setter
instanceOfA.houseNumber = 6;
// would be translated to use the getter
... = instanceOfA.houseNumber;

Now, it would be possible to change the implementation details without
changing clients:
class A {
  property int houseNumber {
     get { ...read value from DB...; return value; }
     set { ...write value in DB...; }
  }
}
// clients remain the same,
// compiler knows to look for setter/getter
// and not use the variable directly
instanceOfA.houseNumber = 6;
... = instanceOfA.houseNumber;

Ouf! I didn't intend this to be a lecture on setters/getters. Sorry if you
knew that stuff...

Max
June 14, 2005
Re: Way to make properties
I didn't read the name of the poster in my reply... Should have since now I
feel stupid having 'explained' all this stuff to you (who knew it for sure).
Wasted my time... oh well...

:-/

Max



"Maxime Larose" <mlarose@broadsoft.com> wrote in message
news:d8mf9u$so2$1@digitaldaemon.com...
>
> "Stewart Gordon" <smjg_1998@yahoo.com> wrote in message
> news:d8m7bp$m5o$1@digitaldaemon.com...
> > Maxime Larose wrote:
> > > I don't understand why you all seem intent on making the language so
> > > verbose. Wouldn't the following be a lot clearer and less error-prone:
> > >
> > > class A {
> > >   property int houseNumber;
> > > }
> > >
> > > With the compiler generating the get and set methods?
> > <snip top of upside-down reply>
> >
> > How would this be different from a normal field?
> >
>
> A setter and getter would be generated for the property. It could
obviously
> be inlined later by the compiler, but the indirection would remain there.
> Later on, it would be possible to manually specify a getter and/or setter
if
> the need arose, and clients would pick it up without changing a line of
> code.
>
> Don't take this bad, but your question suggests you do not know/realise
why
> getters and setters are used in the first place. Why would one do this:
> class A {
>   private int number;
>   public int getNumber { return number; }
>   public void setNumber(int n) { number = n; }
> }
> ...
> instanceOfA.setNumber(6);
> ... = instanceOfA.getNumber();
>
>
> If it's a 100% equivalent to this:
> class A {
>   public int number;
> }
> instanceOfA.number = 6;
> ... = instanceOfA.number;
>
> ???
>
>
> The reason is that these forms are not equivalent, at least conceptually.
> The fact that 'number' is a member variable of class A is an
implementation
> detail, and maybe later on in the program lifecycle the implementation
> detail will change. E.g., for efficiency 'number' could become lazily
> calculated, or it could be writen to and read from a DB, etc.
>
> Thus, setters and getters shield clients from the implementation details.
> If/when 'number''s implementation change, not a single line of code has to
> be changed on the clients. (It may have to be recompiled though, if the
> compiler optimised away the function call.) Now, to be honest, this whole
> idiom is a bit silly because in actual facts 99.9% of the time, the getter
> will simply return the member variable and the setter will set it. In the
> oft-chance that the implementation is changed later on, making the
variable
> private and recompiling will flag all instances of clients using the
> variable directly and it is then quite easy to fix. Actually, unless a
whole
> lot implementation details change, which I've never seen personnally, it
is
> probably more time efficient not to bother with setters and getters and
> later fix the compilation error if the variable is made private.
>
> However, an advantage of setters/getters is it allows one to treat
variables
> more or less the same way across the board (setA/getA everywhere) and
> read-only variables are implemented by simply not coding a setter. In
other
> words it is consistent, i.e. you don't end up with class A being defined
as:
> class A
> {
>   public int number;      // can set and get
>   private char[] street;  // read-only
>   public char[] getStreet();
> }
> ... instanceOfA.number ... // to access number
> ... instanceOfA.street; // invalid
> .. instanceOfA.getStreet();   // to access street
>
> which would make the program look messy. Another compelling reason to use
> setter and getters is that by convention, in certain languages at least (C
> and C++), the interface of a class is defined in terms of methods, not
> exposed public variables.
>
> However, there is absolutely no reasons why a language would not help
> programmers in this regard and give some syntaxing sugar for it, as it is
> one of the most used idiom. Being built in the language, programmers of
that
> language become accustomed to it and do not hesitate to change publicly
> exposed variables!
>
> So, coming back to my suggestion, the following code would tell the
compiler
> to implement the idiom:
> Definition:
> class A {
>    property int houseNumber;
> }
>
> In clients:
> instanceOfA.setHouseNumber(6);
> ... = instanceOfA.getHouseNumber();
> // or even more simply:
> // would be translated to use the setter
> instanceOfA.houseNumber = 6;
> // would be translated to use the getter
> ... = instanceOfA.houseNumber;
>
> Now, it would be possible to change the implementation details without
> changing clients:
> class A {
>    property int houseNumber {
>       get { ...read value from DB...; return value; }
>       set { ...write value in DB...; }
>    }
> }
> // clients remain the same,
> // compiler knows to look for setter/getter
> // and not use the variable directly
> instanceOfA.houseNumber = 6;
> ... = instanceOfA.houseNumber;
>
> Ouf! I didn't intend this to be a lecture on setters/getters. Sorry if you
> knew that stuff...
>
> Max
>
>
>
Next ›   Last »
1 2
Top | Discussion index | About this forum | D home