January 08, 2009
"Michiel Helvensteijn" <nomail@please.com> wrote in message news:gk5f80$2lav$1@digitalmars.com...
> Ary Borenszweig wrote:
>
>>>> It's very different. A setter has a very specific meaning: set some
>>>> value. That's why it's called "value". Another name could be the name
>>>> of
>>>> the property ("len") or something like "newLen". Which other name would
>>>> you use?
>>>
>>> It's not for me to say. It should be up to the programmer.
>>>
>>> You've already shown that there are at least three possibilities.
>>
>> Yes, three. And that's it. That was my point. And they all have pretty much the same meaning.
>>
>> Well, unless you want to name it "nuevaLen", "novaLen", "nouvelleLen", etc. :-P
>
> Perhaps the implicit declaration "value" (or whatever *you* would call it) inadvertently overshadows a member variable with that name. That could result in a bug that would be pretty hard to find.
>

Overshadowing is already a potential issue anyway, with or without properties. Even a user-defined name could still accidentally overshadow something. Also, using "$" could help minimize overshadowing, the only thing that could ever clash with that is the "array.length" shorthand inside array slices/indexes (and even that already has potential for clashing, specifically when using nested indexes).


January 08, 2009
Chad J:
> public property int var
> {
>     get { return var; }
>     set { var = $; }
> }
> 
> public property int foo
> {
>     get { return foo; }
>     set { foo = $; }
> }

I think I have suggested something similar, time ago.

The default situations you have shown may enjoy an even shorter syntax, for example: public property int var { get set }

That can also become the following when you want only a getter or setter:
public property int var { get }
Or:
public property int var { set }


(I don't like all those repeated "foo"/"var", it's not much DRY. But at the moment I see no better solution, that works well for nested classes/structs too).

Let's see if Walter likes all this.

Bye,
bearophile
January 08, 2009
"Chad J" <gamerchad@__spam.is.bad__gmail.com> wrote in message news:gk5fch$2ldo$1@digitalmars.com...
> Michiel Helvensteijn wrote:
>> Nick Sabalausky wrote:
>>
>>> 2. You shouldn't have to manually define a private var to go along with the property. In languages with real properties, the following idiom is used constantly:
>>>
>>> private int _var;
>>> public property int var {
>>>    get { return _var; }
>>>    set { _var = $; }
>>>    void opIncrement() { _var++; }
>>> }
>>>
>>> Why should that be needed? It should be like this:
>>>
>>> public property int var {
>>>    // int internalValue; // Automatically created (but named better)
>>>    get { return internalValue; }
>>>    set { internalValue = $; }
>>>    void opIncrement() { internalValue++; }
>>> }
>>>
>>> In the minority of cases where a property doesn't need this variable, "internalValue" can just be optimized away.
>>
>> If you really want that behavior, you should just use a public variable. Even changing it to a real property later would not matter for the public interface.
>>
>
> That's not quite why it was suggested.
>
> I actually like the idea.
>
> It is true that a public member would be preferred in the trivial case.
> In the general case though, people will have some internal value they
> are working with and whenever someone works with it they want side
> effects to happen.
> Here's an example:
>
> int nTimesVarRead = 0;
>
> public property int var
> {
>    get
>    {
>        nTimesVarRead++;
>        return internalValue;
>    }
>
>    set { internalValue = $; }
> }
>
> compare against:
>
> int nTimesVarRead = 0;
> int m_var; // Annoying extra declaration that is common practice.
>
> public property int var
> {
>    get
>    {
>        nTimesVarRead++;
>        return m_var;
>    }
>
>    set { m_var = $; }
> }
>
> Thus I rather like that idea.
>
> Perhaps, since the compiler knows the name of the property, the name of the generated internal value could just be the name of the property:
>
> public property int var
> {
>    get { return var; }
>    set { var = $; }
> }
>
> public property int foo
> {
>    get { return foo; }
>    set { foo = $; }
> }
>
> etc.

That I don't like, for the same reason VB's syntax for returning a value from a function drives me nuts:

Function Foo
   Foo = 7
End Function

It's a DRY violation. Anytime you change the name of Foo, it's just that much more that also needs to be updated. And if you copy it to use as a starting point for another function, then again you have that much more to update. Granted, that can all be solved with an refactoring feature in the editor, but if I wanted my language to be reliant on IDE features, I'd use Java.

As long as it's come up, this is another case that frequently annoys me:

template foo(alias a /*...*/)
{
    const char[] foo = /*some fancy code-generation here*/;
    //pragma(msg, "foo: "~foo); // for debugging the template
}
mixin(foo!(/*...*/));

I do that frequently, and when developing them I'm constantly changing names, and ever time I do, I have to change the name and then copy-paste the new name to at least three other places. PITA.


January 08, 2009
Nick Sabalausky wrote:

>> Perhaps the implicit declaration "value" (or whatever *you* would call it) inadvertently overshadows a member variable with that name. That could result in a bug that would be pretty hard to find.
>>
> 
> Overshadowing is already a potential issue anyway, with or without properties. Even a user-defined name could still accidentally overshadow something.

Sure, but in that case both of the declarations are explicit. Now there's an invisible variable blocking a visible one. Could be quite confusing.

> Also, using "$" could help minimize overshadowing, the only
> thing that could ever clash with that is the "array.length" shorthand
> inside array slices/indexes (and even that already has potential for
> clashing, specifically when using nested indexes).

Using $ just doesn't make much sense. To what lengths are you willing to go to avoid typing a few more characters? Or do you really find $ more readable? Who could guess that $ inside the set function stands for its invisible parameter?

-- 
Michiel

January 08, 2009
"Nick Sabalausky" <a@a.a> wrote in message news:gk5fo7$2m80$1@digitalmars.com...
> "Michiel Helvensteijn" <nomail@please.com> wrote in message news:gk5b4m$2ekd$1@digitalmars.com...
>> Nick Sabalausky wrote:
>>
>>> 1. Like in C#, you shouldn't need to define paramater lists for "set"
>>> and
>>> "get". They're always going to be the same. In the case of "set", it's
>>> always going to be just the one param, and it'll be the new value, so
>>> just
>>> make a special predefined var. Something like:
>>>
>>> get { return this.len; }
>>> set { this.len = value; } // "value" (like in C#), or "$" or something
>>> like that
>>
>> I have to disagree. By that logic, we would abolish parameter-names altogether and access formal parameters by number.
>
> I don't think that follows at all. Function parameters have user-definable names because functions are a general concept that, for all the syntax is aware, could have any number of params that could each represent just about anything. Property getters/setters are different: A property getter is ALWAYS going to take nothing in and return a value of the same type as the property that represents the value of the property. Otherwise it wouldn't be a property getter. A property setter is ALWAYS going to return nothing and take in exactly one argument, of the same type as the property, and that value will ALWAYS represent the intended new value. Otherwise it wouldn't be a property setter. With this information, requiring a custom user-defined name for the setter parameter becomes completely frivolous. You may as well require people to make up their own names for "void", "if", "while" and "{some array here}.length": they're always going to mean the same thing so it's much better to have it standardized.
>

Sorry, Ary beat me to it. And much less verbosely ;)


January 08, 2009
"bearophile" <bearophileHUGS@lycos.com> wrote in message news:gk5grh$2o8i$1@digitalmars.com...
> Chad J:
>> public property int var
>> {
>>     get { return var; }
>>     set { var = $; }
>> }
>>
>> public property int foo
>> {
>>     get { return foo; }
>>     set { foo = $; }
>> }
>
> I think I have suggested something similar, time ago.
>
> The default situations you have shown may enjoy an even shorter syntax,
> for example:
> public property int var { get set }
>
> That can also become the following when you want only a getter or setter:
> public property int var { get }
> Or:
> public property int var { set }
>
>
> (I don't like all those repeated "foo"/"var", it's not much DRY. But at the moment I see no better solution, that works well for nested classes/structs too).
>

Something like this:

public property int var
{
    get { return property; }
    set { property = $; }
}

Or something like this:

public property int foo
{
    get { return $; }
    set { $ = $new; }
}

> Let's see if Walter likes all this.
>
> Bye,
> bearophile


January 08, 2009
"Michiel Helvensteijn" <nomail@please.com> wrote in message news:gk5h9r$2p7g$1@digitalmars.com...
> Nick Sabalausky wrote:
>
>>> Perhaps the implicit declaration "value" (or whatever *you* would call it) inadvertently overshadows a member variable with that name. That could result in a bug that would be pretty hard to find.
>>>
>>
>> Overshadowing is already a potential issue anyway, with or without properties. Even a user-defined name could still accidentally overshadow something.
>
> Sure, but in that case both of the declarations are explicit. Now there's
> an
> invisible variable blocking a visible one. Could be quite confusing.
>

Possibly. But I've used it a lot in C# and never had a problem. And syntax highlighting can help (as well as the fact that C#'s "value" looks much more like a keyword than my purely tentative "newValue").

>> Also, using "$" could help minimize overshadowing, the only
>> thing that could ever clash with that is the "array.length" shorthand
>> inside array slices/indexes (and even that already has potential for
>> clashing, specifically when using nested indexes).
>
> Using $ just doesn't make much sense. To what lengths are you willing to
> go
> to avoid typing a few more characters? Or do you really find $ more
> readable? Who could guess that $ inside the set function stands for its
> invisible parameter?
>

It's not so much about saving typing as the clarity that comes from consistency. And as with "array[0..$]", or the "a + b" stuff in phobos2's functional-style modules, it's easy if you're aware of it (you can't expect every new language feature to be obvious at a glance to someone who's never glanced at the docs). I'll grant that "$" may not be as descriptive as, say "newValue", but I'd certainly find it much more readable than having it named something completely different in every setter in the codebase.


January 08, 2009
Nick Sabalausky wrote:

> It's a DRY violation.

I agree, good call.
January 08, 2009
Nick Sabalausky wrote:
> "bearophile"<bearophileHUGS@lycos.com>  wrote in message
> news:gk5grh$2o8i$1@digitalmars.com...
>> Chad J:
>>> public property int var
>>> {
>>>      get { return var; }
>>>      set { var = $; }
>>> }
>>>
>>> public property int foo
>>> {
>>>      get { return foo; }
>>>      set { foo = $; }
>>> }
>> I think I have suggested something similar, time ago.
>>
>> The default situations you have shown may enjoy an even shorter syntax,
>> for example:
>> public property int var { get set }
>>
>> That can also become the following when you want only a getter or setter:
>> public property int var { get }
>> Or:
>> public property int var { set }
>>
>>
>> (I don't like all those repeated "foo"/"var", it's not much DRY. But at
>> the moment I see no better solution, that works well for nested
>> classes/structs too).
>>
>
> Something like this:
>
> public property int var
> {
>      get { return property; }
>      set { property = $; }
> }
>
> Or something like this:
>
> public property int foo
> {
>      get { return $; }
>      set { $ = $new; }
> }
>
>> Let's see if Walter likes all this.
>>
>> Bye,
>> bearophile
>
>

I like the general idea, but why invent new words?
how about this:

public property int var {
  get { return this; }
  set { this = new; }
}

there's one issue with the above - what about the "this" of the container class/struct, but that's solved easily with "outer" just like in nested classes.

it makes sense to me since the feature seems to be mainly syntax sugar for something like the following:

class A {
	struct Prop {
		int internal;
		int opCall() { return internal; }
		void opAssign(int value) { internal = value; }
	}
	public Prop prop;
	...
}

void main() {
	auto a = new A;
	int num = a.prop;
	a.prop = 9;
	...
}
January 08, 2009
"Yigal Chripun" <yigal100@gmail.com> wrote in message news:gk5t92$fu2$1@digitalmars.com...
> Nick Sabalausky wrote:
>> "bearophile"<bearophileHUGS@lycos.com>  wrote in message news:gk5grh$2o8i$1@digitalmars.com...
>>> Chad J:
>>>> public property int var
>>>> {
>>>>      get { return var; }
>>>>      set { var = $; }
>>>> }
>>>>
>>>> public property int foo
>>>> {
>>>>      get { return foo; }
>>>>      set { foo = $; }
>>>> }
>>> I think I have suggested something similar, time ago.
>>>
>>> The default situations you have shown may enjoy an even shorter syntax,
>>> for example:
>>> public property int var { get set }
>>>
>>> That can also become the following when you want only a getter or
>>> setter:
>>> public property int var { get }
>>> Or:
>>> public property int var { set }
>>>
>>>
>>> (I don't like all those repeated "foo"/"var", it's not much DRY. But at the moment I see no better solution, that works well for nested classes/structs too).
>>>
>>
>> Something like this:
>>
>> public property int var
>> {
>>      get { return property; }
>>      set { property = $; }
>> }
>>
>> Or something like this:
>>
>> public property int foo
>> {
>>      get { return $; }
>>      set { $ = $new; }
>> }
>>
>>> Let's see if Walter likes all this.
>>>
>>> Bye,
>>> bearophile
>>
>>
>
> I like the general idea, but why invent new words?
> how about this:
>
> public property int var {
>   get { return this; }
>   set { this = new; }
> }
>
> there's one issue with the above - what about the "this" of the container class/struct, but that's solved easily with "outer" just like in nested classes.
>

*smacks forehead* I completely forget about "outer". That's the only reason I didn't suggest "this". That is good. But using "new" in that particular way bothers me a little. What about making the new value a property of "this":

set { this = this.new; }
set { this = this.next; }
set { this = this.prime; } // Math-style
set { this = this.pending; }
set { this = this.hcwgcwFNbchbSCCGUgucG; }

> it makes sense to me since the feature seems to be mainly syntax sugar for something like the following:
>
> class A {
> struct Prop {
> int internal;
> int opCall() { return internal; }
> void opAssign(int value) { internal = value; }
> }
> public Prop prop;
> ...
> }
>
> void main() {
> auto a = new A;
> int num = a.prop;
> a.prop = 9;
> ...
> }

Good point.