January 18, 2012
On Tuesday, January 17, 2012 23:13:21 Peter Alexander wrote:
> On 17/01/12 10:11 PM, Jonathan M Davis wrote:
> > You would need to come up with some really solid arguments why it should be thrown out (and what we should do instead) and get both Walter and Andrei (if not the community at large) to agree that they not only prefer your proposal but that it's worth the issues that the changes are going to cause at this stage.
> 
> There's a few good reasons to throw it out:
> 
> 1. Avoids pointless discussions like this one. These discussions add nothing, it's just mindless bike shedding.
> 
> 2. The -property flag *creates* a new kind of error, but doesn't actually help find real problems with your code. Without properties, member function access would always be a.b(), and this artificial error could be avoided.
> 
> 3. Properties introduce another thing to remember, with no value ("was
> it byKeys, or byKeys()?"). Without properties, it would be byKeys(). No
> need to remember.
> 
> 4. Properties obfuscate code. Is (a.b = c) a variable assignment or arbitrary function call? Who knows! Is a.b an actual variable? Can I write &a.b to get its address, or is it a function masquerading as a variable?
> 
> 5. One less language feature to implement, learn, document, debug, and discuss.
> 
> Is it practical or realistic to throw it out at this stage? I don't know. But there are reasons to.

I'm fully aware that there are those who want to throw it out (e.g. Andrei) and that there are reasons for doing so. My point is that those reasons must be strong enough to justify the cost of getting rid of @property at this stage in the game, or it's not going to happen. As it stands, we're going to have @property with it being enforced.

And there _are_ those of us who like it. I _do_ think that it's an improvement over what we had before. One of the primary reasons for properties IMHO is to be able to swap out functions and public member variables without breaking code, and that's not possible without something like @property with strict enforcement.

- Jonathan M Davis
January 18, 2012
On Tuesday, January 17, 2012 19:31:25 bearophile wrote:
> Nick Sabalausky:
> > Without properties, member function access *ANY* many value
> > accesses are "a.b()". Is this member value a plain-old-var or a
> > function?
> > Who knows! It's a leeked out implementation detail, hooray!
> 
> I have a partially related question.
> 
> Currently this code compiles even with -property:
> 
> void main() {
> int[int] aa = [1:2];
> auto byval = aa.byValue();
> }
> 
> But I think byValue is a property, so isn't it right to give a compilation error if you add () after the name of a property?

Definitely a bug. Strict enforcement requires that parens be used on all function calls and that no properties use parens. If you use parens on them, that would mean that you're using them on the return value of the property (e.g. opCall) - and in fact, that's one of the main reasons that @property was added in the first place, since without enforcement, property functions which return a delegate result in an ambiguity.

- Jonathan M Davis
January 18, 2012
Jonathan M Davis:

> Definitely a bug. Strict enforcement requires that parens be used on all function calls and that no properties use parens.

I agree! I'll take a look in Bugzilla if this bug report is already present. Thank you for your answers :-)

Bye,
bearophile
January 18, 2012
On 01/18/2012 01:40 AM, Jonathan M Davis wrote:
> On Tuesday, January 17, 2012 19:31:25 bearophile wrote:
>> Nick Sabalausky:
>>> Without properties, member function access *ANY* many value
>>> accesses are "a.b()". Is this member value a plain-old-var or a
>>> function?
>>> Who knows! It's a leeked out implementation detail, hooray!
>>
>> I have a partially related question.
>>
>> Currently this code compiles even with -property:
>>
>> void main() {
>> int[int] aa = [1:2];
>> auto byval = aa.byValue();
>> }
>>
>> But I think byValue is a property, so isn't it right to give a compilation
>> error if you add () after the name of a property?
>
> Definitely a bug. Strict enforcement requires that parens be used on all
> function calls and that no properties use parens. If you use parens on them,
> that would mean that you're using them on the return value of the property
> (e.g. opCall) - and in fact, that's one of the main reasons that @property was
> added in the first place, since without enforcement, property functions which
> return a delegate result in an ambiguity.
>
> - Jonathan M Davis

A related and way more embarrassing problem is that lazy function parameters have the same issue.

This program prints nothing:
import std.stdio;
void foo(lazy void delegate() dg){
    dg();
}
void main(){
    foo({writeln("hello");});
}
January 18, 2012
>
> Is it practical or realistic to throw it out at this stage? I don't
> know. But there are reasons to.


I hope we are not dropping properties
regardless of the syntax of how to call them.

Keep @property
Keep methods-as-properties

---------------------------------
(a)	No ()

	obj.property = "test";
	string str = obj.property;

	obj.method = "string";
	obj.method("first");
	string str = obj.method;
	obj.method("first", "second");

---------------------------------
(b)	Optional () for methods

	obj.property = "test";
	string str = obj.property;

	obj.method = "string";
	obj.method("first");
	string str = obj.method;
	string str = obj.method();
	obj.method("first", "second");

---------------------------------
(c)	Mandatory () for methods
		
	obj.property = "test";
	string str = obj.property;

	obj.method = "string";
	obj.method("first");
	string str = obj.method();
	obj.method("first", "second");

---------------------------------
(d) Property and Method separated. (Is this the goal for -property?)

	obj.property = "test";
	string str = obj.property;

	string str = obj.method();
	obj.method("first");
	obj.method("first", "second");

---------------------------------

Who likes (a) ?

Also I think that the @property opDispatch() looks weird.

January 18, 2012
On Tue, 17 Jan 2012 22:13:49 +0100, Peter Alexander <peter.alexander.au@gmail.com> wrote:

> On 17/01/12 6:48 AM, Andrei Alexandrescu wrote:
>> I hate I must ask this:
>>
>> int[string] aa;
>> foreach (k; aa.byKey) { ... }
>>
>> or
>>
>> int[string] aa;
>> foreach (k; aa.byKey()) { ... }
>>
>>
>>
>> Thanks,
>>
>> Andrei "I told you" Alexandrescu
>
> byKey(aa)
>
> Roll a dice, choose one at random.
>
> The only thing properties are good for is distracting us from tabs vs. spaces debates, and other really, really important matters.

But the current compiler behavior is really annoying.
Either nobody should use enforced properties or it should
be part of the standard warning level.
January 18, 2012
On Wednesday, January 18, 2012 09:38:41 Martin Nowak wrote:
> But the current compiler behavior is really annoying. Either nobody should use enforced properties or it should be part of the standard warning level.

Once the implementation of -property has been fully sorted out, I believe that it will be moved to the standard warning level, and then finally to an error, since per TDPL it's a requirement of the language that properties not be called with parens and that non-property functions _must_ be called with parens. The problem is that we're still in the transition period.

- Jonathan M Davis
January 18, 2012
Le 18/01/2012 01:02, Nick Sabalausky a écrit :
> "Alvaro"<alvaroDotSegura@gmail.com>  wrote in message
> news:jf4tr4$lnv$1@digitalmars.com...
>> El 17/01/2012 23:32, Timon Gehr escribi�:
>>> On 01/17/2012 11:19 PM, Alvaro wrote:
>>>> El 17/01/2012 18:24, Andrei Alexandrescu escribi�:
>>>>>> On 2012-01-17 06:48:26 +0000, Andrei Alexandrescu
>>>> ...
>>>>>
>>>>> aa.keys is taken btw.
>>>>>
>>>>
>>>>
>>>> OK, I see, .keys and .values currently return dynamic arrays.
>>>>
>>>> But the most appropriate property name for the above range should indeed
>>>> be .keys !
>>>>
>>>> Now, wouldn't it be be better to turn .keys into the proposed range?
>>>>
>>>> Let's see. What is the use of .keys?
>>>>
>>>> I searched phobos and found that .keys is mostly used to itarate over
>>>> the keys in a foreach loop. With the problem that is needs to allocate a
>>>> dynamic array. If silently changed to the proposed range, the foreach
>>>> loop would do the same and without an allocation.
>>>>
>>>> In a few unittests, .keys is followed by .sort, usually to print the
>>>> keys in order. That would not work... unless the produced range includes
>>>> a .sort method. Alternatively a .sortedKeys property can be added.
>>>>
>>>> The other use I see in phobos is just a typeof(a.keys[0]), which could
>>>> be replaced by typeof(a.keys.front)
>>>>
>>>>
>>>> What is the benefit of .keys as a range? it does not allocate an array,
>>>> just gives the keys.
>>>>
>>>> And if an array is needed, it is easy to turn a range into an array.
>>>> [Well, I'm missing a more direct way of doing that than using foreach
>>>> and appending]
>>>>
>>>
>>> See std.array.array.
>>
>> Oops. Yes, thanks.
>>
>> So, not bad. In those [infrequent, I'd say] cases needing an array one
>> would do:
>>
>>   auto keys = array(aa.keys);
>>
>
> My thoughts exactly. The current .keys made sense back in the days before
> ranges, std.algorithm, etc, but not so much anymore. Vote++
>
>

++ here. keys is the perfect name for that stuff.
January 18, 2012
On 18-01-2012 01:02, Nick Sabalausky wrote:
> "Alvaro"<alvaroDotSegura@gmail.com>  wrote in message
> news:jf4tr4$lnv$1@digitalmars.com...
>> El 17/01/2012 23:32, Timon Gehr escribió:
>>> On 01/17/2012 11:19 PM, Alvaro wrote:
>>>> El 17/01/2012 18:24, Andrei Alexandrescu escribió:
>>>>>> On 2012-01-17 06:48:26 +0000, Andrei Alexandrescu
>>>> ...
>>>>>
>>>>> aa.keys is taken btw.
>>>>>
>>>>
>>>>
>>>> OK, I see, .keys and .values currently return dynamic arrays.
>>>>
>>>> But the most appropriate property name for the above range should indeed
>>>> be .keys !
>>>>
>>>> Now, wouldn't it be be better to turn .keys into the proposed range?
>>>>
>>>> Let's see. What is the use of .keys?
>>>>
>>>> I searched phobos and found that .keys is mostly used to itarate over
>>>> the keys in a foreach loop. With the problem that is needs to allocate a
>>>> dynamic array. If silently changed to the proposed range, the foreach
>>>> loop would do the same and without an allocation.
>>>>
>>>> In a few unittests, .keys is followed by .sort, usually to print the
>>>> keys in order. That would not work... unless the produced range includes
>>>> a .sort method. Alternatively a .sortedKeys property can be added.
>>>>
>>>> The other use I see in phobos is just a typeof(a.keys[0]), which could
>>>> be replaced by typeof(a.keys.front)
>>>>
>>>>
>>>> What is the benefit of .keys as a range? it does not allocate an array,
>>>> just gives the keys.
>>>>
>>>> And if an array is needed, it is easy to turn a range into an array.
>>>> [Well, I'm missing a more direct way of doing that than using foreach
>>>> and appending]
>>>>
>>>
>>> See std.array.array.
>>
>> Oops. Yes, thanks.
>>
>> So, not bad. In those [infrequent, I'd say] cases needing an array one
>> would do:
>>
>>   auto keys = array(aa.keys);
>>
>
> My thoughts exactly. The current .keys made sense back in the days before
> ranges, std.algorithm, etc, but not so much anymore. Vote++
>
>

Vote++ from me as well.

-- 
- Alex
January 18, 2012
On 2012-01-18 09:30, sclytrack wrote:
>
>>
>> Is it practical or realistic to throw it out at this stage? I don't
>> know. But there are reasons to.
>
>
> I hope we are not dropping properties
> regardless of the syntax of how to call them.
>
> Keep @property
> Keep methods-as-properties
>
> ---------------------------------
> (a) No ()
>
> obj.property = "test";
> string str = obj.property;
>
> obj.method = "string";
> obj.method("first");
> string str = obj.method;
> obj.method("first", "second");
>
> ---------------------------------
> (b) Optional () for methods
>
> obj.property = "test";
> string str = obj.property;
>
> obj.method = "string";
> obj.method("first");
> string str = obj.method;
> string str = obj.method();
> obj.method("first", "second");
>
> ---------------------------------
> (c) Mandatory () for methods
>
> obj.property = "test";
> string str = obj.property;
>
> obj.method = "string";
> obj.method("first");
> string str = obj.method();
> obj.method("first", "second");
>
> ---------------------------------
> (d) Property and Method separated. (Is this the goal for -property?)
>
> obj.property = "test";
> string str = obj.property;
>
> string str = obj.method();
> obj.method("first");
> obj.method("first", "second");
>
> ---------------------------------
>
> Who likes (a) ?
>
> Also I think that the @property opDispatch() looks weird.

I would like this:

property:
	getter - parentheses are not allowed
	setter:
		* equal sign is required
		* parentheses are not allowed

method:
	no parameters - parentheses are optional
	parameters:
		* parentheses are required
		* equal sign is not allowed

Examples:

obj.property; // legal
obj.property = 1; // legal
obj.property(); // error
obj.property(1); // error

obj.method; // legal
obj.method(); // legal
obj.method(1); // legal
obj.method = 1; // error

-- 
/Jacob Carlborg