www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - property - take it behind the woodshed and shoot it?

reply Walter Bright <newshound2 digitalmars.com> writes:
This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

Perhaps we should revert to a simple set of rules.

1. Empty parens are optional. If there is an ambiguity with the return value 
taking (), the () go on the return value.

2. the:
    f = g
rewrite to:
    f(g)
only happens if f is a function that only has overloads for () and (one 
argument). No variadics.

3. Parens are required for calling delegates or function pointers.

4. No more  property.
Jan 24 2013
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-24 09:34, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return
 value taking (), the () go on the return value.

 2. the:
     f = g
 rewrite to:
     f(g)
 only happens if f is a function that only has overloads for () and (one
 argument). No variadics.
What do you mean by: "overloads for ()"?
 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
So: void delegate () foo (); foo() // would call the delegate ? -- /Jacob Carlborg
Jan 24 2013
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/24/2013 12:57 AM, Jacob Carlborg wrote:
 only happens if f is a function that only has overloads for () and (one
 argument). No variadics.
What do you mean by: "overloads for ()"?
I mean there are no f(...) and f(U,T) overloads.
 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
So: void delegate () foo (); foo() // would call the delegate ?
Yes.
Jan 24 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 3:57 AM, Jacob Carlborg wrote:
 On 2013-01-24 09:34, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return
 value taking (), the () go on the return value.

 2. the:
 f = g
 rewrite to:
 f(g)
 only happens if f is a function that only has overloads for () and (one
 argument). No variadics.
What do you mean by: "overloads for ()"?
That means there must be two overloads of f exactly: T f(); f(T);
 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
So: void delegate () foo (); foo() // would call the delegate ?
Yes. a = foo; // fetch the delegate b = foo(); // fetch and invoke the delegate Andrei
Jan 24 2013
next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 24 January 2013 at 16:29:07 UTC, Andrei Alexandrescu 
wrote:
 Yes.

 a = foo; // fetch the delegate
 b = foo(); // fetch and invoke the delegate
I generic code, bugs I predict !
Jan 24 2013
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 11:43 AM, deadalnix wrote:
 On Thursday, 24 January 2013 at 16:29:07 UTC, Andrei Alexandrescu wrote:
 Yes.

 a = foo; // fetch the delegate
 b = foo(); // fetch and invoke the delegate
I generic code, bugs I predict !
I agree it's something one must mind. Andrei
Jan 24 2013
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/24/2013 8:43 AM, deadalnix wrote:
 On Thursday, 24 January 2013 at 16:29:07 UTC, Andrei Alexandrescu wrote:
 Yes.

 a = foo; // fetch the delegate
 b = foo(); // fetch and invoke the delegate
I generic code, bugs I predict !
I would also count: f(some tuple) as requiring () even if "some tuple" expands to zero arguments. This should resolve issues with generic code.
Jan 24 2013
prev sibling next sibling parent reply "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Thursday, 24 January 2013 at 16:29:07 UTC, Andrei Alexandrescu 
wrote:
 On 1/24/13 3:57 AM, Jacob Carlborg wrote:
 void delegate () foo ();

 foo() // would call the delegate ?
Yes. a = foo; // fetch the delegate b = foo(); // fetch and invoke the delegate
How about generic code? void callFunc(alias f, Args...)(Args args) { f(args); } void delegate() foo(); void delegate(int) bar(int x); callFunc!foo(); // calls delegate? callFunc!bar(0); // calls bar? Seems like a recipe for disaster.
Jan 24 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 12:15 PM, Peter Alexander wrote:
 On Thursday, 24 January 2013 at 16:29:07 UTC, Andrei Alexandrescu wrote:
 On 1/24/13 3:57 AM, Jacob Carlborg wrote:
 void delegate () foo ();

 foo() // would call the delegate ?
Yes. a = foo; // fetch the delegate b = foo(); // fetch and invoke the delegate
How about generic code? void callFunc(alias f, Args...)(Args args) { f(args); } void delegate() foo(); void delegate(int) bar(int x); callFunc!foo(); // calls delegate? callFunc!bar(0); // calls bar? Seems like a recipe for disaster.
Agreed. This is a good litmus test. One option we had in mind was to still keep property for disambiguating such cases. Andrei
Jan 24 2013
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 24 January 2013 at 18:17:48 UTC, Andrei Alexandrescu 
wrote:
 Agreed. This is a good litmus test. One option we had in mind 
 was to still keep  property for disambiguating such cases.
It seems we've gone full circle. Tends to happen when you try to fix 3 wrong turns with a 4th wrong turn :)
Jan 24 2013
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
Thinking about it, this isn't quite a full circle. It does 
improve a bit.

If we aren't going dip21, how about:

===

Everything stays the way it is now, except:

* if a  property is called with parens, they always apply to the 
return value

* -property hopefully dies.

===


I don't really like it, it leaves a number of problems behind... 
but that would be an improvement on the status quo. I don't hate 
it.


So:

alias void delegate() Callable;

Callable nonprop();
 property Callable prop();

Callable returned = nonprop; // ok, the parens are optional
Callable returned = nonprop(); // ok, nonprop() just calls 
nonprop like any other function

Callable returned = prop; // ok, no parens still calls, just like 
before
Callable returned = prop(); // NOT GOOD: the () applies to the 
Callable (which returns void), not prop, because prop has 
 property

BTW
nonprop()(); // calls the Callable (this expression returns void)
prop()(); // nonsense (prop() returns void, which is not callable)

---

int nonprop();
 property int prop();

int returned = nonprop; // fine, optional parens
int returned = nonprop(); // fine

int returned = prop; // fine, we just call prop
int returned = prop(); // NO GOOD: the () always applies to the 
return value, which in this case is int, which is not callable
Jan 24 2013
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 1:37 PM, Adam D. Ruppe wrote:
 Thinking about it, this isn't quite a full circle. It does improve a bit.
Yes, I was about to write an email to destroy :o).
 If we aren't going dip21, how about:

 ===

 Everything stays the way it is now, except:

 * if a  property is called with parens, they always apply to the return
 value

 * -property hopefully dies.

 ===


 I don't really like it, it leaves a number of problems behind... but
 that would be an improvement on the status quo. I don't hate it.
Interesting, thanks. Andrei
Jan 24 2013
prev sibling parent reply "sclytrack" <sclytrack shorter.com> writes:
On Thursday, 24 January 2013 at 18:38:00 UTC, Adam D. Ruppe wrote:
 Thinking about it, this isn't quite a full circle. It does 
 improve a bit.

 If we aren't going dip21, how about:

 ===

 Everything stays the way it is now, except:

 * if a  property is called with parens, they always apply to 
 the return value

 * -property hopefully dies.

 ===
If this means keeping the writeln = ""; then vote++. I've got no issues with the property syntax for methods. I actually want them. Why should properties only get the shorter syntax?
 I don't really like it, it leaves a number of problems 
 behind... but that would be an improvement on the status quo. I 
 don't hate it.


 So:

 alias void delegate() Callable;

 Callable nonprop();
  property Callable prop();

 Callable returned = nonprop; // ok, the parens are optional
 Callable returned = nonprop(); // ok, nonprop() just calls 
 nonprop like any other function

 Callable returned = prop; // ok, no parens still calls, just 
 like before
 Callable returned = prop(); // NOT GOOD: the () applies to the 
 Callable (which returns void), not prop, because prop has 
  property

 BTW
 nonprop()(); // calls the Callable (this expression returns 
 void)
 prop()(); // nonsense (prop() returns void, which is not 
 callable)

 ---

 int nonprop();
  property int prop();

 int returned = nonprop; // fine, optional parens
 int returned = nonprop(); // fine

 int returned = prop; // fine, we just call prop
 int returned = prop(); // NO GOOD: the () always applies to the 
 return value, which in this case is int, which is not callable
Jan 27 2013
parent "anonymous" <anonymous shorter.com> writes:
On Sunday, 27 January 2013 at 10:30:41 UTC, sclytrack wrote:
 On Thursday, 24 January 2013 at 18:38:00 UTC, Adam D. Ruppe 
 wrote:
 Thinking about it, this isn't quite a full circle. It does 
 improve a bit.

 If we aren't going dip21, how about:

 ===

 Everything stays the way it is now, except:

 * if a  property is called with parens, they always apply to 
 the return value

 * -property hopefully dies.

 ===
If this means keeping the writeln = ""; then vote++. I've got no issues with the property syntax for methods. I actually want them. Why should properties only get the shorter syntax?
Also since you can't overload property opDispatch and opDispatch at the same time without knowing all the property names or method names at compile time you can use the opDispatch for everything if the methods have a property like syntax.
Jan 27 2013
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/24/2013 10:17 AM, Andrei Alexandrescu wrote:
 On 1/24/13 12:15 PM, Peter Alexander wrote:
 On Thursday, 24 January 2013 at 16:29:07 UTC, Andrei Alexandrescu wrote:
 On 1/24/13 3:57 AM, Jacob Carlborg wrote:
 void delegate () foo ();

 foo() // would call the delegate ?
Yes. a = foo; // fetch the delegate b = foo(); // fetch and invoke the delegate
How about generic code? void callFunc(alias f, Args...)(Args args) { f(args); } void delegate() foo(); void delegate(int) bar(int x); callFunc!foo(); // calls delegate? callFunc!bar(0); // calls bar? Seems like a recipe for disaster.
Agreed. This is a good litmus test. One option we had in mind was to still keep property for disambiguating such cases.
Another option is f(args) always requires parens, even if args expands to 0 args.
Jan 24 2013
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/24/2013 8:29 AM, Andrei Alexandrescu wrote:
 What do you mean by: "overloads for ()"?
That means there must be two overloads of f exactly: T f(); f(T);
There could also be f(U), f(V), etc., just that the are all 0 or 1 arg.
Jan 24 2013
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-24 17:29, Andrei Alexandrescu wrote:

 That means there must be two overloads of f exactly:

 T f();
 f(T);
That's somewhat problematic since it won't allow chaining assignments: auto i = f = 3; We need to either allow: T f (); T f (T); Or implement some form of rewrite: f = 3; // calls setter auto i = f; // calls getter This is the preferred solution. -- /Jacob Carlborg
Jan 25 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 09:12:47 UTC, Jacob Carlborg wrote:
 On 2013-01-24 17:29, Andrei Alexandrescu wrote:

 That means there must be two overloads of f exactly:

 T f();
 f(T);
That's somewhat problematic since it won't allow chaining assignments: auto i = f = 3; We need to either allow: T f (); T f (T); Or implement some form of rewrite: f = 3; // calls setter auto i = f; // calls getter This is the preferred solution.
Assignation is right associative, so it is equivalent to : auto i = (f = 3); The setter is called.
Jan 25 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-25 10:16, deadalnix wrote:

 Assignation is right associative, so it is equivalent to :
 auto i = (f = 3);

 The setter is called.
That's what I'm saying, the setter needs to be able to return something and not just void. -- /Jacob Carlborg
Jan 25 2013
parent reply "mist" <none none.none> writes:
On Friday, 25 January 2013 at 13:18:47 UTC, Jacob Carlborg wrote:
 On 2013-01-25 10:16, deadalnix wrote:

 Assignation is right associative, so it is equivalent to :
 auto i = (f = 3);

 The setter is called.
That's what I'm saying, the setter needs to be able to return something and not just void.
Hm, shouldn't it be processed like that: 1) evaluate "f = 3", setter called 2) evaluate "(f = 3)" -> evaluate "f" -> getter called 3) evaluate "auto i = ", setter called ?
Jan 25 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-25 14:26, mist wrote:

 Hm, shouldn't it be processed like that:
 1) evaluate "f = 3", setter called
 2) evaluate "(f = 3)" -> evaluate "f" -> getter called
 3) evaluate "auto i = ", setter called
 ?
Yes, but why would a setter be called at step 3? -- /Jacob Carlborg
Jan 25 2013
parent "mist" <none none.none> writes:
On Friday, 25 January 2013 at 13:52:37 UTC, Jacob Carlborg wrote:
 On 2013-01-25 14:26, mist wrote:

 Hm, shouldn't it be processed like that:
 1) evaluate "f = 3", setter called
 2) evaluate "(f = 3)" -> evaluate "f" -> getter called
 3) evaluate "auto i = ", setter called
 ?
Yes, but why would a setter be called at step 3?
Was thinking about i setter, did not pay attention it is actually a new declaration :) Never mind.
Jan 25 2013
prev sibling next sibling parent reply "anonymous" <anonymous example.com> writes:
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns 
 somewhere.

 Perhaps we should revert to a simple set of rules.
[...]
 4. No more  property.
You went half the way and now you're tired. Going back will be just as painful as going all the way. I say, keep property and fix it.
Jan 24 2013
next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
On Thursday, 24 January 2013 at 09:03:45 UTC, anonymous wrote:
 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright 
 wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns 
 somewhere.

 Perhaps we should revert to a simple set of rules.
[...]
 4. No more  property.
You went half the way and now you're tired. Going back will be just as painful as going all the way. I say, keep property and fix it.
+1
Jan 24 2013
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 4:03 AM, anonymous wrote:
 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.
[...]
 4. No more  property.
You went half the way and now you're tired. Going back will be just as painful as going all the way. I say, keep property and fix it.
This is a fix. Andrei
Jan 24 2013
prev sibling next sibling parent reply "Don" <don nospam.com> writes:
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns 
 somewhere.
I agree, the cure seems to be ten times worse than the disease. It's consumed far more resources than it is worth. In my experience one of the main reasons that projects fail, is that nobody had the courage and humility to say, "this idea is a failure, we need to throw it away and do something completely different".
 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the 
 return value taking (), the () go on the return value.
An example would make this easier to understand.
 2. the:
    f = g
 rewrite to:
    f(g)
 only happens if f is a function that only has overloads for () 
 and (one argument). No variadics.

 3. Parens are required for calling delegates or function 
 pointers.

 4. No more  property.
Jan 24 2013
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/24/2013 1:11 AM, Don wrote:
 1. Empty parens are optional. If there is an ambiguity with the return value
 taking (), the () go on the return value.
An example would make this easier to understand.
Jacob's should do.
Jan 24 2013
parent reply "Minas Mina" <minas_mina1990 hotmail.co.uk> writes:
f = g; where it means f(g) is really ugly. I wouldn't like to see 
this.

Also:

void printSomeStuff()
{
   //...
}

We are going to see code like this:
printSomeStuff; // i think that's ugly.

I suggested make parentheses optional only for UFC syntax.
Also isn't it possible to allow  property for functions that 
belong in a class/struct only?
Jan 24 2013
next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Thursday, 24 January 2013 at 10:22:00 UTC, Minas Mina wrote:
 f = g; where it means f(g) is really ugly. I wouldn't like to 
 see this.

 Also:

 void printSomeStuff()
 {
   //...
 }

 We are going to see code like this:
 printSomeStuff; // i think that's ugly.

 I suggested make parentheses optional only for UFC syntax.
 Also isn't it possible to allow  property for functions that 
 belong in a class/struct only?
property also makes sense for global functions that need to emulate a run-time initialized static variable.
Jan 24 2013
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/24/2013 2:21 AM, Minas Mina wrote:
 We are going to see code like this:
 printSomeStuff; // i think that's ugly.
Eeeyup. As for it being 'ugly', yes, it is a bit unsettling to us old time C programmers, but I think we can get used to it in short order. You can still add the () if you prefer.
 I suggested make parentheses optional only for UFC syntax.
The simpler the rules are, the more likely they are to work.
 Also isn't it possible to allow  property for functions that belong in a
 class/struct only?
I want to get rid of property. It's an eyesore.
Jan 24 2013
parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Walter Bright wrote:

 I want to get rid of  property. It's an eyesore.
Yes! And on falling flat on that please rethink uglinesses like `writefln'. Such mangling of values of parameters into the identifiers of procedures might kill maintainability. Or: is everyone able to "see" the values hidden in several of such appendices coming from several libraries written by several coders? writefln, seefln, grabfln, killfln! `write( format="%s", someExpression, eol);' is in fact longer than `writefln( "%s", someExpression);' Really? -manfred
Jan 24 2013
parent reply Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 24/01/2013 11:48, Manfred Nowak wrote:
 And on falling flat on that please rethink uglinesses like
 `writefln'. Such mangling of values of parameters into the
 identifiers of procedures might kill maintainability. Or: is
 everyone able to "see" the values hidden in several of such
 appendices coming from several libraries written by several
 coders?

 writefln, seefln, grabfln, killfln!

 `write( format="%s", someExpression, eol);' is in fact longer than
 `writefln( "%s", someExpression);'
How about: write!"%s\n" = someExpression; :-p Seriously, it would be nice to have a compile-time checked format string for writefln.
Jan 24 2013
next sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Thu, Jan 24, 2013 at 4:53 PM, Nick Treleaven
<ntrel-public yahoo.co.uk> wrote:

 write!"%s\n" = someExpression;

 :-p

 Seriously, it would be nice to have a compile-time checked format string for
 writefln.
I made a stab at it in a template tutorial that can be found on github: https://github.com/PhilippeSigaud/D-templates-tutorial You can grab the pdf, it's on section 5.11, p. 168 (Statically-Checked Writeln) Use example:
Jan 24 2013
next sibling parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Philippe Sigaud wrote:

 cwritefln!"For sample
Cough! `cfln' would eliminate the five letters `write'. For which purpose are they needed? Seriously, without some guarentee that `!"' starts a compile time checked string---and a defined metalanguage for describing compile time checking of compile time checked strings---close to every coding project will become an unmaintanable mess of DSL implementations "on the fly". The code you supplied on pages 170 to 171 is a good example for this forsight: please declare how much time an average member of an intended group of maintenance coders will need to grab the content of your idea. And of course declare the minimal skills all members of this group must have. -manfred
Jan 24 2013
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Fri, Jan 25, 2013 at 4:47 AM, Manfred Nowak <svv1999 hotmail.com> wrote:
 Philippe Sigaud wrote:

 cwritefln!"For sample
Cough! `cfln' would eliminate the five letters `write'. For which purpose are they needed?
:) Yes, I agree.
 Seriously, without some guarentee that `!"' starts a compile time
 checked string---and a defined metalanguage for describing compile
 time checking of compile time checked strings---close to every
 coding project will become an unmaintanable mess of DSL
 implementations "on the fly".
Well, the string-formatting DSL is well known. I don't think someone would be that distressed by its use.
 The code you supplied on pages 170 to 171 is a good example for
 this forsight: please declare how much time an average member of
 an intended group of maintenance coders will need to grab the
 content of your idea. And of course declare the minimal skills all
 members of this group must have.
Such hate... Keep cool and please give us your own code and preferred solution to compile-time formatting string checking.
Jan 25 2013
parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Philippe Sigaud wrote:

 Such hate...
No hate. Just knowledge out of experience.
 please give us your own code and preferred solution
 to compile-time formatting string checking.
I am not interested in formatting at all. I wrote about the general problem to incorporate expectable many DSL's into one big source base, as D is intended to serve large scale coding. I am sure that your "stab at it" does not show any intent to approach the general problem. -manfred
Jan 25 2013
next sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
 please give us your own code and preferred solution
 to compile-time formatting string checking.
I am not interested in formatting at all. I wrote about the general problem to incorporate expectable many DSL's into one big source base, as D is intended to serve large scale coding.
And what's the solution, for you? Using strings as DSL is somewhat common in D. As for DSL, well, I have a parser generator project here (https://github.com/PhilippeSigaud/Pegged), and I recently added the capacity to add new rules to a grammar at runtime and modify the resulting parse tree. I also used the existent, but unused macro keyword in D to get source code that can define its own subsequent grammar and parse tree transformations. Oh, and grammars can call one another, so adding a new sublanguage to a parent language is doable (I use this from time to time). I still have weeks fo work on this to have it reach the level I want, but I did not hit any wall up to now. So adding clean-looking DSL can be done in D, I think.
 I am sure that your "stab at it" does not show any intent to
 approach the general problem.
No, indeed :) Since it's a recurring question here, I just showed it could be done. It's also a simple example of what can be done with D meta-programming capacities.
Jan 25 2013
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/26/13 2:50 AM, Philippe Sigaud wrote:
 As for DSL, well, I have a parser generator project here
 (https://github.com/PhilippeSigaud/Pegged), and I recently added the
 capacity to add new rules to a grammar at runtime and modify the
 resulting parse tree. I also used the existent, but unused macro
 keyword in D to get source code that can define its own subsequent
 grammar and parse tree transformations.
 Oh, and grammars can call one another, so adding a new sublanguage to
 a parent language is doable (I use this from time to time). I still
 have weeks fo work on this to have it reach the level I want, but I
 did not hit any wall up to now.
 So adding clean-looking DSL can be done in D, I think.

 I am sure that your "stab at it" does not show any intent to
 approach the general problem.
No, indeed :) Since it's a recurring question here, I just showed it could be done. It's also a simple example of what can be done with D meta-programming capacities.
Looking forward to your talk? :o) Andrei
Jan 26 2013
prev sibling next sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 01/26/13 08:50, Philippe Sigaud wrote:
 please give us your own code and preferred solution
 to compile-time formatting string checking.
I am not interested in formatting at all. I wrote about the general problem to incorporate expectable many DSL's into one big source base, as D is intended to serve large scale coding.
And what's the solution, for you? Using strings as DSL is somewhat common in D.
I think his point was that inventing a custom dsl for everything does not scale. And he's of course right. Having one, or at most a few, common "std" dsls, plus ability do define custom ones is enough. But the "std" ones must be able to handle 95%+ of cases. So that everyone does not need to learn a set of custom per-site and/or per-project dsls. BTW, the std compile-time string formatting "dsl" is not only checkable, but can relatively easily be parsed at CT; the compiler will then do the rest. So there's really no point in using such a CT checker - if the string can be checked then it can also be handled directly, skipping any runtime parsing overhead completely.
 As for DSL, well, I have a parser generator project here
 (https://github.com/PhilippeSigaud/Pegged), and I recently added the
 capacity to add new rules to a grammar at runtime and modify the
 resulting parse tree. I also used the existent, but unused macro
 keyword in D to get source code that can define its own subsequent
 grammar and parse tree transformations.
 Oh, and grammars can call one another, so adding a new sublanguage to
 a parent language is doable (I use this from time to time). I still
 have weeks fo work on this to have it reach the level I want, but I
 did not hit any wall up to now.
 So adding clean-looking DSL can be done in D, I think.
Yes, this is possible, and desirable, to avoid "polluting" the main language with certain "features". However it's likely not enough, as there are aspects of D which make pure macro/dsl solutions not as simple as they could be (consider static-foreach). Your inline, parse-time, grammar extensions only work when the parser runs at CT, so the performance issues remain, right? Still, sounds interesting; and could be enough to explore the trickier cases and identify further problems. Must find time to play with it. Is that feature already in the repo? artur
Jan 26 2013
prev sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 01/26/13 11:46, Artur Skawina wrote:
 identify further problems. Must find time to play with it. Is that
 feature already in the repo?
Found it. Unfortunately the old compiler here can't handle newer D features and I can't really upgrade right now, so playing with pegged will have to wait. artur
Jan 26 2013
prev sibling parent Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 24/01/2013 17:04, Philippe Sigaud wrote:
 On Thu, Jan 24, 2013 at 4:53 PM, Nick Treleaven
 <ntrel-public yahoo.co.uk> wrote:

 write!"%s\n" = someExpression;

 :-p

 Seriously, it would be nice to have a compile-time checked format string for
 writefln.
I made a stab at it in a template tutorial that can be found on github: https://github.com/PhilippeSigaud/D-templates-tutorial You can grab the pdf, it's on section 5.11, p. 168 (Statically-Checked Writeln) Use example:
Yes, I wish that was in Phobos ;-) In fact, couldn't cwritefln just be a template overload of writefln? The string value parameter may be enough to distinguish it from the runtime version.
Jan 25 2013
prev sibling parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Nick Treleaven wrote:

 write!"%s\n" = someExpression;
Iff at all I prefer `write!someExpression= "%s\n";' Seriously, checking validity at execution time causes another sort of hiccoughs that should not be part of a language intended for large scale coding. -manfred
Jan 24 2013
parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On 2013-03-25 04:01, Manfred Nowak <svv1999 hotmail.com> wrote:

 Nick Treleaven wrote:

 write!"%s\n" = someExpression;
Iff at all I prefer `write!someExpression= "%s\n";' Seriously, checking validity at execution time causes another sort of hiccoughs that should not be part of a language intended for large scale coding.
From what I can see, Nick's solution allows compile time validity checking whereas yours does not. -- Simen
Jan 25 2013
parent Manfred Nowak <svv1999 hotmail.com> writes:
Simen Kjaeraas wrote:

 Seriously
[...]
 whereas yours does not
To me it is a syntactical change only. Where can I find the semantical change? And ... did you overlook the "seriously". -manfred
Jan 25 2013
prev sibling next sibling parent Manfred Nowak <svv1999 hotmail.com> writes:
Walter Bright wrote:

 4. No more  property.
yippee! -manfred
Jan 24 2013
prev sibling next sibling parent reply "mist" <none none.none> writes:
I am probably I minority here but I liked the most strict 
-property version and it made a lot of sense to me. Rationale is 
simple:
some().ufcs().chaining(); - this is just a minor syntax 
inconvenience
anything; - this drives me crazy, there is no way to understand 
if this a no-op statement variable of function call with some 
side-effect
I'd really like to have all function types to be obliged to use 
() and use property syntax only to those of property semantics 
(no side-effect variable getter/setter)

But looking at other comments this does not seem popular :( Well, 
I can only hope for something simple and non-revolutionary then.
Jan 24 2013
next sibling parent reply Artur Skawina <art.08.09 gmail.com> writes:
On 01/24/13 12:50, mist wrote:
 But looking at other comments this does not seem popular :( 
Language design is not a popularity contest. artur
Jan 24 2013
parent reply "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 13:34:08 UTC, Artur Skawina wrote:
 On 01/24/13 12:50, mist wrote:
 But looking at other comments this does not seem popular :(
Language design is not a popularity contest. artur
Well most discussions seems to flow around simple preference conflict of beautiful UFCS vs consistent function calls. And all compromises tend to explode in difficulty once delegates and function pointers are taken into consideration. I find consistent and unambiguous call syntax more important.
Jan 24 2013
next sibling parent reply Artur Skawina <art.08.09 gmail.com> writes:
On 01/24/13 14:46, mist wrote:
 On Thursday, 24 January 2013 at 13:34:08 UTC, Artur Skawina wrote:
 On 01/24/13 12:50, mist wrote:
 But looking at other comments this does not seem popular :(
Language design is not a popularity contest.
Well most discussions seems to flow around simple preference conflict of beautiful UFCS vs consistent function calls. And all compromises tend to explode in difficulty once delegates and function pointers are taken into consideration. I find consistent and unambiguous call syntax more important.
It's not merely "important"; it is essential. Those arguing for a "beatiful" UFCS syntax have not considered the consequences. Others see no point in arguing against obvious insanity; which skews the "popularity" numbers further. Just wait a year or so, until someone actually runs into the problems, and watch this discussion reincarnate. I can offhand think of three or four different ways to have a sane /and/ "beautiful" UFCS syntax, but even just discussing them would be a waste of time... For example, both of these are doable w/o involving property nor magic ()-less function calls; the second doesn't even require per-function annotations, at the cost of introducing another operator. iota(42, 2_000_000_000).filter!(a=>a&1).map!(to!string).take(10); iota(42, 2_000_000_000)->filter!(a=>a&1)->map!(to!string)->take(10); Having ()-less function calls is just insane; if it isn't obvious to you why, you just haven't read enough code that (ab)uses them. IOW, UFCS and property are not related, except the latter can currently be used as a workaround for missing functionality. artur
Jan 24 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 9:47 AM, Artur Skawina wrote:
 Having ()-less function calls is just insane; if it isn't obvious to you why,
 you just haven't read enough code that (ab)uses them.
You see, this is the kind of argument that I find very damaging to the conversation. It lacks any shred of material evidence, evokes emotion, manipulates the reader's opinion (framing them into incompetent/inexperienced if they disagree), and implies an appeal to authority. Please don't do that anymore. Thanks, Andrei
Jan 24 2013
next sibling parent reply Artur Skawina <art.08.09 gmail.com> writes:
On 01/24/13 19:05, Andrei Alexandrescu wrote:
 On 1/24/13 9:47 AM, Artur Skawina wrote:
 Having ()-less function calls is just insane; if it isn't obvious to you why,
 you just haven't read enough code that (ab)uses them.
You see, this is the kind of argument that I find very damaging to the conversation. It lacks any shred of material evidence, evokes emotion, manipulates the reader's opinion (framing them into incompetent/inexperienced if they disagree), and implies an appeal to authority. Please don't do that anymore.
You're more than welcome to produce counterevidence, or ignore the arguments, for whatever reasons. Ad hominems won't work, not only because I don't take this personally, but because I'm probably the person most willing/likely to discuss any relevant issues around here (I wish there was more like us (ie me)). Trying to make arguments you don't like go away and silencing the messenger is your MO. Please don't do that anymore. Not because I ask you to, but because it does harm the language, and the "community". Trying to at least understand the other point of view and reflecting a bit can be very enlightening. Who knows, you might even learn something new. Having said that, I'll elaborate on the sentence you quoted above. See for example Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the recursion in the tree-walker. This is an example of the kind of abuse of parens-less calls that an unsuspecting programmer shouldn't have to deal with. Sure, in this case it's simple enough, but in more complex scenarios, where the 'inorder' field/method/ufcs definition is not readily available, it would be extremely misleading. It's not reasonable to expect everyone reading the code to check every single object field access, just in case the previous coder decided that the source looked "cuter" w/o the '()'. artur [1] This isn't meant to single out Timon in any way; it's just a recent public code example I happened to remember. I would consider Timon one of the most helpful and knowledgeable people here - thanks for all the help and arguments, even the ones where we disagree, btw.
Jan 24 2013
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 2:03 PM, Artur Skawina wrote:
 On 01/24/13 19:05, Andrei Alexandrescu wrote:
 On 1/24/13 9:47 AM, Artur Skawina wrote:
 Having ()-less function calls is just insane; if it isn't obvious to you why,
 you just haven't read enough code that (ab)uses them.
You see, this is the kind of argument that I find very damaging to the conversation. It lacks any shred of material evidence, evokes emotion, manipulates the reader's opinion (framing them into incompetent/inexperienced if they disagree), and implies an appeal to authority. Please don't do that anymore.
You're more than welcome to produce counterevidence, or ignore the arguments, for whatever reasons. Ad hominems won't work, not only because I don't take this personally, but because I'm probably the person most willing/likely to discuss any relevant issues around here (I wish there was more like us (ie me)).
Good quality discussion is always welcome. I have specifically opposed a specific rhetoric, not a person, so "ad hominem" is inappropriate here.
 Trying to make arguments you don't like go away and silencing the messenger
 is your MO.
Now that's what's called "ad hominem".
 Please don't do that anymore.
I will always protest the rhetoric mentioned, sorry.
 Not because I ask you to, but because it
 does harm the language, and the "community".  Trying to at least understand the
 other point of view and reflecting a bit can be very enlightening. Who knows,
you
 might even learn something new.
Sarcasm is always appreciated :o). On a serious note, it's a bit assuming to conclude that disagreeing with something must be caused by not understanding it. This is not rocket science. The points involved are understood. That doesn't entail agreement.
 Having said that, I'll elaborate on the sentence you quoted above. See for
example
 Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the recursion in
the
 tree-walker.
How about this: insert the parens and then demonstrate how the bug is easier to spot. Wasn't any easier for me. Andrei
Jan 24 2013
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/24/2013 09:13 PM, Andrei Alexandrescu wrote:
 ...
 Having said that, I'll elaborate on the sentence you quoted above. See
 for example
 Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the
 recursion in the
 tree-walker.
How about this: insert the parens and then demonstrate how the bug is easier to spot. Wasn't any easier for me.
There is no bug.
Jan 24 2013
prev sibling parent reply Artur Skawina <art.08.09 gmail.com> writes:
On 01/24/13 21:13, Andrei Alexandrescu wrote:
 On 1/24/13 2:03 PM, Artur Skawina wrote:
 Trying to make arguments you don't like go away and silencing the messenger
 is your MO.
Now that's what's called "ad hominem".
No, it's not - it's just stating the facts; this was not the first such incident.
 Having said that, I'll elaborate on the sentence you quoted above. See for
example
 Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the recursion in
the
 tree-walker.
How about this: insert the parens and then demonstrate how the bug is easier to spot. Wasn't any easier for me.
Bug? In Timon's code? Impossible. :) No, this is just about syntax. Some functions are not suitable for calling w/o '()', and the choice needs to stay with the callee. But the distinction is "sane/insane" for a reason - there's judgment, taste and common sense involved. Trusting every programmer to get it right won't work, unfortunately. artur
Jan 24 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/25/13 2:12 AM, Artur Skawina wrote:
 On 01/24/13 21:13, Andrei Alexandrescu wrote:
 On 1/24/13 2:03 PM, Artur Skawina wrote:
 Trying to make arguments you don't like go away and silencing the messenger
 is your MO.
Now that's what's called "ad hominem".
No, it's not - it's just stating the facts; this was not the first such incident.
Of course it is. The definition is simple enough, e.g. from Wikipedia: An ad hominem (Latin for "to the man"), short for argumentum ad hominem, is an argument made personally against an opponent instead of against their argument.
 Having said that, I'll elaborate on the sentence you quoted above. See for
example
 Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the recursion in
the
 tree-walker.
How about this: insert the parens and then demonstrate how the bug is easier to spot. Wasn't any easier for me.
Bug? In Timon's code? Impossible. :) No, this is just about syntax. Some functions are not suitable for calling w/o '()', and the choice needs to stay with the callee. But the distinction is "sane/insane" for a reason - there's judgment, taste and common sense involved. Trusting every programmer to get it right won't work, unfortunately.
I'd say "sane/insane" is pushing it. Andrei
Jan 24 2013
next sibling parent reply Artur Skawina <art.08.09 gmail.com> writes:
On 01/25/13 08:39, Andrei Alexandrescu wrote:
 On 1/25/13 2:12 AM, Artur Skawina wrote:
 On 01/24/13 21:13, Andrei Alexandrescu wrote:
 On 1/24/13 2:03 PM, Artur Skawina wrote:
 Trying to make arguments you don't like go away and silencing the messenger
 is your MO.
Now that's what's called "ad hominem".
No, it's not - it's just stating the facts; this was not the first such incident.
Of course it is. The definition is simple enough, e.g. from Wikipedia: An ad hominem (Latin for "to the man"), short for argumentum ad hominem, is an argument made personally against an opponent instead of against their argument.
Hmm, I can see how you could view this as an ad hominem, given that definition, but it's not meant to be one and actually isn't - it has no bearing on the property nor ()-less calls issues; this is just about the process. Remember how you originally replied to my message, after removing everything but one sentence, which was clearly both a summary of my subjective position and deliberately phrased in a way to encourage at least some consideration wrt $subject by others making a decision. This isn't a new discussion, there's no need to restate the same arguments, from other threads, over and over again. Your response didn't provide any counterargument nor opinion on the subject; instead you chose to complain about the form and - I have no choice but to assume deliberately - misinterpret it. And asked me not to 'do that', in an attempt to manipulate the discussion. Crying "Ad Hominem!" now, after I point out that such tactics are not really helping to foster discussion, won't make it one, sorry. /I/ have no problem ignoring your comments, but others may not be as thick-skinned or not view D from the same perspective, and not willing to deal with that kind of arrogance. The number of D contributors is low enough, why drive potential ones away?
 and the choice needs to stay with the callee. But the distinction is
"sane/insane"
 for a reason - there's judgment, taste and common sense involved.
 Trusting every programmer to get it right won't work, unfortunately.
I'd say "sane/insane" is pushing it.
Normally, I'd probably agree, but in the context of removing property, but not implementing correct accessors nor enforcing calling syntax "insane" is appropriate. It's "sane/insane", because absolute terms such as "right/wrong" would be too strong; there is a large subjective component to it. artur
Jan 25 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/25/13 5:56 AM, Artur Skawina wrote:
 On 01/25/13 08:39, Andrei Alexandrescu wrote:
 On 1/25/13 2:12 AM, Artur Skawina wrote:
 On 01/24/13 21:13, Andrei Alexandrescu wrote:
 On 1/24/13 2:03 PM, Artur Skawina wrote:
 Trying to make arguments you don't like go away and silencing the messenger
 is your MO.
Now that's what's called "ad hominem".
No, it's not - it's just stating the facts; this was not the first such incident.
Of course it is. The definition is simple enough, e.g. from Wikipedia: An ad hominem (Latin for "to the man"), short for argumentum ad hominem, is an argument made personally against an opponent instead of against their argument.
Hmm, I can see how you could view this as an ad hominem, given that definition,
How can that be seen as anything else? What definition do you have? You made a mistake under the heat of the argument. We all do. Don't try to explain how actually you didn't. The right course is to casually apologize and move on.
 but it's not meant to be one and actually isn't - it has no bearing on
 the  property nor ()-less calls issues; this is just about the process.

 Remember how you originally replied to my message, after removing everything
 but one sentence, which was clearly both a summary of my subjective position
 and deliberately phrased in a way to encourage at least some consideration wrt
 $subject by others making a decision.
I kept the sentence that I had a reply for. The rest I understood and agreed with. Andrei
Jan 25 2013
next sibling parent "John T" <no spam.invalid> writes:
Andrei Alexandrescu wrote:
 You made a mistake under the heat of the argument. We all do. 
 Don't try to explain how actually you didn't. The right course 
 is to casually apologize and move on.
At this point, the only difference between you and Nick S. is the frequency of four-letter words in your posts. It's a real pity, D could have been such a nice language, but with that kind of "leadership"... - John
Jan 25 2013
prev sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 01/25/13 15:28, Andrei Alexandrescu wrote:
 On 1/25/13 5:56 AM, Artur Skawina wrote:
 On 01/25/13 08:39, Andrei Alexandrescu wrote:
 On 1/25/13 2:12 AM, Artur Skawina wrote:
 On 01/24/13 21:13, Andrei Alexandrescu wrote:
 On 1/24/13 2:03 PM, Artur Skawina wrote:
 Trying to make arguments you don't like go away and silencing the messenger
 is your MO.
Now that's what's called "ad hominem".
No, it's not - it's just stating the facts; this was not the first such incident.
Of course it is. The definition is simple enough, e.g. from Wikipedia: An ad hominem (Latin for "to the man"), short for argumentum ad hominem, is an argument made personally against an opponent instead of against their argument.
Hmm, I can see how you could view this as an ad hominem, given that definition,
How can that be seen as anything else? What definition do you have? You made a mistake under the heat of the argument. We all do. Don't try to explain how actually you didn't. The right course is to casually apologize and move on.
No. Please don't try to reinterpret what I said, this is the second time you did this. But, like i said, I can see that you view it like that. Fact is that that comment had absolutely nothing to do with the argument itself - I was only replying to your response, which was unacceptable. So, yes, I am talking about what you did, but that does not automatically mean it's an ad hominem, otherwise any critical comment about how the conversation is handled by the other side would be. I did make that comment too generic, and for that I'll apologize - I really should have said that /it happens/, and not used a figure of speech that can reasonably be misunderstood. I should have reread and caught that, I'm sorry. I'm still saying that these types of responses, when uncalled for (at least I didn't say 'in a well defined language..."), but caused only by your dislike of the argument or form thereof, are inappropriate.
 I kept the sentence that I had a reply for. The rest I understood and agreed
with.
It contained examples showing how all '()' could be omitted within ufcs chains, except the last pair. That would be a reasonable compromise, make code concise and unambiguous to read, but I guess you don't agree that doing it like that would be enough. artur
Jan 25 2013
prev sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Fri, 25 Jan 2013 02:39:15 -0500
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:

 On 1/25/13 2:12 AM, Artur Skawina wrote:
 On 01/24/13 21:13, Andrei Alexandrescu wrote:
 On 1/24/13 2:03 PM, Artur Skawina wrote:
 Trying to make arguments you don't like go away and silencing the
 messenger is your MO.
Now that's what's called "ad hominem".
No, it's not - it's just stating the facts; this was not the first such incident.
Of course it is. The definition is simple enough, e.g. from Wikipedia: An ad hominem (Latin for "to the man"), short for argumentum ad hominem, is an argument made personally against an opponent instead of against their argument.
"Ad hominem" *as a logical fallacy* is only applicable when the argument against the person is *intended* to prove something unrelated to the targeted person. For example, "Joe Schmo is a known asshole" *could* very easily be a logical fallacy. But it clearly *isn't* a fallacy if the speaker is using it to show: "Joe Schmo, your request to be a kindergarten teacher should be rejected." Artur was clearly making a side note about an unfortunate tendency in some of your posts that I've noticed as well. This was to make you aware of it and hopefully do it less. It was NOT, as you suggest, being put forth as evidence for Artur's property-related arguments.
Jan 25 2013
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/24/2013 08:03 PM, Artur Skawina wrote:
 ...

 Having said that, I'll elaborate on the sentence you quoted above. See for
example
 Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the recursion in
the
 tree-walker. This is an example of the kind of abuse of parens-less calls that
an
 unsuspecting programmer shouldn't have to deal with. Sure, in this case it's
simple
 enough, but in more complex scenarios, where the 'inorder' field/method/ufcs
 definition is not readily available, it would be extremely misleading. It's not
 reasonable to expect everyone reading the code to check every single object
field
 access, just in case the previous coder decided that the source looked "cuter"
 w/o the '()'.
 ...
Uh... class Tree(T){ InOrder!T inorder; this(){inorder = InOrder!T(this); } Tree!T l,r; T v; } auto tree(T)(Tree!T l, T v, Tree!T r){ auto t = new Tree!T; t.l=l;t.r=r;t.v=v; return t; } auto tree(T)(T v){ return tree(Tree!T.init,v,Tree!T.init); } struct InOrder(T){ this(Tree!T c){container=c;} Tree!T container; InOrder* t; mixin Yield!(q{ if (container.l !is null){ for(t=[container.l.inorder].ptr;!t.empty;t.popFront()) yield t.front; } yield container.v; if (container.r !is null){ for(t=[container.r.inorder].ptr;!t.empty;t.popFront()) yield t.front; } },T); } //InOrder!T inorder(T)(Tree!T container){ return InOrder!T(container); }
Jan 24 2013
prev sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 24 January 2013 at 18:05:25 UTC, Andrei Alexandrescu 
wrote:
 On 1/24/13 9:47 AM, Artur Skawina wrote:
 Having ()-less function calls is just insane; if it isn't 
 obvious to you why,
 you just haven't read enough code that (ab)uses them.
You see, this is the kind of argument that I find very damaging to the conversation. It lacks any shred of material evidence, evokes emotion, manipulates the reader's opinion (framing them into incompetent/inexperienced if they disagree), and implies an appeal to authority. Please don't do that anymore.
Let me rephrase that in a proper way. Functional style is very painful right now. Function you pass as argument are executed implicitly, function as variable don't behave like native ones, and with the new proposal, it add confusion on the function returned. It is kind of dumb that D do not promote functional style as it has shown to solve many problems that arise right now.
Jan 24 2013
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/25/2013 03:44 AM, deadalnix wrote:
 On Thursday, 24 January 2013 at 18:05:25 UTC, Andrei Alexandrescu wrote:
 On 1/24/13 9:47 AM, Artur Skawina wrote:
 Having ()-less function calls is just insane; if it isn't obvious to
 you why,
 you just haven't read enough code that (ab)uses them.
You see, this is the kind of argument that I find very damaging to the conversation. It lacks any shred of material evidence, evokes emotion, manipulates the reader's opinion (framing them into incompetent/inexperienced if they disagree), and implies an appeal to authority. Please don't do that anymore.
Let me rephrase that in a proper way. Functional style is very painful right now. Function you pass as argument are executed implicitly, function as variable don't behave like native ones, and with the new proposal, it add confusion on the function returned. It is kind of dumb that D do not promote functional style as it has shown to solve many problems that arise right now.
The main issue is horrible garbage collector performance for many small allocations. Syntactically we could do what scala does: scala> def fun()=2 fun: ()Int scala> fun : Int res0: Int = 2 scala> fun : (()=>Int) res1: () => Int = <function0>
Jan 24 2013
prev sibling parent kenji hara <k.hara.pg gmail.com> writes:
2013/1/25 deadalnix <deadalnix gmail.com>

 Functional style is very painful right now. Function you pass as argument
 are executed implicitly, function as variable don't behave like native
 ones, and with the new proposal, it add confusion on the function returned.
I'd like to add a rule which forgotten to mention about optional parentheses for normal functions.
 1. Optional parentheses for normal functions should work shallowly IMO.
1a. Optional parentheses for normal functions is just allowed for the getter usage. int foo(); foo(); // ok void bar(int); bar(1); // ok Kenji Hara
Jan 24 2013
prev sibling parent Johannes Pfau <nospam example.com> writes:
Am Thu, 24 Jan 2013 14:46:32 +0100
schrieb "mist" <none none.none>:

 On Thursday, 24 January 2013 at 13:34:08 UTC, Artur Skawina wrote:
 On 01/24/13 12:50, mist wrote:
 But looking at other comments this does not seem popular :(
Language design is not a popularity contest. artur
Well most discussions seems to flow around simple preference conflict of beautiful UFCS vs consistent function calls. And all compromises tend to explode in difficulty once delegates and function pointers are taken into consideration. I find consistent and unambiguous call syntax more important.
+1 Just as you and Nick I also like consistent function calls much more. Properties only make sense if you have consistent function calls, but then they're essential. If we allow optional parenthesis the properties are pretty much useless.
Jan 24 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 6:50 AM, mist wrote:
 I am probably I minority here but I liked the most strict -property
 version and it made a lot of sense to me. Rationale is simple:
 some().ufcs().chaining(); - this is just a minor syntax inconvenience
It becomes way uglier with templates: some!(e1)().ufcs!(e2)().chaining!(e3)(). In fact look at the code written by Nick in _favor_ of the parens. Self-destruction at its finest.
 anything; - this drives me crazy, there is no way to understand if this
I was amazed at how quickly I got used to it.
 a no-op statement variable of function call with some side-effect
 I'd really like to have all function types to be obliged to use () and
 use property syntax only to those of property semantics (no side-effect
 variable getter/setter)

 But looking at other comments this does not seem popular :( Well, I can
 only hope for something simple and non-revolutionary then.
You'll still be able to use parens. Andrei
Jan 24 2013
parent reply "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 17:49:18 UTC, Andrei Alexandrescu 
wrote:
 On 1/24/13 6:50 AM, mist wrote:
 I am probably I minority here but I liked the most strict 
 -property
 version and it made a lot of sense to me. Rationale is simple:
 some().ufcs().chaining(); - this is just a minor syntax 
 inconvenience
It becomes way uglier with templates: some!(e1)().ufcs!(e2)().chaining!(e3)(). In fact look at the code written by Nick in _favor_ of the parens. Self-destruction at its finest.
I can hardly see any problems in your code sample. Syntax inconvenience means nothing when compared to semantic inconvenience. It is just matter of visual preferences after all, you can get used to it quite fast.
 anything; - this drives me crazy, there is no way to 
 understand if this
I was amazed at how quickly I got used to it.
 ...
 You'll still be able to use parens.


 Andrei
You see, contrary to UFCS chaining this is not habit or syntax issue. It is semantic one - I am loosing an ability to distinct data access from function call by simply looking at code. There is nothing I can get used to - in a sane design I have this info, in D I do not. You have been just shown a few very good examples regarding functions, returning delegates - it is exactly the case where it shines. Yes, I am able to use parens, but in _my_ code I also do not need -property or anything - I am C++ programmer after all, I can discipline myself to certain code style even without compiler help. But writing generic code and reading one of others... I am glad I have not had to do any high-order function generic processing yet.
Jan 24 2013
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 1:35 PM, mist wrote:
 You see, contrary to UFCS chaining this is not habit or syntax issue. It
 is semantic one - I am loosing an ability to distinct data access from
 function call by simply looking at code.
This is the case with any property implementation. Andrei
Jan 24 2013
parent reply "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 20:00:18 UTC, Andrei Alexandrescu 
wrote:
 On 1/24/13 1:35 PM, mist wrote:
 You see, contrary to UFCS chaining this is not habit or syntax 
 issue. It
 is semantic one - I am loosing an ability to distinct data 
 access from
 function call by simply looking at code.
This is the case with any property implementation. Andrei
Not really. Good property usage is somewhat similar to unsafe cast usage - you say to others "Yes, I know what I am doing, please do not pay attention that this data is in fact function". The very point of properties is to be used almost indistinguishable from data and if this usage pattern fails - property author has lied and this is not really a property. And because of issues like "+=" it is rather difficult (if possible) to define good properties in D now.
Jan 24 2013
parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Thu, 24 Jan 2013 21:06:02 +0100
"mist" <none none.none> wrote:
 
 Not really. Good property usage is somewhat similar to unsafe 
 cast usage - you say to others "Yes, I know what I am doing, 
 please do not pay attention that this data is in fact function". 
 The very point of properties is to be used almost 
 indistinguishable from data and if this usage pattern fails - 
 property author has lied and this is not really a property.
 
+1
 And because of issues like "+=" it is rather difficult (if 
 possible) to define good properties in D now.
+1
Jan 24 2013
prev sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 24 January 2013 at 18:35:08 UTC, mist wrote:
 Yes, I am able to use parens, but in _my_ code I also do not 
 need -property or anything - I am C++ programmer after all, I 
 can discipline myself to certain code style even without 
 compiler help. But writing generic code and reading one of 
 others... I am glad I have not had to do any high-order 
 function generic processing yet.
I always create dumb lambda to do so as going fully functional is too painful map!(a => foo(a)) instead of map!foo . That is really annoying.
Jan 24 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/25/2013 03:48 AM, deadalnix wrote:
 On Thursday, 24 January 2013 at 18:35:08 UTC, mist wrote:
 Yes, I am able to use parens, but in _my_ code I also do not need
 -property or anything - I am C++ programmer after all, I can
 discipline myself to certain code style even without compiler help.
 But writing generic code and reading one of others... I am glad I have
 not had to do any high-order function generic processing yet.
I always create dumb lambda to do so as going fully functional is too painful map!(a => foo(a)) instead of map!foo . That is really annoying.
And just as pointless.
Jan 24 2013
prev sibling next sibling parent reply "Bernard Helyer" <b.helyer gmail.com> writes:
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns 
 somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the 
 return value taking (), the () go on the return value.

 2. the:
    f = g
 rewrite to:
    f(g)
 only happens if f is a function that only has overloads for () 
 and (one argument). No variadics.

 3. Parens are required for calling delegates or function 
 pointers.

 4. No more  property.
This is lazy design, plain and simple. You say it's turned into a monster, but property, at its core, is simpler than the heuristics you've demonstrated here. To my mind, property, properly implemented is simple: property functions may be called with no parens or with assignment as the singular argument. Non property functions may not. There. No complications. The only complications come from D's history. And then you want to turn it back? This seems a terrible idea -- the deed is done, pull the trigger. Make property mandatory for property functions. -Bernard.
Jan 24 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Bernard Helyer:

 To my mind,  property, properly implemented is simple:

  property functions may be called with no parens or with 
 assignment as
 the singular argument. Non  property functions may not.

 There. No complications.
Sounds OK. Instead of adding a -property, why wasn't this done since the beginning? (The right switch to add was -noproperty, to disable the feature, because most people do not use switches). Bye, bearophile
Jan 24 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-24 13:35, bearophile wrote:

 Instead of adding a -property, why wasn't this done since the beginning?
It would break tons of code. -- /Jacob Carlborg
Jan 24 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Jacob Carlborg:

 It would break tons of code.
How much work does it take to change that makes and compilation scripts to compile that code using a "-noproperty" switch? I think this silly fear of breaking user code was one of the main causes of the failure of property in the first place. If you introduce a new feature, then you need to introduce it cleanly since the beginning, otherwise you will make a mess. So future D feature must be introduced in a much more clean way in future, or not introduced at all. Bye, bearophile
Jan 24 2013
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-24 14:01, bearophile wrote:
 Jacob Carlborg:

 It would break tons of code.
How much work does it take to change that makes and compilation scripts to compile that code using a "-noproperty" switch?
No one can answer that.
 I think this silly fear of breaking user code was one of the main causes
 of the failure of  property in the first place. If you introduce a new
 feature, then you need to introduce it cleanly since the beginning,
 otherwise you will make a mess. So future D feature must be introduced
 in a much more clean way in future, or not introduced at all.
I agree with you but Walter is very afraid of breaking code. -- /Jacob Carlborg
Jan 24 2013
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/24/2013 5:42 AM, Jacob Carlborg wrote:
 I agree with you but Walter is very afraid of breaking code.
The history of what happens when D code breaks because of language changes is not a happy one.
Jan 24 2013
next sibling parent reply "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 20:52:10 UTC, Walter Bright wrote:
 On 1/24/2013 5:42 AM, Jacob Carlborg wrote:
 I agree with you but Walter is very afraid of breaking code.
The history of what happens when D code breaks because of language changes is not a happy one.
<rage>Please. Go to http://wiki.dlang.org/Release_Process . Read it. Answer the question "Hm, does having well-defined release process with long-term support versions help with instability of breaking changes?". And if answer is "no" then you probably should have contributed your opinion there for a long time, because it _should_ to.</rage> Really, all this backwards-compatibility talk is a crap. There is no way we can say current D design is final and solid and can be polished without any breaking changes. We should not argue about how bad breaking is. We should discus how to do those changes in the least harmful way.
Jan 24 2013
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 3:58 PM, mist wrote:
 Really, all this backwards-compatibility talk is a crap.
There's just a lot of evidence that suggests the contrary. Clearly we don't want or like to be conservative, but apparently we need to. Andrei
Jan 24 2013
next sibling parent reply "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 21:00:32 UTC, Andrei Alexandrescu 
wrote:
 On 1/24/13 3:58 PM, mist wrote:
 Really, all this backwards-compatibility talk is a crap.
There's just a lot of evidence that suggests the contrary. Clearly we don't want or like to be conservative, but apparently we need to. Andrei
Do you read and answer only to the first sentence? Can you honestly say "D design is rock solid and correct, we will never be required to make any backwards-incompatible change"? If you check those evidences, it was never breaking code alone. It was breaking code AND lack of any sane process that allows to stick with acceptable release version for longer time. And I suggest to fix the right thing, not freeze specs and hope all problems will fade themselves.
Jan 24 2013
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 4:06 PM, mist wrote:
 On Thursday, 24 January 2013 at 21:00:32 UTC, Andrei Alexandrescu wrote:
 On 1/24/13 3:58 PM, mist wrote:
 Really, all this backwards-compatibility talk is a crap.
There's just a lot of evidence that suggests the contrary. Clearly we don't want or like to be conservative, but apparently we need to. Andrei
Do you read and answer only to the first sentence?
It was your second paragraph I quoted.
 Can you honestly say
 "D design is rock solid and correct, we will never be required to make
 any backwards-incompatible change"?
Clearly the design is imperfect.
 If you check those evidences, it was never breaking code alone. It was
 breaking code AND lack of any sane process that allows to stick with
 acceptable release version for longer time. And I suggest to fix the
 right thing, not freeze specs and hope all problems will fade themselves.
My understanding is that we're working on such. Andrei
Jan 24 2013
parent "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 21:23:53 UTC, Andrei Alexandrescu 
wrote:
 ...
Sorry Andrei, with all my due respect, you have a brilliant talent to answer something without actually stating any own position on topic. Please take a look to my answer to Walter: http://forum.dlang.org/post/lpdegnaygbiijuwddgpf forum.dlang.org I'd really like to understand your position too, because arguing about sentences leads nowhere.
Jan 25 2013
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 22:06:02 mist wrote:
 On Thursday, 24 January 2013 at 21:00:32 UTC, Andrei Alexandrescu
 
 wrote:
 On 1/24/13 3:58 PM, mist wrote:
 Really, all this backwards-compatibility talk is a crap.
There's just a lot of evidence that suggests the contrary. Clearly we don't want or like to be conservative, but apparently we need to. Andrei
Do you read and answer only to the first sentence? Can you honestly say "D design is rock solid and correct, we will never be required to make any backwards-incompatible change"? If you check those evidences, it was never breaking code alone. It was breaking code AND lack of any sane process that allows to stick with acceptable release version for longer time. And I suggest to fix the right thing, not freeze specs and hope all problems will fade themselves.
The problem is that we have competing goals that we have to deal with 1. Fix any problems in the language so that its design is solid. 2. Avoid breaking people's code. with the perfect language when we're done, it doesn't matter much if no one's using it, and if we are forever breaking people's code, then they're not going to stick around. The trick is deciding when and how we need to and can get away with breaking code. And the longer it takes to solve major design flaws in the language which require breaking code, the more code we'll break when we do make the changes, and the more problems will have, which is one reason why it's so frustrating that it often takes quite a while to properly sort this sort of thing out. - Jonathan M Davis
Jan 24 2013
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 13:26:11 -0800, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Thursday, January 24, 2013 22:06:02 mist wrote:
 On Thursday, 24 January 2013 at 21:00:32 UTC, Andrei Alexandrescu

 wrote:
 On 1/24/13 3:58 PM, mist wrote:
 Really, all this backwards-compatibility talk is a crap.
There's just a lot of evidence that suggests the contrary. Clearly we don't want or like to be conservative, but apparently we need to. Andrei
Do you read and answer only to the first sentence? Can you honestly say "D design is rock solid and correct, we will never be required to make any backwards-incompatible change"? If you check those evidences, it was never breaking code alone. It was breaking code AND lack of any sane process that allows to stick with acceptable release version for longer time. And I suggest to fix the right thing, not freeze specs and hope all problems will fade themselves.
The problem is that we have competing goals that we have to deal with 1. Fix any problems in the language so that its design is solid. 2. Avoid breaking people's code. we do end up with the perfect language when we're done, it doesn't matter much if no one's using it, and if we are forever breaking people's code, then they're not going to stick around. The trick is deciding when and how we need to and can get away with breaking code. And the longer it takes to solve major design flaws in the language which require breaking code, the more code we'll break when we do make the changes, and the more problems will have, which is one reason why it's so frustrating that it often takes quite a while to properly sort this sort of thing out. - Jonathan M Davis
I don't think we can fix property (or remove it) without breaking code. So I would plead with the community to accept that. This is a very important problem to fix. Obviously deciding how to proceed is going to be difficult but I don't think that we have copious amounts of time for the community to slug it out either. You either break properties or optional parens, either way creates problems. I would argue that removing property creates more problems than removing optional parens. One is a highly delicate surgical operation on the parser to handle all the new ambiguities, more documentation to explain, and more chances to the user to D the wrong (but still acceptable) thing, and requires large amounts code refactoring. The other is a simple find/replace in user code, with some simple changes to the parser. I will always vote for the less bug-prone path. Remove Optional Parens. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 24 January 2013 at 21:40:01 UTC, Adam Wilson wrote:
 Remove Optional Parens.
This has absolutely nothing to do with properties because properties are data fields, NOT functions. http://forum.dlang.org/post/fpbvfpvnjtgqbganqece forum.dlang.org
Jan 24 2013
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 13:41:55 -0800, Adam D. Ruppe  
<destructionator gmail.com> wrote:

 On Thursday, 24 January 2013 at 21:40:01 UTC, Adam Wilson wrote:
 Remove Optional Parens.
This has absolutely nothing to do with properties because properties are data fields, NOT functions. http://forum.dlang.org/post/fpbvfpvnjtgqbganqece forum.dlang.org
From the compilers standpoint they are functions. It must be so. That's how they're implemented. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 24 January 2013 at 21:44:12 UTC, Adam Wilson wrote:
 From the compilers standpoint they are functions. It must be 
 so. That's how they're implemented.
No, they are property functions. That's important because it lets them be rewritten at the usage point, similarly to operator overloading and various other tricks in the language, which also doesn't care about function call syntax, despite being implemented as functions. I was messing with the compiler a while ago to make my vision work. Got about 90% there, but it got too messy when doing setters. Only made 5 changes: DsymbolExp::semantic if the function this references was declared as a property, rewrite the symbol to be a call expression Thus "bar", if bar was declared as property, is rewritten into "(bar())" and the rest carries on normally. (So if the whole expression was "bar().foo", the rest of the compiler sees it as "(bar())().foo" and reacts accordingly.) DotVarExp::semantic ditto, but for members instead And the others were trying to make it work for setters in BinExp, AssignExp, and a filthy hack in CallExp itself to find the setter given a getter. The getter change, about 10 lines of code in dmd, was a success. The setters are where I tripped up and couldn't get it to work right, but this is probably because I'm not a dmd master, not because it is impossible.
Jan 24 2013
prev sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 24 January 2013 at 21:00:32 UTC, Andrei Alexandrescu 
wrote:
 On 1/24/13 3:58 PM, mist wrote:
 Really, all this backwards-compatibility talk is a crap.
There's just a lot of evidence that suggests the contrary. Clearly we don't want or like to be conservative, but apparently we need to.
If you or Walter think that D is somehow stable or backward compatible, you must both be very high on drugs. Yes that is an ad hominem. Let me tell you a story. This story take place one month ago. A guy (me) get the news released version of the compiler. After all, he badly needs it as bugs in the previous cause the GC to misbehave in very scary ways. First, some language specs have changed, so his code is broken. But hey, that is to be expected and so the guy fix his code. A bug is discovered in the compiler, it is a regression, and it make the guy's code, once fixed, impossible to compile with 2.061 AT ALL. Hopefully a brave knight (Kenji) cam to fight the monstrous compiler and finally get it to compile the code it should have compiled from day 1. The guy now use a custom patched version of the compiler. No revision of the compiler is released at this point, but worse, the guy's code now trigger some other bugs into 2.061 (but not in his patched version). The guy can't do D on his mac anymore as he have no clue how to do the setup for his patched compiler. After all, he is not really an apple guy. Note that was already using a custom compiler before 2.060 as 2.059 already have blocking bugs for me. D is nothing even remotely close to stable. D introduce breaking change with EVERY new release. Worse, D has no sane way to introduce such breaking change in a sane way. And suddenly, this is an issue ?
Jan 24 2013
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/24/2013 12:58 PM, mist wrote:
 <rage>Please. Go to http://wiki.dlang.org/Release_Process . Read it. Answer the
 question "Hm, does having well-defined release process with long-term support
 versions help with instability of breaking changes?". And if answer is "no"
then
 you probably should have contributed your opinion there for a long time,
because
 it _should_ to.</rage>

 Really, all this backwards-compatibility talk is a crap. There is no way we can
 say current D design is final and solid and can be polished without any
breaking
 changes. We should not argue about how bad breaking is. We should discus how to
 do those changes in the least harmful way.
Having a release process does not remove the pain of breaking changes that make users miserable because their older code no longer compiles.
Jan 24 2013
next sibling parent "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 22:45:52 UTC, Walter Bright wrote:
 Having a release process does not remove the pain of breaking 
 changes that make users miserable because their older code no 
 longer compiles.
Beg my pardon, it is very ignorant position. It assumes user is some kind of stubborn creature that is scared of any spec changes. But it is not really the case. Users are not afraid of compiler release breaking their code - they are afraid of not having a single compiler version that both is stable enough and works for their code. And that it is very different. It is fine to break code in release if you still provide bug-fixes to some older version that may be recommended for usage until time to fix code base is taken. And this is exactly where good release process shines, it is single most important reason to have it. To sum up my position: 1) D spec is imperfect 2) Breaking change are inevitable 3) Saying "breaking changes" are bad means hiding the problem 4) It is better to focus on process to minimize breaking changes damage than rant about how bad they are 5) Leaving feature badly designed for years with no hope to change is worse than breaking code. I'd really like to read your position on _all_ of those statements, because we are running circles here.
Jan 25 2013
prev sibling next sibling parent "mist" <none none.none> writes:
Also I need to remind you that we break code all the time with 
big fixes, literally every release. And end user does not care 
how reasonable breaking it is, they are all the same: time needed 
to update the code base.

We need to admit that breaking is inevitable and go forward from 
there to fix real solvable problems.
Jan 25 2013
prev sibling parent "ggeal" <gathDONTnaSPAMgealaich gmail.com> writes:
On Thursday, 24 January 2013 at 22:45:52 UTC, Walter Bright wrote:
 Having a release process does not remove the pain of breaking 
 changes that make users miserable because their older code no 
 longer compiles.
What about providing a tool to automatically perform the transform necessary to fix the code (w.r.t. the breaking change)? That should be feasible in many cases, and there are languages that have gone down this route already (Python 3 partially, Go fully, if I'm not mistaken). gath
Jan 25 2013
prev sibling next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 24 January 2013 at 20:52:10 UTC, Walter Bright wrote:
 On 1/24/2013 5:42 AM, Jacob Carlborg wrote:
 I agree with you but Walter is very afraid of breaking code.
The history of what happens when D code breaks because of language changes is not a happy one.
That is why semantic needs to be clean. Semy hacky stuff ends up causing trouble and we either have to live with it or break code.
Jan 24 2013
prev sibling parent reply "Don" <don nospam.com> writes:
On Thursday, 24 January 2013 at 20:52:10 UTC, Walter Bright wrote:
 On 1/24/2013 5:42 AM, Jacob Carlborg wrote:
 I agree with you but Walter is very afraid of breaking code.
The history of what happens when D code breaks because of language changes is not a happy one.
I don't believe that is true. Remember when 'bit' was removed from the language? It didn't cause any complaints at all. This attitude is very harmful. Our real problem is that we're not making promises about what we won't change. When we haven't made such promises, we then become fearful of changing *anything*. Then we bend over backwards to avoid changing things that actually nobody cares about. This is a recipe for locking bugs into the language forever. Instead, we should be trying to continuously expand the things we guarantee will continue to work. Ideally we would be precise about the things that are likely to change, and which we don't currently guarantee.
Jan 25 2013
next sibling parent "mist" <none none.none> writes:
On Friday, 25 January 2013 at 09:49:29 UTC, Don wrote:
 ...
++ It feels that "breaking code" has become some kind of scary ghost that is just being afraid of instead of some kind of analysis-based approach.
Jan 25 2013
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/25/13 4:49 AM, Don wrote:
 On Thursday, 24 January 2013 at 20:52:10 UTC, Walter Bright wrote:
 On 1/24/2013 5:42 AM, Jacob Carlborg wrote:
 I agree with you but Walter is very afraid of breaking code.
The history of what happens when D code breaks because of language changes is not a happy one.
I don't believe that is true. Remember when 'bit' was removed from the language? It didn't cause any complaints at all. This attitude is very harmful. Our real problem is that we're not making promises about what we won't change. When we haven't made such promises, we then become fearful of changing *anything*. Then we bend over backwards to avoid changing things that actually nobody cares about. This is a recipe for locking bugs into the language forever. Instead, we should be trying to continuously expand the things we guarantee will continue to work. Ideally we would be precise about the things that are likely to change, and which we don't currently guarantee.
TDPL did exactly that. For example it doesn't mention foreach_reverse or lazy. Far as I know that didn't make a difference. Andrei
Jan 25 2013
parent "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 14:18:06 UTC, Andrei Alexandrescu 
wrote:
 TDPL did exactly that. For example it doesn't mention 
 foreach_reverse or lazy. Far as I know that didn't make a 
 difference.
Wise move !
Jan 25 2013
prev sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
25-Jan-2013 13:49, Don пишет:
 On Thursday, 24 January 2013 at 20:52:10 UTC, Walter Bright wrote:
 On 1/24/2013 5:42 AM, Jacob Carlborg wrote:
 I agree with you but Walter is very afraid of breaking code.
The history of what happens when D code breaks because of language changes is not a happy one.
I don't believe that is true. Remember when 'bit' was removed from the language? It didn't cause any complaints at all. This attitude is very harmful. Our real problem is that we're not making promises about what we won't change. When we haven't made such promises, we then become fearful of changing *anything*. Then we bend over backwards to avoid changing things that actually nobody cares about. This is a recipe for locking bugs into the language forever. Instead, we should be trying to continuously expand the things we guarantee will continue to work. Ideally we would be precise about the things that are likely to change, and which we don't currently guarantee.
+1 -- Dmitry Olshansky
Jan 25 2013
parent reply "Rob T" <alanb ucora.com> writes:
On Friday, 25 January 2013 at 17:52:12 UTC, Dmitry Olshansky 
wrote:
 Instead, we should be trying to continuously expand the things 
 we
 guarantee will continue to work. Ideally we would be precise 
 about the
 things that are likely to change, and which we don't currently 
 guarantee.
+1
I agree with this completely, but we cannot do it until there's a full implementation of a reasonably designed and followed development and release process that includes the language specification. --rt
Jan 25 2013
parent reply "SomeDude" <lovelydear mailmetrash.com> writes:
On Friday, 25 January 2013 at 18:03:54 UTC, Rob T wrote:
 On Friday, 25 January 2013 at 17:52:12 UTC, Dmitry Olshansky 
 wrote:
 Instead, we should be trying to continuously expand the 
 things we
 guarantee will continue to work. Ideally we would be precise 
 about the
 things that are likely to change, and which we don't 
 currently guarantee.
+1
I agree with this completely, but we cannot do it until there's a full implementation of a reasonably designed and followed development and release process that includes the language specification. --rt
+1 The language has reached a point where bugs in the spec are more important than bugs of the implementation. In fact many difficult bugs in the implementation are rooted in spec issues.
Jan 27 2013
parent "Dicebot" <m.strashun gmail.com> writes:
On Sunday, 27 January 2013 at 09:51:04 UTC, SomeDude wrote:
 On Friday, 25 January 2013 at 18:03:54 UTC, Rob T wrote:
 On Friday, 25 January 2013 at 17:52:12 UTC, Dmitry Olshansky 
 wrote:
 Instead, we should be trying to continuously expand the 
 things we
 guarantee will continue to work. Ideally we would be precise 
 about the
 things that are likely to change, and which we don't 
 currently guarantee.
+1
I agree with this completely, but we cannot do it until there's a full implementation of a reasonably designed and followed development and release process that includes the language specification. --rt
+1 The language has reached a point where bugs in the spec are more important than bugs of the implementation. In fact many difficult bugs in the implementation are rooted in spec issues.
I went to stress the "followed" part. I.e. we do have quite a good release process description on wiki with some related parts also mentioned. But if it is followed as good as upon 2.061, it makes not difference.
Jan 27 2013
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 8:01 AM, bearophile wrote:
 I think this silly fear of breaking user code was one of the main causes
 of the failure of  property in the first place.
No. property is bad design, pure and simple. It's great that we're acknowledging that. Andrei
Jan 24 2013
prev sibling parent reply "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 12:53:45 UTC, Jacob Carlborg 
wrote:
 On 2013-01-24 13:35, bearophile wrote:

 Instead of adding a -property, why wasn't this done since the 
 beginning?
It would break tons of code.
And yet it must have been done at some point. With some year-ahead announcement or anything like that, but it was a horrible design error in first place which needs to be fixed.
Jan 24 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
mist:

 but it was a horrible design error in first place
 which needs to be fixed.
Don't forget that our discussions in this thread are mostly academic :-) Bye, bearophile
Jan 24 2013
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-24 14:01, mist wrote:

 And yet it must have been done at some point. With some year-ahead
 announcement or anything like that, but it was a horrible design error
 in first place which needs to be fixed.
Yes, it was a horrible design error but it didn't break any code because the -property flag is optional. -- /Jacob Carlborg
Jan 24 2013
parent "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 13:43:41 UTC, Jacob Carlborg 
wrote:
 On 2013-01-24 14:01, mist wrote:

 And yet it must have been done at some point. With some 
 year-ahead
 announcement or anything like that, but it was a horrible 
 design error
 in first place which needs to be fixed.
Yes, it was a horrible design error but it didn't break any code because the -property flag is optional.
Design error was to not force "-property" since the very beginning. Now good decisions are kind of doomed to break code because restrictions were (and still are) too lax and a lot of inconsistent code is somewhere out there. This is exactly why I voted for LTS + rolling-release model. D is still far from the point where design specs can be frozen and breaking code prohibited. Those still have mistakes.
Jan 24 2013
prev sibling next sibling parent "eles" <eles eles.com> writes:
On Thursday, 24 January 2013 at 12:13:57 UTC, Bernard Helyer 
wrote:
 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright 
 wrote:

  property functions may be called with no parens or with 
 assignment as
 the singular argument. Non  property functions may not.

 There. No complications. The only complications come from D's 
 history.
I would say: kill -property, not property.
Jan 24 2013
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
Absolutely agree.

I think it's pretty weak to say  property is a monster/failure, and then

Finish the deed!

Your set of proposed rules are far more complex and non-uniform... what is
the advantage to that complexity?
On 24 Jan 2013 19:15, "Bernard Helyer" <b.helyer gmail.com> wrote:

 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:

 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return
 value taking (), the () go on the return value.

 2. the:
    f = g
 rewrite to:
    f(g)
 only happens if f is a function that only has overloads for () and (one
 argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
This is lazy design, plain and simple. You say it's turned into a monster, but property, at its core, is simpler than the heuristics you've demonstrated here. To my mind, property, properly implemented is simple: property functions may be called with no parens or with assignment as the singular argument. Non property functions may not. There. No complications. The only complications come from D's history. And then you want to turn it back? This seems a terrible idea -- the deed is done, pull the trigger. Make property mandatory for property functions. -Bernard.
Jan 24 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 7:13 AM, Bernard Helyer wrote:
 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return
 value taking (), the () go on the return value.

 2. the:
 f = g
 rewrite to:
 f(g)
 only happens if f is a function that only has overloads for () and
 (one argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
This is lazy design, plain and simple. You say it's turned into a monster, but property, at its core, is simpler than the heuristics you've demonstrated here. To my mind, property, properly implemented is simple: property functions may be called with no parens or with assignment as the singular argument. Non property functions may not. There. No complications. The only complications come from D's history. And then you want to turn it back? This seems a terrible idea -- the deed is done, pull the trigger. Make property mandatory for property functions.
No. The complications come from the fact that (a) nobody could agree what should be a property and what shouldn't; (b) property adds noise for everybody for the sake of a corner case (functions returning delegates); (c) the property discipline failed to align itself in any way with better code quality. Andrei
Jan 24 2013
next sibling parent reply "David Nadlinger" <see klickverbot.at> writes:
On Thursday, 24 January 2013 at 17:51:32 UTC, Andrei Alexandrescu 
wrote:
 No. The complications come from the fact that (a) nobody could 
 agree what should be a  property and what shouldn't; (b) 
  property adds noise for everybody for the sake of a corner 
 case (functions returning delegates); (c) the  property 
 discipline failed to align itself in any way with better code 
 quality.
The simple(r) explanation is: The current *implementation* is broken. David
Jan 24 2013
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 12:54 PM, David Nadlinger wrote:
 On Thursday, 24 January 2013 at 17:51:32 UTC, Andrei Alexandrescu wrote:
 No. The complications come from the fact that (a) nobody could agree
 what should be a  property and what shouldn't; (b)  property adds
 noise for everybody for the sake of a corner case (functions returning
 delegates); (c) the  property discipline failed to align itself in any
 way with better code quality.
The simple(r) explanation is: The current *implementation* is broken.
Simpler doesn't make it true. Andrei
Jan 24 2013
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 18:54:00 David Nadlinger wrote:
 On Thursday, 24 January 2013 at 17:51:32 UTC, Andrei Alexandrescu
 
 wrote:
 No. The complications come from the fact that (a) nobody could
 agree what should be a  property and what shouldn't; (b)
  property adds noise for everybody for the sake of a corner
 case (functions returning delegates); (c) the  property
 discipline failed to align itself in any way with better code
 quality.
The simple(r) explanation is: The current *implementation* is broken.
Exactly. Most of the problems with property stem from the fact that it's not implemented properly, particularly with regards to the -property flag. - Jonathan M Davis
Jan 24 2013
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 2:14 PM, Jonathan M Davis wrote:
 On Thursday, January 24, 2013 18:54:00 David Nadlinger wrote:
 On Thursday, 24 January 2013 at 17:51:32 UTC, Andrei Alexandrescu

 wrote:
 No. The complications come from the fact that (a) nobody could
 agree what should be a  property and what shouldn't; (b)
  property adds noise for everybody for the sake of a corner
 case (functions returning delegates); (c) the  property
 discipline failed to align itself in any way with better code
 quality.
The simple(r) explanation is: The current *implementation* is broken.
Exactly. Most of the problems with property stem from the fact that it's not implemented properly, particularly with regards to the -property flag.
That is because it's not well defined. Andrei
Jan 24 2013
prev sibling next sibling parent Johannes Pfau <nospam example.com> writes:
Am Thu, 24 Jan 2013 12:51:32 -0500
schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:
 
 No. The complications come from the fact that (a) nobody could agree 
 what should be a  property and what shouldn't;
for properties and those who didn't. Seriously, I never found it have pretty clear rules.
 (b)  property adds
 noise for everybody for the sake of a corner case (functions
 returning delegates); 
Partially true, although the real question is whether the additional () are really noise or actually useful. A hardcore C programmer (wants to see every function call) and a ruby developer could probably have a long discussion about that.
(c) the  property discipline failed to align
 itself in any way with better code quality.
It's hard to verify if code quality changed if the feature isn't properly implemented. Even if it was properly implemented comparing code quality probably isn't easy.
Jan 24 2013
prev sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Thu, 24 Jan 2013 12:51:32 -0500
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 7:13 AM, Bernard Helyer wrote:
 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns
 somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the
 return value taking (), the () go on the return value.

 2. the:
 f = g
 rewrite to:
 f(g)
 only happens if f is a function that only has overloads for () and
 (one argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
This is lazy design, plain and simple. You say it's turned into a monster, but property, at its core, is simpler than the heuristics you've demonstrated here. To my mind, property, properly implemented is simple: property functions may be called with no parens or with assignment as the singular argument. Non property functions may not. There. No complications. The only complications come from D's history. And then you want to turn it back? This seems a terrible idea -- the deed is done, pull the trigger. Make property mandatory for property functions.
No. The complications come from the fact that (a) nobody could agree what should be a property and what shouldn't;
No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you). Stop mischaracterizing what really happened: It's well known that you never liked or fully understood the idea of properties in the first place, even by your own admission. So you made a post some number of months back attempting to drum up dissent for properties by stirring up the notion, which just about only you believed, that the choice between property and function is inherently unclear. So to "prove" this you cherry-picked some grey area cases (gee, occasional grey judgement calls when mapping ideas into code, yea, there's something that doesn't happen without property). You succeeded ONLY in proving that there exist *some* cases which may be grey-area judgement calls (again, big surprise, occasional grey-area judgement calls when writing code). But then you - and ONLY you - took this proof that "*some* cases exist" and declared "Look, look, everyone! I proved that *nobody* can agree on property vs function *in general*! QED!" And you continue declaring that non-sequitur to this day.
 (b)  property adds
 noise for everybody for the sake of a corner case (functions
 returning delegates);
The only reason functions returning delegates have *ever* been an any issue at all is *purely* because of the insistence on optional parens on arbitrary function calls.
 (c) the  property discipline failed to align
 itself in any way with better code quality.
 
Ok, now *that* argument is just pure unadulterated bullshit. In yes, the general consensus IS that they DO definitely help. Please take your blinders off, and you'll see that. But then there's D, which adds a half-baked and incompletely-implemented "properties" - and did so *reluctantly* I should add. Leaves it in that broken state untouched for a year or two. And now here you are effectively saying "This half-designed/half-implemented feature is causing dissent and not helping people, therefore the problem must be the whole idea of properties and couldn't possibly be due to our broken version of them" (for the record - I *do* find D's current properties helpful, just not as helpful as they would be if they weren't broken).
Jan 24 2013
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 3:45 PM, Nick Sabalausky wrote:
 On Thu, 24 Jan 2013 12:51:32 -0500
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org>  wrote:
 No, you merely came up with *some* specific cherry-picked examples that
 sparked *some* debate (with most of the disagreing coming from
 you).
I simply mentioned three reasons that came to mind. Andrei
Jan 24 2013
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 3:45 PM, Nick Sabalausky wrote:
 On Thu, 24 Jan 2013 12:51:32 -0500
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org>  wrote:
 No, you merely came up with *some* specific cherry-picked examples that
 sparked *some* debate (with most of the disagreing coming from
 you).
I simply mentioned three reasons that came to mind. Andrei
While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that has an brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens! -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 13:08:08 Adam Wilson wrote:
 On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu
 
 <SeeWebsiteForEmail erdani.org> wrote:
 On 1/24/13 3:45 PM, Nick Sabalausky wrote:
 On Thu, 24 Jan 2013 12:51:32 -0500
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 No, you merely came up with *some* specific cherry-picked examples that
 sparked *some* debate (with most of the disagreing coming from
 you).
I simply mentioned three reasons that came to mind. Andrei
While I don't approve of Mr. Sabalausky's tone or attitude,
He does have a tendancy to get out of hand in that regard.
 the crux of
 his argument is logically sound. The problem with  property isn't
  property, it's D's insistence on optional parens. If paren usage was
 clearly defined then this would be a non-issue. I would like to point out
 that I can't think of another systems/general purpose language that has an

 brutally simple. Java's is brutally simple. In C/C++ everything is a
 function or field, so, brutally simple.
 
 Make D's calling syntax simpler, end optional parens!
Exactly. That's what _should_ have happened. We wouldn't have all of these optional parens. Unfortunately however, optional parens are so popular for at least some use cases (e.g. UFCS), that I don't think that there's much chance of them going away. - Jonathan M Davis
Jan 24 2013
next sibling parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 13:19:49 -0800, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Thursday, January 24, 2013 13:08:08 Adam Wilson wrote:
 On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu

 <SeeWebsiteForEmail erdani.org> wrote:
 On 1/24/13 3:45 PM, Nick Sabalausky wrote:
 On Thu, 24 Jan 2013 12:51:32 -0500
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 No, you merely came up with *some* specific cherry-picked examples  
that
 sparked *some* debate (with most of the disagreing coming from
 you).
I simply mentioned three reasons that came to mind. Andrei
While I don't approve of Mr. Sabalausky's tone or attitude,
He does have a tendancy to get out of hand in that regard.
 the crux of
 his argument is logically sound. The problem with  property isn't
  property, it's D's insistence on optional parens. If paren usage was
 clearly defined then this would be a non-issue. I would like to point  
 out
 that I can't think of another systems/general purpose language that has  
 an

 brutally simple. Java's is brutally simple. In C/C++ everything is a
 function or field, so, brutally simple.

 Make D's calling syntax simpler, end optional parens!
Exactly. That's what _should_ have happened. We wouldn't have all of these optional parens. Unfortunately however, optional parens are so popular for at least some use cases (e.g. UFCS), that I don't think that there's much chance of them going away. - Jonathan M Davis
because it's syntactically clear. Yes, it might be slightly annoying to have to type the (), but that's how you define a function in every other language. A shortcut with side-effects isn't a short-cut, it's a bug factory. And to be honest, once the language spec settles down tools like ReSharper/VisualAssist/etc. can take care of the extra parens. I hand type -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/24/2013 10:24 PM, Adam Wilson wrote:
 ...


 because it's syntactically clear. Yes, it might be slightly annoying to
 have to type the (), but that's how you define a function in every other
 language. A shortcut with side-effects isn't a short-cut, it's a bug
 factory.
It is not a shortcut, it is a formatting option, and using it does not have side effects.
 And to be honest, once the language spec settles down tools
 like ReSharper/VisualAssist/etc. can take care of the extra parens.
Tools will be configurable to highlight certain constructs anyway.

 code.
It is about reading, not typing.
Jan 24 2013
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 15:04:20 -0800, Timon Gehr <timon.gehr gmx.ch> wrote:

 On 01/24/2013 10:24 PM, Adam Wilson wrote:
 ...


 because it's syntactically clear. Yes, it might be slightly annoying to
 have to type the (), but that's how you define a function in every other
 language. A shortcut with side-effects isn't a short-cut, it's a bug
 factory.
It is not a shortcut, it is a formatting option, and using it does not have side effects.
 And to be honest, once the language spec settles down tools
 like ReSharper/VisualAssist/etc. can take care of the extra parens.
Tools will be configurable to highlight certain constructs anyway.

 code.
It is about reading, not typing.
*sigh* ideally yes, it's just a formating option. The problem is that right now, it's NOT. Consider: module main; import std.stdio; struct Thing { int foo() { return 0; } // method int bar; // data field property int baz() { return 0; } // data field } int main(string[] argv) { writeln("Hello D-World!"); return 0; Thing t; t.bar = 10; // this is a data field because it is // declared as "int bar" above, // not because I didn't use parens down here t.foo; // this is a function call because t.foo is a function t.baz; // this is a data field because i declared // " property int" above, not because I left off parens here t.bar(); // error, type int has no call method t.baz(); // is this a function or a property? oops have to go look at the code. } But what happens if t.baz returns a delegate? Because properties, which conceptually have nothing to do with functions, are implemented as functions they have the same optional parens rules as functions. The problem is that they aren't intended to be used as functions so in the case of delegate, you get massive explosions in the compiler. For something that should be straight-forward. If t.baz is a delegate than t.baz() should call the DELEGATE, but it doesn't... Optional Parens Encourage Ambiguity. Ambiguity Fosters Bugs. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/25/2013 12:23 AM, Adam Wilson wrote:
 ...

 But what happens if t.baz returns a delegate?
You mean, a parameterless delegate. How many times does this occur that it supports nuking a entire language feature?
 Because properties, which conceptually have nothing to do with
 functions, are implemented as functions they have the same optional
 parens rules as functions.
Because the compiler is broken.
 The problem is that they aren't intended to
 be used as functions so in the case of delegate, you get massive
 explosions in the compiler. For something that should be
 straight-forward. If t.baz is a delegate than t.baz() should call the
 DELEGATE, but it doesn't...
It should for properties.
 Optional Parens Encourage Ambiguity.
We could talk about fixing that particular situation, eg, only allow paren-free calls when no parameterless callable is returned, with a very explicit error message. (Like Jesse suggests as well.) However, note that scala does the same we do now: scala> def foo()=()=>2 foo: ()() => Int scala> foo res1: () => Int = <function0> scala> foo() res2: () => Int = <function0> scala> foo()() res3: Int = 2 I do not think this is a recurring discussion topic on the scala newsgroup. I think we might actually be fine.
 Ambiguity Fosters Bugs.
Delegates not being called is noticed quickly.
Jan 24 2013
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 8:01 PM, Timon Gehr wrote:
 On 01/25/2013 12:23 AM, Adam Wilson wrote:
 ...

 But what happens if t.baz returns a delegate?
You mean, a parameterless delegate. How many times does this occur that it supports nuking a entire language feature?
 Because properties, which conceptually have nothing to do with
 functions, are implemented as functions they have the same optional
 parens rules as functions.
Because the compiler is broken.
 The problem is that they aren't intended to
 be used as functions so in the case of delegate, you get massive
 explosions in the compiler. For something that should be
 straight-forward. If t.baz is a delegate than t.baz() should call the
 DELEGATE, but it doesn't...
It should for properties.
 Optional Parens Encourage Ambiguity.
We could talk about fixing that particular situation, eg, only allow paren-free calls when no parameterless callable is returned, with a very explicit error message. (Like Jesse suggests as well.) However, note that scala does the same we do now: scala> def foo()=()=>2 foo: ()() => Int scala> foo res1: () => Int = <function0> scala> foo() res2: () => Int = <function0> scala> foo()() res3: Int = 2 I do not think this is a recurring discussion topic on the scala newsgroup. I think we might actually be fine.
 Ambiguity Fosters Bugs.
Delegates not being called is noticed quickly.
I feel we're getting somewhere! Andrei
Jan 24 2013
prev sibling next sibling parent reply kenji hara <k.hara.pg gmail.com> writes:
2013/1/25 Adam Wilson <flyboynw gmail.com>

 On Thu, 24 Jan 2013 15:04:20 -0800, Timon Gehr <timon.gehr gmx.ch> wrote:

  On 01/24/2013 10:24 PM, Adam Wilson wrote:
 ...


 because it's syntactically clear. Yes, it might be slightly annoying to
 have to type the (), but that's how you define a function in every other
 language. A shortcut with side-effects isn't a short-cut, it's a bug
 factory.
It is not a shortcut, it is a formatting option, and using it does not have side effects. And to be honest, once the language spec settles down tools
 like ReSharper/VisualAssist/etc. can take care of the extra parens.
Tools will be configurable to highlight certain constructs anyway.
 code.
It is about reading, not typing.
*sigh* ideally yes, it's just a formating option. The problem is that right now, it's NOT. Consider: module main; import std.stdio; struct Thing { int foo() { return 0; } // method int bar; // data field property int baz() { return 0; } // data field } int main(string[] argv) { writeln("Hello D-World!"); return 0; Thing t; t.bar = 10; // this is a data field because it is // declared as "int bar" above, // not because I didn't use parens down here t.foo; // this is a function call because t.foo is a function t.baz; // this is a data field because i declared // " property int" above, not because I left off parens here t.bar(); // error, type int has no call method t.baz(); // is this a function or a property? oops have to go look at the code. } But what happens if t.baz returns a delegate? Because properties, which conceptually have nothing to do with functions, are implemented as functions they have the same optional parens rules as functions. The problem is that they aren't intended to be used as functions so in the case of delegate, you get massive explosions in the compiler. For something that should be straight-forward. If t.baz is a delegate than t.baz() should call the DELEGATE, but it doesn't... Optional Parens Encourage Ambiguity. Ambiguity Fosters Bugs.
1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. and removing redundant ()s. Kenji Hara
Jan 24 2013
next sibling parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 17:15:09 -0800, kenji hara <k.hara.pg gmail.com> wrote:

 2013/1/25 Adam Wilson <flyboynw gmail.com>

 On Thu, 24 Jan 2013 15:04:20 -0800, Timon Gehr <timon.gehr gmx.ch>  
 wrote:

  On 01/24/2013 10:24 PM, Adam Wilson wrote:
 ...


 because it's syntactically clear. Yes, it might be slightly annoying  
 to
 have to type the (), but that's how you define a function in every  
 other
 language. A shortcut with side-effects isn't a short-cut, it's a bug
 factory.
It is not a shortcut, it is a formatting option, and using it does not have side effects. And to be honest, once the language spec settles down tools
 like ReSharper/VisualAssist/etc. can take care of the extra parens.
Tools will be configurable to highlight certain constructs anyway. I hand type a small fraction of the parens that actually appear in my
 code.
It is about reading, not typing.
*sigh* ideally yes, it's just a formating option. The problem is that right now, it's NOT. Consider: module main; import std.stdio; struct Thing { int foo() { return 0; } // method int bar; // data field property int baz() { return 0; } // data field } int main(string[] argv) { writeln("Hello D-World!"); return 0; Thing t; t.bar = 10; // this is a data field because it is // declared as "int bar" above, // not because I didn't use parens down here t.foo; // this is a function call because t.foo is a function t.baz; // this is a data field because i declared // " property int" above, not because I left off parens here t.bar(); // error, type int has no call method t.baz(); // is this a function or a property? oops have to go look at the code. } But what happens if t.baz returns a delegate? Because properties, which conceptually have nothing to do with functions, are implemented as functions they have the same optional parens rules as functions. The problem is that they aren't intended to be used as functions so in the case of delegate, you get massive explosions in the compiler. For something that should be straight-forward. If t.baz is a delegate than t.baz() should call the DELEGATE, but it doesn't... Optional Parens Encourage Ambiguity. Ambiguity Fosters Bugs.
1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. UFCS and removing redundant ()s. Kenji Hara
I can completely agree with this change. It is perfectly workable to fix properties without changing optional parens. I just won't use them :-P -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
next sibling parent reply kenji hara <k.hara.pg gmail.com> writes:
2013/1/25 Adam Wilson <flyboynw gmail.com>

 On Thu, 24 Jan 2013 17:15:09 -0800, kenji hara <k.hara.pg gmail.com>
 wrote:

 1. Optional parentheses for normal functions should work shallowly IMO.
 2. Optional parentheses for property functions should not work. Applying
 ()
 for property function name always applied to its returned value.


 UFCS
 and removing redundant ()s.


 Kenji Hara
I can completely agree with this change. It is perfectly workable to fix properties without changing optional parens. I just won't use them :-P
I have thought an additional idea. If we really want a feature to disable optional parentheses for normal functions, we can add function attribute to the language spec. int foo(); property int bar(); function int baz(); // new! int x1 = foo(); // ok int x2 = foo; // optional parentheses, allowed int y1 = bar(); // disallowed, calling int is meaningless int y2 = bar; // ok int z1 = baz(); // ok int z2 = baz; // *disallowed* by function attribute How about? Kenji Hara
Jan 24 2013
next sibling parent "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 17:27:52 -0800, kenji hara <k.hara.pg gmail.com> wrote:

 2013/1/25 Adam Wilson <flyboynw gmail.com>

 On Thu, 24 Jan 2013 17:15:09 -0800, kenji hara <k.hara.pg gmail.com>
 wrote:

 1. Optional parentheses for normal functions should work shallowly IMO.
 2. Optional parentheses for property functions should not work.  
 Applying
 ()
 for property function name always applied to its returned value.


 UFCS
 and removing redundant ()s.


 Kenji Hara
I can completely agree with this change. It is perfectly workable to fix properties without changing optional parens. I just won't use them :-P
I have thought an additional idea. If we really want a feature to disable optional parentheses for normal functions, we can add function attribute to the language spec. int foo(); property int bar(); function int baz(); // new! int x1 = foo(); // ok int x2 = foo; // optional parentheses, allowed int y1 = bar(); // disallowed, calling int is meaningless int y2 = bar; // ok int z1 = baz(); // ok int z2 = baz; // *disallowed* by function attribute How about? Kenji Hara
Very clever Mr. Hara, I like it a lot! But good luck convincing Walter+Andrei. :-) -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 8:27 PM, kenji hara wrote:
 I have thought an additional idea.
 If we really want a feature to disable optional parentheses for normal
 functions, we can add  function attribute to the language spec.

 int foo();
  property int bar();
  function int baz();  // new!

 int x1 = foo();  // ok
 int x2 = foo;  // optional parentheses, allowed
 int y1 = bar();  // disallowed, calling int is meaningless
 int y2 = bar;  // ok
 int z1 = baz();  // ok
 int z2 = baz;  // *disallowed* by  function attribute

 How about?

 Kenji Hara
Brings completeness. But at this point I'm inclined to simplify, never apply "()" deeply is very sensible. If we also find a simple way to implement writing for properties we may be able to eliminate property entirely. Andrei
Jan 24 2013
prev sibling next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 01:28:05 UTC, kenji hara wrote:
 I have thought an additional idea.
 If we really want a feature to disable optional parentheses for 
 normal
 functions, we can add  function attribute to the language spec.

 int foo();
  property int bar();
  function int baz();  // new!

 int x1 = foo();  // ok
 int x2 = foo;  // optional parentheses, allowed
 int y1 = bar();  // disallowed, calling int is meaningless
 int y2 = bar;  // ok
 int z1 = baz();  // ok
 int z2 = baz;  // *disallowed* by  function attribute

 How about?
function seems like an extra complication. Ambiguity between setter and getter for properties when UFCS come into play are not solved. Functional style is impaired as you can't pass regular function around, just function . You'll still find trap in generic code around the behavior of regular functions.
Jan 24 2013
next sibling parent reply kenji hara <k.hara.pg gmail.com> writes:
2013/1/25 deadalnix <deadalnix gmail.com>
  function seems like an extra complication. Ambiguity between setter and
 getter for  properties when UFCS come into play are not solved. Functional
 style is impaired as you can't pass regular function around, just  function
 . You'll still find trap in generic code around the behavior of regular
 functions.
That's a good point. We need to solve another ambiguity about top-level property function which have a parameter, between top-level property setter and UFCS property getter. module abc; property int foo(int n); void main() { foo = 1; // top-level property setter 1.foo; // property getter with UFCS } We cannot distinguish the two usages without adding any new features. Kenji Hara
Jan 24 2013
parent reply "mist" <none none.none> writes:
On Friday, 25 January 2013 at 05:35:19 UTC, kenji hara wrote:
 module abc;
  property int foo(int n);

 void main() {
   foo = 1;  // top-level property setter
   1.foo;  // property getter with UFCS
 }

 We cannot distinguish the two usages without adding any new 
 features.

 Kenji Hara
"1.foo" must be compile error here. Makes as much sense as int a; void main() { 1.a; } Property must behave exactly like data or it is not a property.
Jan 25 2013
parent reply "TommiT" <tommitissari hotmail.com> writes:
On Friday, 25 January 2013 at 10:56:14 UTC, mist wrote:
 On Friday, 25 January 2013 at 05:35:19 UTC, kenji hara wrote:
 module abc;
  property int foo(int n);

 void main() {
  foo = 1;  // top-level property setter
  1.foo;  // property getter with UFCS
 }

 We cannot distinguish the two usages without adding any new 
 features.

 Kenji Hara
"1.foo" must be compile error here. Makes as much sense as int a; void main() { 1.a; } Property must behave exactly like data or it is not a property.
I don't see 1.foo the way you see it. I see it like this: property bool is_zero(X value) { return value == 0; } void main() { X value; value.is_zero; } It's just that X happens to be a built-in type, instead of a user-defined type. But I don't see why should that matter.
Jan 25 2013
next sibling parent "TommiT" <tommitissari hotmail.com> writes:
On Friday, 25 January 2013 at 14:18:43 UTC, TommiT wrote:
 ... But I don't see why should that matter.
But I don't see why that should matter. ...aced it.
Jan 25 2013
prev sibling parent reply "mist" <none none.none> writes:
On Friday, 25 January 2013 at 14:18:43 UTC, TommiT wrote:
 I don't see 1.foo the way you see it. I see it like this:

  property bool is_zero(X value)
 {
     return value == 0;
 }

 void main()
 {
     X value;
     value.is_zero;
 }

 It's just that X happens to be a built-in type, instead of a 
 user-defined type. But I don't see why should that matter.
It is a tempting attempt to save two symbols of typing that completely breaks property semantics. I am objecting against it. With all my passion. Use value.is_zero() for UFCS magic.
Jan 25 2013
next sibling parent reply "TommiT" <tommitissari hotmail.com> writes:
On Friday, 25 January 2013 at 14:29:22 UTC, mist wrote:
 It is a tempting attempt to save two symbols of typing that 
 completely breaks property semantics. I am objecting against 
 it. With all my passion.
 Use value.is_zero() for UFCS magic.
My understanding of the point of UFCS has been that it enables you to add functionality to a type without actually modifying the type. So, let me get this straight... are you saying that the following code snippet breaks property semantics? struct MyType {} property bool is_valid(MyType) { return true; } void main() { MyType mt; mt.is_valid; } Or, are you saying that we shouldn't be able to add properties to built-in types? Or are you saying something else entirely?
Jan 25 2013
parent reply "mist" <none none.none> writes:
Meaning of  property for free functions is well-defined. Most 

rememeber.

I see two possible approaches here:

1)
-----
 property void symbol1(Data);
 property Data symbol1();
Data symbol2;
...
symbol1 = symbol2; // allowed, symbol1 behaves same as symbol2 
for user
symbol2.symbol1; // prohibited, symbol1 is semantically a global 
variable
-----

2)
-----
 property void symbol1(Data);
 property Data symbol1();
Data symbol2;
...
symbol1 = symbol2; // prohibited, symbol1 has meaning only within 
UFCS and imitates Data member.
symbol2.symbol1; // Fine, rewritten as symbol1(symbol2), follows 
general property rules but for compound symbol
-----

First one seems more natural to me, but I can live with either 
approach. Not both. Also please mote that UFCS is meant for 
enhancing data type functionality with free functions, not 
implementing every possible feature available to that data type 
with native syntax.
Jan 25 2013
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-25 15:55, mist wrote:
 Meaning of  property for free functions is well-defined. Most likely

for existing classes. The end result is the same. -- /Jacob Carlborg
Jan 25 2013
parent reply "mist" <none none.none> writes:
On Friday, 25 January 2013 at 15:02:46 UTC, Jacob Carlborg wrote:
 On 2013-01-25 15:55, mist wrote:
 Meaning of  property for free functions is well-defined. Most 
 likely

 rememeber.
methods for existing classes. The end result is the same.
Great, could you give a sample? Does it work on compile time or injects in run-time? Is calling of such methods allowed in usual free form? following materials available in the internet, would be really interesting to learn from their approach.
Jan 25 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-25 16:05, mist wrote:

 Great, could you give a sample? Does it work on compile time or injects
 in run-time? Is calling of such methods allowed in usual free form?


 materials available in the internet, would be really interesting to
 learn from their approach.
The secret is to add "this" in front of the argument type you want to the method to extend: namespace ExtensionMethods { public static class MyExtensions { public static int WordCount(this String str) { return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; } } } using ExtensionMethods; string s = "Hello Extension Methods"; int i = s.WordCount(); http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx -- /Jacob Carlborg
Jan 25 2013
parent reply "mist" <none none.none> writes:
On Friday, 25 January 2013 at 15:13:21 UTC, Jacob Carlborg wrote:
 The secret is to add "this" in front of the argument type you 
 want to the method to extend:

 namespace ExtensionMethods
 {
     public static class MyExtensions
     {
         public static int WordCount(this String str)
         {
             return str.Split(new char[] { ' ', '.', '?' },
                              
 StringSplitOptions.RemoveEmptyEntries).Length;
         }
     }
 }

 using ExtensionMethods;

 string s = "Hello Extension Methods";
 int i = s.WordCount();

 http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx
Good. Main questions remain though: is property syntax allowed on extension methods? Is WordCount(s) call allowed?
Jan 25 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-01-25 16:16, mist wrote:

 Good. Main questions remain though: is property syntax allowed on
 extension methods? Is WordCount(s) call allowed?
I'm not particular familiar with this, perhaps someone else can answer these questions. -- /Jacob Carlborg
Jan 25 2013
prev sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 14:55:09 UTC, mist wrote:
 Meaning of  property for free functions is well-defined. Most 

 rememeber.

 I see two possible approaches here:

 1)
 -----
  property void symbol1(Data);
  property Data symbol1();
 Data symbol2;
 ...
 symbol1 = symbol2; // allowed, symbol1 behaves same as symbol2 
 for user
 symbol2.symbol1; // prohibited, symbol1 is semantically a 
 global variable
 -----

 2)
 -----
  property void symbol1(Data);
  property Data symbol1();
 Data symbol2;
 ...
 symbol1 = symbol2; // prohibited, symbol1 has meaning only 
 within UFCS and imitates Data member.
 symbol2.symbol1; // Fine, rewritten as symbol1(symbol2), 
 follows general property rules but for compound symbol
 -----

 First one seems more natural to me, but I can live with either 
 approach. Not both. Also please mote that UFCS is meant for 
 enhancing data type functionality with free functions, not 
 implementing every possible feature available to that data type 
 with native syntax.
See what is proposed here : http://forum.dlang.org/thread/kdqrnl$13ft$1 digitalmars.com?page=3#post-uagknsecziepoedcabvr:40forum.dlang.org
Jan 25 2013
parent "mist" <none none.none> writes:
On Friday, 25 January 2013 at 15:05:11 UTC, deadalnix wrote:
 See what is proposed here : 
 http://forum.dlang.org/thread/kdqrnl$13ft$1 digitalmars.com?page=3#post-uagknsecziepoedcabvr:40forum.dlang.org
Looks somewhat solid to me, with some disagreement on UFCS side :) Will reply with comments to that post.
Jan 25 2013
prev sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Fri, 25 Jan 2013 15:29:21 +0100
"mist" <none none.none> wrote:

 On Friday, 25 January 2013 at 14:18:43 UTC, TommiT wrote:
 I don't see 1.foo the way you see it. I see it like this:

  property bool is_zero(X value)
 {
     return value == 0;
 }

 void main()
 {
     X value;
     value.is_zero;
 }

 It's just that X happens to be a built-in type, instead of a 
 user-defined type. But I don't see why should that matter.
It is a tempting attempt to save two symbols of typing that completely breaks property semantics. I am objecting against it. With all my passion. Use value.is_zero() for UFCS magic.
I think you might have misunderstood it. What he's trying to do is use UFCS to add a property to a type instead of adding a function.
Jan 25 2013
parent "mist" <none none.none> writes:
On Friday, 25 January 2013 at 19:54:29 UTC, Nick Sabalausky wrote:
 I think you might have misunderstood it. What he's trying to do 
 is use
 UFCS to add a property to a type instead of adding a function.
I got it. What I am questioning is that allowing this in some way is a must. And somewhat changed my mind after that :) There is semantic ambiguity here currently (rules are too lax) that I have described in wiki http://wiki.dlang.org/Property_Discussion_Wrap-up - and I pretty much like proposal there.
Jan 25 2013
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 14:35:08 kenji hara wrote:
 2013/1/25 deadalnix <deadalnix gmail.com>
 
  function seems like an extra complication. Ambiguity between setter and
 getter for  properties when UFCS come into play are not solved. Functional
 style is impaired as you can't pass regular function around, just
  function
 . You'll still find trap in generic code around the behavior of regular
 functions.
That's a good point. We need to solve another ambiguity about top-level property function which have a parameter, between top-level property setter and UFCS property getter. module abc; property int foo(int n); void main() { foo = 1; // top-level property setter 1.foo; // property getter with UFCS } We cannot distinguish the two usages without adding any new features.
Well, better that then get rid of property. The other big question is what to do with opDispatch, since unless we add the ability to overload on property with opDispatch, then it can't work with both properties and non-property functions. Maybe opPropDispatch or somesuch could be introduced to solve that particular problem. As for the top-level property problem, we could do something like property(set) / property(get) to distinguish. Or if we don't want the extra complication, we can just leave it. As long as you can use it as both a getter and a setter, it works, even if it still allows for weird uses. It would be nice to have a way to disambiguate it however. - Jonathan M Davis
Jan 24 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 05:51:44 UTC, Jonathan M Davis 
wrote:
 Well, better that then get rid of  property. The other big 
 question is what to
 do with opDispatch, since unless we add the ability to overload 
 on  property
 with opDispatch, then it can't work with both properties and 
 non-property
 functions. Maybe opPropDispatch or somesuch could be introduced 
 to solve that
 particular problem.
Can you explain the problem you see with opDispatch ?
Jan 24 2013
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 07:14:29 deadalnix wrote:
 On Friday, 25 January 2013 at 05:51:44 UTC, Jonathan M Davis
 
 wrote:
 Well, better that then get rid of  property. The other big
 question is what to
 do with opDispatch, since unless we add the ability to overload
 on  property
 with opDispatch, then it can't work with both properties and
 non-property
 functions. Maybe opPropDispatch or somesuch could be introduced
 to solve that
 particular problem.
Can you explain the problem you see with opDispatch ?
If you make opDispatch property, then you can't use it with normal functions, and if you don't make it property, then it can't be used with property functions. And you can't overload on property, so opDispatch is pretty much screwed with regards to properties at this point. It's certainly fixable, but there will need to be a (small) change in the language to do so. - Jonathan M Davis
Jan 24 2013
parent "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 06:21:59 UTC, Jonathan M Davis 
wrote:
 If you make opDispatch  property, then you can't use it with 
 normal functions,
 and if you don't make it  property, then it can't be used with 
 property
 functions. And you can't overload on  property, so opDispatch 
 is pretty much
 screwed with regards to properties at this point. It's 
 certainly fixable, but
 there will need to be a (small) change in the language to do so.
OK, so opDispatch must definitively be transformed ! I have to say I didn't saw that coming. It isn't that big of a deal if we consider we rewrite that way : a.b => a.opDispatch!"b" a.b!T => a.opDispatch!("b", T) No need for opDispatch to actually be a function. According to what is passed as string, opDispatch can resolve itself as a function or a delegate. See example : class Madness { private void function(Madness)[string] fun; property auto opDispatch(string name)() { immutable f = fun[name]; return { return f(this); }; } } A proper inlining mechanism should handle that.
Jan 24 2013
prev sibling parent "eles" <eles eles.com> writes:
On Friday, 25 January 2013 at 01:28:05 UTC, kenji hara wrote:
 2013/1/25 Adam Wilson <flyboynw gmail.com>

 On Thu, 24 Jan 2013 17:15:09 -0800, kenji hara 
 <k.hara.pg gmail.com>
 wrote:

 1. Optional parentheses for normal functions should work 
 shallowly IMO.
 2. Optional parentheses for property functions should not 
 work. Applying
 ()
 for property function name always applied to its returned 
 value.


 combination of
 UFCS
 and removing redundant ()s.

 required.

 Kenji Hara
I can completely agree with this change. It is perfectly workable to fix properties without changing optional parens. I just won't use them :-P
I have thought an additional idea. If we really want a feature to disable optional parentheses for normal functions, we can add function attribute to the language spec. int foo(); property int bar(); function int baz(); // new! int x1 = foo(); // ok int x2 = foo; // optional parentheses, allowed
I dunno, but for me the line above is a function pointer that is stored into an integer for later retrieval and use.
Jan 25 2013
prev sibling parent reply kenji hara <k.hara.pg gmail.com> writes:
2013/1/25 kenji hara <k.hara.pg gmail.com>
 I have thought an additional idea.
 If we really want a feature to disable optional parentheses for normal
 functions, we can add  function attribute to the language spec.

 int foo();
  property int bar();
  function int baz();  // new!

 int x1 = foo();  // ok
 int x2 = foo;  // optional parentheses, allowed
 int y1 = bar();  // disallowed, calling int is meaningless
 int y2 = bar;  // ok
 int z1 = baz();  // ok
 int z2 = baz;  // *disallowed* by  function attribute
I think calling a function which does not annotated with attribute without parenthesis is legal, Even if a function has some side-effects and a name looks like verb. Because native English grammar does not require parentheses. He runs(). // normal function call He runs. // optional parentheses Kenji Hara
Jan 24 2013
parent "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 01:38:01 UTC, kenji hara wrote:
 2013/1/25 kenji hara <k.hara.pg gmail.com>
 I have thought an additional idea.
 If we really want a feature to disable optional parentheses 
 for normal
 functions, we can add  function attribute to the language spec.

 int foo();
  property int bar();
  function int baz();  // new!

 int x1 = foo();  // ok
 int x2 = foo;  // optional parentheses, allowed
 int y1 = bar();  // disallowed, calling int is meaningless
 int y2 = bar;  // ok
 int z1 = baz();  // ok
 int z2 = baz;  // *disallowed* by  function attribute
I think calling a function which does not annotated with attribute without parenthesis is legal, Even if a function has some side-effects and a name looks like verb. Because native English grammar does not require parentheses. He runs(). // normal function call He runs. // optional parentheses Kenji Hara
English grammar don't have any functional style enable. It is not possible to return runs itself.
Jan 24 2013
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/24/2013 5:15 PM, kenji hara wrote:
 1. Optional parentheses for normal functions should work shallowly IMO.
 2. Optional parentheses for property functions should not work. Applying () for
 property function name always applied to its returned value.


 removing redundant ()s.

Create a new property attribute, say, prop. Imbue it with the new behavior. Leave the old property as it is, and let it cycle through the usual warning, deprecation, removal process.
Jan 25 2013
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 00:19:28 Walter Bright wrote:
 On 1/24/2013 5:15 PM, kenji hara wrote:
 1. Optional parentheses for normal functions should work shallowly IMO.
 2. Optional parentheses for property functions should not work. Applying
 () for property function name always applied to its returned value.
 

 UFCS and removing redundant ()s.

Create a new property attribute, say, prop. Imbue it with the new behavior. Leave the old property as it is, and let it cycle through the usual warning, deprecation, removal process.
Considering that it's always been the plan that property would be enforced such that any use of it would be illegal with parens (it's explicitly among the things tha TDPL says about property), the expectation of pretty much every D programmer is that that's how property functions are to be used, and it shouldn't come as any surprise when that's enforced. As such, I really don't think that it's a big deal if we simply start enforcing that property functions be called without parens. And if you're really concerned about breakage, then we could start with making it a warning rather than an error. But I wager that in almost all cases, any such warning or error would be triggered by a mistake rather than someone intentially using parens with an property function. - Jonathan M Davis
Jan 25 2013
prev sibling next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 08:19:28 UTC, Walter Bright wrote:
 On 1/24/2013 5:15 PM, kenji hara wrote:
 1. Optional parentheses for normal functions should work 
 shallowly IMO.
 2. Optional parentheses for property functions should not 
 work. Applying () for
 property function name always applied to its returned value.


 combination of UFCS and
 removing redundant ()s.

 required.
Create a new property attribute, say, prop. Imbue it with the new behavior. Leave the old property as it is, and let it cycle through the usual warning, deprecation, removal process.
Yes, or maybe we should adopt a sane release process . . .
Jan 25 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 00:29:52 Jonathan M Davis wrote:
 On Friday, January 25, 2013 00:19:28 Walter Bright wrote:
 On 1/24/2013 5:15 PM, kenji hara wrote:
 1. Optional parentheses for normal functions should work shallowly IMO.
 2. Optional parentheses for property functions should not work. Applying
 () for property function name always applied to its returned value.
 

 UFCS and removing redundant ()s.

Create a new property attribute, say, prop. Imbue it with the new behavior. Leave the old property as it is, and let it cycle through the usual warning, deprecation, removal process.
Considering that it's always been the plan that property would be enforced such that any use of it would be illegal with parens (it's explicitly among the things tha TDPL says about property), the expectation of pretty much every D programmer is that that's how property functions are to be used, and it shouldn't come as any surprise when that's enforced. As such, I really don't think that it's a big deal if we simply start enforcing that property functions be called without parens. And if you're really concerned about breakage, then we could start with making it a warning rather than an error. But I wager that in almost all cases, any such warning or error would be triggered by a mistake rather than someone intentially using parens with an property function.
In fact, I'd argue that making property enforce that a function be called without parens would be on par with things like starting to enforce that final switch has cases for all of the values in an enum. Yes, it can break code, but it only breaks code because the feature wasn't enforcing what it was supposed to enforce per the spec. And we've made those sorts of changes before. It's really just a bug fix, albeit one that risks having a larger impact than many. Code which follows the spec won't be broken by the change. - Jonathan M Davis
Jan 25 2013
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
2013/1/25 Walter Bright <newshound2 digitalmars.com>

 On 1/24/2013 5:15 PM, kenji hara wrote:

 1. Optional parentheses for normal functions should work shallowly IMO.
 2. Optional parentheses for property functions should not work. Applying
 () for
 property function name always applied to its returned value.


 UFCS and
 removing redundant ()s.

Create a new property attribute, say, prop. Imbue it with the new behavior. Leave the old property as it is, and let it cycle through the usual warning, deprecation, removal process.
Instead, we can simply change the semantic behavior, when -property switch is specified. Because -property switch should have been used for enabling "experimental feature". In phobos, we need to care the semantic change by adding `static if` branches. By the following code we can detect whether the -property switch is really specified or not. enum enforceProperty = !__traits(compiles, { int prop(){ return 1; } int n = prop; }); Kenji Hara
Jan 25 2013
prev sibling parent reply "eles" <eles eles.com> writes:
On Friday, 25 January 2013 at 08:19:28 UTC, Walter Bright wrote:
 On 1/24/2013 5:15 PM, kenji hara wrote:
 Create a new property attribute, say,  prop. Imbue it with the 
 new behavior. Leave the old  property as it is, and let it 
 cycle through the usual warning, deprecation, removal process.
I think the way picked to do the change is, now, of secondary importance. Prioritary is to decide what is the aim of that change. OTOH, I reallyy do not like " prop" (proposal? proposition? property? proponent?), maybe a better name is needed. Tooo bad, I feel like the best word for that, namely " property" was wasted.
Jan 25 2013
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 09:54:02 eles wrote:
 Tooo bad, I feel like the best word for that, namely " property"
 was wasted.
I dispute that we can't just use property since it was its design from the get-go that it would require that there be no parens (it's even discussed in TDPL). It's just that it hasn't been properly enforced. Making it so that it's enforced would be like when we fixed it so that the compiler enforced that final switch statements had cases for all of an enum's values. Code which followed the spec was unaffected, and for any code that _was_ affected, the new enforcement was catching a bug. - Jonathan M Davis
Jan 25 2013
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 10:15:09 kenji hara wrote:
 1. Optional parentheses for normal functions should work shallowly IMO.
 2. Optional parentheses for property functions should not work. Applying ()
 for property function name always applied to its returned value.
 

 and removing redundant ()s.

I'd say that we should do both. It's ridiculous to accept parens on property functions, since the whole point is that they be used as if they were variables. They're _supposed_ to be illegal (though -property doesn't check for it right now like it's supposed to - it only checks whether parens are used on non-property functions). So, I don't think that there's any question - Jonathan M Davis
Jan 24 2013
prev sibling parent reply kenji hara <k.hara.pg gmail.com> writes:
2013/1/25 Jonathan M Davis <jmdavisProg gmx.com>

 On Friday, January 25, 2013 10:15:09 kenji hara wrote:
 1. Optional parentheses for normal functions should work shallowly IMO.
 2. Optional parentheses for property functions should not work. Applying
()
 for property function name always applied to its returned value.


UFCS
 and removing redundant ()s.

I'd say that we should do both. It's ridiculous to accept parens on property functions, since the whole point is that they be used as if they were variables. They're _supposed_ to be illegal (though -property doesn't check for it right now like it's supposed to - it only checks whether parens are used on non-property functions). So, I don't think that there's any question put enough.
Two months ago, I've tried to implement the rule and posted an experimental pull request. https://github.com/D-Programming-Language/dmd/pull/1311
From that experience, we still need to define some behaviors of corner
cases, even if the rule is applied. One of them is getting an address of property function which returns ref. property ref int foo(); auto x = &foo; // x is a function pointer, or an address of returned value? This is the most sensible problem. (a) If typeof(x) should be a function pointer, we need to use a utility function to get int*. ref identity(T)(ref T t) { return t; } int* p1 = &(identity(foo)); // foo is evaluated to ref int in function argument, // and identity gets through the reference. int* p1 = &foo.identity; // with UFCS, parentheses can be removed. This is a real issue. In phobos, the ref-ness of front property is actually checked in std.range.moveFront. (b) If typeof(x) should be a int*, we will lose the way to getting a function pointer of foo. That is more serious than (a). If we adopt this rule, we will *really* get lost the way to distinguish property functions and raw data fields. (Note that: In current typeof(foo) already returns int. So AddressExp is only one way to getting (normal|property) function information by its type.) From the view of meta-programming, I think this makes a serious flaw. Kenji Hara
Jan 24 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/25/2013 03:09 AM, kenji hara wrote:
 ...

  property ref int foo();
 auto x = &foo;   // x is a function pointer, or an address of returned
 value?
Address of returned value.
 This is the most sensible problem.
 (a) If typeof(x) should be a function pointer, we need to use a utility
 function to get int*.
     ref identity(T)(ref T t) { return t; }
     int* p1 = &(identity(foo));
        // foo is evaluated to ref int in function argument,
        // and identity gets through the reference.
     int* p1 = &foo.identity;
        // with UFCS, parentheses can be removed.

     This is a real issue. In phobos, the ref-ness of front property is
 actually checked in std.range.moveFront.
This is a serious issue.
 (b) If typeof(x) should be a int*, we will lose the way to getting a
 function pointer of foo.
     That is more serious than (a). If we adopt this rule, we will
 *really* get lost the way to distinguish property functions and raw data
 fields. (Note that: In current typeof(foo) already returns int. So
 AddressExp is only one way to getting (normal|property) function
 information by its type.) From the view of meta-programming, I think
 this makes a serious flaw.
We might add the necessary __traits to make up for it.
Jan 24 2013
prev sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 24 January 2013 at 21:20:01 UTC, Jonathan M Davis 
wrote:
 We wouldn't have all of these problems if we'd just

http://msdn.microsoft.com/en-us/library/w86s7x04(v=VS.80).aspx "To the user of an object, a property appears to be a field, accessing the property requires exactly the same syntax." Say it with me: properties are DATA FIELDS. Function syntax has NOTHING to do with them! We could change function syntax to require you to draw out some ASCII art of a running cat.... and it shouldn't affect properties one bit. Optional parens is a matter of function syntax. Properties are data fields, so function syntax doesn't matter to them.
Jan 24 2013
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 13:34:45 -0800, Adam D. Ruppe  
<destructionator gmail.com> wrote:

 On Thursday, 24 January 2013 at 21:20:01 UTC, Jonathan M Davis wrote:
 We wouldn't have all of these problems if we'd just

http://msdn.microsoft.com/en-us/library/w86s7x04(v=VS.80).aspx "To the user of an object, a property appears to be a field, accessing the property requires exactly the same syntax." Say it with me: properties are DATA FIELDS. Function syntax has NOTHING to do with them! We could change function syntax to require you to draw out some ASCII art of a running cat.... and it shouldn't affect properties one bit. Optional parens is a matter of function syntax. Properties are data fields, so function syntax doesn't matter to them.
The problem is that optional parens introduce ambiguity in relation to what is a property versus a function from the compilers prospective. So they are a matter of functional call syntax in that they are non-trivial for the compiler to deduce between the two. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 24 January 2013 at 21:41:58 UTC, Adam Wilson wrote:
 The problem is that optional parens introduce ambiguity in 
 relation to what is a property versus a function from the 
 compilers prospective.
No, it doesn't. struct Thing { int foo() { return 0; } // method int bar; // data field property int baz() { return 0; } // data field } Thing t; t.bar = 10; // this is a data field because it is // declared as "int bar" above, // not because I didn't use parens down here t.foo; // this is a function call because t.foo is a function t.baz; // this is a data field because i declared // " property int" above, not because I left off parens here t.bar(); // error, type int has no call method t.baz(); // error, type int has no call method
Jan 24 2013
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 13:45:44 -0800, Adam D. Ruppe  
<destructionator gmail.com> wrote:

 On Thursday, 24 January 2013 at 21:41:58 UTC, Adam Wilson wrote:
 The problem is that optional parens introduce ambiguity in relation to  
 what is a property versus a function from the compilers prospective.
No, it doesn't. struct Thing { int foo() { return 0; } // method int bar; // data field property int baz() { return 0; } // data field } Thing t; t.bar = 10; // this is a data field because it is // declared as "int bar" above, // not because I didn't use parens down here t.foo; // this is a function call because t.foo is a function t.baz; // this is a data field because i declared // " property int" above, not because I left off parens here t.bar(); // error, type int has no call method t.baz(); // error, type int has no call method
Right, this conversation is about removing property, which invalidates your argument by turning the data into a function, which is what we want to avoid. Also you might want to run your examples before posting them. t.baz() is NOT an error, which incidentally why the ambiguities I mentioned exist and need to be quashed. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 24 January 2013 at 21:53:27 UTC, Adam Wilson wrote:
 Right, this conversation is about removing  property, which 
 invalidates your argument by turning the data into a function, 
 which is what we want to avoid.
Yeah, that's why I'm against the OP proposal.
 Also you might want to run your examples before posting them.
I did.... on my modified dmd where property has a less stupid (but still buggy) implementation. It works correctly there!
Jan 24 2013
parent "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 14:06:47 -0800, Adam D. Ruppe  
<destructionator gmail.com> wrote:

 On Thursday, 24 January 2013 at 21:53:27 UTC, Adam Wilson wrote:
 Right, this conversation is about removing  property, which invalidates  
 your argument by turning the data into a function, which is what we  
 want to avoid.
Yeah, that's why I'm against the OP proposal.
Hehe, so am I! :-)
 Also you might want to run your examples before posting them.
I did.... on my modified dmd where property has a less stupid (but still buggy) implementation. It works correctly there!
I see. I like it. :-) -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 24 January 2013 at 21:09:39 UTC, Adam Wilson wrote:
 The problem with  property isn't  property, it's D's
 insistence on optional parens.
No, this isn't a problem; function call syntax has nothing whatsoever to do with property because a property is NOT logically a function! This is so important: a property is supposed to be indistinguishable from a data member. That's the fundamental definition. It should be fully interchangeable for a plain data member. In other words, as far as the user is concerned, a property *is* a data member, NOT a function! If functions have optional parens, that changes nothing about how you access data members.... and since properties are data members, it changes absolutely nothing about them either. If we required data to be accessed with foo->bar and methods to be called [foo:bar].... a property would be accessed foo->bar. The method syntax is irrelevant. That the property is implemented with a function call should not be known to the user code.
Jan 24 2013
next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 22:24:58 Adam D. Ruppe wrote:
 On Thursday, 24 January 2013 at 21:09:39 UTC, Adam Wilson wrote:
 The problem with  property isn't  property, it's D's
 insistence on optional parens.
No, this isn't a problem; function call syntax has nothing whatsoever to do with property because a property is NOT logically a function!
D's insistance on optional parens _does_ cause problems with functions that return delegates, but property itself isn't really affected by optional parens save for the visual ambiguity caused by optional parens.
 This is so important: a property is supposed to be
 indistinguishable from a data member. That's the fundamental
 definition. It should be fully interchangeable for a plain data
 member.
 
 In other words, as far as the user is concerned, a property *is*
 a data member, NOT a function!
 
 If functions have optional parens, that changes nothing about how
 you access data members.... and since properties are data
 members, it changes absolutely nothing about them either.
 
 If we required data to be accessed with foo->bar and methods to
 be called [foo:bar].... a property would be accessed foo->bar.
 The method syntax is irrelevant.
 
 That the property is implemented with a function call should not
 be known to the user code.
This should probably be emphasized more. A property is an abstraction for a variable and how it's implemented should be irrelevant to the caller. Ideally, it would even be irrelevant whether it's a variable or a property function (though making that the case would require both implementing http://d.puremagic.com/issues/show_bug.cgi?id=8006 and providing a way to mark variables such that they're treated as rvalues rather than lvalues; otherwise, it's still possible to break code when turning a variable into a property function). And we can (and should) implement property in a way that deals with properties properly regardless of what we do with parenless function calls. - Jonathan M Davis
Jan 24 2013
parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Thu, 24 Jan 2013 22:52:05 +0100
"Jonathan M Davis" <jmdavisProg gmx.com> wrote:
 
 And we can (and should) implement  property in a way that deals with 
 properties properly regardless of what we do with parenless function
 calls.
 
I should clarify that this is my view as well. I may be vocally opposed to optional-parens for function calls, but even I'll admit that *is* a much lesser issue than making sure property stays and is implemented properly.
Jan 24 2013
parent kenji hara <k.hara.pg gmail.com> writes:
We can delay the decision about "optional parentheses for normal functions".
It can be separated from "strict prohibition of optional parentheses for
property functions"

Kenji Hara


2013/1/25 Nick Sabalausky <SeeWebsiteToContactMe semitwist.com>

 On Thu, 24 Jan 2013 22:52:05 +0100
 "Jonathan M Davis" <jmdavisProg gmx.com> wrote:
 And we can (and should) implement  property in a way that deals with
 properties properly regardless of what we do with parenless function
 calls.
I should clarify that this is my view as well. I may be vocally opposed to optional-parens for function calls, but even I'll admit that *is* a much lesser issue than making sure property stays and is implemented properly.
Jan 24 2013
prev sibling parent reply kenji hara <k.hara.pg gmail.com> writes:
2013/1/25 Jonathan M Davis <jmdavisProg gmx.com>

 On Thursday, January 24, 2013 22:24:58 Adam D. Ruppe wrote:
 On Thursday, 24 January 2013 at 21:09:39 UTC, Adam Wilson wrote:
 The problem with  property isn't  property, it's D's
 insistence on optional parens.
No, this isn't a problem; function call syntax has nothing whatsoever to do with property because a property is NOT logically a function!
D's insistance on optional parens _does_ cause problems with functions that return delegates, but property itself isn't really affected by optional parens save for the visual ambiguity caused by optional parens.
I think that the "optional parentheses" feature for normal functions should always work in _shallowly_. Even if a function returns some callable object, "optional parentheses" should not applied to the return object recursively. That means: void delegate() foo() { ... } void main() { auto x = foo(); // typeof(x) == void delegate() auto y = foo; // typeof(y) == void delegate() } Kenji Hara
Jan 24 2013
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 25 January 2013 at 00:42:09 UTC, kenji hara wrote:
 I think that the "optional parentheses" feature for normal 
 functions should always work in _shallowly_.
I agree. This is the way it makes sense (and the way it is now).
Jan 24 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 7:44 PM, Adam D. Ruppe wrote:
 On Friday, 25 January 2013 at 00:42:09 UTC, kenji hara wrote:
 I think that the "optional parentheses" feature for normal functions
 should always work in _shallowly_.
I agree. This is the way it makes sense (and the way it is now).
So would Kenji's proposal float your boat? Andrei
Jan 24 2013
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 25 January 2013 at 02:03:27 UTC, Andrei Alexandrescu 
wrote:
 would Kenji's proposal float your boat?
Yeah, as described in more detail in this post: http://forum.dlang.org/thread/kdqrnl$13ft$1 digitalmars.com?page=16 There's some details I'd still argue, about address of (i say should be the return value), += etc on property (should become setter(getter() + rhs), unless there is no setter, in which case leave it how it is and let it operate on the return value naturally) .... but I'm willing to compromise if we can get these two points: Callable bar(); bar; // must work, returns the callable callable bar()(); // calls the callable property Callable foo(); foo; // just returns the callable foo(); // must call the *Callable*, not just foo And that's what Kenji is talking about, so yes, it is acceptable. The rest is just gravy. BTW I still say the sanest way to implement this is to rewrite foo into (foo()) ASAP. The parens will follow naturally from that, as will references and most everything else. The only hard part after that is to fix up setters, and perhaps clean existing mess out of dmd. But I'm willing to defer to Walter or Kenji's expertise on actually making it happen.
Jan 24 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 7:41 PM, kenji hara wrote:
 I think that the "optional parentheses" feature for normal functions
 should always work in _shallowly_. Even if a function returns some
 callable object, "optional parentheses" should not applied to the return
 object recursively.

 That means:
 void delegate() foo() { ... }
 void main() {
    auto x = foo();  // typeof(x) == void delegate()
    auto y = foo;    // typeof(y) == void delegate()
 }

 Kenji Hara
Interesting, so that would mean if anyone ever wants to get the delegate AND call it in one shot would need to write: foo()(). I think this proposal has merit. Andrei
Jan 24 2013
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 21:01:33 Andrei Alexandrescu wrote:
 On 1/24/13 7:41 PM, kenji hara wrote:
 I think that the "optional parentheses" feature for normal functions
 should always work in _shallowly_. Even if a function returns some
 callable object, "optional parentheses" should not applied to the return
 object recursively.
 
 That means:
 void delegate() foo() { ... }
 void main() {
 
 auto x = foo(); // typeof(x) == void delegate()
 auto y = foo; // typeof(y) == void delegate()
 
 }
 
 Kenji Hara
Interesting, so that would mean if anyone ever wants to get the delegate AND call it in one shot would need to write: foo()(). I think this proposal has merit.
I believe that that's what we have now. The problem is when you want a property which returns a delegate. And for that, we need property. Getting rid of property makes it a problem, whereas with property, it can work - as can property functions which return delegates. - Jonathan M Davis
Jan 24 2013
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 9:11 PM, Jonathan M Davis wrote:
 I believe that that's what we have now. The problem is when you want a
 property which returns a delegate. And for that, we need  property. Getting
 rid of  property makes it a problem, whereas with  property, it can work - as
 can property functions which return delegates.
Well how about we just renounce those for the sake of simplification. Andrei
Jan 24 2013
next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 21:24:05 Andrei Alexandrescu wrote:
 On 1/24/13 9:11 PM, Jonathan M Davis wrote:
 I believe that that's what we have now. The problem is when you want a
 property which returns a delegate. And for that, we need  property.
 Getting
 rid of  property makes it a problem, whereas with  property, it can work -
 as can property functions which return delegates.
Well how about we just renounce those for the sake of simplification.
Without explicit properties you can't switch back and forth between something being a property function and a variable - which is one of the main points of properties in the first place. With explicit properties, it's possible. Also, I think that there's real value from an API perspective to mark what is and isn't intended to be used as a property. - Jonathan M Davis
Jan 24 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 03:38:20 Jonathan M Davis wrote:
 On Thursday, January 24, 2013 21:24:05 Andrei Alexandrescu wrote:
 On 1/24/13 9:11 PM, Jonathan M Davis wrote:
 I believe that that's what we have now. The problem is when you want a
 property which returns a delegate. And for that, we need  property.
 Getting
 rid of  property makes it a problem, whereas with  property, it can work
 -
 as can property functions which return delegates.
Well how about we just renounce those for the sake of simplification.
Without explicit properties you can't switch back and forth between something being a property function and a variable - which is one of the main points of properties in the first place. With explicit properties, it's possible. Also, I think that there's real value from an API perspective to mark what is and isn't intended to be used as a property.
And actually, something far more important than any of those reasons is the issue of setters. We've focused most of this discussion on optional parens and the situation with getter properties, but setter properties and their issues are also important. Would you want code like this to compile? range.popFront = 17; container.linearRemove = range; path.baseName = ".xyz"; str.icmp = "hello"; enforce(a == b) = "msg"; arr.sameHead = arr2; With property, we can restrict the functions which can be used with the setter syntax to functions where that makes sense. Without it, all kinds of ridiculous code like the code above would be allowed. Allowing optional parens is one thing, but conflating that with properties is something else entirely. Property functions are not just functions which are called without parens, and we shouldn't act like they are. - Jonathan M Davis
Jan 24 2013
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
2013/1/25 Jonathan M Davis <jmdavisProg gmx.com>

 And actually, something far more important than any of those reasons is the
 issue of setters. We've focused most of this discussion on optional parens
 and
 the situation with getter properties, but setter properties and their
 issues
 are also important. Would you want code like this to compile?

 range.popFront = 17;
 container.linearRemove = range;
 path.baseName = ".xyz";
 str.icmp = "hello";
 enforce(a == b) = "msg";
 arr.sameHead = arr2;

 With  property, we can restrict the functions which can be used with the
 setter syntax to functions where that makes sense. Without it, all kinds of
 ridiculous code like the code above would be allowed.

 Allowing optional parens is one thing, but conflating that with properties
 is
 something else entirely. Property functions are not just functions which
 are
 called without parens, and we shouldn't act like they are.
 1a. Optional parentheses for normal functions is just allowed for the
getter usage.
 int foo();
 foo(); // ok


 void bar(int);
 bar(1); // ok

If based on that, such situations which you are worried will not occur. Kenji Hara
Jan 24 2013
prev sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 02:24:06 UTC, Andrei Alexandrescu 
wrote:
 On 1/24/13 9:11 PM, Jonathan M Davis wrote:
 I believe that that's what we have now. The problem is when 
 you want a
 property which returns a delegate. And for that, we need 
  property. Getting
 rid of  property makes it a problem, whereas with  property, 
 it can work - as
 can property functions which return delegates.
Well how about we just renounce those for the sake of simplification.
I don't understand. We want to drop feature that work in other languages and bring benefit, but it is actually impossible to drop a feature that bring many ambiguities for a small syntactic sugar ?
Jan 24 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-01-25 03:11, Jonathan M Davis wrote:
 On Thursday, January 24, 2013 21:01:33 Andrei Alexandrescu wrote:
 Interesting, so that would mean if anyone ever wants to get the delegate
 AND call it in one shot would need to write: foo()().

 I think this proposal has merit.
I believe that that's what we have now.
Yes, that's the way it's always been since the D1 days. -- /Jacob Carlborg
Jan 25 2013
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 4:08 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 3:45 PM, Nick Sabalausky wrote:
 On Thu, 24 Jan 2013 12:51:32 -0500
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 No, you merely came up with *some* specific cherry-picked examples that
 sparked *some* debate (with most of the disagreing coming from
 you).
I simply mentioned three reasons that came to mind. Andrei
While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that is brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!
Simplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. Andrei
Jan 24 2013
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 13:54:09 -0800, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 4:08 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 3:45 PM, Nick Sabalausky wrote:
 On Thu, 24 Jan 2013 12:51:32 -0500
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 No, you merely came up with *some* specific cherry-picked examples  
 that
 sparked *some* debate (with most of the disagreing coming from
 you).
I simply mentioned three reasons that came to mind. Andrei
While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that is brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!
Simplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. Andrei
Then property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 4:56 PM, Adam Wilson wrote:
 Simplicity is clearly good, but there's something to be said about
 those warts in chained calls. The UFCS-enabled idioms clearly bring a
 strong argument to the table, there's no ignoring it.

 Andrei
Then property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.
I'm not all that convinced, and it's easy to get wedged into a black vs white position that neglects many subtleties. Properties are DATA, well except when you need to pass fields by reference etc. at which point the syntactic glue comes unglued. There's been a lot of strong positions years ago about functions vs. procedures, statements vs. expressions, or even (the glorious 60s!) in-language I/O primitives vs. I/O as library facilities. Successful languages managed to obviate such dichotomies. Andrei
Jan 24 2013
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 24 January 2013 at 22:04:02 UTC, Andrei Alexandrescu 
wrote:
 Properties are DATA, well except when you need to pass fields 
 by reference etc. at which point the syntactic glue comes 
 unglued.
An enum or a literal can't be passed by reference or otherwise have the address taken either, but we don't argue about if they're data or not, and don't change barely related parts of the language over them. void foo(ref int a) {} int b; foo(b); // ok foo(10); // nope test.d(6): Error: function test.foo (ref int a) is not callable using argument types (int) test.d(6): Error: constant 10 is not an lvalue No big deal. Similarly: enum c = 20; foo(c); test.d(12): Error: function test.foo (ref int a) is not callable using argument types (int) test.d(12): Error: constant 20 is not an lvalue Note: the error message betrays some truth about enum's implementation.... but who cares. And finally: property int bar() { return 0; } foo(bar); test.d(9): Error: function test.foo (ref int a) is not callable using argument types (int) test.d(9): Error: bar() is not an lvalue Like the enum, we see a hint in the error message that the compiler is doing a little magic... but who cares.
Jan 24 2013
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 23:15:38 Adam D. Ruppe wrote:
 On Thursday, 24 January 2013 at 22:04:02 UTC, Andrei Alexandrescu
 
 wrote:
 Properties are DATA, well except when you need to pass fields
 by reference etc. at which point the syntactic glue comes
 unglued.
An enum or a literal can't be passed by reference or otherwise have the address taken either, but we don't argue about if they're data or not, and don't change barely related parts of the language over them.
[snip] However, I do think that would be able to mark variables such that they're treated as rvalues such that swapping a variable out with a property function dosen't break code (at least if http://d.puremagic.com/issues/show_bug.cgi?id=8006 gets implemented). - Jonathan M Davis
Jan 24 2013
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 24 January 2013 at 22:28:04 UTC, Jonathan M Davis 
wrote:
 However, I do think that would be able to mark variables such 
 that they're treated as rvalues such that swapping a
 variable out with a property function dosen't break code
agreed
Jan 24 2013
parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
25-Jan-2013 02:32, Adam D. Ruppe пишет:
 On Thursday, 24 January 2013 at 22:28:04 UTC, Jonathan M Davis wrote:
 However, I do think that would be able to mark variables such that
 they're treated as rvalues such that swapping a
 variable out with a property function dosen't break code
IMHO this is a critical part of what a property should do - transparently swapping fields with some functional accessors. -- Dmitry Olshansky
Jan 25 2013
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 22:09:18 Dmitry Olshansky wrote:
 25-Jan-2013 02:32, Adam D. Ruppe пишет:
 On Thursday, 24 January 2013 at 22:28:04 UTC, Jonathan M Davis wrote:
 However, I do think that would be able to mark variables such that
 they're treated as rvalues such that swapping a
 variable out with a property function dosen't break code
IMHO this is a critical part of what a property should do - transparently swapping fields with some functional accessors.
And for that, we need to keep property. It's impossible without explicit properties (though there are obviously some improvements that we have to make in order to make it work properly with property). - Jonathan M Davis
Jan 25 2013
prev sibling next sibling parent "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 14:04:02 -0800, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 4:56 PM, Adam Wilson wrote:
 Simplicity is clearly good, but there's something to be said about
 those warts in chained calls. The UFCS-enabled idioms clearly bring a
 strong argument to the table, there's no ignoring it.

 Andrei
Then property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.
I'm not all that convinced, and it's easy to get wedged into a black vs white position that neglects many subtleties. Properties are DATA, well except when you need to pass fields by reference etc. at which point the syntactic glue comes unglued.
... wat? I fail to see what byref has to do with this. It shouldn't matter what the data is to the compiler as both are built on top of functions, the compiler just enforces different calling syntax for each. If this is a problem for properties then it is a problem for functions to... Because from a compiler POV Data.Property.FieldOfReference; is no different than Data.Function().FieldOfReference; But from a syntax standpoint the difference important because Data.Property(InRef, Count).FieldOfReference; is utterly nonsensical where Data.Function(InRef, Count).FieldOfReference; is perfectly legitimate.
 There's been a lot of strong positions years ago about functions vs.  
 procedures, statements vs. expressions, or even (the glorious 60s!)  
 in-language I/O primitives vs. I/O as library facilities. Successful  
 languages managed to obviate such dichotomies.


 Andrei
-- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
prev sibling next sibling parent "Rob T" <alanb ucora.com> writes:
On Thursday, 24 January 2013 at 22:04:02 UTC, Andrei Alexandrescu 
wrote:
[..]
 There's been a lot of strong positions years ago about 
 functions vs. procedures, statements vs. expressions, or even 
 (the glorious 60s!) in-language I/O primitives vs. I/O as 
 library facilities. Successful languages managed to obviate 
 such dichotomies.


 Andrei
Yeah, back in the day it was a relief to no longer have to decide if I needed to write a function or if I needed to write a procedure. With D, it's been a relief to no longer have to use empty () everywhere. I think we've become stuck in a way of thinking that is creating a lot more complexity than is actually required. For example, I can change my perception of what a variable is and instead view it to be specialized form of function. It has a default implementation and implied storage, which is returned by ref. The compiler can optimize away the need to a real function call. If you take on a view like that, then it may be possible to simplify the language by merging specialized types with alternate syntax into one generalized type with identical syntax. You'll also be forced to implement things in a more consistent and unambiguous way as you proceed along. For example, there has to be different methods for getting the address of the data vs the address of the implementation, and the same solution can work for all types provided that they are treated in the same way. --rt
Jan 24 2013
prev sibling next sibling parent reply kenji hara <k.hara.pg gmail.com> writes:
I can imagine a situation that we might not want to treat property
functions as DATAs simply.

If you have a struct which have some property functions as members, and
you'd want to serialize it:

struct S {
   int value_;
    property int value() { return value_; }
}

At least, the serialization library should recognize the S.value is a
_property function_, not a int DATA.

In most case, property functions should be treated as a simple DATA field.
but in a few case, it shouldn't. I have thought AddressExpression &func is
one of the places.

Related bugzilla issue I posted:
http://d.puremagic.com/issues/show_bug.cgi?id=9062

Kenji Hara

2013/1/25 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>

 On 1/24/13 4:56 PM, Adam Wilson wrote:

 Simplicity is clearly good, but there's something to be said about
 those warts in chained calls. The UFCS-enabled idioms clearly bring a
 strong argument to the table, there's no ignoring it.

 Andrei
Then property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.
I'm not all that convinced, and it's easy to get wedged into a black vs white position that neglects many subtleties. Properties are DATA, well except when you need to pass fields by reference etc. at which point the syntactic glue comes unglued. There's been a lot of strong positions years ago about functions vs. procedures, statements vs. expressions, or even (the glorious 60s!) in-language I/O primitives vs. I/O as library facilities. Successful languages managed to obviate such dichotomies. Andrei
Jan 24 2013
next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 00:55:54 UTC, kenji hara wrote:
 I can imagine a situation that we might not want to treat 
 property
 functions as DATAs simply.

 If you have a struct which have some property functions as 
 members, and
 you'd want to serialize it:

 struct S {
    int value_;
     property int value() { return value_; }
 }

 At least, the serialization library should recognize the 
 S.value is a
 _property function_, not a int DATA.

 In most case, property functions should be treated as a simple 
 DATA field.
 but in a few case, it shouldn't. I have thought 
 AddressExpression &func is
 one of the places.

 Related bugzilla issue I posted:
 http://d.puremagic.com/issues/show_bug.cgi?id=9062
Indeed ! property should be different as far as reflection is involved. For usage, it shouldn't make any difference.
Jan 24 2013
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-25 01:55, kenji hara wrote:
 I can imagine a situation that we might not want to treat property
 functions as DATAs simply.

 If you have a struct which have some property functions as members, and
 you'd want to serialize it:

 struct S {
     int value_;
      property int value() { return value_; }
 }

 At least, the serialization library should recognize the S.value is a
 _property function_, not a int DATA.
A serialization library would only recognize "value_" since it's an instance variable. -- /Jacob Carlborg
Jan 25 2013
parent "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 11:00:34 UTC, Jacob Carlborg wrote:
 On 2013-01-25 01:55, kenji hara wrote:
 I can imagine a situation that we might not want to treat 
 property
 functions as DATAs simply.

 If you have a struct which have some property functions as 
 members, and
 you'd want to serialize it:

 struct S {
    int value_;
     property int value() { return value_; }
 }

 At least, the serialization library should recognize the 
 S.value is a
 _property function_, not a int DATA.
A serialization library would only recognize "value_" since it's an instance variable.
getFields/getProperties/getMethods and you are done. It don't sounds that much of a problem to me.
Jan 25 2013
prev sibling parent luka8088 <luka8088 owave.net> writes:
On 24.1.2013 23:04, Andrei Alexandrescu wrote:
 On 1/24/13 4:56 PM, Adam Wilson wrote:
 Simplicity is clearly good, but there's something to be said about
 those warts in chained calls. The UFCS-enabled idioms clearly bring a
 strong argument to the table, there's no ignoring it.

 Andrei
Then property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.
I'm not all that convinced, and it's easy to get wedged into a black vs white position that neglects many subtleties. Properties are DATA, well except when you need to pass fields by reference etc. at which point the syntactic glue comes unglued. There's been a lot of strong positions years ago about functions vs. procedures, statements vs. expressions, or even (the glorious 60s!) in-language I/O primitives vs. I/O as library facilities. Successful languages managed to obviate such dichotomies. Andrei
Maybe this will clarify what is meant by "properties are data": // http://dpaste.dzfl.pl/822aab11 auto foo () { return { return 0; }; } property auto bar () { return { return 0; }; } void main () { auto localFoo = foo; assert(!is(typeof(localFoo) == typeof(foo))); auto localBar = bar; assert(is(typeof(localBar) == typeof(bar))); } function: auto localFoo = foo; // call foo and store the result typeof(localFoo) // typeof(data returned by foo) - function pointer typeof(foo) // typeof(function foo) - function data: auto localBar = bar; // get data represented by bar typeof(localBar) // typeof(data represented by bar) - function pointer typeof(bar) // typeof(data represented by bar) - function pointer Data represented by bar can be some value, or a function call that returns a value. As a user of that property I don't care. And I don't want my code to break if that property changes from a function pointer to a function that returns a function pointer. Hence typeof(foo) is a function, and typeof(bar) is a type of that property (type that is returned by a calling bar). I would like to emphasize that property is not a syntactic, but rather a semantic issue.
Jan 25 2013
prev sibling parent reply Robert Schadek <realburner gmx.de> writes:
On 01/24/2013 10:56 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 13:54:09 -0800, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 4:08 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 3:45 PM, Nick Sabalausky wrote:
 On Thu, 24 Jan 2013 12:51:32 -0500
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 No, you merely came up with *some* specific cherry-picked examples 
 that
 sparked *some* debate (with most of the disagreing coming from
 you).
I simply mentioned three reasons that came to mind. Andrei
While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that has an calling syntax specification as vague and convoluted as D's. is brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!
Simplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. Andrei
Then property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.
At while you're at it, just get ride of: int[] a. a.length = 10; That this grows the array stills creeps me out. Robert
Jan 24 2013
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 14:15:45 -0800, Robert Schadek <realburner gmx.de>  
wrote:

 On 01/24/2013 10:56 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 13:54:09 -0800, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 4:08 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 3:45 PM, Nick Sabalausky wrote:
 On Thu, 24 Jan 2013 12:51:32 -0500
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 No, you merely came up with *some* specific cherry-picked examples  
 that
 sparked *some* debate (with most of the disagreing coming from
 you).
I simply mentioned three reasons that came to mind. Andrei
While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that has an calling syntax specification as vague and convoluted as D's. is brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!
Simplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. Andrei
Then property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.
At while you're at it, just get ride of: int[] a. a.length = 10; That this grows the array stills creeps me out. Robert
Well, from a syntax standpoint it's legitimate, and D's dynamic arrays are using it is that D's GC is absurdly naive. When this seemingly benign action causes your program to freeze for non-trivial fractions of a second for the millionth time, it can be quite despair inducing... -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
parent reply Robert burner Schadek <realburner gmx.de> writes:
On 01/24/2013 11:32 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 14:15:45 -0800, Robert Schadek <realburner gmx.de> 
 wrote:

 On 01/24/2013 10:56 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 13:54:09 -0800, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 4:08 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 3:45 PM, Nick Sabalausky wrote:
 On Thu, 24 Jan 2013 12:51:32 -0500
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 No, you merely came up with *some* specific cherry-picked 
 examples that
 sparked *some* debate (with most of the disagreing coming from
 you).
I simply mentioned three reasons that came to mind. Andrei
While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that has an calling syntax specification as vague and convoluted as is brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!
Simplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. Andrei
Then property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.
At while you're at it, just get ride of: int[] a. a.length = 10; That this grows the array stills creeps me out. Robert
Well, from a syntax standpoint it's legitimate, and D's dynamic arrays problem with using it is that D's GC is absurdly naive. When this seemingly benign action causes your program to freeze for non-trivial fractions of a second for the millionth time, it can be quite despair inducing...
Yes, the syntax is legit. It's the semantic that "scares" me. IMHO it feels strange that assigning a variable resizes a array. Something like a.resize(10) would make me feel better.
Jan 25 2013
parent reply "mist" <none none.none> writes:
On Friday, 25 January 2013 at 10:26:14 UTC, Robert burner Schadek 
wrote:
 ...
 Yes, the syntax is legit. It's the semantic that "scares" me. 
 IMHO it feels strange that assigning a variable resizes a 
 array. Something like a.resize(10) would make me feel better.
Ye, it was one of the first "Erm wtf?" moments when I started to learn D. And living confirmation that core developers don't really have a strong vision what properties should be.
Jan 25 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Friday, 25 January 2013 at 11:01:31 UTC, mist wrote:
 On Friday, 25 January 2013 at 10:26:14 UTC, Robert burner 
 Schadek wrote:
 ...
 Yes, the syntax is legit. It's the semantic that "scares" me. 
 IMHO it feels strange that assigning a variable resizes a 
 array. Something like a.resize(10) would make me feel better.
Ye, it was one of the first "Erm wtf?" moments when I started to learn D. And living confirmation that core developers don't really have a strong vision what properties should be.
I can view *reading* size as a property, but I don't think the setter itself should be a property, since it actually *does* something. Heck, it can throw an exception (!) However, I really think we are way past the point we can change array's interface. I'd just leave it be.
Jan 25 2013
next sibling parent "mist" <none none.none> writes:
Why? Other than "breaking code".
Jan 25 2013
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 12:24:56 monarch_dodra wrote:
 On Friday, 25 January 2013 at 11:01:31 UTC, mist wrote:
 On Friday, 25 January 2013 at 10:26:14 UTC, Robert burner
 
 Schadek wrote:
 ...
 Yes, the syntax is legit. It's the semantic that "scares" me.
 IMHO it feels strange that assigning a variable resizes a
 array. Something like a.resize(10) would make me feel better.
Ye, it was one of the first "Erm wtf?" moments when I started to learn D. And living confirmation that core developers don't really have a strong vision what properties should be.
I can view *reading* size as a property, but I don't think the setter itself should be a property, since it actually *does* something. Heck, it can throw an exception (!)
So? Of course, setters can throw exceptions. Why wouldn't they be able to? For instance, if you try and set the hour on a TimeOfDay to 25, it's going to throw a DateTimeException. I could see an argument that the operations that length does when set are expensive enough that it shouldn't be a setter property, but setters are not necessarily going to be as simple as setting a variable, and throwing exceptions from them is normal, depending on what they need to do. I could see generally restricting them to operations which are on properties say something along those lines), but you make it sound as if all a setter property should ever do is simply set a variable, and if that were the case, you might as well just make it a public variable.
 However, I really think we are way past the point we can change
 array's interface. I'd just leave it be.
It's far too late at this point. I don't know if it was a good design choice or not (and I rarely use it myself), but it's not going to change. - Jonathan M Davis
Jan 25 2013
prev sibling next sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Thu, 24 Jan 2013 13:08:08 -0800
"Adam Wilson" <flyboynw gmail.com> wrote:

 On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:
 
 On 1/24/13 3:45 PM, Nick Sabalausky wrote:
 On Thu, 24 Jan 2013 12:51:32 -0500
 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org>  wrote:
 No, you merely came up with *some* specific cherry-picked examples
 that sparked *some* debate (with most of the disagreing coming from
 you).
I simply mentioned three reasons that came to mind.
And I simply pointed out how they are incorrect.
 
 While I don't approve of Mr. Sabalausky's tone or attitude,
Sorry about that. I'm just frustrated at fighting another uphill D battle against those who have far, far more pull than I do, and are every bit as difficult to sway as I am ;). It's nothing personal against Andrei or Walter or anyone else.
Jan 24 2013
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 25 January 2013 at 01:54:03 UTC, Nick Sabalausky wrote:
 Sorry about that. I'm just frustrated at fighting another 
 uphill D battle against those who have far, far more pull
 than I do, and are every bit as difficult to sway as I am ;).
I literally screamed at my computer screen a couple times in this thread. This is an argument we've been having for years and I've gotta say, I'm kinda fed up with it. But I feel like we're finding common ground this time, where we weren't able to the last several times.
Jan 24 2013
next sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Fri, 25 Jan 2013 02:57:22 +0100
"Adam D. Ruppe" <destructionator gmail.com> wrote:

 On Friday, 25 January 2013 at 01:54:03 UTC, Nick Sabalausky wrote:
 Sorry about that. I'm just frustrated at fighting another 
 uphill D battle against those who have far, far more pull
 than I do, and are every bit as difficult to sway as I am ;).
I literally screamed at my computer screen a couple times in this thread. This is an argument we've been having for years and I've gotta say, I'm kinda fed up with it.
Getting screamed at and just taking it, without ever giving me crap back about it, is one of the top killer features of electronics technology. It's like a squeezy stress ball, except it's always handy when you need it...Probably because it's usually also the cause, but hey.
 But I feel like we're finding common ground this time, where we 
 weren't able to the last several times.
Maybe because we're *all* finally tired of arguing about it ;)
Jan 24 2013
prev sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Fri, 25 Jan 2013 02:57:22 +0100
"Adam D. Ruppe" <destructionator gmail.com> wrote:

 On Friday, 25 January 2013 at 01:54:03 UTC, Nick Sabalausky wrote:
 Sorry about that. I'm just frustrated at fighting another 
 uphill D battle against those who have far, far more pull
 than I do, and are every bit as difficult to sway as I am ;).
I literally screamed at my computer screen a couple times in this thread. This is an argument we've been having for years and I've gotta say, I'm kinda fed up with it.
What really got me upset about it was that here we have one of my favorite modern language features, properties, and then all of a sudden outright remove it from the language entirely, instead of enacting, or at least promising to *eventually* enact, the long overdue fixes I've been anxiously awaiting.
Jan 25 2013
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 25 January 2013 at 20:10:01 UTC, Nick Sabalausky wrote:
 What really got me upset about it was that here we have one of 
 my favorite modern language features, properties, and then all 

 trying to
 gut it if not outright remove it from the language entirely
Amen.
Jan 25 2013
prev sibling parent reply "Rob T" <alanb ucora.com> writes:
On Friday, 25 January 2013 at 20:10:01 UTC, Nick Sabalausky wrote:
 What really got me upset about it was that here we have one of 
 my
 favorite modern language features, properties, and then all of 
 a sudden

 if not
 outright remove it from the language entirely, instead of 
 enacting, or
 at least promising to *eventually* enact, the long overdue 
 fixes I've
 been anxiously awaiting.
If I correctly understand Walters proposal and Andrei's view point, neither are proposing to fully axe property-like behavior. I stand to be corrected, but they both seem to think that enforcement through property is not required, and that's the main point being put on the chopping block. Walter and Andrei may want to clarify since I cannot speak for them. --rt
Jan 25 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/25/13 3:18 PM, Rob T wrote:
 On Friday, 25 January 2013 at 20:10:01 UTC, Nick Sabalausky wrote:
 What really got me upset about it was that here we have one of my
 favorite modern language features, properties, and then all of a sudden

 outright remove it from the language entirely, instead of enacting, or
 at least promising to *eventually* enact, the long overdue fixes I've
 been anxiously awaiting.
If I correctly understand Walters proposal and Andrei's view point, neither are proposing to fully axe property-like behavior. I stand to be corrected, but they both seem to think that enforcement through property is not required, and that's the main point being put on the chopping block. Walter and Andrei may want to clarify since I cannot speak for them.
That's right with the amendment that we're looking for a solution, not pushing one. Even the title of the thread is a question. Clearly properties are good to have. In an ideal world we wouldn't need a keyword for them and we'd have some simple rules for determining property status (especially when it comes to writes). If syntactic help is necessary, so be it. We want to make the language better, not worse. Andrei
Jan 25 2013
next sibling parent "Rob T" <alanb ucora.com> writes:
On Friday, 25 January 2013 at 21:20:33 UTC, Andrei Alexandrescu 
wrote:
 On 1/25/13 3:18 PM, Rob T wrote:
 On Friday, 25 January 2013 at 20:10:01 UTC, Nick Sabalausky 
 wrote:
 What really got me upset about it was that here we have one 
 of my
 favorite modern language features, properties, and then all 
 of a sudden

 it if not
 outright remove it from the language entirely, instead of 
 enacting, or
 at least promising to *eventually* enact, the long overdue 
 fixes I've
 been anxiously awaiting.
If I correctly understand Walters proposal and Andrei's view point, neither are proposing to fully axe property-like behavior. I stand to be corrected, but they both seem to think that enforcement through property is not required, and that's the main point being put on the chopping block. Walter and Andrei may want to clarify since I cannot speak for them.
That's right with the amendment that we're looking for a solution, not pushing one. Even the title of the thread is a question. Clearly properties are good to have. In an ideal world we wouldn't need a keyword for them and we'd have some simple rules for determining property status (especially when it comes to writes). If syntactic help is necessary, so be it. We want to make the language better, not worse. Andrei
OK, understood. I started a discussion in wiki showing how property-like behaviour without full variable emulation can work unambiguously for a few of the edge cases, such as reference returns and taking the addresses, eg, &prop. http://wiki.dlang.org/Talk:Property_Discussion_Wrap-up#ref_returns_and_taking_the_address If we try and fully emulate variables, a ton of complexity starts to creep in. If we do not fully emulate variables, then it significantly weakens the arguments in favor of using property as a means to emulate variable. --rt
Jan 25 2013
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-25 22:20, Andrei Alexandrescu wrote:

 That's right with the amendment that we're looking for a solution, not
 pushing one. Even the title of the thread is a question.

 Clearly properties are good to have. In an ideal world we wouldn't need
 a keyword for them and we'd have some simple rules for determining
 property status (especially when it comes to writes). If syntactic help
 is necessary, so be it. We want to make the language better, not worse.
It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name. -- /Jacob Carlborg
Jan 26 2013
next sibling parent reply "Nicolas Sicard" <dransic gmail.com> writes:
On Saturday, 26 January 2013 at 13:21:37 UTC, Jacob Carlborg 
wrote:
 It's always possible to avoid keywords in favor of syntax. 
 Example:

 Declaring a getter:

 int foo {}

 Just as a regular function declaration but without the 
 parentheses.

 Declaring a setter:

 void foo= (int value) {}

 Append an equal sign to the function name.
How would you declare a template property? The getter would be ambiguous with a regular function declaration, wouldn't it?
Jan 26 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-01-26 16:06, Nicolas Sicard wrote:

 How would you declare a template property? The getter would be ambiguous
 with a regular function declaration, wouldn't it?
Right... didn't think of that. -- /Jacob Carlborg
Jan 26 2013
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/26/13 8:21 AM, Jacob Carlborg wrote:
 On 2013-01-25 22:20, Andrei Alexandrescu wrote:

 That's right with the amendment that we're looking for a solution, not
 pushing one. Even the title of the thread is a question.

 Clearly properties are good to have. In an ideal world we wouldn't need
 a keyword for them and we'd have some simple rules for determining
 property status (especially when it comes to writes). If syntactic help
 is necessary, so be it. We want to make the language better, not worse.
It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.
This is interesting. I wonder how to make it work for UFCS functions (which _do_ have one argument). Andrei
Jan 26 2013
next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Saturday, 26 January 2013 at 16:29:16 UTC, Andrei Alexandrescu 
wrote:
 On 1/26/13 8:21 AM, Jacob Carlborg wrote:
 On 2013-01-25 22:20, Andrei Alexandrescu wrote:

 That's right with the amendment that we're looking for a 
 solution, not
 pushing one. Even the title of the thread is a question.

 Clearly properties are good to have. In an ideal world we 
 wouldn't need
 a keyword for them and we'd have some simple rules for 
 determining
 property status (especially when it comes to writes). If 
 syntactic help
 is necessary, so be it. We want to make the language better, 
 not worse.
It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.
This is interesting. I wonder how to make it work for UFCS functions (which _do_ have one argument).
I have to say it will get my vote if a way if found to make this UFCS compliant.
Jan 26 2013
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-01-26 17:29, Andrei Alexandrescu wrote:

 This is interesting. I wonder how to make it work for UFCS functions
 (which _do_ have one argument).
There's two problems with the getter syntax. 1. How to distinguish a template property from a regular function 2. How to distinguish a property without an implementation from a variable declaration -- /Jacob Carlborg
Jan 26 2013
prev sibling parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Sat, 26 Jan 2013 16:29:16 -0000, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/26/13 8:21 AM, Jacob Carlborg wrote:
 On 2013-01-25 22:20, Andrei Alexandrescu wrote:

 That's right with the amendment that we're looking for a solution, not
 pushing one. Even the title of the thread is a question.

 Clearly properties are good to have. In an ideal world we wouldn't need
 a keyword for them and we'd have some simple rules for determining
 property status (especially when it comes to writes). If syntactic help
 is necessary, so be it. We want to make the language better, not worse.
It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.
This is interesting. I wonder how to make it work for UFCS functions (which _do_ have one argument).
int foo(this Person p) {} void foo= (this Person p, int value) {} R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Jan 28 2013
parent "Adam Wilson" <flyboynw gmail.com> writes:
On Mon, 28 Jan 2013 05:26:43 -0800, Regan Heath <regan netmail.co.nz>  
wrote:

 On Sat, 26 Jan 2013 16:29:16 -0000, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/26/13 8:21 AM, Jacob Carlborg wrote:
 On 2013-01-25 22:20, Andrei Alexandrescu wrote:

 That's right with the amendment that we're looking for a solution, not
 pushing one. Even the title of the thread is a question.

 Clearly properties are good to have. In an ideal world we wouldn't  
 need
 a keyword for them and we'd have some simple rules for determining
 property status (especially when it comes to writes). If syntactic  
 help
 is necessary, so be it. We want to make the language better, not  
 worse.
It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.
This is interesting. I wonder how to make it work for UFCS functions (which _do_ have one argument).
int foo(this Person p) {} void foo= (this Person p, int value) {} R
Extension Method. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 28 2013
prev sibling next sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 26 January 2013 at 13:21:37 UTC, Jacob Carlborg 
wrote:
 It's always possible to avoid keywords in favor of syntax. 
 Example:

 Declaring a getter:

 int foo {}

 Just as a regular function declaration but without the 
 parentheses.

 Declaring a setter:

 void foo= (int value) {}

 Append an equal sign to the function name.
The root of the issue is that in C/C++/D there is tremendous difference between object types and functions types (which are incompatible) and property is like a bridge between them - I think that is why the feature is demanded. However in D a property is essentially a function. Few characteristics that are intrinsic to data types are typeof(prop) which is data type for properties and parenthesis-less access. There is no property as a special entity per se. confusion between data and functions. In D it would look like this: class A { private int i; property int foo // may be without property at all? { get { return i; } set { i = value; } } } In this solution property is not defined by naming of two separate functions and is independent of any function in general.
Jan 26 2013
next sibling parent "Adam Wilson" <flyboynw gmail.com> writes:
On Sat, 26 Jan 2013 11:10:20 -0800, Maxim Fomin <maxim maxim-fomin.ru>  
wrote:

 On Saturday, 26 January 2013 at 13:21:37 UTC, Jacob Carlborg wrote:
 It's always possible to avoid keywords in favor of syntax. Example:

 Declaring a getter:

 int foo {}

 Just as a regular function declaration but without the parentheses.

 Declaring a setter:

 void foo= (int value) {}

 Append an equal sign to the function name.
The root of the issue is that in C/C++/D there is tremendous difference between object types and functions types (which are incompatible) and property is like a bridge between them - I think that is why the feature is demanded. However in D a property is essentially a function. Few characteristics that are intrinsic to data types are typeof(prop) which is data type for properties and parenthesis-less access. There is no property as a special entity per se. between data and functions. In D it would look like this: class A { private int i; property int foo // may be without property at all? { get { return i; } set { i = value; } } } In this solution property is not defined by naming of two separate functions and is independent of any function in general.
for the compiler to determine whether or not it is a property. class A { private int i; public int foo { get { return i; } set { i = value; } } } -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 26 2013
prev sibling parent reply Artur Skawina <art.08.09 gmail.com> writes:
On 01/26/13 20:10, Maxim Fomin wrote:
 On Saturday, 26 January 2013 at 13:21:37 UTC, Jacob Carlborg wrote:
 It's always possible to avoid keywords in favor of syntax. Example:

 Declaring a getter:

 int foo {}

 Just as a regular function declaration but without the parentheses.

 Declaring a setter:

 void foo= (int value) {}

 Append an equal sign to the function name.
The root of the issue is that in C/C++/D there is tremendous difference between object types and functions types (which are incompatible) and property is like a bridge between them - I think that is why the feature is demanded. However in D a property is essentially a function. Few characteristics that are intrinsic to data types are typeof(prop) which is data type for properties and parenthesis-less access. There is no property as a special entity per se. between data and functions. In D it would look like this: class A { private int i; property int foo // may be without property at all? { get { return i; } set { i = value; } } } In this solution property is not defined by naming of two separate functions and is independent of any function in general.
Hmm, the current state of them being defined by two separate functions really isn't ideal. But introducing new keywords or magic identifiers just for this does not seem right. class A { private int i; int foo { out { return i; } in(int v) { i = v; } } } or class A { private int i; property foo { int out { return i; } in(int v) { i = v; } } } artur
Jan 26 2013
next sibling parent reply "Rob T" <alanb ucora.com> writes:
On Saturday, 26 January 2013 at 21:48:54 UTC, Artur Skawina wrote:
[..]
 Hmm, the current state of them being defined by two separate 
 functions really
 isn't ideal. But introducing new keywords or magic identifiers 
 just for this
 does not seem right.

    class A
    {
        private int i;
        int foo {
            out { return i; }
            in(int v) { i = v; }
        }
    }

 or

    class A
    {
        private int i;
         property foo {
            int out { return i; }
            in(int v) { i = v; }
        }
    }

 artur
In a more pefect world, we'd redefine what a variable and function is, merging the two together as one, let the compiler optimize things appropriately, and make the language issues far more consistent and simple. For example, typeof(x) is way too simplistic to be of use when you have objects that have more than on type. For example, a property has a setter, getter, and storage type, so what should typeof(prop) return? It can only tell you one thing out of at least 3 things, so it's insufficient. Great for C, useless for D. We're basically finding ourselves in the same position C++ has found itself in, where the old concepts are no longer suitable for a modern language, but there's no practical way to resolve the situation without redesigning the whole language into a new one. D tried to make a better C++, and it has done a good job of that up to a point, but since it has made use of many of the old paradigms as its base, it can only do so much. One solution is to not bother trying to add on any extra complexity that does not fit in. --rt
Jan 26 2013
parent Ziad Hatahet <hatahet gmail.com> writes:
On Sat, Jan 26, 2013 at 2:24 PM, Rob T <alanb ucora.com> wrote:

 We're basically finding ourselves in the same position C++ has found
 itself in, where the old concepts are no longer suitable for a modern
 language, but there's no practical way to resolve the situation without
 redesigning the whole language into a new one. D tried to make a better
 C++, and it has done a good job of that up to a point, but since it has
 made use of many of the old paradigms as its base, it can only do so much.
That is what I have been noticing as well, unfortunately. As a long time lurker, I like many of the concepts that D introduces, but the many little quirks here and there add up and probably make adoption by a large community much less likely. It would be great if we had more programming languages competing to change the systems programming landscape. The popular systems languages we have been stuck with (namely C and C++) are a mess, and the "replacements" I see announced every once in a while never seem to become bigger than side projects. Currently, the only other potential option I see is Rust. Why not take it all the way? Start with a proper release plan, be willing to break backward compatibility (maybe even by changing the name of the language -- perception matters), take into account all what was learned from the past 10+ years of D's history, potentially try to get corporate backing, and maybe we will have something that is practically viable to push aside C and C++. Then again, maybe I dream too much... -- Ziad
Jan 26 2013
prev sibling next sibling parent reply "Rob T" <alanb ucora.com> writes:
We can almost implement properties as a regular struct

struct prop
{
     int _val;
     ref prop opAssign( int a_val )
     {
         writeln("assignment = ", a_val );
         _val = a_val;
         return this;
     }
     int opCall()
     {
         writeln("opcall = ", _val );
         return _val;
     }

     // other op overloads, like ++, --, etc

}

If we change a few things it may work. Instead of struct it could 
be named prop

eg

prop P
{

    ...

}

opCall needs to be changed so there's no need to specify the (). 
No dounbt other changes will be needed too to make it more 
convenient to use and less error prone.

The advantage is that with a "property as a struct" 
implementation, you can wrap up a lot more than just a setter and 
getter around only one variable, eg internally there could be 
several vars or even none at all depending on the needs.

--rt
Jan 26 2013
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sun, Jan 27, 2013 at 01:15:29AM +0100, Rob T wrote:
 We can almost implement properties as a regular struct
[...] You do it like this: import std.stdio; struct IntProp { int __impl; property /* <-- ah, the irony! */ int value() { return __impl + 123; } alias value this; // watch this magic void opAssign(int val) { __impl = val - 123; } } struct S { IntProp prop; } void main() { S s; writeln(s.prop); s.prop = 321; writeln(s.prop); } T -- Gone Chopin. Bach in a minuet.
Jan 26 2013
next sibling parent reply "Rob T" <alanb ucora.com> writes:
On Sunday, 27 January 2013 at 01:11:05 UTC, H. S. Teoh wrote:
 On Sun, Jan 27, 2013 at 01:15:29AM +0100, Rob T wrote:
 We can almost implement properties as a regular struct
[...] You do it like this: import std.stdio; struct IntProp { int __impl; property /* <-- ah, the irony! */ int value() { return __impl + 123; } alias value this; // watch this magic void opAssign(int val) { __impl = val - 123; } } struct S { IntProp prop; } void main() { S s; writeln(s.prop); s.prop = 321; writeln(s.prop); } T
Ah cool! You don't really need property however if we adopt the optional () unless that's to be enforced. The really nice thing about this, is we can return the struct as a ref, and it still works, and also take the address of the struct and it continues to work. Even better I can add more member functions to it and expand on what it can do. The "property as a function" approach is far more limiting and has issues, such as ref returns and taking the address. Anyone know what's missing or what won't work with this approach? --rt
Jan 26 2013
parent Artur Skawina <art.08.09 gmail.com> writes:
On 01/27/13 03:48, Rob T wrote:
 On Sunday, 27 January 2013 at 01:11:05 UTC, H. S. Teoh wrote:
 On Sun, Jan 27, 2013 at 01:15:29AM +0100, Rob T wrote:
 We can almost implement properties as a regular struct
[...] You do it like this: import std.stdio; struct IntProp { int __impl; property /* <-- ah, the irony! */ int value() { return __impl + 123; } alias value this; // watch this magic void opAssign(int val) { __impl = val - 123; } } struct S { IntProp prop; } void main() { S s; writeln(s.prop); s.prop = 321; writeln(s.prop); } T
Ah cool! You don't really need property however if we adopt the optional () unless that's to be enforced. The really nice thing about this, is we can return the struct as a ref, and it still works, and also take the address of the struct and it continues to work. Even better I can add more member functions to it and expand on what it can do. The "property as a function" approach is far more limiting and has issues, such as ref returns and taking the address. Anyone know what's missing or what won't work with this approach?
auto w = Widget(); w.width = 3; w.height = 14; auto a = w.area; Consider an implementation of Widget where some/all of these fields are properties. Also, does adding a "virtual" area property (ie one calculated on demand from the others) influence the layout of the object? Should it? IOW, there are many problems with such a solution, some of which can be worked around, others fixed with relatively small language changes (legalizing zero-sized objects, making a static-outer implementation cleanly doable etc). But would there really be enough gain to justify making properties that much more complicated? The present approach is a reasonable compromise, it just needs proper call handling. Consider the case, that is some times brought up here, where you use a library which at some point is changed and some object fields are replaced by properties. You recompile your code with that newer version. What keeps working? What breaks? Which breakages can be avoided? Which ones would you really want to examine and handle manually? Any field->property change breaks the ABI, but this can only be avoided by preemptively using accessors. That doesn't affect property as such, except that having some kind of syntax sugar would make creating the required forwarders easier. Handling property evaluation correctly not only makes sense, it's necessary to make them work correctly. But further "improvements" bring few extra benefits, while complicating the language. Parens-less function calls are a much bigger problem; I can't see much gain from "cleaning up" the property design. While killing property /is/ an option, it's not a good one either, especially if ()-enforcement on all calls doesn't happen before such a change. artur
Jan 27 2013
prev sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
It would be cool if we could declare variables with anonymous 
types;

struct { opAssign() {} } foo;
Jan 26 2013
next sibling parent reply "Zach the Mystic" <reachBUTMINUSTHISzach gOOGLYmail.com> writes:
On Sunday, 27 January 2013 at 02:54:55 UTC, Adam D. Ruppe wrote:
 It would be cool if we could declare variables with anonymous 
 types;

 struct { opAssign() {} } foo;
This would be much easier to understand: alias foo struct { opAssign() {} }; Is "singleton structures", a.k.a. properties, a good name for these?
Jan 26 2013
parent "Zach the Mystic" <reachBUTMINUSTHISzach gOOGLYmail.com> writes:
On Sunday, 27 January 2013 at 05:32:25 UTC, Zach the Mystic wrote:
 On Sunday, 27 January 2013 at 02:54:55 UTC, Adam D. Ruppe wrote:
 It would be cool if we could declare variables with anonymous 
 types;

 struct { opAssign() {} } foo;
This would be much easier to understand: alias foo struct { opAssign() {} }; Is "singleton structures", a.k.a. properties, a good name for these?
Actually, I don't even think you need alias: foo struct { opAssign() {} }
Jan 26 2013
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sun, Jan 27, 2013 at 03:54:54AM +0100, Adam D. Ruppe wrote:
 It would be cool if we could declare variables with anonymous types;
 
 struct { opAssign() {} } foo;
I was thinking we could just use a template to alleviate much of the boilerplate of creating a property using a struct. For example, something like: struct Property(T, alias setter, alias getter) { property T get() { return nullaryFunc!setter(); } alias get this; void opAssign(T val) { return unaryFunc!setter(val); } // ... add other standard stuff like opAssignOp, etc. } Then you could use it like this: struct S { int x, y; Property!(int, ()=>x+y, (int z) { y=z-x; }) derivedProp; } The syntax could do with some improvement, though. Maybe an alias: struct S { alias Property!(int, ()=>x+y, (int z) { y=z-x; }) DerivedProp; int x, y; DerivedProp derivedProp; } S s; s.derivedProp = 123; auto ptr = &s.derivedProp; writeln(*ptr); // etc. T -- Arise, you prisoners of Windows / Arise, you slaves of Redmond, Wash, / The day and hour soon are coming / When all the IT folks say "Gosh!" / It isn't from a clever lawsuit / That Windowsland will finally fall, / But thousands writing open source code / Like mice who nibble through a wall. -- The Linux-nationale by Greg Baker
Jan 26 2013
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-26 22:48, Artur Skawina wrote:

 Hmm, the current state of them being defined by two separate functions really
 isn't ideal. But introducing new keywords or magic identifiers just for this
 does not seem right.

     class A
     {
         private int i;
         int foo {
             out { return i; }
             in(int v) { i = v; }
         }
     }

 or

     class A
     {
         private int i;
          property foo {
             int out { return i; }
             in(int v) { i = v; }
         }
     }
That might conflict with contracts, which also uses "in" and "out". -- /Jacob Carlborg
Jan 27 2013
parent reply Artur Skawina <art.08.09 gmail.com> writes:
On 01/27/13 13:02, Jacob Carlborg wrote:
 On 2013-01-26 22:48, Artur Skawina wrote:
 
 Hmm, the current state of them being defined by two separate functions really
 isn't ideal. But introducing new keywords or magic identifiers just for this
 does not seem right.

     class A
     {
         private int i;
         int foo {
             out { return i; }
             in(int v) { i = v; }
         }
     }

 or

     class A
     {
         private int i;
          property foo {
             int out { return i; }
             in(int v) { i = v; }
         }
     }
That might conflict with contracts, which also uses "in" and "out".
It overloads the keywords, but afaict should be unambiguous and is not worse than the other meanings of 'in' (operator, modifier). But I haven't really used contracts w/ D (the basic features need to work right first, before worrying about extras like that); somebody who actually uses them would be in a better position to determine if overloading 'in' and 'out' further would be too confusing. I mentioned this as a possibility, but am not actually convinced that it's a good idea yet. Things like mixin in getters and setters via separate templates would be impaired - this may be unusual, but doesn't meet the "insane" criteria, so shouldn't be disallowed. Which means several property blocks would have to be allowed and effectively merged together. artur
Jan 27 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-27 13:52, Artur Skawina wrote:

 It overloads the keywords, but afaict should be unambiguous and is not
 worse than the other meanings of 'in' (operator, modifier). But I haven't
 really used contracts w/ D (the basic features need to work right first,
 before worrying about extras like that); somebody who actually uses them
 would be in a better position to determine if overloading 'in' and 'out'
 further would be too confusing.
I'm not talking about confusing. I'm thinking if it's ambiguous or not and how to attach contracts to a property with this syntax. -- /Jacob Carlborg
Jan 27 2013
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/27/2013 02:27 PM, Jacob Carlborg wrote:
 On 2013-01-27 13:52, Artur Skawina wrote:

 It overloads the keywords, but afaict should be unambiguous and is not
 worse than the other meanings of 'in' (operator, modifier). But I haven't
 really used contracts w/ D (the basic features need to work right first,
 before worrying about extras like that); somebody who actually uses them
 would be in a better position to determine if overloading 'in' and 'out'
 further would be too confusing.
I'm not talking about confusing. I'm thinking if it's ambiguous or not and how to attach contracts to a property with this syntax.
class A{ private int i; int foo{ out out(result){assert(result<=0);}body{return i; } in(int v)in{assert(v<=0);}out{assert(foo<=0);}body{ i = v; } } }
Jan 27 2013
prev sibling parent "Michael" <pr m1xa.com> writes:
I think that "property as contract for accessing to variable" is 
good point. Maybe we have lack proper terminology, but idea is 
good.
Also it is can be pointed as "property itself - is static 
contract to accessing variable".

class A{
    private int i;
    int foo{
        out out(result){assert(result<=0);}body{return i; }
        in(int v)in{assert(v<=0);}out{assert(foo<=0);}body{ i = 
 v; }
    }
}
Unified: class A { private int i; int foo { out{assert( value<=0);}body{return i; } in{assert( value<=0);}body{ i = value; } } } value - in getter it's return value; value - in setter it's param value; void type is not allowed. In theory, property always have only one in/out parameter of same type and performs lightweight actions.
Jan 27 2013
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/26/2013 5:21 AM, Jacob Carlborg wrote:
 On 2013-01-25 22:20, Andrei Alexandrescu wrote:

 That's right with the amendment that we're looking for a solution, not
 pushing one. Even the title of the thread is a question.

 Clearly properties are good to have. In an ideal world we wouldn't need
 a keyword for them and we'd have some simple rules for determining
 property status (especially when it comes to writes). If syntactic help
 is necessary, so be it. We want to make the language better, not worse.
It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses.
Problems if you want to declare the getter but not provide an implementation.
 Declaring a setter:

 void foo= (int value) {}

 Append an equal sign to the function name.
It is rather similar to a variable declaration with initializer: T foo = expression;
Jan 26 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-01-27 02:23, Walter Bright wrote:

 Problems if you want to declare the getter but not provide an
 implementation.
Yeah, I noticed that. And declaring a tempalte property.
 It is rather similar to a variable declaration with initializer:

     T foo = expression;
Yeah, you're right. -- /Jacob Carlborg
Jan 27 2013
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-24 22:08, Adam Wilson wrote:

 While I don't approve of Mr. Sabalausky's tone or attitude, the crux of
 his argument is logically sound. The problem with  property isn't
  property, it's D's insistence on optional parens. If paren usage was
 clearly defined then this would be a non-issue. I would like to point
 out that I can't think of another systems/general purpose language that

 is brutally simple. Java's is brutally simple. In C/C++ everything is a
 function or field, so, brutally simple.

 Make D's calling syntax simpler, end optional parens!
There are many languages that allow optional parentheses when calling a function. Ruby, CoffeeScript and Groovy to mention a few. -- /Jacob Carlborg
Jan 25 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 09:38:27 UTC, Jacob Carlborg wrote:
 On 2013-01-24 22:08, Adam Wilson wrote:

 While I don't approve of Mr. Sabalausky's tone or attitude, 
 the crux of
 his argument is logically sound. The problem with  property 
 isn't
  property, it's D's insistence on optional parens. If paren 
 usage was
 clearly defined then this would be a non-issue. I would like 
 to point
 out that I can't think of another systems/general purpose 
 language that
 has an calling syntax specification as vague and convoluted as 

 is brutally simple. Java's is brutally simple. In C/C++ 
 everything is a
 function or field, so, brutally simple.

 Make D's calling syntax simpler, end optional parens!
There are many languages that allow optional parentheses when calling a function. Ruby, CoffeeScript and Groovy to mention a few.
From what I see on CofeeScript website, it has a VERY different semantic than D on function.
Jan 25 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-01-25 10:49, deadalnix wrote:

 From what I see on CofeeScript website, it has a VERY different
 semantic than D on function.
How do you mean? Well it has the same semantics as JavaScript since it's compiled to JavaScript. -- /Jacob Carlborg
Jan 25 2013
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 15:45:42 Nick Sabalausky wrote:
 On Thu, 24 Jan 2013 12:51:32 -0500
 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 No. The complications come from the fact that (a) nobody could agree
 what should be a  property and what shouldn't;
No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you). Stop mischaracterizing what really happened: It's well known that you never liked or fully understood the idea of properties in the first place, even by your own admission. So you made a post some number of months back attempting to drum up dissent for properties by stirring up the notion, which just about only you believed, that the choice between property and function is inherently unclear. So to "prove" this you cherry-picked some grey area cases (gee, occasional grey judgement calls when mapping ideas into code, yea, there's something that doesn't happen without property). You succeeded ONLY in proving that there exist *some* cases which may be grey-area judgement calls (again, big surprise, occasional grey-area judgement calls when writing code). But then you - and ONLY you - took this proof that "*some* cases exist" and declared "Look, look, everyone! I proved that *nobody* can agree on property vs function *in general*! QED!" And you continue declaring that non-sequitur to this day.
I've never understood what's so hard about knowing what should and shouldn't be considered a property. It's generally very clear IMHO, and if clarification pointing out. Really, it comes down primarily to whether a function would make sense as a variable.
 (b)  property adds
 noise for everybody for the sake of a corner case (functions
 returning delegates);
The only reason functions returning delegates have *ever* been an any issue at all is *purely* because of the insistence on optional parens on arbitrary function calls.
Indeed.
 (c) the  property discipline failed to align
 itself in any way with better code quality.
Ok, now *that* argument is just pure unadulterated bullshit. In yes, the general consensus IS that they DO definitely help. Please take your blinders off, and you'll see that. But then there's D, which adds a half-baked and incompletely-implemented "properties" - and did so *reluctantly* I should add. Leaves it in that broken state untouched for a year or two. And now here you are effectively saying "This half-designed/half-implemented feature is causing dissent and not helping people, therefore the problem must be the whole idea of properties and couldn't possibly be due to our broken version of them" (for the record - I *do* find D's current properties helpful, just not as helpful as they would be if they weren't broken).
I think that you're being too extreme in your language and tone here, but I have to agree. - Jonathan M Davis
Jan 24 2013
prev sibling next sibling parent "ponce" <spam spam.org> writes:
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 4. No more  property.
Looks fine for me. D2 code is better but sometimes so much noisier than D1. There, I said it.
Jan 24 2013
prev sibling next sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns 
 somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the 
 return value taking (), the () go on the return value.

 2. the:
    f = g
 rewrite to:
    f(g)
 only happens if f is a function that only has overloads for () 
 and (one argument). No variadics.

 3. Parens are required for calling delegates or function 
 pointers.

 4. No more  property.
Under the proposed rules, which of the lines in the output of the following program will be the same? --- import std.stdio; int globalInt = 42; auto ref g() { return globalInt; }; auto globalG = &g; auto ref f() { return globalG; } void main() { writeln("&globalInt: ", &globalInt); writeln("globalInt: ", globalInt); writeln("&globalG: ", &globalG); writeln("globalG: ", globalG); writeln("---"); writeln("&f: ", &f); writeln("&f(): ", &f()); writeln("&g: ", &g); writeln("&g(): ", &g()); } --- Also, don't forget that property was actually introduced to solve specific syntactic issues, not just because somebody didn't like the laxness of the previous rules. Now, yes, the current implementation in DMD doesn't solve the issues, while introducing new issues by disallowing parameterless function calls altogether. But I think the last larger discussion on the topic some two to three months ago produced a set of property rules that would actually work. I think there is a summary in DIP21. Anyway, I think you should turn your proposal into a DIP, and better sooner than later so that the details on the edge cases, impact in terms of breaking code, … aren't lost in an endless forum discussion. David
Jan 24 2013
prev sibling next sibling parent reply =?UTF-8?B?U8O2bmtlIEx1ZHdpZw==?= <sludwig outerproduct.org> writes:
Am 24.01.2013 09:34, schrieb Walter Bright:
 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.
 
 Perhaps we should revert to a simple set of rules.
I think Adam D. Ruppe has proposed this in the past and, although I don't really like omitting parentheses on ordinary function calls in general (apart from UFCS template functions), it's clear, simple and I think everyone could be happy with it: 1. Normal function calls _may_ omit parentheses, but "a = b" is _not_ interpreted as "a(b)" 2. property functions can _not_ be called with parentheses and "a = b" _is_ interpreted as "a(b)" 3. Calling a normal function always returns its return value
 
 1. Empty parens are optional. If there is an ambiguity with the return value
taking (), the () go on
 the return value.
This sounds like a recipe for disaster. Thinking about generic code calling functions... it would surely be very surprising to see how f() sometimes does not return ReturnType!f, but something completely different. It would also break all existing code that currently expects f() to simply return its return value. More importantly, adding or removing an opCall or changing the return type of a function would possibly silently change the meaning of code that calls the function. IMO it is also utterly unexpected/counter-intuitive for a seeming function call not to return its return value, but call it and return the result.
 
 2. the:
    f = g
 rewrite to:
    f(g)
 only happens if f is a function that only has overloads for () and (one
argument). No variadics.
I can live with omitted parentheses (*). However, what's really ugly is picking the unintended form in case of a setter (i.e. both, "obj.prop(value)" instead of "obj.prop = value;", or "countElements = obj;" instead of "obj.countElements()"). And in my experience, people /will/ mix the different forms all over the place. So although I know that some people have a different opinion, I still find it a very useful thing to be able to force correct usage up to a certain degree - stylistically and to avoid ambiguities (not only for the compiler, but also for a human reader). Adam's proposal solves this nicely and it's about as simple as it gets. (*) IMO they are kind of ugly semantically if they are omitted for anything else than properties or UFCS-template functions, but you may well call that a matter of taste
 
 3. Parens are required for calling delegates or function pointers.
 
 4. No more  property.
Jan 24 2013
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-01-24 14:28, Sönke Ludwig wrote:

 1. Normal function calls _may_ omit parentheses, but "a = b" is _not_
interpreted as "a(b)"
 2.  property functions can _not_ be called with parentheses and "a = b" _is_
interpreted as "a(b)"
 3. Calling a normal function always returns its return value
+1 -- /Jacob Carlborg
Jan 24 2013
prev sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 24 January 2013 at 13:28:48 UTC, Sönke Ludwig wrote:
 Am 24.01.2013 09:34, schrieb Walter Bright:
 This has turned into a monster. We've taken 2 or 3 wrong turns 
 somewhere.
 
 Perhaps we should revert to a simple set of rules.
I think Adam D. Ruppe has proposed this in the past and, although I don't really like omitting parentheses on ordinary function calls in general (apart from UFCS template functions), it's clear, simple and I think everyone could be happy with it: 1. Normal function calls _may_ omit parentheses, but "a = b" is _not_ interpreted as "a(b)" 2. property functions can _not_ be called with parentheses and "a = b" _is_ interpreted as "a(b)" 3. Calling a normal function always returns its return value
This greatly impairs functional style. Just as you demonstrated nicely with return values, this one cause the same problem with arguments (either to template or functions).
 
 1. Empty parens are optional. If there is an ambiguity with 
 the return value taking (), the () go on
 the return value.
This sounds like a recipe for disaster. Thinking about generic code calling functions... it would surely be very surprising to see how f() sometimes does not return ReturnType!f, but something completely different. It would also break all existing code that currently expects f() to simply return its return value. More importantly, adding or removing an opCall or changing the return type of a function would possibly silently change the meaning of code that calls the function. IMO it is also utterly unexpected/counter-intuitive for a seeming function call not to return its return value, but call it and return the result.
Great explanation on how it mess up return values when using very functional style.
Jan 24 2013
prev sibling next sibling parent reply Iain Buclaw <ibuclaw ubuntu.com> writes:
On 24 January 2013 08:34, Walter Bright <newshound2 digitalmars.com> wrote:

 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return
 value taking (), the () go on the return value.

 2. the:
    f = g
 rewrite to:
    f(g)
 only happens if f is a function that only has overloads for () and (one
 argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
As much as I want to agree, I also feel this comes as too little, too late to come to this conclusion now. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Jan 24 2013
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 8:38 AM, Iain Buclaw wrote:
 On 24 January 2013 08:34, Walter Bright <newshound2 digitalmars.com
 <mailto:newshound2 digitalmars.com>> wrote:

     This has turned into a monster. We've taken 2 or 3 wrong turns
     somewhere.

     Perhaps we should revert to a simple set of rules.

     1. Empty parens are optional. If there is an ambiguity with the
     return value taking (), the () go on the return value.

     2. the:
         f = g
     rewrite to:
         f(g)
     only happens if f is a function that only has overloads for () and
     (one argument). No variadics.

     3. Parens are required for calling delegates or function pointers.

     4. No more  property.



 As much as I want to agree, I also feel this comes as too little, too
 late to come to this conclusion now.
Too little is a good thing actually! Andrei
Jan 24 2013
prev sibling next sibling parent d coder <dlang.coder gmail.com> writes:
 As much as I want to agree, I also feel this comes as too little, too late
 to come to this conclusion now.
+1 And therefor we should take out property ASAP :-)
Jan 24 2013
prev sibling next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns 
 somewhere.
I'm so happy to read this !!!!
 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the 
 return value taking (), the () go on the return value.

 2. the:
    f = g
 rewrite to:
    f(g)
 only happens if f is a function that only has overloads for () 
 and (one argument). No variadics.

 3. Parens are required for calling delegates or function 
 pointers.

 4. No more  property.
I'm so unhappy to read this :((((((( Ok let me be more constructive. The current state of thing have 2 issues : on is that non properties are conflated with properties, and the other is that setter is conflated with getter. You solution isn't good because it conflate things even more. Here is my proposal : For regular functions : 1. funName is the function itself : void funName() {} static assert(is(typeof(funName) == void function())); // Pass. funName has no address, it is equivalent to enum function void() funName = {}; &funName become a NOOP and is deprecated, for compatibility reasons. It is not ambiguous as funName has no address anyway. 2. funName() call the function. Rationale : function as variable or defined in the source now behave the same way (expect the deprecated & behavior). It makes it easier to write generic code, and in general consistency is a plus (easier to learn the language, less dark corner case to consider, easier interaction with other features). 3. getter is an attribute. A function marked getter is automatically executed : () is added automatically : getter void funName() {} funName; // function get executed. funName(); // Error, void is not callable. 4. getter can be used as UFCS. getter void funName(T t) {} T t; t.funName; // function gets executed. funName(t); // Error, funName require 1 argument, 0 given. 5. setter is an attribute. A setter method can *only* be used in rhs of an expression. The assigned value is used as argument. setter void funName(T t) {} T t; funName = t; // function gets executed. funName(t); // Error, funName must be used in an assign expression. 6. setter can as well be used as UFCS : getter void funName(T t, U u) {} T t; U u; t.funName = u; // function gets executed. t.funName(u); // Error, funName must be used in an assign expression. 7a. A function can be defined as both setter and getter, and cumulate both behavior. 7b. property is deprecated and redefined as setter *and* getter for a transitional period. 8. method behave as functions : class A { void foo() {} } A a; static assert(is(typeof(a.foo) : void delegate())); // Pass. &a.foo; // deprecated NOOP for compatibility. a.foo(); // call a.foo 9. UFCS without () are delegate like construct : void foo(T t) {} T t; t.foo; // Is a struct with a function pointer and t. (equivalent to a delegate). The struct member's type is the same as the first argument. If a copy is necessary postblit is called - but will not be called at function call. If foo take a reference, a pointer is stored. t.foo(); // call foo with t as parameter. 10. To allow chain of UFCS calls without () everywhere, an opDispatch is defined in object.d : the function/delegate get's called and the result is used as parameter for foo. This eliminate the need for () on all functions of an UFCS chain expect the last one, which is a price to pay for cleanly defined, unambiguous semantic. Waiting for the shitstorm . . .
Jan 24 2013
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-24 14:41, deadalnix wrote:

 3.  getter is an attribute. A function marked  getter is automatically
 executed : () is added automatically :
       getter void funName() {}
      funName; // function get executed.
      funName(); // Error, void is not callable.

 4.  getter can be used as UFCS.
      getter void funName(T t) {}
     T t; t.funName; // function gets executed.
     funName(t); // Error, funName require 1 argument, 0 given.

 5.  setter is an attribute. A setter method can *only* be used in rhs of
 an expression. The assigned value is used as argument.
      setter void funName(T t) {}
     T t; funName = t; // function gets executed.
     funName(t); // Error, funName must be used in an assign expression.

 6.  setter can as well be used as UFCS :
      getter void funName(T t, U u) {}
     T t; U u; t.funName = u; // function gets executed.
     t.funName(u); // Error, funName must be used in an assign expression.
What about property(getter) and property(setter) instead? Otherwise we need two new built-in attributes.
 8. method behave as functions :
      class A { void foo() {} }
      A a;
      static assert(is(typeof(a.foo) : void delegate())); // Pass.
      &a.foo; // deprecated NOOP for compatibility.
      a.foo(); // call a.foo
The address operator wouldn't be needed to get a delegate for a method anymore? -- /Jacob Carlborg
Jan 24 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 24 January 2013 at 13:56:03 UTC, Jacob Carlborg 
wrote:
 On 2013-01-24 14:41, deadalnix wrote:

 3.  getter is an attribute. A function marked  getter is 
 automatically
 executed : () is added automatically :
      getter void funName() {}
     funName; // function get executed.
     funName(); // Error, void is not callable.

 4.  getter can be used as UFCS.
     getter void funName(T t) {}
    T t; t.funName; // function gets executed.
    funName(t); // Error, funName require 1 argument, 0 given.

 5.  setter is an attribute. A setter method can *only* be used 
 in rhs of
 an expression. The assigned value is used as argument.
     setter void funName(T t) {}
    T t; funName = t; // function gets executed.
    funName(t); // Error, funName must be used in an assign 
 expression.

 6.  setter can as well be used as UFCS :
     getter void funName(T t, U u) {}
    T t; U u; t.funName = u; // function gets executed.
    t.funName(u); // Error, funName must be used in an assign 
 expression.
What about property(getter) and property(setter) instead? Otherwise we need two new built-in attributes.
I don't really care about the syntax. If any new attribute has to be added, they should be defined in some modules instead of builtin.
 8. method behave as functions :
     class A { void foo() {} }
     A a;
     static assert(is(typeof(a.foo) : void delegate())); // 
 Pass.
     &a.foo; // deprecated NOOP for compatibility.
     a.foo(); // call a.foo
The address operator wouldn't be needed to get a delegate for a method anymore?
No, which would eliminate the difference behavior between function as variables and function defined in source code. This is a big step forward for functional style.
Jan 24 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-24 15:04, deadalnix wrote:

 No, which would eliminate the difference behavior between function as
 variables and function defined in source code. This is a big step
 forward for functional style.
Then what do you mean by: &a.foo; // deprecated NOOP for compatibility. -- /Jacob Carlborg
Jan 24 2013
parent "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 24 January 2013 at 14:19:34 UTC, Jacob Carlborg 
wrote:
 On 2013-01-24 15:04, deadalnix wrote:

 No, which would eliminate the difference behavior between 
 function as
 variables and function defined in source code. This is a big 
 step
 forward for functional style.
Then what do you mean by: &a.foo; // deprecated NOOP for compatibility.
a.foo is the same as &a.foo . The reason is that &a.foo is used in a lot of code today as it is the only way to perform such action. As a.foo is not an rvalue, it does not conflict. To achieve the ideally consistent behavior it should be disabled at some point.
Jan 24 2013
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 8:41 AM, deadalnix wrote:
[snip]
 Waiting for the shitstorm . . .
Nothing like that at least from me but I can plainly say this proposal has merit but will never get implemented. Andrei
Jan 24 2013
parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 01/24/2013 12:57 PM, Andrei Alexandrescu wrote:
 On 1/24/13 8:41 AM, deadalnix wrote:
 [snip]
 Waiting for the shitstorm . . .
Nothing like that at least from me but I can plainly say this proposal has merit but will never get implemented. Andrei
Wait, so Walter would be willing to ice property, but deprecating it in favor of this meritorious proposal will never happen? I, for one, would love to see good ideas go into the language that I like to use. I'd be willing to s/ property/ getter| setter/ all of my code for this. I wonder how hard it would be to write a tool that does the conversion and gets the disambiguation right in 90% of the cases...
Jan 25 2013
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/24/2013 5:41 AM, deadalnix wrote:
 For regular functions :
 1. funName is the function itself :
    void funName() {}
    static assert(is(typeof(funName) == void function())); // Pass.
    funName has no address, it is equivalent to enum function void() funName =
{};
    &funName become a NOOP and is deprecated, for compatibility reasons. It is
 not ambiguous as funName has no address anyway.
Dang, I hadn't thought of the typeof(funName) issue.
Jan 24 2013
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/24/2013 12:23 PM, Walter Bright wrote:
 On 1/24/2013 5:41 AM, deadalnix wrote:
 For regular functions :
 1. funName is the function itself :
    void funName() {}
    static assert(is(typeof(funName) == void function())); // Pass.
    funName has no address, it is equivalent to enum function void() funName =
{};
    &funName become a NOOP and is deprecated, for compatibility reasons. It is
 not ambiguous as funName has no address anyway.
Dang, I hadn't thought of the typeof(funName) issue.
On further thought, if funName is a property, then typeof(funName) should give the return type of the property, not the 'function' type.
Jan 24 2013
prev sibling parent reply "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 13:41:42 UTC, deadalnix wrote:
 For regular functions :
 1. funName is the function itself :
   void funName() {}
   static assert(is(typeof(funName) == void function())); // 
 Pass.
   funName has no address, it is equivalent to enum function 
 void() funName = {};
   &funName become a NOOP and is deprecated, for compatibility 
 reasons. It is not ambiguous as funName has no address anyway.
Agree with differentiation but why no address? For me funName looks like function pointer variable, why prohibiting to cast this to raw address? &funName is legacy, agree.
 2. funName() call the function.
And if funName is a getter returning delegate?
 3.  getter is an attribute. A function marked  getter is 
 automatically executed : () is added automatically :
      getter void funName() {}
     funName; // function get executed.
     funName(); // Error, void is not callable.
Agree, but property is enough. I ll insist below that ambiguous cases should be simply an error. And I'd also like to prohibit getters returning void ;)
 4.  getter can be used as UFCS.
     getter void funName(T t) {}
    T t; t.funName; // function gets executed.
    funName(t); // Error, funName require 1 argument, 0 given.
Fine by me, but error message is weird. Better "Error, funName is not usable with free-from syntax".
 5.  setter is an attribute. A setter method can *only* be used 
 in rhs of an expression. The assigned value is used as argument.
     setter void funName(T t) {}
    T t; funName = t; // function gets executed.
    funName(t); // Error, funName must be used in an assign 
 expression.
Disagree, it is inconsistent with getter. property ... funName(T t ... ) should always behave as t.funName property. It is unnecessary complication.
 6.  setter can as well be used as UFCS :
     getter void funName(T t, U u) {}
    T t; U u; t.funName = u; // function gets executed.
    t.funName(u); // Error, funName must be used in an assign 
 expression.
And this is exactly the syntax I'd like to see. Again, as void return should be disallowed for getters, no ambiguity here and same property suits just fine.
 7a. A function can be defined as both  setter and  getter, and 
 cumulate both behavior.
Feels like unnecessary complication. But if you want to, simply having both return type and 2 parameters is enough.
 7b.  property is deprecated and redefined as  setter *and* 
  getter for a transitional period.
;)
 8. method behave as functions :
     class A { void foo() {} }
     A a;
     static assert(is(typeof(a.foo) : void delegate())); // Pass.
     &a.foo; // deprecated NOOP for compatibility.
     a.foo(); // call a.foo
Agree;
 9. UFCS without () are delegate like construct :
 10. To allow chain of UFCS calls without () everywhere, an 
 opDispatch is defined in object.d
Very complicated for no real gain. Just prohibit function call without (), including (). Profit!
 Waiting for the shitstorm . . .
Welcome ;)
Jan 25 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 15:32:13 UTC, mist wrote:
 On Thursday, 24 January 2013 at 13:41:42 UTC, deadalnix wrote:
 For regular functions :
 1. funName is the function itself :
  void funName() {}
  static assert(is(typeof(funName) == void function())); // 
 Pass.
  funName has no address, it is equivalent to enum function 
 void() funName = {};
  &funName become a NOOP and is deprecated, for compatibility 
 reasons. It is not ambiguous as funName has no address anyway.
Agree with differentiation but why no address? For me funName looks like function pointer variable, why prohibiting to cast this to raw address? &funName is legacy, agree.
No adress because : - it would now be impossible to ensure transition using & as NOOP. - this address is useless anyway. That'd be a pointer to a pointer to instructions. I played with that using modified version of SDC, and this is clearly what does work best. If you really need an address, you can do : immutable f = function void() {};
 2. funName() call the function.
And if funName is a getter returning delegate?
funName is not a getter and don't return a delegate. How a getter behave is explained below. Mixing everything together is the perfect way to create a mess.
 3.  getter is an attribute. A function marked  getter is 
 automatically executed : () is added automatically :
     getter void funName() {}
    funName; // function get executed.
    funName(); // Error, void is not callable.
Agree, but property is enough. I ll insist below that ambiguous cases should be simply an error. And I'd also like to prohibit getters returning void ;)
You didn't addressed why property. Answer you gave to point 5 and 6 make me think you aren't aware of the ambiguities property causes with UFCS. Please note that : [1, 2].front and front = [1, 2] are semantically 100% equivalent. I do agree that a getter returning void is weird, but that wasn't really important here.
 4.  getter can be used as UFCS.
    getter void funName(T t) {}
   T t; t.funName; // function gets executed.
   funName(t); // Error, funName require 1 argument, 0 given.
Fine by me, but error message is weird. Better "Error, funName is not usable with free-from syntax".
The above code is rewritten ad funName()(t) . That is why you get that error message. The error message goes out before the compiler has even considered funName was used in a call expression. Your proposal may be an improvement for that very case, but isn't in general the error presented above.
 7a. A function can be defined as both  setter and  getter, and 
 cumulate both behavior.
Feels like unnecessary complication. But if you want to, simply having both return type and 2 parameters is enough.
7a is required for 7b to work. That is not complication, that is simplification.
 7b.  property is deprecated and redefined as  setter *and* 
  getter for a transitional period.
 9. UFCS without () are delegate like construct :
 10. To allow chain of UFCS calls without () everywhere, an 
 opDispatch is defined in object.d
Very complicated for no real gain. Just prohibit function call without (), including (). Profit!
Many people here disagree. I tend to be amongst thoses people. This specific case imply no ambiguity, and is similar to other simplification D already make like . dereferencing pointers.
Jan 25 2013
parent reply "mist" <none none.none> writes:
On Friday, 25 January 2013 at 15:57:16 UTC, deadalnix wrote:
 No adress because :
  - it would now be impossible to ensure transition using & as 
 NOOP.
  - this address is useless anyway. That'd be a pointer to a 
 pointer to instructions.
Need to think about it.
 funName is not a getter and don't return a delegate. How a 
 getter behave is explained below. Mixing everything together is 
 the perfect way to create a mess.
Well, but it is were good design vs mess of special cases really shines :) Anyway, in this statement by "function" you mean "non-property function", ye?
 You didn't addressed why  property. Answer you gave to point 5 
 and 6 make me think you aren't aware of the ambiguities 
  property causes with UFCS. Please note that :
 [1, 2].front and front = [1, 2] are semantically 100% 
 equivalent.
Not really as I see it. [1, 2].front // requires signature " property T front(int[])" front = [1, 2] // compile error arr.front = [1, 2] // requires signature " property void front(T, int[])"
 The above code is rewritten ad funName()(t) .
Ah, _now_ I am starting to get your proposal. And do not like it in that regard.
 Many people here disagree. I tend to be amongst thoses people. 
 This specific case imply no ambiguity, and is similar to other 
 simplification D already make like . dereferencing pointers.
Well, then it is probably best to focus on free-form property semantics and leave argument about optional parens and friends - there were enough of them in this topic ;) I'll push for optional ones to the end but hope at least for the solution where ambiguity is consistently resolved.
Jan 25 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 16:11:53 UTC, mist wrote:
 funName is not a getter and don't return a delegate. How a 
 getter behave is explained below. Mixing everything together 
 is the perfect way to create a mess.
Well, but it is were good design vs mess of special cases really shines :) Anyway, in this statement by "function" you mean "non-property function", ye?
That is one case where it matters.
 You didn't addressed why  property. Answer you gave to point 5 
 and 6 make me think you aren't aware of the ambiguities 
  property causes with UFCS. Please note that :
 [1, 2].front and front = [1, 2] are semantically 100% 
 equivalent.
Not really as I see it. [1, 2].front // requires signature " property T front(int[])" front = [1, 2] // compile error arr.front = [1, 2] // requires signature " property void front(T, int[])"
So you DO make a difference between setters and getters.
 The above code is rewritten ad funName()(t) .
Ah, _now_ I am starting to get your proposal. And do not like it in that regard.
funName(t) is valid if funName returns a delegate. The compiler shouldn't even try to interpret funName(...) as a call of funName.
Jan 25 2013
parent reply "mist" <none none.none> writes:
On Friday, 25 January 2013 at 16:29:40 UTC, deadalnix wrote:
 So you DO make a difference between setters and getters.
Yes, sure. But I do not need new keywords for that.
 funName(t) is valid if funName returns a delegate. The compiler 
 shouldn't even try to interpret funName(...) as a call of 
 funName.
Yes, I have finally understood how it is intended to work. I just do not like complexity with re-writing funName(t) as funName()(t) and hidden struct creation from function symbols. I cheer any compiling restrictions, but overall type system should be as transparent as possible for normal cases. Like brutal simplicity of my proposal better :) But it is an interesting approach, thank you for the insight.
Jan 25 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 16:47:56 UTC, mist wrote:
 On Friday, 25 January 2013 at 16:29:40 UTC, deadalnix wrote:
 So you DO make a difference between setters and getters.
Yes, sure. But I do not need new keywords for that.
Because you invalidate most legitimate use of a setter.
 funName(t) is valid if funName returns a delegate. The 
 compiler shouldn't even try to interpret funName(...) as a 
 call of funName.
Yes, I have finally understood how it is intended to work. I just do not like complexity with re-writing funName(t) as funName()(t) and hidden struct creation from function symbols. I cheer any compiling restrictions, but overall type system should be as transparent as possible for normal cases. Like brutal simplicity of my proposal better :)
A struct with a function pointer and data already exists in D. This is called a delegate.
 But it is an interesting approach, thank you for the insight.
Jan 25 2013
parent "mist" <none none.none> writes:
On Friday, 25 January 2013 at 16:53:43 UTC, deadalnix wrote:
 Because you invalidate most legitimate use of a setter.
Erm.. Whaaat? How this case is legitimate at all? Please elaborate. In example you define a property for some data type and then try to assign to this property without using any context. It is like calling class method and skipping "this". As I have mentioned in other thread, there are 2 contradictory approaches: either free-form property has semantics of global variable or it has semantics of data member of its first argument. Not both.
 A struct with a function pointer and data already exists in D. 
 This is called a delegate.
And additional hidden implementation complications differ it from all other function types. Rare special case for clearly defined situations. I like it that way. Leave function to be just like good old C function.
Jan 25 2013
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
No, god no. This would break code AGAIN and still not fix the 
problems, instead introducing new ones!

I think any property proposal that talks about parenthesis in the 
definition is wrong. With a good definition, the existing type 
system will handle the parenthesis.

 property int foo() { return 10; }

foo(); // the correct error is "type int is not callable"

This is the key point:

A property is NOT a function as far as user code is concerned. 
That's just an implementation detail.

As far as user code is concerned, a property IS its return value.


If you implement that, leaving all the other rules in the 
language exactly the same, we'll actually fix some problems 
without breaking the overwhelming bulk of existing code.


Fixing the rest of the problems is then about getting op*Assign 
to work right.



Functions not marked  property should NOT change AT ALL from what 
we have now. I am against removing the existing optional 
parenthesis rule, and I am against removing the  property 
decoration.

Fix it this time, don't break it in a different place.
Jan 24 2013
next sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Thursday, 24 January 2013 at 13:43:34 UTC, Adam D. Ruppe wrote:
 No, god no. This would break code AGAIN and still not fix the 
 problems, instead introducing new ones!

 I think any property proposal that talks about parenthesis in 
 the definition is wrong. With a good definition, the existing 
 type system will handle the parenthesis.

  property int foo() { return 10; }

 foo(); // the correct error is "type int is not callable"

 This is the key point:

 A property is NOT a function as far as user code is concerned. 
 That's just an implementation detail.

 As far as user code is concerned, a property IS its return 
 value.


 If you implement that, leaving all the other rules in the 
 language exactly the same, we'll actually fix some problems 
 without breaking the overwhelming bulk of existing code.


 Fixing the rest of the problems is then about getting op*Assign 
 to work right.



 Functions not marked  property should NOT change AT ALL from 
 what we have now. I am against removing the existing optional 
 parenthesis rule, and I am against removing the  property 
 decoration.

 Fix it this time, don't break it in a different place.
I wholeheartedly agree. David
Jan 24 2013
prev sibling next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 24 January 2013 at 13:43:34 UTC, Adam D. Ruppe wrote:
 Functions not marked  property should NOT change AT ALL from 
 what we have now. I am against removing the existing optional 
 parenthesis rule, and I am against removing the  property 
 decoration.
I'll be rude, but that is needed. The whole mess we have today is because of this kind of reasoning (note that I'm only talking about the quoted part, the rest of your post is very good). The process goes as follow. 1. Let's add this special case here, this allow for user X to drop few chars in his source file. 2. How, user Y discovered that this interact in a weird way with feature Z. Let's live with it forever/break code/add this little tweak to feature Z to make it work. 3. If break code isn't chosen, much latter, user K notice that bunch of function of phobos don't take into account some corner cases and go crazy due to the tweak above. Phobos is fixed with adding a big amount of complexity or stay broken as it would mess up too much code. All other libs are broken is that case. 4. Current situation.
Jan 24 2013
prev sibling next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 14:43:33 Adam D. Ruppe wrote:
 No, god no. This would break code AGAIN and still not fix the
 problems, instead introducing new ones!
 
 I think any property proposal that talks about parenthesis in the
 definition is wrong. With a good definition, the existing type
 system will handle the parenthesis.
 
  property int foo() { return 10; }
 
 foo(); // the correct error is "type int is not callable"
 
 This is the key point:
 
 A property is NOT a function as far as user code is concerned.
 That's just an implementation detail.
 
 As far as user code is concerned, a property IS its return value.
 
 
 If you implement that, leaving all the other rules in the
 language exactly the same, we'll actually fix some problems
 without breaking the overwhelming bulk of existing code.
 
 
 Fixing the rest of the problems is then about getting op*Assign
 to work right.
 
 
 
 Functions not marked  property should NOT change AT ALL from what
 we have now. I am against removing the existing optional
 parenthesis rule, and I am against removing the  property
 decoration.
 
 Fix it this time, don't break it in a different place.
Yes. I think that it's fairly clear that we need to do something like this. Getting rid of property is throwing out the baby with the bathwater. Not having it is a complete mess. And plenty of corner cases have been shown just in this thread which show how not having property causes problems, completely aside from the issue of whether you should be allowed to call functions without parens. Personally, I'd love strict property enforcement, but I think that it's clear at this point that that's not going to fly. However, a solution like this which is effectively weak property enforcement (parens illegal on property functions but optional for normal functions) fixes the worst technical problems caused by the lack of property, and this particular proposal seems like a solid way to go about it. - Jonathan M Davis
Jan 24 2013
parent reply =?UTF-8?B?U8O2bmtlIEx1ZHdpZw==?= <sludwig outerproduct.org> writes:
Am 24.01.2013 20:14, schrieb Jonathan M Davis:
 On Thursday, January 24, 2013 14:43:33 Adam D. Ruppe wrote:
 No, god no. This would break code AGAIN and still not fix the
 problems, instead introducing new ones!

 (...)
Yes. I think that it's fairly clear that we need to do something like this. Getting rid of property is throwing out the baby with the bathwater. Not having it is a complete mess. And plenty of corner cases have been shown just in this thread which show how not having property causes problems, completely aside from the issue of whether you should be allowed to call functions without parens. Personally, I'd love strict property enforcement, but I think that it's clear at this point that that's not going to fly. However, a solution like this which is effectively weak property enforcement (parens illegal on property functions but optional for normal functions) fixes the worst technical problems caused by the lack of property, and this particular proposal seems like a solid way to go about it. - Jonathan M Davis
I see it exactly the same way.
Jan 24 2013
parent "mist" <none none.none> writes:
One thing I am interested to hear from ones who think allowing 
no-parens calls is fine is the following snippet:

http://dpaste.1azy.net/cd2f759e

------------------------------------------------------------
import std.stdio;

alias Delegate1 = int delegate();
alias Delegate2 = Delegate1 delegate();

Delegate2 func()
{
	writeln("Function");
	return (){
		writeln("First delegate");
		return (){
			writeln("Second delegate");
			return 42;
		};
	};
}

int call(alias func)()
{
	return func;
}

void main()
{
	writeln("Case 1");
	func;
	writeln("Case 2");
	func();
	writeln("Case 3");
	func()();
	writeln("Case 4");
	auto tmp = func();
	// tmp; // Error: var has no effect in expression (tmp)
}
------------------------------------------------------------

Upon any design choice questions should asked:
1) How this should behave to be consistent?
2) Should this error be an error?
3) How much special casing are you ready to throw in?

Also I really like an addition with prohibiting to use  property 
functions _with_ parens. Add this to prohibiting no-parens calls 
for normal ones and you will get my ideal solution, strict and 
clear.

And I still don't see why it won't fly. Yes, it will break user 
code. No, this is not an issue. At this point it is clear some 
design mistakes need to be corrected without stockpiling 
workarounds and one of major goals for new release process was to 
allow breaking changes with least possible user inconvenience. If 
it is not the case, then new release process has failed as much 
as  property.
Jan 24 2013
prev sibling parent reply "Alvaro" <alvaroSPAMALOTsegura gmail.com> writes:
I agree with Adam's view and I really think  property is a good 
thing.

APIs have to specify their semantics and clearly distinguish 
properties from functions, which may be implemented similarly but 
*mean* different things. Basically a property is a *thing* or a 
characteristic, normally a noun, whereas a property is an action, 
normally a verb.

As a special case, a property can be a delegate or function, and 
calling it with () would apply the parens to the delegate (which 
the user is explicitly calling), but not to the property.

Properties as they are can also be used to emulate "indexed 
properties", as in other languages. If a property's type is a 
struct that implements [] and []= then we can do:

image.pixels[x,y] = Rgb(255,0,0);

And yes, I think properties should always be called ["used" I 
would rather say] without parens, and functions always be called 


But anyway as I don't develop the compiler, I speak from a 
distance, and I'm not aware of the implementation complications 
there may be...



On Thursday, 24 January 2013 at 13:43:34 UTC, Adam D. Ruppe wrote:
 No, god no. This would break code AGAIN and still not fix the 
 problems, instead introducing new ones!

 I think any property proposal that talks about parenthesis in 
 the definition is wrong. With a good definition, the existing 
 type system will handle the parenthesis.

  property int foo() { return 10; }

 foo(); // the correct error is "type int is not callable"

 This is the key point:

 A property is NOT a function as far as user code is concerned. 
 That's just an implementation detail.

 As far as user code is concerned, a property IS its return 
 value.


 If you implement that, leaving all the other rules in the 
 language exactly the same, we'll actually fix some problems 
 without breaking the overwhelming bulk of existing code.


 Fixing the rest of the problems is then about getting op*Assign 
 to work right.



 Functions not marked  property should NOT change AT ALL from 
 what we have now. I am against removing the existing optional 
 parenthesis rule, and I am against removing the  property 
 decoration.

 Fix it this time, don't break it in a different place.
Jan 29 2013
parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
29-Jan-2013 17:27, Alvaro пишет:
 I agree with Adam's view and I really think  property is a good thing.

 APIs have to specify their semantics and clearly distinguish properties
 from functions, which may be implemented similarly but *mean* different
 things. Basically a property is a *thing* or a characteristic, normally
 a noun, whereas a property is an action, normally a verb.
A typo pretty much ruined otherwise good point :) -- Dmitry Olshansky
Jan 29 2013
prev sibling next sibling parent Iain Buclaw <ibuclaw ubuntu.com> writes:
On 24 January 2013 13:40, d coder <dlang.coder gmail.com> wrote:

 As much as I want to agree, I also feel this comes as too little, too late
 to come to this conclusion now.
+1 And therefor we should take out property ASAP :-)
Not going to happen. Effectively what is being proposed here is that we are going to be stuck with the current state of property for the next 7 years, and no bugs will be fixed on it as its on deprecation. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Jan 24 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/24/13, Walter Bright <newshound2 digitalmars.com> wrote:
 2. the:
     f = g
 rewrite to:
     f(g)
 only happens if f is a function that only has overloads for () and (one
 argument). No variadics.
This is going to be a problem in API refactoring. if "f" used to be a field but is now turned into a (potentially) expensive function call, the user will have no idea. Anyway we'll lose track of everything in this thread just like in all the other threads, so I suggest that we: - Create a new branch in DMD which will only be used to work on property freely - Add all test-cases which are affected by this feature - Work on this branch for some time until we get a solid implementation - Discuss property enforcement on a casis-by-casis base in the forums, rather than discussing it wholesome. Special rules should be ok as long as we properly define them and document them. And later we'll merge this into master and add some solid bit of documentation to go with it. Whatever we decide it should be a result of focused work, and not executive decisions due to perceived maintenance costs. We haven't really had a focused effort on properly implementing property, we've had sporadic pull requests instead.
Jan 24 2013
prev sibling next sibling parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 01/24/2013 03:34 AM, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return
 value taking (), the () go on the return value.

 2. the:
 f = g
 rewrite to:
 f(g)
 only happens if f is a function that only has overloads for () and (one
 argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
I somehow feel like someone read my article from a couple years ago (http://www.prowiki.org/wiki4d/wiki.cgi?DocComments/Property) and you implemented the less important part and consciously ignored the more important part. The section titled "semantic rewriting of properties" is the important one. Do that. It removes a source of bugs and gives intuitive behavior to our property-functions (ex: prop++; works in general). property is considerably less meaningful: take it or leave it, I certainly won't care. It's a bikeshed full of personal opinions. If we had godly hindsight, then we would have made fields non-addressable by default so that people get safe design behavior by default: non-addressable fields can be turned into properties (assuming property rewriting exists) without breaking API, which creates closure for the whole concept. There would, of course, have to be a way to make it possible to explicitly mark variables as addressable in cases where you need to make pointers to them. That non-addressability semantic might have helped reference-counting too. The mistake's made though; we'll probably just have to take that one in the gut.
Jan 24 2013
prev sibling next sibling parent "Robert Jacques" <rjacque2 live.johnshopkins.edu> writes:
On Thu, 24 Jan 2013 02:34:42 -0600, Walter Bright  
<newshound2 digitalmars.com> wrote:

 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return  
 value taking (), the () go on the return value.

 2. the:
     f = g
 rewrite to:
     f(g)
 only happens if f is a function that only has overloads for () and (one  
 argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
vote++
Jan 24 2013
prev sibling next sibling parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright  
<newshound2 digitalmars.com> wrote:

 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return  
 value taking (), the () go on the return value.

 2. the:
     f = g
 rewrite to:
     f(g)
 only happens if f is a function that only has overloads for () and (one  
 argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
clear guidelines and syntax enforcement. I think it's a case of D trying to be TO flexible. Function Calls have Parens. Period. Property Calls do NOT have Parens. Period. It's quick, clean, and easy to parse. for a property consumer the rules are trivial. That's the whole point of properties. In D: Optional parens for everyone! Parsing nightmare for all! I also want to reiterate a point I've seen on this thread. Parens on properties is a very C programmer thing. What is the net effect of forcing properties to have parens? I have to type two more shift-characters to satisfy the compiler because we couldn't be arsed to get the current implementation right. Ehm. That's not how you make a case to newbie... Banish that idea, permanently! Let's consider what a property really is. It's a data encapsulation tool. They allow us to expose object internal data in a safe way. Nuking the idea is a step backwards. While I get that C++ users would immediately be comfortable with the ambiguities of not having a distinct property mechanism, you're going to correct functions the compiler will automagically figure out it's a property. And consider that in not all cases do I want int GetMyData() { } to be callable without parens as you are suggesting here. Although I provide no demo implementation, imagine that this is a non-trivial function that it runs against guidelines.) Now some innocent programmer calls my function as a property not realizing what is really going on and BOOM! He just wrote himself a bug. And yes, i've written code like this before. And before the academics pile on me for it. My job is to write code that gets the job done, being academically correct is for when all other requirements have been satisfied. In the real world, we don't have the luxury of spending a day to make our code ideal. One of the principles of encapsulated data is that accessing the data has zero side-effects. This change makes what is happening ambiguous to the user of the property/function. Ambiguity is bad and will NOT solve our problems. My vote: Fix property. Dropping it will create even more problems and not likely fix many of the current ones. You never solve problems by making the code more ambiguous. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
parent reply "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 20:20:42 UTC, Adam Wilson wrote:
 Let's consider what a property really is. It's a data 
 encapsulation tool. They allow us to expose object internal 
 data in a safe way. Nuking the idea is a step backwards.
This, this and this again. Reading this thread I sometimes get the feeling that part of programmers treat property as a nice way to save 2 extra symbols. Or probably to play with verb/noun meaning. It has different goals from both of those.
Jan 24 2013
parent reply "eles" <eles eles.com> writes:
On Thursday, 24 January 2013 at 20:26:50 UTC, mist wrote:
 On Thursday, 24 January 2013 at 20:20:42 UTC, Adam Wilson wrote:
I think the widest spread use case of a property is: you start with a variable as memeber of a class, you write a lot of assignment code, then you decide that you need to do some more extensive processing instead of simple assignment, and all that without breaking existing code. so, you transform the variable into a property. of course, it could happen the other way around (converting a function into a property/variable).
Jan 24 2013
parent reply "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 20:44:33 UTC, eles wrote:
 On Thursday, 24 January 2013 at 20:26:50 UTC, mist wrote:
 On Thursday, 24 January 2013 at 20:20:42 UTC, Adam Wilson 
 wrote:
I think the widest spread use case of a property is: you start with a variable as memeber of a class, you write a lot of assignment code, then you decide that you need to do some more extensive processing instead of simple assignment, and all that without breaking existing code. so, you transform the variable into a property. of course, it could happen the other way around (converting a function into a property/variable).
It is a wrong use case for a property. Necessity to change data assignment/access to call of function with side-effect is design error and should be fixed with programmers experience, not property hacks.
Jan 24 2013
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 21:47:38 mist wrote:
 On Thursday, 24 January 2013 at 20:44:33 UTC, eles wrote:
 On Thursday, 24 January 2013 at 20:26:50 UTC, mist wrote:
 On Thursday, 24 January 2013 at 20:20:42 UTC, Adam Wilson
 wrote:
I think the widest spread use case of a property is: you start with a variable as memeber of a class, you write a lot of assignment code, then you decide that you need to do some more extensive processing instead of simple assignment, and all that without breaking existing code. so, you transform the variable into a property. of course, it could happen the other way around (converting a function into a property/variable).
It is a wrong use case for a property. Necessity to change data assignment/access to call of function with side-effect is design error and should be fixed with programmers experience, not property hacks.
Being able to swap out a public variable with a function without having to change any code using it is arguably the primary reasons that property functions exist in the first place. Yes, making it so that the property function has a _side-effect_ is a bug, but replacing variables with property functions is not. A classic example of why it's useful is when you refactor a class such that a public variable becomes a calculated value such that it doesn't make sense to have a variable for it anymore. Instead of breaking all of the code that uses the variable by changing it a function, you change it to be a property function, and all of the code which used it continues to compile and work just fine. D's properties need some work before that will really work properly (e.g. http://d.puremagic.com/issues/show_bug.cgi?id=8006 ), but it works just fine - Jonathan M Davis
Jan 24 2013
next sibling parent "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 13:00:35 -0800, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Thursday, January 24, 2013 21:47:38 mist wrote:
 On Thursday, 24 January 2013 at 20:44:33 UTC, eles wrote:
 On Thursday, 24 January 2013 at 20:26:50 UTC, mist wrote:
 On Thursday, 24 January 2013 at 20:20:42 UTC, Adam Wilson
 wrote:
I think the widest spread use case of a property is: you start with a variable as memeber of a class, you write a lot of assignment code, then you decide that you need to do some more extensive processing instead of simple assignment, and all that without breaking existing code. so, you transform the variable into a property. of course, it could happen the other way around (converting a function into a property/variable).
It is a wrong use case for a property. Necessity to change data assignment/access to call of function with side-effect is design error and should be fixed with programmers experience, not property hacks.
Being able to swap out a public variable with a function without having to change any code using it is arguably the primary reasons that property functions exist in the first place. Yes, making it so that the property function has a _side-effect_ is a bug, but replacing variables with property functions is not. A classic example of why it's useful is when you refactor a class such that a public variable becomes a calculated value such that it doesn't make sense to have a variable for it anymore. Instead of breaking all of the code that uses the variable by changing it a function, you change it to be a property function, and all of the code which used it continues to compile and work just fine. D's properties need some work before that will really work properly (e.g. http://d.puremagic.com/issues/show_bug.cgi?id=8006 ), but it works just fine - Jonathan M Davis
++ to Mr. Davis! This is much more concise way of stating what I was trying to say. And it is an argument that should NOT be lightly dismissed, it is a very real, very common problem. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
prev sibling parent reply "mist" <none none.none> writes:
On Thursday, 24 January 2013 at 21:00:49 UTC, Jonathan M Davis 
wrote:
 Being able to swap out a public variable with a function 
 without having to
 change any code using it is arguably the primary reasons that 
 property
 functions exist in the first place. ...
Yes, but not just any function. Side-effect free function that controls access to data. And Adam suggested it is fine to use properties to add side-effects to data assignments which is drastically different. I agree with all your words so it is probably just misunderstanding.
Jan 24 2013
next sibling parent "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 13:14:00 -0800, mist <none none.none> wrote:

 On Thursday, 24 January 2013 at 21:00:49 UTC, Jonathan M Davis wrote:
 Being able to swap out a public variable with a function without having  
 to
 change any code using it is arguably the primary reasons that property
 functions exist in the first place. ...
Yes, but not just any function. Side-effect free function that controls access to data. And Adam suggested it is fine to use properties to add side-effects to data assignments which is drastically different. I agree with all your words so it is probably just misunderstanding.
side-effects, but that it runs counter to guidelines. I personally do NOT write properties with side-effects. I was attempting to illustrate in a [much to] concise way why optional parens are bad... -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
prev sibling parent reply "mist" <none none.none> writes:
%s/Adam/eles/g
Jan 24 2013
parent "eles" <eles eles.com> writes:
"more extensive processing" does not necessarily involve side 
effects.

beside that, as long as those side effects only affects the 
instance owning that property, nothing is wrong about it.

changing a normal member variable could also result in changing 
the instance's state and behaviour (think that the variable is a 
flag).
Jan 24 2013
prev sibling next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 00:34:42 Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.
 
 Perhaps we should revert to a simple set of rules.
 
 1. Empty parens are optional. If there is an ambiguity with the return value
 taking (), the () go on the return value.
 
 2. the:
 f = g
 rewrite to:
 f(g)
 only happens if f is a function that only has overloads for () and (one
 argument). No variadics.
 
 3. Parens are required for calling delegates or function pointers.
 
 4. No more  property.
Another issue to consider is enhancements such as http://d.puremagic.com/issues/show_bug.cgi?id=8006 As a property function is supposed to be an abstraction for a variable, and you really should be able to swap out property functions and public variables without breaking code, things like foo.prop += 5; and ++foo.prop; should work. Unfortunately, D's current property implementation is poor enough that that code doesn't currently, but that can be fixed in a backwards- compatible-manner. But implementing something like that becomes more problematic without explicit properties (potentially even dangerous, depending on what ends up happening with those sorts of expressions with non- property functions which are called without parens). Maybe it could be done, but it seems to me that it's the sort of thing that should be controlled. We don't want lots of voodoo happening with functions called without parens, as we risk getting some nasty bugs when using functions that weren't really meant to be properties. But we _do_ want some of that voodoo with functions that are designed to be properties. So, I really think that we need to have explicit properties, even if we allow paran-less function calls in some other cases. with properties from the get-go. - Jonathan M Davis
Jan 24 2013
parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 01/24/2013 03:45 PM, Jonathan M Davis wrote:
 On Thursday, January 24, 2013 00:34:42 Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return value
 taking (), the () go on the return value.

 2. the:
 f = g
 rewrite to:
 f(g)
 only happens if f is a function that only has overloads for () and (one
 argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
Another issue to consider is enhancements such as http://d.puremagic.com/issues/show_bug.cgi?id=8006 As a property function is supposed to be an abstraction for a variable, and you really should be able to swap out property functions and public variables without breaking code, things like foo.prop += 5; and ++foo.prop; should work. Unfortunately, D's current property implementation is poor enough that that code doesn't currently, but that can be fixed in a backwards- compatible-manner.
I think what you want is semantic property rewriting. Please see this: http://www.prowiki.org/wiki4d/wiki.cgi?DocComments/Property#Semanticrewritingofproperties
 But implementing something like that becomes more problematic without explicit
 properties (potentially even dangerous, depending on what ends up happening
 with those sorts of expressions with non- property functions which are called
 without parens). Maybe it could be done, but it seems to me that it's the sort
 of thing that should be controlled. We don't want lots of voodoo happening
 with functions called without parens, as we risk getting some nasty bugs when
 using functions that weren't really meant to be properties. But we _do_ want
 some of that voodoo with functions that are designed to be properties.

 So, I really think that we need to have explicit properties, even if we allow
 paran-less function calls in some other cases.


 with properties from the get-go.

 - Jonathan M Davis
Jan 24 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/24/13, Walter Bright <newshound2 digitalmars.com> wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.
It is super-ironic that you want to simply pull-out and destroy a feature because it wasn't properly defined or implemented, yet you single-handedly introduced UDAs into the language with its own syntax without any prior approval of the community. Will we be making a "UDAs - take it behind the woodshed and shoot it?" thread a year from now?
Jan 24 2013
prev sibling next sibling parent reply "Nathan M. Swan" <nathanmswan gmail.com> writes:
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns 
 somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the 
 return value taking (), the () go on the return value.

 2. the:
    f = g
 rewrite to:
    f(g)
 only happens if f is a function that only has overloads for () 
 and (one argument). No variadics.

 3. Parens are required for calling delegates or function 
 pointers.

 4. No more  property.
What about code that's always ignored property? int delegate() _del; int delegate() getDelegate() { return _del; } auto del = getDelegate(); // does _del get called? Just a thought, NMS
Jan 24 2013
next sibling parent Sean Kelly <sean invisibleduck.org> writes:
On Jan 24, 2013, at 1:40 PM, Nathan M. Swan <nathanmswan gmail.com> =
wrote:

 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns =
somewhere.
=20
 Perhaps we should revert to a simple set of rules.
=20
 1. Empty parens are optional. If there is an ambiguity with the =
return value taking (), the () go on the return value.
=20
 2. the:
   f =3D g
 rewrite to:
   f(g)
 only happens if f is a function that only has overloads for () and =
(one argument). No variadics.
=20
 3. Parens are required for calling delegates or function pointers.
=20
 4. No more  property.
=20 What about code that's always ignored property? =20 =20 int delegate() _del; =20 int delegate() getDelegate() { return _del; } =20 auto del =3D getDelegate(); // does _del get called?
I think a clarification of rule 1 is that parens will be = right-associative. So in your example, _del would be called.=
Jan 24 2013
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 13:48:53 Sean Kelly wrote:
 On Jan 24, 2013, at 1:40 PM, Nathan M. Swan <nathanmswan gmail.com> wrote:
 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.
 
 Perhaps we should revert to a simple set of rules.
 
 1. Empty parens are optional. If there is an ambiguity with the return
 value taking (), the () go on the return value.>> 
 2. the:
 f = g
 
 rewrite to:
 f(g)
 
 only happens if f is a function that only has overloads for () and (one
 argument). No variadics.
 
 3. Parens are required for calling delegates or function pointers.
 
 4. No more  property.
What about code that's always ignored property? int delegate() _del; int delegate() getDelegate() { return _del; } auto del = getDelegate(); // does _del get called?
I think a clarification of rule 1 is that parens will be right-associative. So in your example, _del would be called.
I'd argue for simply making it so that the parens are required when a function returns something which is callable. So, getDelegate would be illegal, getDelegate() would return the delegate, and getDelegate()() would call the delegate. - Jonathan M Davis
Jan 24 2013
prev sibling next sibling parent reply Robert <jfanatiker gmx.at> writes:
Apart from +=, ++, what breaks compatibility of fields and properties,
is that you can't take the address of a property, but of a field (as
already mentioned). To increase compatibility and in order to avoid
breaking peoples' code, when a field is changed to a property, maybe,
simply offer the possibility to declare fields to be a property too,
with  property. And make it so that the access to such a field behaves
exactly the same as to a property: No address taking, and as long as
properties don't support ++, +=, ... maybe even forbid those.

Example:

 property int a;

would be completely equivalent to:

int a_;

 property int a() {
return a_;
}
 property int a(int new_a) {
 a_=new_a;
 return a_;
}

I think this would suffice to make the property concept really sound and
working in practice.

If, this is considered a good thing, I could create yet another property
DIP.

Another thing I am wondering, will this still be possible:

void myProperty(int a)  property {}

void function(int) dg=&myProperty;

Or in other words, will taking the address of a property method still be
possible? I think it would be quite sensible and useful (for e.g.
std.signals), taking the address of a transient return value does not
make any sense anyway, so no ambiguity here. On the other hand it would
break compatibility with fields again. So if we also want to make sure
the way back (from property methods to field) works, disallowing taking
the address might be the way to go for a finally proper implementation. 



Best regards,

Robert
Jan 24 2013
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 24 January 2013 at 22:27:02 UTC, Robert wrote:
  property int a;

 would be completely equivalent to: <snip>
Not bad.
 Another thing I am wondering, will this still be possible:

 void myProperty(int a)  property {}

 void function(int) dg=&myProperty;
If I get things my way, no. I'd rewrite that, internally, into &(myProperty()), and then, (unless it returns ref), you'd get an error about can't take address of an rvalue. There'd be no way, under my preference, to treat a property like a function at all.
 I think it would be quite sensible and useful
Indeed, but there's an easy alternative too that works with both kinds of data, properties and regular: wrapping it in an function at the usage site, e.g. "(a) => myProp = a;"
Jan 24 2013
parent Robert <jfanatiker gmx.at> writes:
Yeah, I thought of that and the compiler can optimize it away if not
needed. So this would be fine, but see my second, improved proposal.

On Thu, 2013-01-24 at 23:37 +0100, Adam D. Ruppe wrote:
 Indeed, but there's an easy alternative too that works with both 
 kinds of data, properties and regular: wrapping it in an function 
 at the usage site, e.g. "(a) => myProp = a;"
Jan 24 2013
prev sibling next sibling parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 14:26:50 -0800, Robert <jfanatiker gmx.at> wrote:

 Apart from +=, ++, what breaks compatibility of fields and properties,
 is that you can't take the address of a property, but of a field (as
 already mentioned). To increase compatibility and in order to avoid
 breaking peoples' code, when a field is changed to a property, maybe,
 simply offer the possibility to declare fields to be a property too,
 with  property. And make it so that the access to such a field behaves
 exactly the same as to a property: No address taking, and as long as
 properties don't support ++, +=, ... maybe even forbid those.

 Example:

  property int a;

 would be completely equivalent to:

 int a_;

  property int a() {
 return a_;
 }
  property int a(int new_a) {
  a_=new_a;
  return a_;
 }

 I think this would suffice to make the property concept really sound and
 working in practice.

 If, this is considered a good thing, I could create yet another property
 DIP.

 Another thing I am wondering, will this still be possible:

 void myProperty(int a)  property {}

 void function(int) dg=&myProperty;

 Or in other words, will taking the address of a property method still be
 possible? I think it would be quite sensible and useful (for e.g.
 std.signals), taking the address of a transient return value does not
 make any sense anyway, so no ambiguity here. On the other hand it would
 break compatibility with fields again. So if we also want to make sure
 the way back (from property methods to field) works, disallowing taking
 the address might be the way to go for a finally proper implementation.



 Best regards,

 Robert
Consider: property int Count { get; set; } A read-write integer property with an automatically implemented getter and setter functions in IL. property int Count { get; } A read-only integer property with an automatically implemented getter function. property int Count { set; } A write-only integer property with an automatically implemented setter function. This is rarely used, but I have seen it. the user code. The getter/setter then work against this field. The one problem with your example is that you haven't defined a way to -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-24 23:41, Adam Wilson wrote:

 The one problem with your example is that you haven't defined a way to

property(get, set) int a; property(get) int b; property(set) int c; property int d; // same as "a" -- /Jacob Carlborg
Jan 25 2013
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Fri, 25 Jan 2013 05:00:32 -0800, Jacob Carlborg <doob me.com> wrote:

 On 2013-01-24 23:41, Adam Wilson wrote:

 The one problem with your example is that you haven't defined a way to

property(get, set) int a; property(get) int b; property(set) int c; property int d; // same as "a"
This, for the love of all that is good in the world, a million times this! -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 25 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-01-25 18:12, Adam Wilson wrote:

  property(get, set) int a;
  property(get) int b;
  property(set) int c;
  property int d; // same as "a"
This, for the love of all that is good in the world, a million times this!
I think this syntax feels quite obvious. -- /Jacob Carlborg
Jan 25 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-01-24 23:26, Robert wrote:
 Apart from +=, ++, what breaks compatibility of fields and properties,
 is that you can't take the address of a property, but of a field (as
 already mentioned). To increase compatibility and in order to avoid
 breaking peoples' code, when a field is changed to a property, maybe,
 simply offer the possibility to declare fields to be a property too,
 with  property. And make it so that the access to such a field behaves
 exactly the same as to a property: No address taking, and as long as
 properties don't support ++, +=, ... maybe even forbid those.

 Example:

  property int a;

 would be completely equivalent to:

 int a_;

  property int a() {
 return a_;
 }
  property int a(int new_a) {
   a_=new_a;
   return a_;
 }
I really like this. Although this is not really what the rest of the thread is about can could perhaps be introduced separately. What I like about this is that I get a virtual property and doesn't have to write the boiler plate code by hand.
 I think this would suffice to make the property concept really sound and
 working in practice.

 If, this is considered a good thing, I could create yet another property
 DIP.

 Another thing I am wondering, will this still be possible:

 void myProperty(int a)  property {}

 void function(int) dg=&myProperty;

 Or in other words, will taking the address of a property method still be
 possible? I think it would be quite sensible and useful (for e.g.
 std.signals), taking the address of a transient return value does not
 make any sense anyway, so no ambiguity here. On the other hand it would
 break compatibility with fields again. So if we also want to make sure
 the way back (from property methods to field) works, disallowing taking
 the address might be the way to go for a finally proper implementation.


Scala solves the first one by always implementing public instance variables as virtual functions. -- /Jacob Carlborg
Jan 25 2013
prev sibling next sibling parent reply Robert <jfanatiker gmx.at> writes:
Proper property design:
 
  property int a;
 
gets actually lowered by the compiler to:
 
 int a_;
 
  property int a() {
 return a_;
 }
  property int a(int new_a) {
  a_=new_a;
  return a_;
 }
 
-> field property, and get/set property are actually the same thing. -> It is guaranteed that they behave the same way and can always be exchanged. -> Taking the address of the getter/setter also always works, enabling things like connecting the setter to a signal for example. I don't know about you guys, but I love this. It is just perfect. What do I miss? Best regards, Robert
Jan 24 2013
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 14:47:44 -0800, Robert <jfanatiker gmx.at> wrote:

 Proper property design:
  property int a;
gets actually lowered by the compiler to:
 int a_;

  property int a() {
 return a_;
 }
  property int a(int new_a) {
  a_=new_a;
  return a_;
 }
-> field property, and get/set property are actually the same thing. -> It is guaranteed that they behave the same way and can always be exchanged. -> Taking the address of the getter/setter also always works, enabling things like connecting the setter to a signal for example. I don't know about you guys, but I love this. It is just perfect. What do I miss? Best regards, Robert
The syntax provides no way to define read-only or write-only properties. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
next sibling parent Robert <jfanatiker gmx.at> writes:
There is, just don't do:

 property int a;

but

int a_;

 property int a() { return a_}


but adding syntactic sugar later on, if really desired, should not be
too hard.




On Thu, 2013-01-24 at 14:48 -0800, Adam Wilson wrote:
 The syntax provides no way to define read-only or write-only
 properties.  

Jan 24 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-01-24 23:48, Adam Wilson wrote:

 The syntax provides no way to define read-only or write-only properties.

property(get, set) int a; property(get) int b; property(set) int c; property int d; // same as "a" -- /Jacob Carlborg
Jan 25 2013
prev sibling next sibling parent "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright  
<newshound2 digitalmars.com> wrote:

 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return  
 value taking (), the () go on the return value.

 2. the:
     f = g
 rewrite to:
     f(g)
 only happens if f is a function that only has overloads for () and (one  
 argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
I want to point out another usage of properties that invades my work every day. Consider: public partial class CustomerXAML : DependencyObject { public Guid ID { get { return (Guid)GetValue(IDProperty); } set { SetValue(IDProperty, value); } } public static readonly DependencyProperty IDProperty = DependencyProperty.Register("ID", typeof(Guid), typeof(CustomerXAML), null); } Where: public class DependencyObject { public object GetValue(DependencyProperty prop); public void SetValue(DependencyProperty prop, object value); } What does this code say? I am dealing with data or calling a function? Well to those of you not familiar with WPF/XAML's Dependency pattern let me explain. You're doing both. You see XAML uses something that for lack of a better term I will call a "sparse memory model". Another way to describe it is to say that the DependencyObject stores ONLY the values that have been changed from the default value. They had to do this because their object model is ridiculous and they needed over a gigabyte of RAM just to instantiate all the objects required to draw an empty window. They discovered that most of the values in the object didn't change from the defaults. However, the changes had to be stored in a Dictionary (think Map) for speed, that's what all the typeof's in the Register function are for. And storing/retrieving those directly from the Map would have lead to all sorts of problems. So GetValue/SetValue handle that for you and allows them to do much more, like databinding and update callbacks. My point is this. This does not violate encapsulation, we ARE working with just DATA, but we want to hide the implementation details of HOW we are working with said data, and in this case we CANNOT use a simple backing field. From a user perspective CustomerXAML.ID is JUST data FIELD. But behind the scenes it's a bit more complicated than that. THAT is the power of properties. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
prev sibling next sibling parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright  
<newshound2 digitalmars.com> wrote:

 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return  
 value taking (), the () go on the return value.

 2. the:
     f = g
 rewrite to:
     f(g)
 only happens if f is a function that only has overloads for () and (one  
 argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
I just worked through this with Alexander Bothe (of Mono-D fame). Here is public Action temp { get; set; } public Action Event { get { return temp; } } t.Event; //returns the delegate t.Event(); //calls the delegate. Simple, clean, clear, concise. No problems with optional parens. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 6:52 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright
 <newshound2 digitalmars.com> wrote:

 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return
 value taking (), the () go on the return value.

 2. the:
 f = g
 rewrite to:
 f(g)
 only happens if f is a function that only has overloads for () and
 (one argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
I just worked through this with Alexander Bothe (of Mono-D fame). Here public Action temp { get; set; } public Action Event { get { return temp; } } t.Event; //returns the delegate t.Event(); //calls the delegate. Simple, clean, clear, concise. No problems with optional parens.
This looks essentially the same as Walter's proposal. Andrei
Jan 24 2013
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/25/2013 01:12 AM, Andrei Alexandrescu wrote:
 On 1/24/13 6:52 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright
 <newshound2 digitalmars.com> wrote:

 This has turned into a monster. We've taken 2 or 3 wrong turns
 somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return
 value taking (), the () go on the return value.

 2. the:
 f = g
 rewrite to:
 f(g)
 only happens if f is a function that only has overloads for () and
 (one argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
I just worked through this with Alexander Bothe (of Mono-D fame). Here public Action temp { get; set; } public Action Event { get { return temp; } } t.Event; //returns the delegate t.Event(); //calls the delegate. Simple, clean, clear, concise. No problems with optional parens.
This looks essentially the same as Walter's proposal. Andrei
Not at all. Walter's proposal just chooses the other option when stuff is "ambiguous" and adds a hideous special rule in case the empty argument list was obtained from an empty sequence.
Jan 24 2013
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 16:29:24 -0800, Timon Gehr <timon.gehr gmx.ch> wrote:

 On 01/25/2013 01:12 AM, Andrei Alexandrescu wrote:
 On 1/24/13 6:52 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright
 <newshound2 digitalmars.com> wrote:

 This has turned into a monster. We've taken 2 or 3 wrong turns
 somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return
 value taking (), the () go on the return value.

 2. the:
 f = g
 rewrite to:
 f(g)
 only happens if f is a function that only has overloads for () and
 (one argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
I just worked through this with Alexander Bothe (of Mono-D fame). Here public Action temp { get; set; } public Action Event { get { return temp; } } t.Event; //returns the delegate t.Event(); //calls the delegate. Simple, clean, clear, concise. No problems with optional parens.
This looks essentially the same as Walter's proposal. Andrei
Not at all. Walter's proposal just chooses the other option when stuff is "ambiguous" and adds a hideous special rule in case the empty argument list was obtained from an empty sequence.
Basically this. I was writing a longer post that essentially said this. Also non-logical special case rules like this make the language harder to learn, therefore harder to evangelize. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 7:36 PM, Adam Wilson wrote:
 Also non-logical special case rules like this make the language harder
 to learn, therefore harder to evangelize.
Definitely. But it shouldn't be forgotten that syntactic warts are also a liability. Andrei
Jan 24 2013
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 18:00:06 -0800, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 7:36 PM, Adam Wilson wrote:
 Also non-logical special case rules like this make the language harder
 to learn, therefore harder to evangelize.
Definitely. But it shouldn't be forgotten that syntactic warts are also a liability. Andrei
I would argue that given how common they already are, cost of the wart is far smaller than the benefit of not having the unique-to-D special case that makes the language that much harder to learn. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 9:54 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 18:00:06 -0800, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 7:36 PM, Adam Wilson wrote:
 Also non-logical special case rules like this make the language harder
 to learn, therefore harder to evangelize.
Definitely. But it shouldn't be forgotten that syntactic warts are also a liability. Andrei
I would argue that given how common they already are, cost of the wart is far smaller than the benefit of not having the unique-to-D special case that makes the language that much harder to learn.
Again, the question needs asking: is it a given that we need to allow optional parentheses? Otherwise we'll keep on rehashing this over and over again. Andrei
Jan 24 2013
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, January 24, 2013 22:52:36 Andrei Alexandrescu wrote:
 Again, the question needs asking: is it a given that we need to allow
 optional parentheses? Otherwise we'll keep on rehashing this over and
 over again.
I hate optional parentheses with a passion, but I think that it's quite clear that too many people want them (including many who want property) and that too much code will break if we make the change. I think that we can reach a consensus on how property should function, but we'll never get a consensus that optional parentheses should be done away with. So, yes. I think that we can move forward with the assumption that optional parens are here to stay (much as I don't personally like that). - Jonathan M Davis
Jan 24 2013
next sibling parent reply "eles" <eles eles.com> writes:
On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis 
wrote:
 On Thursday, January 24, 2013 22:52:36 Andrei Alexandrescu 
 wrote:
 I hate optional parentheses with a passion, but I think that 
 it's quite clear
 that too many people want them (including many who want 
  property) and that
I hate the optional parentheses (I really see no point for this except in to!"conversions" but that's templates), I want not understand why those two issues are so difficult to accept and implement.
Jan 24 2013
next sibling parent reply "eles" <eles eles.com> writes:
On Friday, 25 January 2013 at 06:47:30 UTC, eles wrote:
 On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis 
 wrote:
 On Thursday, January 24, 2013 22:52:36 Andrei Alexandrescu 
 wrote:
Seriously, who wants to try criticizing this?: http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx Just provide serious answers why we cannot do that in D.
Jan 24 2013
parent "eles" <eles eles.com> writes:
On Friday, 25 January 2013 at 06:54:15 UTC, eles wrote:
 On Friday, 25 January 2013 at 06:47:30 UTC, eles wrote:
 On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis 
 wrote:
 On Thursday, January 24, 2013 22:52:36 Andrei Alexandrescu 
 wrote:
"Properties have many uses: they can validate data before allowing a change; they can transparently expose data on a class where that data is actually retrieved from some other source, such as a database; they can take an action when data is changed, such as raising an event, or changing the value of other fields." I think that having *clear* properties in D is worthing.
Jan 24 2013
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 07:47:27 eles wrote:
 On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis
 
 wrote:
 On Thursday, January 24, 2013 22:52:36 Andrei Alexandrescu
 wrote:
 I hate optional parentheses with a passion, but I think that
 it's quite clear
 that too many people want them (including many who want
  property) and that
I hate the optional parentheses (I really see no point for this except in to!"conversions" but that's templates), I want not understand why those two issues are so difficult to accept and implement.
The issue is that lots of people like optional parentheses. I expect that even if there were no support for properties in the language whatsoever, the folks who like to be able to elide parens would still like that and want it. However, even if we're stuck with parenless function calls being legal, we can without parens. It's just that many function calls would be able to look like they were getter properties if they're called without parens. But because of the tons of arguments over property (many of them really being over parenless function calls rather than property itself) and the fact that Andrei has never liked the idea of property in the first place, Walter and Andrei seem to be trying to get rid of it and simplify the language - hence this thread. So, we're forced to argue in favor of property. At this point, I think that the best that we can hope for is 1. Parenless function calls will continue to function essentially as they have been. 2. It will be illegal to use a non- property function as a setter. 3. property will be kept, and property functions must be called without parens. If we go that route, we may also be able to make some improvements to property functions to make them closer to how variables are (e.g. make a.prop += 1 valid), and property functions will be able to be essentially as they are in calls. - Jonathan M Davis
Jan 24 2013
parent reply "eles" <eles eles.com> writes:
On Friday, 25 January 2013 at 07:14:19 UTC, Jonathan M Davis 
wrote:
 On Friday, January 25, 2013 07:47:27 eles wrote:
 On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis
However, even if we're stuck with parenless function calls being legal, we can that it be used without parens.
I think the root reason of this fight over what properties are and how are used/usable boils down to the way they are deined in 1. in D they are defined as functions (or very similarily to those), so many people are perceiving them as FUNCTIONS to which one tries to stick some variable-like calls people tend to see those as some variables with some extra. IMHO the chosen syntax for defining properties matters in the first place. I do not dear to suggest implementing a more variable-like syntax of the barricade we wand D's properties to be.
Jan 25 2013
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 09:49:00 eles wrote:
 On Friday, 25 January 2013 at 07:14:19 UTC, Jonathan M Davis
 
 wrote:
 On Friday, January 25, 2013 07:47:27 eles wrote:
 On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis
However, even if we're stuck with parenless function calls being legal, we can that it be used without parens.
I think the root reason of this fight over what properties are and how are used/usable boils down to the way they are deined in 1. in D they are defined as functions (or very similarily to those), so many people are perceiving them as FUNCTIONS to which one tries to stick some variable-like calls people tend to see those as some variables with some extra. IMHO the chosen syntax for defining properties matters in the first place. I do not dear to suggest implementing a more variable-like syntax of the barricade we wand D's properties to be.
better, but it's too late now. But a lot of the problem stems from the fact that the original way that properties were implemented in D was essentially what Walter is proposing now, and I believe that the fact that that worked originally was at least partially by accident. So, it's pretty much always been the case in D that properties were implemented via functions, and any probably would have been a good idea). - Jonathan M Davis
Jan 25 2013
prev sibling parent reply "SomeDude" <lovelydear mailmetrash.com> writes:
On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis 
wrote:
 I hate optional parentheses with a passion

 - Jonathan M Davis
Same here.
Jan 27 2013
next sibling parent reply "sclytrack" <sclytrack shorter.com> writes:
On Sunday, 27 January 2013 at 10:54:05 UTC, SomeDude wrote:
 On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis 
 wrote:
 I hate optional parentheses with a passion

 - Jonathan M Davis
Same here.
In Delphi they are also optional and nobody uses them. However, everybody else doesn't use them. :-)
Jan 27 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 27 January 2013 at 11:18:01 UTC, sclytrack wrote:
 On Sunday, 27 January 2013 at 10:54:05 UTC, SomeDude wrote:
 On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis 
 wrote:
 I hate optional parentheses with a passion

 - Jonathan M Davis
Same here.
In Delphi they are also optional and nobody uses them. However, everybody else doesn't use them.
Delphi has no real functional capabilities.
Jan 27 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/27/2013 12:35 PM, deadalnix wrote:
 On Sunday, 27 January 2013 at 11:18:01 UTC, sclytrack wrote:
 On Sunday, 27 January 2013 at 10:54:05 UTC, SomeDude wrote:
 On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis wrote:
 I hate optional parentheses with a passion

 - Jonathan M Davis
Same here.
In Delphi they are also optional and nobody uses them. However, everybody else doesn't use them.
Delphi has no real functional capabilities.
What about scala?
Jan 27 2013
parent "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 27 January 2013 at 13:16:59 UTC, Timon Gehr wrote:
 On 01/27/2013 12:35 PM, deadalnix wrote:
 On Sunday, 27 January 2013 at 11:18:01 UTC, sclytrack wrote:
 On Sunday, 27 January 2013 at 10:54:05 UTC, SomeDude wrote:
 On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis 
 wrote:
 I hate optional parentheses with a passion

 - Jonathan M Davis
Same here.
In Delphi they are also optional and nobody uses them. However, everybody else doesn't use them.
Delphi has no real functional capabilities.
What about scala?
I'm not a scala specialist (however, one of my coworker is, so I'll ask him tomorrow) but my understanding is that that autocall functionality in scala is more limited than in D.
Jan 27 2013
prev sibling next sibling parent reply "Michael" <pr m1xa.com> writes:
int CoolThing { in; out; } - auto property without implementation;

int CoolThing { private in; out; } - private setter; public 
getter;

int CoolThing
{
    in
    {
       _privateCoolThing =  value * 42;
    }

    out
    {
       return 42;
    }
}

Explicit calling: void in_CoolThing(int); int out_CoolThing(); 
Proper "Property rewrite" can be implemented.

Property CoolThing looks like code contract for 
_privateCoolThing. So it's maybe + or -.



--no-parenthesis for current behaviour for non-property functions.
Jan 27 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-27 12:20, Michael wrote:
 int CoolThing { in; out; } - auto property without implementation;

 int CoolThing { private in; out; } - private setter; public getter;

 int CoolThing
 {
     in
     {
        _privateCoolThing =  value * 42;
     }

     out
     {
        return 42;
     }
 }

 Explicit calling: void in_CoolThing(int); int out_CoolThing(); Proper
 "Property rewrite" can be implemented.

 Property CoolThing looks like code contract for _privateCoolThing. So
 it's maybe + or -.



 --no-parenthesis for current behaviour for non-property functions.
Won't this conflict with contracts, which also uses the "in" and "out" keywords? -- /Jacob Carlborg
Jan 27 2013
parent "Michael" <pr m1xa.com> writes:
On Sunday, 27 January 2013 at 12:07:35 UTC, Jacob Carlborg wrote:
 Won't this conflict with contracts, which also uses the "in" 
 and "out" keywords?
As suggestion:
Property CoolThing looks like code contract for 
_privateCoolThing. So it's maybe + or -.

Jan 27 2013
prev sibling parent reply "TommiT" <tommitissari hotmail.com> writes:
On Sunday, 27 January 2013 at 10:54:05 UTC, SomeDude wrote:
 On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis 
 wrote:
 I hate optional parentheses with a passion

 - Jonathan M Davis
Same here.
If that's the level of abstraction on which you want to discuss about optional parentheses, then I could say that "I love optional parentheses", and since "Love conquers all", my argument would win against your argument. But, joking aside, I think that all hate against optional parentheses stems from the increase of ambiguity they indisputably cause. However, let's imagine a future where your perfect D IDE paints function calls red, and variables blue. Then, it will be obvious to you which identifiers are variables and which are function calls based on their color. In this situation it will feel silly to have to write those empty parentheses, because they don't make the code any less ambiguous (it's already perfectly unambiguous because of the colors) and, infact, those empty parentheses make the code (a bit) harder to read.
Jan 27 2013
next sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Sunday, 27 January 2013 at 13:24:31 UTC, TommiT wrote:
 But, joking aside, I think that all hate against optional 
 parentheses stems from the increase of ambiguity they 
 indisputably cause. However, let's imagine a future where your 
 perfect D IDE paints function calls red, and variables blue. 
 Then, it will be obvious to you which identifiers are variables 
 and which are function calls based on their color. In this 
 situation it will feel silly to have to write those empty 
 parentheses, because they don't make the code any less 
 ambiguous (it's already perfectly unambiguous because of the 
 colors) and, infact, those empty parentheses make the code (a 
 bit) harder to read.
If we require clever IDE to distinguish visually something as basic as data semantics and callable semantics it is an indicator language design is screwed. Relying on IDE features is what made Java unusable for expressive, robust code. I may use an IDE help when I need to learn architecture level connections in new project, but at scope level semantics for reader should be perfectly clear and unambiguous even if opened in notepad. 2 cents from vim user and optional parens hater here.
Jan 27 2013
next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 27 January 2013 at 13:42:33 UTC, Dicebot wrote:
 On Sunday, 27 January 2013 at 13:24:31 UTC, TommiT wrote:
 But, joking aside, I think that all hate against optional 
 parentheses stems from the increase of ambiguity they 
 indisputably cause. However, let's imagine a future where your 
 perfect D IDE paints function calls red, and variables blue. 
 Then, it will be obvious to you which identifiers are 
 variables and which are function calls based on their color. 
 In this situation it will feel silly to have to write those 
 empty parentheses, because they don't make the code any less 
 ambiguous (it's already perfectly unambiguous because of the 
 colors) and, infact, those empty parentheses make the code (a 
 bit) harder to read.
If we require clever IDE to distinguish visually something as basic as data semantics and callable semantics it is an indicator language design is screwed. Relying on IDE features is what made Java unusable for expressive, robust code. I may use an IDE help when I need to learn architecture level connections in new project, but at scope level semantics for reader should be perfectly clear and unambiguous even if opened in notepad. 2 cents from vim user and optional parens hater here.
You're being an extremist here. From a vim user and automagic function call hater as well ;) First many reliable code have been written in Java. Quite a lot of it in fact. And refusing IDE help make no real sense. Even vim is an IDE, and not a simple editor.
Jan 27 2013
next sibling parent "Dicebot" <m.strashun gmail.com> writes:
On Sunday, 27 January 2013 at 13:56:53 UTC, deadalnix wrote:
 You're being an extremist here. From a vim user and automagic 
 function call hater as well ;)

 First many reliable code have been written in Java. Quite a lot 
 of it in fact. And refusing IDE help make no real sense. Even 
 vim is an IDE, and not a simple editor.
Probably, but that is a result of general mainstream moving to IDE-reliance. You need to sound somewhat radical to be noticed :) I did not say Java is not _reliable_. I have said it is not _expressive_ on language level and relies on boilerplate generation by IDE for something as basic as properties. I do not use vim as an IDE - no plugins, no clever macros, no ctags etc. Any editor with file list, syntax highlighting and tabs works for me; it just happens that it is more convenient to use vim when you mostly do console stuff anyway. That may come from the fact of having most commercial experience in large teams with huge legacy codebases - readability and support issues take there >90% of time and efforts, contrary to actually coding. Made me interested in languages that do enforce such stuff at language level.
Jan 27 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/27/13 8:56 AM, deadalnix wrote:
 On Sunday, 27 January 2013 at 13:42:33 UTC, Dicebot wrote:
 On Sunday, 27 January 2013 at 13:24:31 UTC, TommiT wrote:
 But, joking aside, I think that all hate against optional parentheses
 stems from the increase of ambiguity they indisputably cause.
 However, let's imagine a future where your perfect D IDE paints
 function calls red, and variables blue. Then, it will be obvious to
 you which identifiers are variables and which are function calls
 based on their color. In this situation it will feel silly to have to
 write those empty parentheses, because they don't make the code any
 less ambiguous (it's already perfectly unambiguous because of the
 colors) and, infact, those empty parentheses make the code (a bit)
 harder to read.
If we require clever IDE to distinguish visually something as basic as data semantics and callable semantics it is an indicator language design is screwed. Relying on IDE features is what made Java unusable for expressive, robust code. I may use an IDE help when I need to learn architecture level connections in new project, but at scope level semantics for reader should be perfectly clear and unambiguous even if opened in notepad. 2 cents from vim user and optional parens hater here.
You're being an extremist here. From a vim user and automagic function call hater as well ;) First many reliable code have been written in Java. Quite a lot of it in fact. And refusing IDE help make no real sense. Even vim is an IDE, and not a simple editor.
Language adoption is a complex phenomenon with many variables, and it's easy to neglect certain aspects when assessing the impact of others. Java started as a well-designed language albeit small and underpowered. It enjoyed the benefit of unwavering support from a large corporation and an estimated one billion dollars in marketing budget. (I remember in 1998 non-programming managers in NYC were talking "we must adopt Java!" without even knowing what Java meant. Java may as well be the only programming language in history to enjoy management support before programmer support.) That has caused Java to evolve quite differently from languages with grass-roots support (e.g. C++, Ruby, PHP, or Python). Generally the latter languages grew with little tooling support aside from the traditional Unix toolset, and that is to some extent reflected in the languages themselves. are available for dedicated tooling support. It would have evolved differently otherwise, and I assume many people would have a dimmer view Andrei
Jan 27 2013
next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 27 January 2013 at 14:26:20 UTC, Andrei Alexandrescu 
wrote:

 resources are available for dedicated tooling support. It would 
 have evolved differently otherwise, and I assume many people 

 use it with vim and emacs.
That is kind of my point : such language is made for tooling. With the 2 side of the medal : tooling is great, because language have been made with tooling in mind, but coding without tooling is not the best experience. Not that tremendous efforts are put now to introduce tooling in because C++ is tooling hostile. I know resource are a factor. But clearly not the only one. Doing some tooling on Java is braindead simple, the compiler provide everything you need to reuse it/parts of it.
Jan 27 2013
prev sibling parent Jeff Nowakowski <jeff dilacero.org> writes:
On 01/27/2013 09:26 AM, Andrei Alexandrescu wrote:
 Language adoption is a complex phenomenon with many variables, and it's
 easy to neglect certain aspects when assessing the impact of others.
Indeed it is, as you show below.
 Java started as a well-designed language albeit small and underpowered.
 It enjoyed the benefit of unwavering support from a large corporation
 and an estimated one billion dollars in marketing budget. (I remember in
 1998 non-programming managers in NYC were talking "we must adopt Java!"
 without even knowing what Java meant. Java may as well be the only
 programming language in history to enjoy management support before
 programmer support.)
First off, where do you get this billion dollar marketing figure from? I've seen it from you before, with no citation, and could find no such citation myself when doing a Web search. Second, Java was a "right place, right time" language. It was initially pegged for consumer devices, and was part of a bid to get cable company adoption for a TV add-on device, but when that fell flat it occurred to them the Web was a good fit. It was (in theory, but not in practice -- Flash ended up winning the browser), the hype machine exploded, and the rest is history. For example, if you read this article here: http://vidlar.powweb.com/internett/the-java_net/history.html ...you'll see their growth was fairly organic. Yes, I'm sure they had a marketing budget, but I highly doubt that in 1998 they were spending $1 billion.
 That has caused Java to evolve quite differently from languages with
 grass-roots support (e.g. C++, Ruby, PHP, or Python). Generally the
 latter languages grew with little tooling support aside from the
 traditional Unix toolset, and that is to some extent reflected in the
 languages themselves.
One thing you're missing about Java is that because of it's simplicity of design and static typing, it was so easy to write tools for. No crazy macros or templates, and lots of type information.

 are available for dedicated tooling support. It would have evolved
 differently otherwise, and I assume many people would have a dimmer view

an IDE out of the box from Sun. For many it was emacs or whatever, then there was JBuilder (from Borland), and then IBM and IntelliJ, etc.
Jan 27 2013
prev sibling next sibling parent reply "TommiT" <tommitissari hotmail.com> writes:
On Sunday, 27 January 2013 at 13:42:33 UTC, Dicebot wrote:
 If we require clever IDE to distinguish visually something as 
 basic as data semantics and callable semantics it is an 
 indicator language design is screwed.
Why is it an indicator of that?
 I may use an IDE help when I need to learn architecture level 
 connections in new project, but at scope level semantics for 
 reader should be perfectly clear and unambiguous even if opened 
 in notepad.
Notepad opens text files. There is nothing that says that the source files of X programming language must be text files. It's just a convention, not a law or a real limitation in designing languages. Therefore you can't assume that an X source file can be opened and read with notepad. Someone might design a language that wouldn't rely on those symbols that just happen to be found on keyboards, but instead, relied more on text formatting and colors.
Jan 27 2013
next sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Sunday, 27 January 2013 at 14:11:13 UTC, TommiT wrote:
 On Sunday, 27 January 2013 at 13:42:33 UTC, Dicebot wrote:
 If we require clever IDE to distinguish visually something as 
 basic as data semantics and callable semantics it is an 
 indicator language design is screwed.
Why is it an indicator of that?
Because it fails to maintain and control semantics on its own.
 Notepad opens text files. There is nothing that says that the 
 source files of X programming language must be text files. It's 
 just a convention, not a law or a real limitation in designing 
 languages.
Text is still most efficient form of providing information. Please call me back when something better will be invented. Then we can speak about minimal editing environment for it.
Jan 27 2013
parent reply "TommiT" <tommitissari hotmail.com> writes:
On Sunday, 27 January 2013 at 14:14:18 UTC, Dicebot wrote:
 Text is still most efficient form of providing information. 
 Please call me back when something better will be invented. 
 Then we can speak about minimal editing environment for it.
Okay, here's what I invented in 5 minutes that would be better than plain text: * Arguments to a function call would go, instead of inside parentheses, inside a box with a solid, black border and some nice and unique background color. * Template arguments would go in a box with a hatched border line and a different background color. * Blocks are, instead of surrounded by braces, indicated by this thing that looks like a tall, black, thin, right-opening square bracket that spans the whole block and sits directly to the left of the left-most characters of the statements inside the block. * Instead of having '*' indicate both "multiply" and "dereference", invent and use a new symbol that means "dereference". The same goes for all symbols, like '&', '!', '~', ' ', that don't have a universally defined meaning that corresponds to its meaning in language X. In order to input those "things that are not symbols found on your keyboard", you'd either need to learn keyboard shortcuts by heart, or use a custom keyboard, which is what tv and movie editors have done for 20 years with their Avid keyboards. Most other creative jobs require custom tools for performing the craft, why not programming?
Jan 27 2013
next sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Sunday, 27 January 2013 at 15:09:10 UTC, TommiT wrote:
 On Sunday, 27 January 2013 at 14:14:18 UTC, Dicebot wrote:
 Text is still most efficient form of providing information. 
 Please call me back when something better will be invented. 
 Then we can speak about minimal editing environment for it.
Okay, here's what I invented in 5 minutes that would be better than plain text: * Arguments to a function call would go, instead of inside parentheses, inside a box with a solid, black border and some nice and unique background color. * Template arguments would go in a box with a hatched border line and a different background color. * Blocks are, instead of surrounded by braces, indicated by this thing that looks like a tall, black, thin, right-opening square bracket that spans the whole block and sits directly to the left of the left-most characters of the statements inside the block. * Instead of having '*' indicate both "multiply" and "dereference", invent and use a new symbol that means "dereference". The same goes for all symbols, like '&', '!', '~', ' ', that don't have a universally defined meaning that corresponds to its meaning in language X. In order to input those "things that are not symbols found on your keyboard", you'd either need to learn keyboard shortcuts by heart, or use a custom keyboard, which is what tv and movie editors have done for 20 years with their Avid keyboards. Most other creative jobs require custom tools for performing the craft, why not programming?
And how it is any better? Also D sources are unicode, so last two are possible just now and you need no special keyboard for it. Still the same good old text.
Jan 27 2013
parent reply "TommiT" <tommitissari hotmail.com> writes:
On Sunday, 27 January 2013 at 15:22:34 UTC, Dicebot wrote:
 And how it is any better? Also D sources are unicode, so last 
 two are possible just now and you need no special keyboard for 
 it. Still the same good old text.
I don't know if what I invented is any better, but my attempt was to make something that's easier to read and less ambiguous than plain text. For example parenthesis would be used only to define the order in which expressions are evaluated, and _not_ to indicate a section of arguments. But are you really arguing that: "there can be nothing better than plain text for programmers to declare their intent". I wonder why we even have graphic operating systems, if graphic elements don't make thing easier to use and understand. To me, saying that "D is bad language, because in order to most effectively write and understand the code requires some dedicated software" is like saying "Avid is a bad editing software, because using it most effectively requires some custom keyboard". You can write and understand D code, where parentheses of nullary function calls have been omitted, in notepad - it just may not be most optimal environment. Just like you can use Avid with a regular keyboard, it just may not be most optimal to do so (unless you remember all the keys by heart already).
Jan 27 2013
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sun, Jan 27, 2013 at 04:42:39PM +0100, TommiT wrote:
[...]
 But are you really arguing that: "there can be nothing better than
 plain text for programmers to declare their intent". I wonder why we
 even have graphic operating systems, if graphic elements don't make
 thing easier to use and understand.
[...] I wonder the same thing too. I'm a CLI fanatic. ;-) And in fact, I honestly find GUI's a pain to use, due to their non-scriptability and needless reliance on the rodent. Yes, it makes things more appealing to the eye, but easier to use is arguable (there are too many GUI apps out there that are clearly written by people who have no idea what UI design means), and ease of understanding is also questionable (ever used a GUI app with icons that require clairvoyance to figure out what it means?). Some tasks are more suited for GUI interfaces, like image editing, 3D modelling, etc.. But I find GUIs to be an unnecessary waste of resources on most other tasks. But yes, I know I'm in the minority, and I'm quite OK with that. T -- The trouble with TCP jokes is that it's like hearing the same joke over and over.
Jan 27 2013
prev sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Sunday, 27 January 2013 at 15:42:40 UTC, TommiT wrote:
 On Sunday, 27 January 2013 at 15:22:34 UTC, Dicebot wrote:
 And how it is any better? Also D sources are unicode, so last 
 two are possible just now and you need no special keyboard for 
 it. Still the same good old text.
I don't know if what I invented is any better, but my attempt was to make something that's easier to read and less ambiguous than plain text. For example parenthesis would be used only to define the order in which expressions are evaluated, and _not_ to indicate a section of arguments. But are you really arguing that: "there can be nothing better than plain text for programmers to declare their intent". I wonder why we even have graphic operating systems, if graphic elements don't make thing easier to use and understand. To me, saying that "D is bad language, because in order to most effectively write and understand the code requires some dedicated software" is like saying "Avid is a bad editing software, because using it most effectively requires some custom keyboard". You can write and understand D code, where parentheses of nullary function calls have been omitted, in notepad - it just may not be most optimal environment. Just like you can use Avid with a regular keyboard, it just may not be most optimal to do so (unless you remember all the keys by heart already).
More noise -> not easier to read. It may has a merit when designing grammar unambiguous for reader with limited symbol count is impossible but otherwise simple unambiguous representation beats complex one. Also your proposal is not very different from plain text, it is about on the level of syntax highlighting. We do have graphic operating systems and power users still do use consoles/shells for advanced operating system-related work. Because graphic elements are easier to understand, but harder (less efficient) to use. I am perfectly fine with relaxed mouse clicking when I am browsing or watching films or whatever, but when I do work - please, give me a pair of my trusted text shells. I don't know what Avid is but if it requires custom keyboard for proper usage - it is either bad or targeted to users with weak computer competence (and googling shows it is some audio editing stuff, this second option is likely).
Jan 27 2013
parent "TommiT" <tommitissari hotmail.com> writes:
On Sunday, 27 January 2013 at 15:59:42 UTC, Dicebot wrote:
 I don't know what Avid is but if it requires custom keyboard 
 for proper usage - it is either bad or targeted to users with 
 weak computer competence (and googling shows it is some audio 
 editing stuff, this second option is likely).
I was referring to Avid video editing software, which has been used for pretty much all movies and tv series made since 1990. There you can see the custom keyboard in its natural environment: http://meganandtimmy.com/wp-content/uploads/2012/04/Avid.jpeg But this is getting really far from the subject now.
Jan 27 2013
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sun, Jan 27, 2013 at 04:09:09PM +0100, TommiT wrote:
[...]
 Most other creative jobs require custom tools for performing the
 craft, why not programming?
Because it's not *necessary*. Having a universal representation has many advantages, *independence* from custom tools, scriptability, testability, etc.. Independence from specialized tools, contrary to popular opinion, is a very good thing. Having a universal representation like text lets *anyone* write tools for it easily, and more importantly, tools that can work with more than just that specific representation. This is incentive for people to actually invest the effort to make said tools, because the target market is much wider (==lower risk, greater ROI). It also lets more tools than the creators of the thing being represented thought of to be used for manipulating it -- i.e., saves them the effort of reinventing an entire ecosystem, you just leverage what's already out there. Having specialized representations means that far fewer tools can be used for manipulating it, and these tools must be specifically made for the job. Why artificially limit yourself in this way, when generic formats and generic tools are far more useful? Always reminds me of the difficulty of automating the test of GUI apps. You need specialized software to record interactions and replay them, whereas with a text-based interface, you can *generate* test cases that no human has ever done before, thereby making it possible to have more complete coverage than would be possible with any record/replay-based system. GUI apps are also non-scriptable, which greatly limits their usability in automated environments. Recorded GUI scripts are also usually in a non-interoperable format, which makes sharing / editing by others, etc., more difficult than necessary. Obligatory quote: A program should be written to model the concepts of the task it performs rather than the physical world or a process because this maximizes the potential for it to be applied to tasks that are conceptually similar and, more important, to tasks that have not yet been conceived. -- Michael B. Allen I see many more disadvantages to things like colors, fonts, reliance on specific tools, than advantages. Things that artificially limit themselves for no good reason other than convenience are rarely worth the trouble. (Caveat: I'm another slobbering vim fanatic. I don't even use syntax highlighting. So you may take a big grain of salt with everything I say. :-P) T -- The richest man is not he who has the most, but he who needs the least.
Jan 27 2013
prev sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 01/27/13 15:11, TommiT wrote:
 There is nothing that says that the source files of X programming language
must be text files. It's just a convention, not a law or a real limitation in
designing languages. Therefore you can't assume that an X source file can be
opened and read with notepad. Someone might design a language that wouldn't
rely on those symbols that just happen to be found on keyboards, but instead,
relied more on text formatting and colors.
Except we're not talking about such hypothetical language, but one where text *is* the natural form for source code. It also happens to be called "D", which means that it will be universally expected to have certain properties. Something can be a great idea in one context, while being an extremely bad one in another. artur
Jan 27 2013
prev sibling parent reply "TommiT" <tommitissari hotmail.com> writes:
On Sunday, 27 January 2013 at 13:42:33 UTC, Dicebot wrote:
 ... but at scope level semantics for reader should be perfectly 
 clear and unambiguous even if opened in notepad.
I think we have been throwing the term ambiguous around too carelessly. Obviously code must be semantically unambiguous when viewed in a Notepad. I don't think that's an issue with optional parentheses - the issue is just that it's "not as easy to read", which I don't think means the same as ambiguous (I'm sure about all english words though). "Not as easy to read" shouldn't sound nearly as bad as ambiguous - it's just a little inconvenience that can be gotten rid of by using an IDE that does semantic colorization.
Jan 27 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Sunday, 27 January 2013 at 17:19:15 UTC, TommiT wrote:
 On Sunday, 27 January 2013 at 13:42:33 UTC, Dicebot wrote:
 ... but at scope level semantics for reader should be 
 perfectly clear and unambiguous even if opened in notepad.
I think we have been throwing the term ambiguous around too carelessly. Obviously code must be semantically unambiguous when viewed in a Notepad. I don't think that's an issue with optional parentheses - the issue is just that it's "not as easy to read", which I don't think means the same as ambiguous (I'm sure about all english words though). "Not as easy to read" shouldn't sound nearly as bad as ambiguous - it's just a little inconvenience that can be gotten rid of by using an IDE that does semantic colorization.
"easy to read" == "I can find part of code that interests me easily" "unambiguous" == "I can understand semantics of code I have just read with as little additional context as possible" Ambiguity is mentioned often because there is one for compiler and one for programmer. Those two are sometimes similar but rather different in nature.
Jan 27 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/27/2013 06:33 PM, Dicebot wrote:
 ...
 "unambiguous" == "I can understand semantics of code I have just read
 with as little additional context as possible"
 ...
In order to do that, it is necessary aware of the precise definitions, or at least specifications, of referenced declarations in any case. So by your definition, the current function call syntax is "unambiguous".
Jan 27 2013
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/28/2013 12:34 AM, Timon Gehr wrote:
 On 01/27/2013 06:33 PM, Dicebot wrote:
 ...
 "unambiguous" == "I can understand semantics of code I have just read
 with as little additional context as possible"
 ...
In order to do that, it is necessary
to be
 aware of the precise definitions,
 or at least specifications, of referenced declarations in any case. So
 by your definition, the current function call syntax is "unambiguous".
Jan 27 2013
prev sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Sunday, 27 January 2013 at 23:34:59 UTC, Timon Gehr wrote:
 In order to do that, it is necessary aware of the precise 
 definitions, or at least specifications, of referenced 
 declarations in any case. So by your definition, the current 
 function call syntax is "unambiguous".
Sure, it is for compiler. And it for me if I check the definition of symbol. But without going to some other source file and looking up definition there is no way to guess if this: ----- auto ret = something.anything; ----- ..actually does anything else but reassigning a field to a variable. In my personal experience time lost to check such stuff out is much more than time saved by fast and convenient parens-less coding. Thus the attitude.
Jan 28 2013
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Monday, 28 January 2013 at 08:14:45 UTC, Dicebot wrote:
 Sure, it is for compiler. And it for me if I check the 
 definition of symbol.
However, as long as we have properties *at all* you'd have to property syntax, it is still possible .anything is a function call.
Jan 28 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Monday, 28 January 2013 at 13:30:33 UTC, Adam D. Ruppe wrote:
 On Monday, 28 January 2013 at 08:14:45 UTC, Dicebot wrote:
 Sure, it is for compiler. And it for me if I check the 
 definition of symbol.
However, as long as we have properties *at all* you'd have to property syntax, it is still possible .anything is a function call.
No, I am repeating this again and again - when I see a property I need to think it is a variable. It is intended fooling of the reader and reason to have properties. Thus no checking in that case, I just assume it is a field or variable or anything like that. And if I'll spend few days debugging the case that comes down to my colleague has designed a property that does not behave like a field - I'll go and politely ask to stop doing this. May be also will punch him. Problem solved.
Jan 28 2013
parent reply "TommiT" <tommitissari hotmail.com> writes:
On Monday, 28 January 2013 at 13:34:33 UTC, Dicebot wrote:
 And if I'll spend few days debugging the case that comes down 
 to my colleague has designed a property that does not behave 
 like a field - I'll go and politely ask to stop doing this.
Do you consider a dynamic arrays' length property to be a good, properly designed property: array.length = 7; It does behave like a field, but it's got pretty serious side effects that you just need to know about. And, I don't see much point in having properties that are not allowed to have any side-effects.
Jan 28 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Monday, 28 January 2013 at 16:45:57 UTC, TommiT wrote:
 Do you consider a dynamic arrays' length property to be a good, 
 properly designed property:
No.
 And, I don't see much point in having properties that are not 
 allowed to have any side-effects.
Then you need something other than properties.
Jan 28 2013
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/28/13 11:50 AM, Dicebot wrote:
 On Monday, 28 January 2013 at 16:45:57 UTC, TommiT wrote:
 Do you consider a dynamic arrays' length property to be a good,
 properly designed property:
No.
 And, I don't see much point in having properties that are not allowed
 to have any side-effects.
Then you need something other than properties.
Wait, so you're against any writable properties? Maybe there's a confusion somewhere. Andrei
Jan 28 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Monday, 28 January 2013 at 16:59:40 UTC, Andrei Alexandrescu 
wrote:
 Wait, so you're against any writable properties? Maybe there's 
 a confusion somewhere.

 Andrei
Ah, yes, there is a confusion between "side-effect" from the pure function point of view and "side-effect" from property functionality point of view. I'd say that property setter should be a pure function with one exception : it is allowed to changed "this" fields. No global state changes, no calls to impure global functions, not even calls to "this" non-property functions.
Jan 28 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-28 18:11, Dicebot wrote:

 Ah, yes, there is a confusion between "side-effect" from the pure
 function point of view and "side-effect" from property functionality
 point of view. I'd say that property setter should be a pure function
 with one exception : it is allowed to changed "this" fields. No global
 state changes, no calls to impure global functions, not even calls to
 "this" non-property functions.
What about getters and setters and gets and sets a value from a cache? -- /Jacob Carlborg
Jan 28 2013
parent "Dicebot" <m.strashun gmail.com> writes:
On Monday, 28 January 2013 at 19:43:39 UTC, Jacob Carlborg wrote:
 On 2013-01-28 18:11, Dicebot wrote:
 What about getters and setters and gets and sets a value from a 
 cache?
Would not have made them properties either. It is somewhat similar to cache and const vs logical const issue. But you are right, this is were personal preferences start varying a lot, I don't realistically hope someone will give me language that restrictive in its core for my needs :) Just expressing personal attitude because I am in the hospital, bored and have a crazy amount of free time to chat on newsgroup :) That may sound weird but I do like when core language features are very restrictive and require programmer to express his intentions verbosely. And provide _possibility_ to do cool stuff via advanced clearly separated advanced features. Like safe vs system but for syntactic language features. Not gonna convince anyone but at least pushing it my way makes me feel good :)
Jan 28 2013
prev sibling parent reply "TommiT" <tommitissari hotmail.com> writes:
On Monday, 28 January 2013 at 16:50:27 UTC, Dicebot wrote:
 And, I don't see much point in having properties that are not 
 allowed to have any side-effects.
Then you need something other than properties.
I think you're putting too much faith on the power of convention and on the similarity between your's and everybody else's notions of how much side effects a settable property can have while not giving the user any surprises. Let's say your type has three properties: Changing any one of those properties must (logically) change at least one other property. Therefore, you can't just pretend that properties are simple data fields.
Jan 28 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Monday, 28 January 2013 at 17:14:31 UTC, TommiT wrote:
 On Monday, 28 January 2013 at 16:50:27 UTC, Dicebot wrote:
 And, I don't see much point in having properties that are not 
 allowed to have any side-effects.
Then you need something other than properties.
I think you're putting too much faith on the power of convention and on the similarity between your's and everybody else's notions of how much side effects a settable property can have while not giving the user any surprises. Let's say your type has three properties: Changing any one of those properties must (logically) change at least one other property. Therefore, you can't just pretend that properties are simple data fields.
That is no different from volatile variables. My notion is at rare. It all comes from "property == variable" mantra.
Jan 28 2013
parent reply "TommiT" <tommitissari hotmail.com> writes:
On Monday, 28 January 2013 at 17:30:40 UTC, Dicebot wrote:
 Let's say your type has three properties:




 Changing any one of those properties must (logically) change 
 at least one other property. Therefore, you can't just pretend 
 that properties are simple data fields.
That is no different from volatile variables.
If you think my example of {start_time, end_time, duration} represents proper use of properties, then I don't see why you oppose array.length. To me it seems like the same thing. Array has some length, and you can change it by changing its length property. T represents a certain time range, and you can change it by changing any of its three properties {start_time, end_time, duration} which describe that time range.

 should be not that rare. It all comes from "property == 
 variable" mantra.
I'm just saying that when you read some code written by some person X, you can't rely on person X having the same notion of what properties should be as you do. For this reason you can't only read the documentation of methods and skip reading the documentation of properties, because properties may do/change things that you wouldn't have made them do/change.
Jan 28 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Monday, 28 January 2013 at 17:52:45 UTC, TommiT wrote:
 If you think my example of {start_time, end_time, duration} 
 represents proper use of properties, then I don't see why you 
 oppose array.length. To me it seems like the same thing. Array 
 has some length, and you can change it by changing its length 
 property. T represents a certain time range, and you can change 
 it by changing any of its three properties {start_time, 
 end_time, duration} which describe that time range.
T changes its inner encapsulated states. Period. It is no different that properties that calculate result on the fly, like range.empty (which is good property usage). Array.length allocates. Takes from some global resources, takes some considerable time, calls some global allocating function. For me it is a crucial difference that pushes symbol to the world of functions.
Jan 28 2013
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Jan 28, 2013 at 07:04:21PM +0100, Dicebot wrote:
 On Monday, 28 January 2013 at 17:52:45 UTC, TommiT wrote:
If you think my example of {start_time, end_time, duration}
represents proper use of properties, then I don't see why you
oppose array.length. To me it seems like the same thing. Array has
some length, and you can change it by changing its length
property. T represents a certain time range, and you can change it
by changing any of its three properties {start_time, end_time,
duration} which describe that time range.
T changes its inner encapsulated states. Period. It is no different that properties that calculate result on the fly, like range.empty (which is good property usage). Array.length allocates. Takes from some global resources, takes some considerable time, calls some global allocating function. For me it is a crucial difference that pushes symbol to the world of functions.
In the dinosaur age of Motorola 6502 processors, writing certain values to certain "magic" memory addresses triggers side-effects like switching the console into graphics mode. One could argue this is bad design, but it *is* a precedent for side-effects when assigning values to what can be thought of as "just a variable". By comparison, array.length is pretty tame (no visible side-effects except that the array becomes longer). T -- Life is too short to run proprietary software. -- Bdale Garbee
Jan 28 2013
parent "David Nadlinger" <see klickverbot.at> writes:
On Monday, 28 January 2013 at 18:10:33 UTC, H. S. Teoh wrote:
 By comparison, array.length is
 pretty tame (no visible side-effects except that the array 
 becomes
 longer).
... *and* possibly relocated in memory, so that it no longer aliases any other slices originally pointing to the same chunk of data. This is the main reason why .length looks far to innocent in my regard - although I don't really feel strongly about the issue. David
Jan 28 2013
prev sibling next sibling parent "TommiT" <tommitissari hotmail.com> writes:
On Monday, 28 January 2013 at 18:04:22 UTC, Dicebot wrote:
 T changes its inner encapsulated states. Period. It is no 
 different that properties that calculate result on the fly, 
 like range.empty (which is good property usage).

 Array.length allocates. Takes from some global resources, takes 
 some considerable time, calls some global allocating function.

 For me it is a crucial difference that pushes symbol to the 
 world of functions.
The question "what is or should be a property?" is a question of semantics. I don't see what performance or those implementation details you mentioned have to do with semantics. What if our container type wasn't a dynamic array? Let's say it's a pseudo container that pretends to be a vector of consecutive int values, but in reality it just has two integers which denote the beginning and the end of the range. Now changing the length property of that container takes constant time (it just sets the end value anew).
Jan 28 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/28/13 1:04 PM, Dicebot wrote:
 On Monday, 28 January 2013 at 17:52:45 UTC, TommiT wrote:
 If you think my example of {start_time, end_time, duration} represents
 proper use of properties, then I don't see why you oppose
 array.length. To me it seems like the same thing. Array has some
 length, and you can change it by changing its length property. T
 represents a certain time range, and you can change it by changing any
 of its three properties {start_time, end_time, duration} which
 describe that time range.
T changes its inner encapsulated states. Period. It is no different that properties that calculate result on the fly, like range.empty (which is good property usage). Array.length allocates. Takes from some global resources, takes some considerable time, calls some global allocating function. For me it is a crucial difference that pushes symbol to the world of functions.
I guess you hate if people want their bigints to assign with a = b. Andrei
Jan 28 2013
next sibling parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Monday, 28 January 2013 at 18:43:19 UTC, Andrei Alexandrescu 
wrote:
 On 1/28/13 1:04 PM, Dicebot wrote:
 On Monday, 28 January 2013 at 17:52:45 UTC, TommiT wrote:
 If you think my example of {start_time, end_time, duration} 
 represents
 proper use of properties, then I don't see why you oppose
 array.length. To me it seems like the same thing. Array has 
 some
 length, and you can change it by changing its length 
 property. T
 represents a certain time range, and you can change it by 
 changing any
 of its three properties {start_time, end_time, duration} which
 describe that time range.
T changes its inner encapsulated states. Period. It is no different that properties that calculate result on the fly, like range.empty (which is good property usage). Array.length allocates. Takes from some global resources, takes some considerable time, calls some global allocating function. For me it is a crucial difference that pushes symbol to the world of functions.
I guess you hate if people want their bigints to assign with a = b. Andrei
widget.height = 100 should be condemned, too - it changes the state of the entire GUI system. Let's face it: there are *no* objective criteria for determining whether a mutator should be a function or property setter.
Jan 28 2013
parent reply "Michael" <pr m1xa.com> writes:
On Monday, 28 January 2013 at 21:03:04 UTC, Max Samukha wrote:
 Let's face it: there are *no* objective criteria for 
 determining whether a mutator should be a function or property 
 setter.
Yes, but also it's should be a lightweight action (main idea). As proposal: http://forum.dlang.org/post/ydcjggoibjmuuoobgrvq forum.dlang.org http://msdn.microsoft.com/en-us/library/w86s7x04.aspx http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx and quote

 --no-parenthesis for current behaviour for non-property 
 functions.
Jan 28 2013
parent "Max Samukha" <maxsamukha gmail.com> writes:
On Monday, 28 January 2013 at 21:54:21 UTC, Michael wrote:
 On Monday, 28 January 2013 at 21:03:04 UTC, Max Samukha wrote:
 Let's face it: there are *no* objective criteria for 
 determining whether a mutator should be a function or property 
 setter.
Yes, but also it's should be a lightweight action (main idea).
I think we need something more measurable than lightweight-ness to justify a language feature.
 As proposal:

 http://forum.dlang.org/post/ydcjggoibjmuuoobgrvq forum.dlang.org


 http://msdn.microsoft.com/en-us/library/w86s7x04.aspx
 http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx

 and quote


 --no-parenthesis for current behaviour for non-property 
 functions.
Jan 29 2013
prev sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Monday, 28 January 2013 at 18:43:19 UTC, Andrei Alexandrescu 
wrote:
 I guess you hate if people want their bigints to assign with a 
 = b.
Have never used bigints. You mean that copy construction upon assignment allocates too? Yes, I do now like this, too, but see no sane to get around this as it will feel unnatural either way. Arrays, however, will not suffer at all from switching to array.resize(42) syntax from array.length = 42 syntax.
Jan 28 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/28/13 4:32 PM, Dicebot wrote:
 On Monday, 28 January 2013 at 18:43:19 UTC, Andrei Alexandrescu wrote:
 I guess you hate if people want their bigints to assign with a = b.
Have never used bigints. You mean that copy construction upon assignment allocates too? Yes, I do now like this, too, but see no sane to get around this as it will feel unnatural either way.
So maybe it's time to adjust your preferences.
 Arrays, however, will
 not suffer at all from switching to array.resize(42) syntax from
 array.length = 42 syntax.
Well I think this is a given now. So again - time to adjust preferences :o). Andrei
Jan 28 2013
next sibling parent "eles" <eles eles.com> writes:
On Monday, 28 January 2013 at 21:43:25 UTC, Andrei Alexandrescu 
wrote:
 On 1/28/13 4:32 PM, Dicebot wrote:
 On Monday, 28 January 2013 at 18:43:19 UTC, Andrei 
 Alexandrescu wrote:
 Arrays, however, will
 not suffer at all from switching to array.resize(42) syntax 
 from
 array.length = 42 syntax.
Well I think this is a given now. So again - time to adjust preferences :o).
My feeling is that the array.length getter/setter problem is affected by the perceived assymetry between the getter and the setter operation. Even more, that feeling is exacerbated by the involvment of a canonical type. People expect some expensive background operations for user-defined, complicated types, but not for canonical types. Properties too, are plagued by this, but at least there the choice is explicitly marked and assumed. As for the a=b bigInts vs the array.length=5 problem: the former operation affects the content of a and b. The latter not only affects the content of array.length, but also the very content of array itself. I know the border is thin, however, it exists at the psychological level, since many will gladly accept reallocation in a=b, but not in array.length=5. Maybe is just the power of habit. Maybe not.
Jan 28 2013
prev sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Monday, 28 January 2013 at 21:43:25 UTC, Andrei Alexandrescu 
wrote:
 So maybe it's time to adjust your preferences.
Ye, I know, I speak too much :( Sure, switching to low profile mode.
Jan 29 2013
next sibling parent "eles" <eles eles.com> writes:
On Tuesday, 29 January 2013 at 10:26:54 UTC, Dicebot wrote:
 On Monday, 28 January 2013 at 21:43:25 UTC, Andrei Alexandrescu 
 wrote:
 So maybe it's time to adjust your preferences.
Ye, I know, I speak too much :( Sure, switching to low profile mode.
Reason and reasonable trade-off should prevail.
Jan 29 2013
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/29/13 5:26 AM, Dicebot wrote:
 On Monday, 28 January 2013 at 21:43:25 UTC, Andrei Alexandrescu wrote:
 So maybe it's time to adjust your preferences.
Ye, I know, I speak too much :( Sure, switching to low profile mode.
That's not the right conclusion. Andrei
Jan 29 2013
prev sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 27 January 2013 at 13:24:31 UTC, TommiT wrote:
 But, joking aside, I think that all hate against optional 
 parentheses stems from the increase of ambiguity they 
 indisputably cause. However, let's imagine a future where your 
 perfect D IDE paints function calls red, and variables blue.
That is not good because in functional style, you manipulate function like variable.
Jan 27 2013
prev sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 03:52:36 UTC, Andrei Alexandrescu 
wrote:
 On 1/24/13 9:54 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 18:00:06 -0800, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/13 7:36 PM, Adam Wilson wrote:
 Also non-logical special case rules like this make the 
 language harder
 to learn, therefore harder to evangelize.
Definitely. But it shouldn't be forgotten that syntactic warts are also a liability. Andrei
I would argue that given how common they already are, cost of the wart is far smaller than the benefit of not having the unique-to-D special case that makes the language that much harder to learn.
Again, the question needs asking: is it a given that we need to allow optional parentheses? Otherwise we'll keep on rehashing this over and over again.
It is NOT and workaround have been proposed to solve the UFCS () invasion case, which is probably the only one that don't boil down to lazyness when digging a little.
Jan 24 2013
prev sibling next sibling parent reply "eles" <eles eles.com> writes:
On Friday, 25 January 2013 at 00:12:48 UTC, Andrei Alexandrescu 
wrote:
 On 1/24/13 6:52 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright
 <newshound2 digitalmars.com> wrote:
This looks essentially the same as Walter's proposal.
in D. So, it is nit Walter's proposal, it is property proposal.
Jan 25 2013
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/25/13 3:10 AM, eles wrote:
 On Friday, 25 January 2013 at 00:12:48 UTC, Andrei Alexandrescu wrote:
 On 1/24/13 6:52 PM, Adam Wilson wrote:
 On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright
 <newshound2 digitalmars.com> wrote:
This looks essentially the same as Walter's proposal.
So, it is nit Walter's proposal, it is property proposal.
Agreed. Andrei
Jan 25 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-01-25 01:12, Andrei Alexandrescu wrote:

 public Action temp { get; set; }
 public Action Event { get { return temp; } }
 t.Event; //returns the delegate
 t.Event(); //calls the delegate.

 Simple, clean, clear, concise. No problems with optional parens.


This looks essentially the same as Walter's proposal.
This code contains explicit properties. Walter's proposal was to remove the explicit properties. -- /Jacob Carlborg
Jan 25 2013
prev sibling next sibling parent reply "Jesse Phillips" <Jessekphillips+D gmail.com> writes:
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 1. Empty parens are optional. If there is an ambiguity with the 
 return value taking (), the () go on the return value.
As mentioned, this seems dangerous. I'd suggest requiring when there is ambiguity. It still has generic problems, but it will never be silent.
 4. No more  property.
I'm on the side that would miss optional parens if they died. In would be nice if property actually made a function behave like a field. foo += bar; It seems there are lots of complications around this? So yes kill property. On another note, To properly correct this situation we will break code. So before you get started be sure to try out the new feature preview release approach :)
Jan 24 2013
next sibling parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 16:34:44 -0800, Jesse Phillips  
<Jessekphillips+D gmail.com> wrote:

 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 1. Empty parens are optional. If there is an ambiguity with the return  
 value taking (), the () go on the return value.
As mentioned, this seems dangerous. I'd suggest requiring when there is ambiguity. It still has generic problems, but it will never be silent.
 4. No more  property.
I'm on the side that would miss optional parens if they died. In would be nice if property actually made a function behave like a field. foo += bar; It seems there are lots of complications around this? So yes kill property. On another note, To properly correct this situation we will break code. So before you get started be sure to try out the new feature preview release approach :)
The problem is that the moment we start talking about property the optional parens people (colloquially referred to henceforth as "your side") start jumping in and attacking us about how removing optional parens would make your sides lives utter misery. I don't even notice the extra parens any more. But most importantly, the syntax is ambiguous to neither the compiler or myself, I know at a subconscious level what I am looking at.) However, the property issue can be addressed without removing your sides optional parens. Adam Ruppe is working on just such a fix right now. Everyone just needs to relax and take a chill pill (or a shot of whiskey if that's your thing). -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 25 January 2013 at 00:43:46 UTC, Adam Wilson wrote:
 However, the  property issue can be addressed without removing 
 your sides optional parens. Adam Ruppe is working on just such 
 a fix right now.
Well, not right now - I made progress on it a while ago and hit a snag. Can't work on it now because I'm actually behind schedule on an important work product that is coming up on a deadline in a few weeks. I can waste a few minutes to argue, but a few hours or days to hack dmd is a no go right now.
Jan 24 2013
parent "Adam Wilson" <flyboynw gmail.com> writes:
On Thu, 24 Jan 2013 16:47:34 -0800, Adam D. Ruppe  
<destructionator gmail.com> wrote:

 On Friday, 25 January 2013 at 00:43:46 UTC, Adam Wilson wrote:
 However, the  property issue can be addressed without removing your  
 sides optional parens. Adam Ruppe is working on just such a fix right  
 now.
Well, not right now - I made progress on it a while ago and hit a snag. Can't work on it now because I'm actually behind schedule on an important work product that is coming up on a deadline in a few weeks. I can waste a few minutes to argue, but a few hours or days to hack dmd is a no go right now.
I know how that is. No worries. My misunderstanding. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/25/2013 01:42 AM, Adam Wilson wrote:
 ...

 day. I don't even notice the extra parens any more. But most
 importantly, the syntax is ambiguous to neither the compiler or myself,
 I know at a subconscious level what I am looking at.)
 ...
working in other languages.
Jan 24 2013
prev sibling parent reply "Jesse Phillips" <Jessekphillips+D gmail.com> writes:
On Friday, 25 January 2013 at 00:43:46 UTC, Adam Wilson wrote:
 The problem is that the moment we start talking about  property 
 the optional parens people (colloquially referred to henceforth 
 as "your side") start jumping in and attacking us about how 
 removing optional parens would make your sides lives utter 
 misery.
Well, I'd hope property could give the compiler enough information to give syntax that matches fields. That hasn't happened yet so I don't see it worth keeping. And if the property syntax has to be changed from a function I'd consider it a failure too. That said many that want property, want optional parens to die, as shown by your side comment that follows.

 freaking, day. I don't even notice the extra parens any more. 
 But most importantly, the syntax is ambiguous to neither the 
 compiler or myself, I know at a subconscious level what I am 
 looking at.)
I haven't had to deal with reading much other peoples code in D or Ruby, so I don't have much information on the readability challenges from one side or the other, but so far my experience has been that it doesn't matter. And while it is a hot topic, D has had it for a long time and no real evidence it is a big problem has risen. (Only the return a delegate from a function)
Jan 25 2013
parent reply "Rob T" <alanb ucora.com> writes:
On Friday, 25 January 2013 at 16:43:45 UTC, Jesse Phillips wrote:
[...]
 That said many that want  property, want optional parens to 
 die, as shown by your side comment that follows.
I think that observation pins the whole debate down, and it's an incredible amount of debate for something that boils down little more than personal taste. We don't even need property-like behavior, it's not that important. Meanwhile really serious problems exist that are not being attended to. The concept of a property works perfectly fine without explicit property enforcement (except for perhaps an edge case or two that can be corrected). When I started with D, the TDPL told me that I had to put property in, and it was actually a relief to discover that I did not have to do that. It's a waste of time, and more than half the time I could not decide if I wanted property-like behavior or not, so the lack of enforcement was a plus for me. If the default behavior is optional parens plus no property enforcement, i.e., the current behavior, then for the people who want to change the default behavior need to specify property and we implement enforcement for those situations. However, for the remaining functions, the property behavior is optional and not enforced, so some means such as the function proposal will be needed to enforce the traditional c-like function call syntax. But is there any real need for the extra complications of implementing property and c-style function call enforcement? This is D and there's no law that states that D must behave exactly like C. I think Walters proposal to shoot property is perfectly sound. Get rid of it, fix the edge cases, and move on to solving the problems that matter a whole lot more than this one. If Walter's proposal is not sound, then we need real clear technical reasons why enforcement is required, as opposed to arguments that boil down to personal tastes. --rt
Jan 25 2013
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 25 January 2013 at 17:17:11 UTC, Rob T wrote:
 I think Walters proposal to shoot  property is perfectly sound. 
 Get rid of it, fix the edge cases, and move on to solving the 
 problems that matter a whole lot more than this one.
The reason property exists in the first place is to fix the edge cases. It got screwed up beyond all recognition by the parenthesis debate, extending its effect well, well beyond the edge case... but that *was* why it was introduced in the first place.
Jan 25 2013
parent reply "Rob T" <alanb ucora.com> writes:
On Friday, 25 January 2013 at 17:24:23 UTC, Adam D. Ruppe wrote:
 On Friday, 25 January 2013 at 17:17:11 UTC, Rob T wrote:
 I think Walters proposal to shoot  property is perfectly 
 sound. Get rid of it, fix the edge cases, and move on to 
 solving the problems that matter a whole lot more than this 
 one.
The reason property exists in the first place is to fix the edge cases. It got screwed up beyond all recognition by the parenthesis debate, extending its effect well, well beyond the edge case... but that *was* why it was introduced in the first place.
So historically, the fist implementation of the property concept was through a syntax change, allowing removal of empty parens for the getter and assignment syntax for the setter. But due to edge cases, property was conjured up to solve them through property syntax enforcement. The syntax change was partially implemented without property enforcement leaving it optional, and this brought on the big debate concerning enforcement of parens. Why was a partial implementation of an experimental half-backed idea released into the wild? In the future, we can avoid messes like this through a better design and development process with a little planning behind it. The property feature would have remained in experimental mode until most or all of the debate had been settled, then moved into beta for usage trials, and finally into a production release with no more debate and no more bugs or broken edge cases remaining. --rt
Jan 25 2013
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 25 January 2013 at 18:00:24 UTC, Rob T wrote:
 So historically, the fist implementation of the property 
 concept was through a syntax change, allowing removal of empty 
 parens for the getter and assignment syntax for the setter.
That was actually before my time. The optional parens feature has been in D for as long as I can remember; it was there well before 1.0. But yeah, property was added a few years ago over concerns about a small handful of edge cases.
 Why was a partial implementation of an experimental half-backed 
 idea released into the wild?
This is the reason it is on a compiler switch, -property, instead of the main language. Without -property, the property decoration is ignored. (And with -property, it doesn't do anything useful. The implementation is basically: -property: break my code property: please don't break this code It doesn't fix a single thing, and IIRC the implementor knew it; he just put it in as a first step toward something more complete.)
Jan 25 2013
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-25 19:00, Rob T wrote:

 Why was a partial implementation of an experimental half-backed idea
 released into the wild?
It seems just to be how things are done in the D community. Another recent example of this is the UDA that popped up and got implemented from nowhere. -- /Jacob Carlborg
Jan 26 2013
next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Saturday, 26 January 2013 at 13:28:46 UTC, Jacob Carlborg 
wrote:
 On 2013-01-25 19:00, Rob T wrote:

 Why was a partial implementation of an experimental 
 half-backed idea
 released into the wild?
It seems just to be how things are done in the D community. Another recent example of this is the UDA that popped up and got implemented from nowhere.
Jan 26 2013
prev sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Saturday, 26 January 2013 at 13:28:46 UTC, Jacob Carlborg 
wrote:
 Another recent example of this is the UDA that popped up and 
 got implemented from nowhere.
That design is almost identical to a discussion we had a few months ago about it though; the timing was a surprise, but it wasn't bungled the way property was.
Jan 26 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-01-26 17:26, Adam D. Ruppe wrote:

 That design is almost identical to a discussion we had a few months ago
 about it though; the timing was a surprise, but it wasn't bungled the
 way  property was.
Not the syntax. Walter added a two syntaxes one deprecated using brackets and the one we're using now with the at sign and parentheses. -- /Jacob Carlborg
Jan 26 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/25/13 12:17 PM, Rob T wrote:
 On Friday, 25 January 2013 at 16:43:45 UTC, Jesse Phillips wrote:
 [...]
 That said many that want  property, want optional parens to die, as
 shown by your side comment that follows.
I think that observation pins the whole debate down, and it's an incredible amount of debate for something that boils down little more than personal taste. We don't even need property-like behavior, it's not that important. Meanwhile really serious problems exist that are not being attended to. The concept of a property works perfectly fine without explicit property enforcement (except for perhaps an edge case or two that can be corrected). When I started with D, the TDPL told me that I had to put property in, and it was actually a relief to discover that I did not have to do that. It's a waste of time, and more than half the time I could not decide if I wanted property-like behavior or not, so the lack of enforcement was a plus for me. If the default behavior is optional parens plus no property enforcement, i.e., the current behavior, then for the people who want to change the default behavior need to specify property and we implement enforcement for those situations. However, for the remaining functions, the property behavior is optional and not enforced, so some means such as the function proposal will be needed to enforce the traditional c-like function call syntax. But is there any real need for the extra complications of implementing property and c-style function call enforcement? This is D and there's no law that states that D must behave exactly like C. I think Walters proposal to shoot property is perfectly sound. Get rid of it, fix the edge cases, and move on to solving the problems that matter a whole lot more than this one. If Walter's proposal is not sound, then we need real clear technical reasons why enforcement is required, as opposed to arguments that boil down to personal tastes.
I agree with all of the above. There has been a fair amount of rationalization and appeal to emotion on all sides. It would be great to get back to reason and clearly compartmentalize objective arguments (of which there have been a few very profound ones) and personal preference. On the objective side there are a few challenges that have been well discussed: 1. Syntactic and semantic implications of properties that return callable entities 2. Introspection, how does one distinguish between a genuine field and a property when necessary 3. Impact on existing and future code On the subjective side, Walter's and my opinion and experience have been largely aligned. With that in mind but speaking for myself unless otherwise noted, here are some bits of my subjective opinion: 1. In C and C++ the syntax "func" or "object.method" does nothing interesting or useful. In C, "func" is actually equivalent with "&func". In C it's actually worse, "func" yields the type "reference to function" which is highly restricted and obeys some rather arcane rules (in particular it's implicitly convertible to pointer to function). C has no methods so the syntax "object.method" does not apply to it. In C++, "object.method" is probably the oddest construct in the entire language: it returns a type that exists but has no name, is not expressible syntactically, is not first class (one can't assign "object.method" to a variable), and has only two allowed operations: take address or apply the function call operator "()". Various C++ implementations have extensions that fix this. Both Walter and I consider these serious lapses in language design. Two of the most accessible elements of syntax do things of considerably low interest and use. I hope I now clarified why I have a dim view of arguments that - implicitly or explicitly - assume the C or C++ behavior in this area is an example to follow on technical grounds. (Clearly, familiarity is a much better argument.) 2. I have tried to add property appropriately in Phobos, in particular for ranges: struct SomeRange { property bool empty(); property ref T front(); void popFront(); } There's more " property" to be seen with "save" and "back". Subjectively that just didn't work well for me. It adds clutter to an otherwise simple and straightforward API, and penalizes usage for benefits that I could never reap. I understand how some people are glad to put that in everywhere, and find meaning in requiring parens with popFront and popBack but not the others. Yet for me it was liberating (see 1 above too) I could just write "r.popFront" without the parens and have it do its deed. It is the right semantics for a simple syntax. 3. Whatever we do going forward should be _simple_ but not _simplistic_. Right now it's easy to forget that we're all close to the subject. We have it in working memory (at least it's what I think about all the time) and any incremental complexity is an easy cost to absorb intellectually. But when we need to teach this to newcomers or even approach it again with a "cold cache", any undue complexity will be jarring. 4. Whether we like it or not, backward compatibility is an issue. The parens or no parens aspect upon a function call is too ubiquitous to write off as an obscure circumstance. So I don't think the obscurity argument applies. Granted, there are several ways to approach the compatibility issue, all with their specific tradeoffs. All I'm saying is that careful considerations of compatibility must be integral to whatever we do about this. 5. This is a matter in which reasonable people may disagree. For better or worse Walter and to a lesser extent myself are in the position to decide. We're doing the best to gather, mind, and integrate opinions and suggestions but clearly no decision that would please everyone. So please bear with us. I understand this may be frustrating but the best we all can do is think beyond our own preference and on behalf of the larger community. Thanks, Andrei
Jan 25 2013
next sibling parent "mist" <none none.none> writes:
Finally, stating some opinions clearly.
Thank you.
Jan 25 2013
prev sibling next sibling parent Johannes Pfau <nospam example.com> writes:
Am Fri, 25 Jan 2013 14:59:58 -0500
schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 I agree with all of the above. There has been a fair amount of 
 rationalization and appeal to emotion on all sides. It would be great
 to get back to reason and clearly compartmentalize objective
 arguments (of which there have been a few very profound ones) and
 personal preference.
Do that on this wiki page: http://wiki.dlang.org/Property_Discussion_Wrap-up
 There's more " property" to be seen with "save" and "back".
 Subjectively that just didn't work well for me. It adds clutter to an
 otherwise simple and straightforward API, and penalizes usage for
 benefits that I could never reap.
I think it actually makes sense. I even tried writing ranges for std.digest where front was not a property but a field and was surprised it didn't work. (isInputRange shouldn't check for property. It should check for "can be used like a field" which means field+property.).
 I understand how some people are
 glad to put that in everywhere, and find meaning in requiring parens
 with popFront and popBack but not the others. Yet for me it was
 liberating (see 1 above too) I could just write "r.popFront" without
 the parens and have it do its deed. It is the right semantics for a
 simple syntax.
Please read the wiki page. popFront or popFront() is orthogonal to the property discussion.
 
 3. Whatever we do going forward should be _simple_ but not
 _simplistic_. Right now it's easy to forget that we're all close to
 the subject. We have it in working memory (at least it's what I think
 about all the time) and any incremental complexity is an easy cost to
 absorb intellectually.
 
 But when we need to teach this to newcomers or even approach it again 
 with a "cold cache", any undue complexity will be jarring.
Wiki page, wiki page ;-)
 
 4. Whether we like it or not, backward compatibility is an issue. The 
 parens or no parens aspect upon a function call is too ubiquitous to 
 write off as an obscure circumstance. So I don't think the obscurity 
 argument applies.
 
 Granted, there are several ways to approach the compatibility issue,
 all with their specific tradeoffs. All I'm saying is that careful 
 considerations of compatibility must be integral to whatever we do
 about this.
The approach described on the wiki does break some code, but that code shouldn't compile anyway: property functions with wrong number of arguments and similar stuff. Only controversial thing is taking the address of a property, but I can't think of a solution which would work well with generic code so I'd just say forbid that.
 
 5. This is a matter in which reasonable people may disagree. For
 better or worse Walter and to a lesser extent myself are in the
 position to decide. We're doing the best to gather, mind, and
 integrate opinions and suggestions but clearly no decision that would
 please everyone.
Would be nice if the arguments for the final decision are added to the wiki page :-)
Jan 25 2013
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 25 January 2013 at 19:59:59 UTC, Andrei Alexandrescu 
wrote:
 2. I have tried to add  property appropriately in Phobos, in 
 particular for ranges:
These are examples of why I'm firmly in the pro-optional parenthesis camp. With them, stuff like this becomes irrelevant; it works either way. But, remember, the problem property needs to solve is none of this. There's no pressing reason to put it on range functions. My view is property maybe somewhat rare in usage: if in doubt, do NOT use it. But there's cases where there is no doubt, and we don't want to throw the baby out with the bathwater there. One example where I'd love property: a dynamic object. Suppose we extend Variant to work Javascript style: Variant v; v.prop = function() { }; v.prop(); // we expect this to call the function, not return a reference to it That would be an property.... range.popFront doesn't need to be. It works fine with the existing optional parenthesis rule.
Jan 25 2013
prev sibling next sibling parent reply "mist" <none none.none> writes:
2 cents regarding your position on " property" usage in phobos:

1) You can always use shorter syntax:
 property:
int func1();
int func2();
...

2) D is not scripting language (primarily) and as such should 
value issues related to long-term large code base support more 
than saving some typing in declaration. It is slightly similar to 
strong vs weak typing.

That is not gonna convince you but I hope this will be taken into 
consideration somehow.
Jan 25 2013
parent reply "Rob T" <alanb ucora.com> writes:
On Friday, 25 January 2013 at 21:51:14 UTC, mist wrote:
 2 cents regarding your position on " property" usage in phobos:

 1) You can always use shorter syntax:
  property:
 int func1();
 int func2();
 ...
This already works property { int func1(); int func2(); } --rt
Jan 25 2013
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 23:04:58 Rob T wrote:
 On Friday, 25 January 2013 at 21:51:14 UTC, mist wrote:
 2 cents regarding your position on " property" usage in phobos:
 
 1) You can always use shorter syntax:
  property:
 int func1();
 int func2();
 ...
This already works property { int func1(); int func2(); }
They both already work and have do so for ages. - Jonathan M Davis
Jan 25 2013
parent reply "mist" <none none.none> writes:
On Friday, 25 January 2013 at 22:15:51 UTC, Jonathan M Davis 
wrote:
 They both already work and have do so for ages.

 - Jonathan M Davis
Erm? Yes, and thus it was an answer to "you need to mess every function declaration with an annotation"
Jan 25 2013
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 23:23:50 mist wrote:
 On Friday, 25 January 2013 at 22:15:51 UTC, Jonathan M Davis
 
 wrote:
 They both already work and have do so for ages.
 
 - Jonathan M Davis
Erm? Yes, and thus it was an answer to "you need to mess every function declaration with an annotation"
I know. I was responding to Rob's post which implied that the syntax you gave didn't currently work. - Jonathan M Davis
Jan 25 2013
parent reply "Rob T" <alanb ucora.com> writes:
On Friday, 25 January 2013 at 22:39:07 UTC, Jonathan M Davis 
wrote:
 On Friday, January 25, 2013 23:23:50 mist wrote:
 On Friday, 25 January 2013 at 22:15:51 UTC, Jonathan M Davis
 
 wrote:
 They both already work and have do so for ages.
 
 - Jonathan M Davis
Erm? Yes, and thus it was an answer to "you need to mess every function declaration with an annotation"
I know. I was responding to Rob's post which implied that the syntax you gave didn't currently work. - Jonathan M Davis
I misread the post by mist, I incorrectly thought that it was a new syntax proposal as I did not know about property:. --rt
Jan 25 2013
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 23:56:24 Rob T wrote:
 I misread the post by mist, I incorrectly thought that it was a
 new syntax proposal as I did not know about  property:
: works works with any function attribute, as does {}. - Jonathan M Davis
Jan 25 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-01-26 02:48, Jonathan M Davis wrote:

 : works works with any function attribute, as does {}.
And even for user defined attributes :) -- /Jacob Carlborg
Jan 26 2013
prev sibling next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 14:59:58 Andrei Alexandrescu wrote:
 2. I have tried to add  property appropriately in Phobos, in particular
 for ranges:
 
 struct SomeRange {
  property bool empty();
  property ref T front();
 void popFront();
 }
 
 There's more " property" to be seen with "save" and "back". Subjectively
 that just didn't work well for me. It adds clutter to an otherwise
 simple and straightforward API, and penalizes usage for benefits that I
 could never reap. I understand how some people are glad to put that in
 everywhere, and find meaning in requiring parens with popFront and
 popBack but not the others. Yet for me it was liberating (see 1 above
 too) I could just write "r.popFront" without the parens and have it do
 its deed. It is the right semantics for a simple syntax.
That's simply a question of being able to make function calls without parens. That's different from the question of properties, much as there may be syntactic similarities. While properties do involve not using parens, there's a lot more to them than simply not using parens. A property function is fundamentally different from a normal function by its very nature, not just by its call syntax. A property is an abstraction for a variable (and therefore should be swappable with a variable), whereas a function is explicitly an action. So, regardless of what we do with parenless function calls, getting rid of explicit properties will have serious side effects.
 5. This is a matter in which reasonable people may disagree. For better
 or worse Walter and to a lesser extent myself are in the position to
 decide. We're doing the best to gather, mind, and integrate opinions and
 suggestions but clearly no decision that would please everyone. So
 please bear with us. I understand this may be frustrating but the best
 we all can do is think beyond our own preference and on behalf of the
 larger community.
If we throw away property, then it will be impossible to swap between using variables and property functions, which is one of the main purposes of properties. For instance, it should be possible for a range's front to be variable if that range doesn't need a function for it. There are currently implementation problems with property which prevent us from being able to do that with property, but they can be fixed. However, without explicit properties of some kind, it's just not possible. Not only are the semantics of a property function still too different from a variable (e.g. += doesn't yet work with a property function), but the issue of parens on property functions is a problem. We need to able to make it so that it's illegal to use parens on a property function, not only so that you could potentially swap it out for a public variable if the function was no longer needed but more importantly so that generic APIs (such as ranges) can guarantee that using a variable instead of a property function will work (e.g. if you can call front with parens, then front can never be an actual variable). And for that, you need explicit properties, not just the syntactic sugar of being allowed to drop parens. Also, too much of this discussion has focused on getters. property also has a large impact with setter properties. Without it, you'll be able to do stuff like range.popFrontN = 7; "hello".icmp = "world"; "/usr/bin".buildPath = "dmd"; which makes no sense. As long as we have explicit properties, we can restrict the setter syntax to functions that are actually properties and could conceivably be replaced with variables. Without them, arbitrary functions could be set as if they were variables, many (most?) of which would make absolutely no sense as variables under any circumstances. Keeping parenless functions is one thing, but getting rid of explicit properties is another thing altogether. - Jonathan M Davis
Jan 25 2013
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/25/2013 2:14 PM, Jonathan M Davis wrote:
 A property function is fundamentally different from a
 normal function by its very nature, not just by its call syntax.
I would have agreed with you on that for years, simply taking its veracity as an axiom, but lately I am not convinced at all of that assertion. I suspect the differences between a property, field, and method are purely contrivance. For example, even accessing a global variable isn't straightforward, if you look under the hood. If it's in a DLL or TLS, there may be a function call in there that is non-trivial.
Jan 25 2013
next sibling parent Manfred Nowak <svv1999 hotmail.com> writes:
Walter Bright wrote:

 For example, even accessing a global variable isn't
 straightforward, if you look under the hood.
Depending on the education under the hood is always a turing machine, Lisp, pseudo code, ... -manfred
Jan 25 2013
prev sibling next sibling parent reply "Mehrdad" <wfunction hotmail.com> writes:
On Saturday, 26 January 2013 at 05:39:05 UTC, Walter Bright wrote:
 On 1/25/2013 2:14 PM, Jonathan M Davis wrote:
 A property function is fundamentally different from a
 normal function by its very nature, not just by its call 
 syntax.
I would have agreed with you on that for years, simply taking its veracity as an axiom, but lately I am not convinced at all of that assertion. I suspect the differences between a property, field, and method are purely contrivance. For example, even accessing a global variable isn't straightforward, if you look under the hood. If it's in a DLL or TLS, there may be a function call in there that is non-trivial.
Walter, that's not how TLS variables are generally implemented in C/C++. They're *normal* variables, placed in a special section of the executable, which is automatically switched in and out on every context switch by the OS. This is true on Windows, and I believe in Linux as well (http://stackoverflow.com/questions/2459692)
Jan 25 2013
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/25/2013 10:06 PM, Mehrdad wrote:
 Walter, that's not how TLS variables are generally implemented in C/C++.
Since I implemented them, I know how they work.
 They're *normal* variables, placed in a special section of the executable,
which
 is automatically switched in and out on every context switch by the OS.
This is not necessarily true at all. It isn't for OSX, for example, and there's nothing in the semantics of TLS which preclude calling a function.
Jan 25 2013
parent reply "Mehrdad" <wfunction hotmail.com> writes:
On Saturday, 26 January 2013 at 07:25:24 UTC, Walter Bright wrote:
 On 1/25/2013 10:06 PM, Mehrdad wrote:
 Walter, that's not how TLS variables are generally implemented 
 in C/C++.
Since I implemented them, I know how they work.
I wasn't being pedantic. That's why I said generally, not always. Obviously you can implement things a million different ways...
 They're *normal* variables, placed in a special section of the 
 executable, which
 is automatically switched in and out on every context switch 
 by the OS.
This is not necessarily true at all. It isn't for OSX, for example, and there's nothing in the semantics of TLS which preclude calling a function.
Again, I didn't say they're "necessarily" true either, hence why I mentioned Linux and Windows specifically. OS X is really the odd one out here, not Windows or Linux. But you missed my point, which was, yes, a lot of things COULD contain function calls. Even the two lines int i = 0; i++; COULD contain a function call, but how is that in any shape or form relevant to the discussion about property in any way? Generally, it isn't a function call, and as far as the code is concerned, it isn't a function call. The fact that you may have happened to implement something as a function call doesn't mean anything with regards to the difference between a function call and a direct access for the _programmer_.
Jan 25 2013
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/25/2013 11:52 PM, Mehrdad wrote:
 The fact that you may have happened to implement something as a function call
 doesn't mean anything with regards to the difference between a function call
and
 a direct access for the _programmer_.
I.e. the difference is purely a contrivance, which was my point.
Jan 26 2013
parent "deadalnix" <deadalnix gmail.com> writes:
On Saturday, 26 January 2013 at 09:04:47 UTC, Walter Bright wrote:
 On 1/25/2013 11:52 PM, Mehrdad wrote:
 The fact that you may have happened to implement something as 
 a function call
 doesn't mean anything with regards to the difference between a 
 function call and
 a direct access for the _programmer_.
I.e. the difference is purely a contrivance, which was my point.
Yes, that the whole point of abstraction. It happen that variables and functions are both very useful ones.
Jan 26 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-01-26 08:52, Mehrdad wrote:

 Again, I didn't say they're "necessarily" true either, hence why I
 mentioned Linux and Windows specifically.
 OS X is really the odd one out here, not Windows or Linux.
They can be implemented as a function call on (at least) Linux as well. It's depends on which model is used. Which model is used then depends on various things like who the compiler is able to optimize and dynamic libraries are involved or not. Mac OS X chose the easiest way out and implemented only one mode. A model that works in all cases, and that is a function call. -- /Jacob Carlborg
Jan 26 2013
prev sibling parent Johannes Pfau <nospam example.com> writes:
Am Fri, 25 Jan 2013 21:38:44 -0800
schrieb Walter Bright <newshound2 digitalmars.com>:

 On 1/25/2013 2:14 PM, Jonathan M Davis wrote:
 A property function is fundamentally different from a
 normal function by its very nature, not just by its call syntax.
I would have agreed with you on that for years, simply taking its veracity as an axiom, but lately I am not convinced at all of that assertion. I suspect the differences between a property, field, and method are purely contrivance. For example, even accessing a global variable isn't straightforward, if you look under the hood. If it's in a DLL or TLS, there may be a function call in there that is non-trivial.
Although variable access might be implemented as a non-trivial function calls everyone tries to make these as fast as possible. Think of PLT/GOT or the TLS register on ARM processors. And this is the difference between variable/property and function: Access to the former has to be 'fast'. There's no real definition of fast in this case, but I doubt an O(n^2) implementation of TLS or variable access in general would be acceptable to anyone.
Jan 26 2013
prev sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Friday, 25 January 2013 at 19:59:59 UTC, Andrei Alexandrescu 
wrote:
 1. Syntactic and semantic implications of properties that 
 return callable entities
I don't understand why this is a special case in the first place. It should behave just like a variable of the same type, period.
 C has no methods so the syntax "object.method" does not apply 
 to it. In C++, "object.method" is probably the oddest construct 
 in the entire language: it returns a type that exists but has 
 no name, is not expressible syntactically, is not first class 
 (one can't assign "object.method" to a variable), and has only 
 two allowed operations: take address or apply the function call 
 operator "()". Various C++ implementations have extensions that 
 fix this.

 Both Walter and I consider these serious lapses in language 
 design. Two of the most accessible elements of syntax do things 
 of considerably low interest and use. I hope I now clarified 
 why I have a dim view of arguments that - implicitly or 
 explicitly - assume the C or C++ behavior in this area is an 
 example to follow on technical grounds. (Clearly, familiarity 
 is a much better argument.)
nicely. That is why I propose to do the same here (and serious option). I know that Javascript is a poorly designed language, but on that very specific topic most people agree that was has been done at the time was pure genius. It removes the weird C/C++ object that have no expressible type, and simplify the situation. Additional benefice is that funName now behave the same in all situation, which is also a simplification of the situation.
 2. I have tried to add  property appropriately in Phobos, in 
 particular for ranges:

 struct SomeRange {
    property bool empty();
    property ref T front();
   void popFront();
 }

 There's more " property" to be seen with "save" and "back". 
 Subjectively that just didn't work well for me. It adds clutter 
 to an otherwise simple and straightforward API, and penalizes 
 usage for benefits that I could never reap. I understand how 
 some people are glad to put that in everywhere, and find 
 meaning in requiring parens with popFront and popBack but not 
 the others. Yet for me it was liberating (see 1 above too) I 
 could just write "r.popFront" without the parens and have it do 
 its deed. It is the right semantics for a simple syntax.
If you ask me, I think property have been abused in range design. Many ranges properties really shouldn't be properties. Additionally, this kind of boilerplate can easily be written by efficient to write program in them, as the tooling to a great job for you. As I discussed with you, tooling appears slowly in D because the language itself is unstable, the specification have many quirks, and dmd is not reusable for the job. We can either make more quirks in order to make our life easier, or less quirks in order for tools to make our life easier. The first one have immediate return on investment, however, it is shortsighted IMO.
 3. Whatever we do going forward should be _simple_ but not 
 _simplistic_. Right now it's easy to forget that we're all 
 close to the subject. We have it in working memory (at least 
 it's what I think about all the time) and any incremental 
 complexity is an easy cost to absorb intellectually.

 But when we need to teach this to newcomers or even approach it 
 again with a "cold cache", any undue complexity will be jarring.
Everybody know how a variable behave. This is the most simple and straightforward way for a property to work.
 4. Whether we like it or not, backward compatibility is an 
 issue. The parens or no parens aspect upon a function call is 
 too ubiquitous to write off as an obscure circumstance. So I 
 don't think the obscurity argument applies.

 Granted, there are several ways to approach the compatibility 
 issue, all with their specific tradeoffs. All I'm saying is 
 that careful considerations of compatibility must be integral 
 to whatever we do about this.
Whatever solution we choose, it will break stuff. We'd better think of a nice way to handle the transition than a way to not break code. Think that PHP went from value typed object to reference typed object between 4 and 5. This is a major breakage of a codebase that is much bigger than D's. I was made possible by a great release management. We'd better acknowledge that our release management sucks, and fix that, than fearing the consequences of it everywhere.
Jan 25 2013
parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
26-Jan-2013 09:04, deadalnix пишет:
 On Friday, 25 January 2013 at 19:59:59 UTC, Andrei Alexandrescu wrote:
 1. Syntactic and semantic implications of properties that return
 callable entities
I don't understand why this is a special case in the first place. It should behave just like a variable of the same type, period.
 C has no methods so the syntax "object.method" does not apply to it.
 In C++, "object.method" is probably the oddest construct in the entire
 language: it returns a type that exists but has no name, is not
 expressible syntactically, is not first class (one can't assign
 "object.method" to a variable), and has only two allowed operations:
 take address or apply the function call operator "()". Various C++
 implementations have extensions that fix this.

 Both Walter and I consider these serious lapses in language design.
 Two of the most accessible elements of syntax do things of
 considerably low interest and use. I hope I now clarified why I have a
 dim view of arguments that - implicitly or explicitly - assume the C
 or C++ behavior in this area is an example to follow on technical
 grounds. (Clearly, familiarity is a much better argument.)
has been mentioned here, it sound like a serious option). I know that Javascript is a poorly designed language, but on that very specific topic most people agree that was has been done at the time was pure genius. It removes the weird C/C++ object that have no expressible type, and simplify the situation. Additional benefice is that funName now behave the same in all situation, which is also a simplification of the situation.
 2. I have tried to add  property appropriately in Phobos, in
 particular for ranges:

 struct SomeRange {
    property bool empty();
    property ref T front();
   void popFront();
 }

 There's more " property" to be seen with "save" and "back".
 Subjectively that just didn't work well for me. It adds clutter to an
 otherwise simple and straightforward API, and penalizes usage for
 benefits that I could never reap. I understand how some people are
 glad to put that in everywhere, and find meaning in requiring parens
 with popFront and popBack but not the others. Yet for me it was
 liberating (see 1 above too) I could just write "r.popFront" without
 the parens and have it do its deed. It is the right semantics for a
 simple syntax.
If you ask me, I think property have been abused in range design. Many ranges properties really shouldn't be properties. Additionally, this kind of boilerplate can easily be written by to write program in them, as the tooling to a great job for you.
Automated tooling is admitting a defeat if we talk about expressive languages. Java was designed with automatic code manipulation in mind and even with todays proliferation of generators it's a pain to work with. TL;DR code is written once and read many times. -- Dmitry Olshansky
Jan 26 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Saturday, 26 January 2013 at 08:29:40 UTC, Dmitry Olshansky 
wrote:
 Automated tooling is admitting a defeat if we talk about 
 expressive languages. Java was designed with automatic code 
 manipulation in mind and even with todays proliferation of 
 generators it's a pain to work with.

 TL;DR code is written once and read many times.
Using tooling is admitting defeat ? That is very misplaced pride (and not even an argument). And if you think that verbose code is less readable, think twice, or follow both links : http://code.jquery.com/jquery.js http://code.jquery.com/jquery.min.js No doubt the less verbose one is more readable !
Jan 26 2013
parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
26-Jan-2013 12:57, deadalnix пишет:
 On Saturday, 26 January 2013 at 08:29:40 UTC, Dmitry Olshansky wrote:
 Automated tooling is admitting a defeat if we talk about expressive
 languages. Java was designed with automatic code manipulation in mind
 and even with todays proliferation of generators it's a pain to work
 with.

 TL;DR code is written once and read many times.
Using tooling is admitting defeat ? That is very misplaced pride (and not even an argument).
There is no pride. Requiring a separate tool to generate code even in simple cases is a defeat. Using tools is fine to refactor, navigate etc. but not to generate "boilerplate" as in the end it still has to be read, modified and fitted with the rest of code. Boilerplate generally has no place in code at all if we can help it.
 And if you think that verbose code is less readable, think twice, or
 follow both links :
 http://code.jquery.com/jquery.js
 http://code.jquery.com/jquery.min.js

 No doubt the less verbose one is more readable !
Obfuscation/minification and boilerplate is not the same. And I bet the second example is the same exact code so you missed the point completely. -- Dmitry Olshansky
Jan 26 2013
prev sibling parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 01/24/2013 07:34 PM, Jesse Phillips wrote:
 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 1. Empty parens are optional. If there is an ambiguity with the return
 value taking (), the () go on the return value.
As mentioned, this seems dangerous. I'd suggest requiring when there is ambiguity. It still has generic problems, but it will never be silent.
 4. No more  property.
I'm on the side that would miss optional parens if they died. In would be nice if property actually made a function behave like a field. foo += bar; It seems there are lots of complications around this? So yes kill property.
This has nothing to do with property. It has to do with defining what += /does/ to a property. I think that what you want is semantic property rewriting. See this: http://www.prowiki.org/wiki4d/wiki.cgi?DocComments/Property#Semanticrewritingofproperties
 On another note,

 To properly correct this situation we will break code. So before you get
 started be sure to try out the new feature preview release approach :)
Jan 24 2013
prev sibling next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 10:37:51 kenji hara wrote:
 2013/1/25 kenji hara <k.hara.pg gmail.com>
 
 I have thought an additional idea.
 If we really want a feature to disable optional parentheses for normal
 functions, we can add  function attribute to the language spec.
 
 int foo();
  property int bar();
  function int baz(); // new!
 
 int x1 = foo(); // ok
 int x2 = foo; // optional parentheses, allowed
 int y1 = bar(); // disallowed, calling int is meaningless
 int y2 = bar; // ok
 int z1 = baz(); // ok
 int z2 = baz; // *disallowed* by  function attribute
I think calling a function which does not annotated with attribute without parenthesis is legal, Even if a function has some side-effects and a name looks like verb. Because native English grammar does not require parentheses. He runs(). // normal function call He runs. // optional parentheses
Honestly, I don't think that English grammar has anything to do with this. Code isn't English, even if the symbol names chosen are in English. A programming language's grammar should reflect what works best for having a language which is appropriately usable and maintainable. That doesn't necessarily have anything to do with the grammar of any natural language, especially when you consider how different programming language grammars are from those of natural languages. - Jonathan M Davis
Jan 24 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/13 9:02 PM, Jonathan M Davis wrote:
 On Friday, January 25, 2013 10:37:51 kenji hara wrote:
 2013/1/25 kenji hara<k.hara.pg gmail.com>

 I have thought an additional idea.
 If we really want a feature to disable optional parentheses for normal
 functions, we can add  function attribute to the language spec.

 int foo();
  property int bar();
  function int baz(); // new!

 int x1 = foo(); // ok
 int x2 = foo; // optional parentheses, allowed
 int y1 = bar(); // disallowed, calling int is meaningless
 int y2 = bar; // ok
 int z1 = baz(); // ok
 int z2 = baz; // *disallowed* by  function attribute
I think calling a function which does not annotated with attribute without parenthesis is legal, Even if a function has some side-effects and a name looks like verb. Because native English grammar does not require parentheses. He runs(). // normal function call He runs. // optional parentheses
Honestly, I don't think that English grammar has anything to do with this. Code isn't English, even if the symbol names chosen are in English. A programming language's grammar should reflect what works best for having a language which is appropriately usable and maintainable. That doesn't necessarily have anything to do with the grammar of any natural language, especially when you consider how different programming language grammars are from those of natural languages.
I agree parallels with natural language are tenuous. Anyhow, here's a thought. It is becoming rather clear that one way or another that optional parens are here to stay. So no more need to argue over that - it's just there. Once we consider this a given, the design space is much easier to navigate (which is what Kenji is doing). Andrei
Jan 24 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-01-25 03:19, Andrei Alexandrescu wrote:

 I agree parallels with natural language are tenuous.
No, they're not. Perhaps in this particular case. But code is for humans to be able to read and write. That's why it looks similar to natural languages. Otherwise we would just program in machine code. The computer doesn't really care. -- /Jacob Carlborg
Jan 25 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 11:09:15 kenji hara wrote:
    That is more serious than (a). If we adopt this rule, we will *really*
 get lost the way to distinguish property functions and raw data fields.
 (Note that: In current typeof(foo) already returns int. So AddressExp is
 only one way to getting (normal|property) function information by its
 type.) From the view of meta-programming, I think this makes a serious flaw.
We could add a __trait which detected whether a field was an actual variable or not. - Jonathan M Davis
Jan 24 2013
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
2013/1/25 Jonathan M Davis <jmdavisProg gmx.com>

 On Friday, January 25, 2013 11:09:15 kenji hara wrote:
    That is more serious than (a). If we adopt this rule, we will *really*
 get lost the way to distinguish property functions and raw data fields.
 (Note that: In current typeof(foo) already returns int. So AddressExp is
 only one way to getting (normal|property) function information by its
 type.) From the view of meta-programming, I think this makes a serious
flaw. We could add a __trait which detected whether a field was an actual variable or not.
OK, let's think. When a property function exists: property int foo(); static assert(__traits(isProperty, foo) == true); Pros: We can get minimum information. Cons: We cannot check whether the foo is other function attributes: pure, nothrow, safe. static assert(__traits(getPropertyType, foo).stringof == " property int()"); Pros: We can access all information about property function. Cons: __traits() is parsed as an expression, so we cannot use it as a type directly. __traits(getPropertyType, foo)* fp; // declaring function pointer Instead, some template should be required. TypeTuple!(__traits(getPropertyType, foo))[0]* fp; auto fp = &foo; // Not allowed, because property function foo returns an rvalue. auto fp = cast(function)&foo; //New, Gets a function pointer of foo Pros1: Can access fully information of foo from typeof(fp). Pros2: We can call a property function indirectly through function pointer. Pros3: Newly syntax and semantics has no conflict with existings. Cons: cast(function) and cast(delegete) necessary. auto p = cast( property)&foo; // p is a function pointer. auto p = cast( property)&s.foo; // p is a delegate. Pros: Only one new syntax is necessary. Cons: Ugly... --- In the compile world of D, a function type is already a first class object to carry the information related function. Similarly, function pointer and delegate are widely used as a runtime container to make runtime bindings to function symbols.
From these facts, creating an escape hatch from property function to normal
function type/pointer is enough worthwhile to me. It makes it possible to reuse a number of meta-programming operations for normal function/function type/function pointers. overloaded functions by CastExpression. void foo() {} void foo(int) {} auto fp = cast(void function())&foo; // fp is equal to the address of first foo. So, I prefer adding newly meanings to CastExp. Kenji Hara
Jan 24 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 13:47:31 kenji hara wrote:
 2013/1/25 Jonathan M Davis <jmdavisProg gmx.com>
 
 And actually, something far more important than any of those reasons is
 the
 issue of setters. We've focused most of this discussion on optional parens
 and
 the situation with getter properties, but setter properties and their
 issues
 are also important. Would you want code like this to compile?
 
 range.popFront = 17;
 container.linearRemove = range;
 path.baseName = ".xyz";
 str.icmp = "hello";
 enforce(a == b) = "msg";
 arr.sameHead = arr2;
 
 With  property, we can restrict the functions which can be used with the
 setter syntax to functions where that makes sense. Without it, all kinds
 of
 ridiculous code like the code above would be allowed.
 
 Allowing optional parens is one thing, but conflating that with properties
 is
 something else entirely. Property functions are not just functions which
 are
 called without parens, and we shouldn't act like they are.
I know, and I agree with it. But Andrei is pushing for removing property entirely and looking for arguments to keep it. And IMHO, the issue of how setters are handled is an extremely good reason to keep property. - Jonathan M Davis
Jan 24 2013
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
2013/1/25 Jonathan M Davis <jmdavisProg gmx.com>

 I know, and I agree with it. But Andrei is pushing for removing  property
 entirely and looking for arguments to keep it. And IMHO, the issue of how
 setters are handled is an extremely good reason to keep  property.
I'd like to argue that we should keep property attribute. Kenji Hara
Jan 24 2013
prev sibling next sibling parent "mist" <none none.none> writes:
OK, it has become difficult to follow all thread (newsgroups are 
not that perfect for this), so I will do "tl; dr" in a form of I 
final proposal.

Basic statement 1: Breaking user code is inevitable
Basic statement 2: Special cases are indicators something wrong 
is with design
Basic statement 3: Data is not function. Function is not data. 
(Sorry, John von Neumann!) Property is data.

Proposal itself:
*) -property flag becomes no-op
*) parens for all callables are mandatory
*) parens for properties are prohibited
*) properties are always treated to be of type of their return 
data
*) As a consequence - in UFCS property always behaves as a 
parameter, never as function

Transition issues:
*) Before merging new behavior to master, staging is created from 
last backwards-compatible. Official announcement is made that it 
will be bug-fix supported for at least 6 months.
*) Meta bugzilla issue is created to make Phobos code more strict 
in this regard. Release with new behavior will be allowed to go 
to staging only after this issue is taken care of.
*) All property-related issues that ensure data-like behavior 
like "+=" are marked as preapproved.

And yes, I know that Andrei has already made his decision about 
optional parens and this is also a no-op. But oh well.
Jan 25 2013
prev sibling next sibling parent reply "eles" <eles eles.com> writes:
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:

One more thing (see also this:
http://www.25hoursaday.com/CsharpVsJava.html#properties)

In order to avoid properties throwing exceptions, maybe is wise
to impose getters and setters to be nothrow.



try{

myClock.Hours   = 28;  /* setter throws exception because 28 is
an invalid hour value */
myClock.Minutes = 15;
myClock.Seconds = 39;

}catch(InvalidTimeValueException itve){

/* figure out which field was invalid and report error */

}
Jan 25 2013
next sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On 2013-37-25 17:01, eles <eles eles.com> wrote:

 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:

 One more thing (see also this:
 http://www.25hoursaday.com/CsharpVsJava.html#properties)

 In order to avoid properties throwing exceptions, maybe is wise
 to impose getters and setters to be nothrow.



 try{

 myClock.Hours   = 28;  /* setter throws exception because 28 is
 an invalid hour value */
 myClock.Minutes = 15;
 myClock.Seconds = 39;

 }catch(InvalidTimeValueException itve){

 /* figure out which field was invalid and report error */

 }
But setting the hours field to 28 is natural? While I want all properties to be safe nothrow pure, it is unlikely to be a good idea to force this upon people. I'm all for putting it in the style guide, though. -- Simen
Jan 25 2013
parent reply "eles" <eles eles.com> writes:
On Friday, 25 January 2013 at 16:48:21 UTC, Simen Kjaeraas wrote:
 On 2013-37-25 17:01, eles <eles eles.com> wrote:

 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright 
 wrote:
But setting the hours field to 28 is natural? While I want all properties to be safe nothrow pure, it is unlikely to be a good idea to force this upon people. I'm all for putting it in the style guide, though.
See this answer here: http://forum.dlang.org/post/mdhvjbjqryzjljzqleay forum.dlang.org The problem is that programmers would start feeling like "it's better" to check every assignment for exceptions, in the case that the variable is latter converted into a throwing property. I have no solution to that, though... OOH, I feel it will lead to bad programming style. OTOH, I feel like masking a database interrogation behind a property will throw some exception sooner or later. So, I am clueless.
Jan 25 2013
parent "Rob T" <alanb ucora.com> writes:
On Friday, 25 January 2013 at 19:50:23 UTC, eles wrote:
 On Friday, 25 January 2013 at 16:48:21 UTC, Simen Kjaeraas 
 wrote:
 On 2013-37-25 17:01, eles <eles eles.com> wrote:

 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright 
 wrote:
But setting the hours field to 28 is natural? While I want all properties to be safe nothrow pure, it is unlikely to be a good idea to force this upon people. I'm all for putting it in the style guide, though.
See this answer here: http://forum.dlang.org/post/mdhvjbjqryzjljzqleay forum.dlang.org The problem is that programmers would start feeling like "it's better" to check every assignment for exceptions, in the case that the variable is latter converted into a throwing property. I have no solution to that, though... OOH, I feel it will lead to bad programming style. OTOH, I feel like masking a database interrogation behind a property will throw some exception sooner or later. So, I am clueless.
You can easily wrap all of your functions in a try catch block that will act as a safety net and catch all potential Exception throws. Unfortunately I don't know if there's a performance hit with wrapping up all functions in this way. --rt
Jan 25 2013
prev sibling next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 17:37:48 eles wrote:
 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 
 One more thing (see also this:
 http://www.25hoursaday.com/CsharpVsJava.html#properties)
 
 In order to avoid properties throwing exceptions, maybe is wise
 to impose getters and setters to be nothrow.
 

 
 try{
 
 myClock.Hours = 28; /* setter throws exception because 28 is
 an invalid hour value */
 myClock.Minutes = 15;
 myClock.Seconds = 39;
 
 }catch(InvalidTimeValueException itve){
 
 /* figure out which field was invalid and report error */
 
 }
And why wouldn't setters be able to throw. Why on earth would you do other than throw in code like you have above? How on earth would a setter report a bad argument if it was forced to be nothrow? Exceptions are the correct solution. Setters _need_ to be able to throw. Plenty of them don't need to, but plenty of them do. For instance, many of the properties in std.datetime will throw if you give them invalid values (like setting the hour to 28). I don't see how you could possibly argue that a setter should not be able to throw. - Jonathan M Davis
Jan 25 2013
parent reply "eles" <eles eles.com> writes:
On Friday, 25 January 2013 at 19:30:41 UTC, Jonathan M Davis 
wrote:
 On Friday, January 25, 2013 17:37:48 eles wrote:
 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright
And why wouldn't setters be able to throw. Why on earth would you do other than throw in code like you have above? How on earth would a setter report a bad argument if it was forced to be nothrow? Exceptions are the correct solution. Setters _need_ to be able to throw. Plenty of them don't need to, but plenty of them do. For instance, many of the properties in std.datetime will throw if you give them invalid values (like setting the hour to 28). I don't see how you could possibly argue that a setter should not be able to throw.
You are right. In fact, just after I post the message, I was hit by second toughts. But a issue still remains: assignments of variables are not usually checked for exceptions. Programmers do not have in mind that they could trigger exceptions. However, properties could do. The danger that I see is that programmers will start to "preventively" check everything for exceptions, "just in case" that those current variable assignments would be latter turned into properties. Do you feel like embracing all your code in try/catch?
Jan 25 2013
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 20:41:01 eles wrote:

 You are right. In fact, just after I post the message, I was hit
 by second toughts.
 
 But a issue still remains: assignments of variables are not
 usually checked for exceptions. Programmers do not have in mind
 that they could trigger exceptions.
 
 However, properties could do.
 
 The danger that I see is that programmers will start to
 "preventively" check everything for exceptions, "just in case"
 that those current variable assignments would be latter turned
 into properties.
 
 Do you feel like embracing all your code in try/catch?
Except that variable assignments _can_ throw, because opAssign could throw. It's true that replacing a variable with a property function which checks its arguments would likely add a new exception to catch, but there's really no way around that. But if the property function checks for stuff which was supposed to be valid before, you changed the semantics anyway, which could be done in a variety of other ways (e.g. making the property function multiply the argument by 7). The reality of the matter is that a property function _isn't_ a variable, just like an overloaded operator isn't the same as using that operator on a built-in type. And the issues are pretty much the same as they are with overloaded operators. But what should be done with try-catch blocks depends on what the code's doing, and if you're having to litter your code with them, you're probably doing something wrong anyway. Still, the possible breakage caused by replacing a variable with a property function which throws is the sort of thing that needs to be considered when making that change. - Jonathan m Davis
Jan 25 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-01-25 17:37, eles wrote:

 One more thing (see also this:
 http://www.25hoursaday.com/CsharpVsJava.html#properties)

 In order to avoid properties throwing exceptions, maybe is wise
 to impose getters and setters to be nothrow.



 try{

 myClock.Hours   = 28;  /* setter throws exception because 28 is
 an invalid hour value */
 myClock.Minutes = 15;
 myClock.Seconds = 39;

 }catch(InvalidTimeValueException itve){

 /* figure out which field was invalid and report error */

 }
One of the points of properties is to have a field with validation. To indicate the validation failed you would throw an exception. Therefore properties need to be able to throw exceptions. -- /Jacob Carlborg
Jan 26 2013
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Jan 24, 2013 at 12:34:42AM -0800, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns
 somewhere.
 
 Perhaps we should revert to a simple set of rules.
 
 1. Empty parens are optional. If there is an ambiguity with the
 return value taking (), the () go on the return value.
 
 2. the:
    f = g
 rewrite to:
    f(g)
 only happens if f is a function that only has overloads for () and
 (one argument). No variadics.
 
 3. Parens are required for calling delegates or function pointers.
 
 4. No more  property.
I've refrained so far from participating in this thread, but maybe it's time to say something. 1) property and optional parentheses are orthogonal issues. Let's not conflate them and cause more unnecessary confusion in what is already a complex and convoluted discussion. 2) Personally, I don't like leaving out parentheses, but I don't really care either way. In any case, this has nothing to do with property. 3) So, as far as property is concerned, let's forget about optional parentheses or not. 3) property is necessary for good abstraction. Yes, there have been precedents of abuse (like .dup and .idup, which really should *not* be properties but methods), and there are problems in the current implementation of property, but the _concept_ of property itself is a sound one. People have already mentioned the use case of a member variable that needs to be replaced with a getter/setter method. Conceptually speaking, the user of the class should not need to know or care whether it's just a POD field or an abstract entity manipulated by property functions. For example, an Array class has a .length property, and user code should not need to know nor care if this length is an actual size_t field, or something else. All it needs to know is you can get a size_t out of it, and (optionally) change its value (if it's non-const, or if there's a setter method). Sometimes, you get into the situation where it's *possible* to implement a property as a plain old field, but not desirable because of the SSOT (single source of truth) principle. It could be a computed value based on implementation-specific parameters, for example. It would not be nice if you had to store its value, then change code everywhere to make sure that it's always updated when the underlying parameters change. Lots of ugly, unnecessary, inefficient, and fragile code. Therefore, property is necessary. If it causes a problem with the syntax, well, that's a problem with the syntax, not with the concept of property itself. As far as syntax is concerned, it should be very straightforward. Given that the goal of property is to simulate a variable, it should syntactically be identical to a variable, regardless of what it returns. So, given: struct S { property T prop() { ... } } S s; Then: a) Writing s.prop returns a value of type T, for any type T (POD or struct or class or delegate or whatever); b) Writing s.prop() invokes opCall on the *return value* (because .prop behaves exactly as though it were an actual field); c) As a corollary, if T is not callable, then s.prop() is illegal; d) &s.prop returns a pointer to T (if .prop returns a ref). e) As for taking the address of the .prop function itself, my take on it is that (i) from a user's POV, .prop should be indistinguishable from a plain old field, so you shouldn't ever need to do this, and therefore (ii) it's impossible, and (iii) if you *really* need to do it, do this instead: struct S { property T prop() { return this.propImpl(); } // You really only need to know about propImpl if you're // inside S's implementation anyway, so this is private. private T propImpl() { ... } void someMethod() { auto ptr = &propImpl; // There, now you have it. } } f) IOW, .prop cannot be distinguished from an actual field under normal circumstances. If you *really* need to do this (e.g. in serialization code), then use __traits. Consequently: - Assignment syntax like f=g should NOT be treated equivalently to f(g) because conceptually it makes no sense. Writing writeln = "abc"; makes no sense because writeln is not a value that you write to. Writing s.prop = "abc" *does* make sense, because S.prop is a property, and therefore behaves like a variable. Writeln is a function, not a property, so this is illegal. - Syntax like s.prop++ should work automatically (equivalent to s.prop(s.prop+1)), if .prop has both a getter and setter property. It should NOT be allowed for arbitrary methods m just because m has both overloads of m() and m(T). - It's illegal to mark a function that takes 2 or more arguments as property, because it makes no sense. The bottom line is, if you mark a function as property, then it should behave as if it were a variable of its return type. This has nothing to do with optional parentheses or not, and assignment syntax should be reserved for variables (and by extension property, because property means something behaves like a variable), not arbitrary functions. T -- What are you when you run out of Monet? Baroque.
Jan 25 2013
next sibling parent reply "mist" <none none.none> writes:
On Friday, 25 January 2013 at 18:41:46 UTC, H. S. Teoh wrote:
 ...
Sound base that avoid discussion of controversial topics :) Looks like I can agree with almost everything. Probably even everything. Only thing that needs to be defined is property on free-functions: disallow, treat as global variable or treat as an extension methods. We has small discussion on this topic with deadalanix afair somewhere up the topic.
Jan 25 2013
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 19:51:53 mist wrote:
 On Friday, 25 January 2013 at 18:41:46 UTC, H. S. Teoh wrote:
 ...
Sound base that avoid discussion of controversial topics :) Looks like I can agree with almost everything. Probably even everything. Only thing that needs to be defined is property on free-functions: disallow, treat as global variable or treat as an extension methods. We has small discussion on this topic with deadalanix afair somewhere up the topic.
So, you're arguing that property shouldn't be usable on anything but member functions? We've had discussions on that in the past, and most everyone agreed that it should be legal to use property on module-level variables, and I've never heard anyone try to argue before that it shouldn't work with UFCS (which is what I assume you mean by extension methods - I don't know what else you would mean). There's an ambiguity problem that needs to be solved with free functions where in some cases, you can't properly distinguish between whether it's supposed to be a getter or a setter, but that can be fixed (e.g. property(get) and property(set)), but I think that if you're going to argue that something like bool exists(string filename) {...} if(filename.exists) or S globalVar() {...} if(globalVar == blah) shouldn't work, then you're fighting a losing battle. An both of those idioms are used in Phobos. I agree that calling it a property is a little silly when it's a module-level variable, since there's no object for it to be a property of, but really, property is an abstraction for variables in general, not just member variables. - Jonathan M Davis
Jan 25 2013
parent reply "mist" <none none.none> writes:
On Friday, 25 January 2013 at 19:30:26 UTC, Jonathan M Davis 
wrote:
 ...
I am not going to argue anything, I am just asking _how_ they are supposed to work, what are exact semantic. I have added various syntax cases to wiki: What I am going to argue is if all of those example are supposed to work. We can't define property semantics to be "just like data" when property symbol can't be just interchanged with data symbol. From the syntax point of view no issues there.
Jan 25 2013
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Jan 25, 2013 at 08:46:51PM +0100, mist wrote:
 On Friday, 25 January 2013 at 19:30:26 UTC, Jonathan M Davis wrote:
...
I am not going to argue anything, I am just asking _how_ they are supposed to work, what are exact semantic. I have added various syntax cases to wiki: What I am going to argue is if all of those example are supposed to work. We can't define property semantics to be "just like data" when property symbol can't be just interchanged with data symbol. From the syntax point of view no issues there.
From my stance that  property should make the function behave like a
variable, all of the examples in the above link can be resolved thus:
	struct Type
	{
	     property void native(int);
	}
This should behave as though you wrote this: struct Type { // const because there is no setter const int native; }
	 property void external1(int);       // valid? (no assignment context)
Valid, this is equivalent to defining a module-level variable: int external1;
	 property void external2(Type, int); // valid? (extra parameter comparing to
typical setter)
Valid, because UFCS lets you use it as though it were a member variable of Type.
	void main()
	{
	    Type t;
	    t.native = 42;    // typical
	    external1 = 42;   // allowed or not?
Allowed, because external1 behaves like a module-level variable.
	    42.external1;     // allowed or not?
Not allowed, because the following isn't allowed either: int x; void main() { 1.x; // Error: nonsensical syntax } IOW, property functions must be treated as variables externally, NOT as normal functions.
	    t.external2 = 42; // allowed or not?
	}
Allowed, because external2, via UFCS, behaves as though it were a member variable of Type. All of the confusing/unclear/ambiguous cases come from an incomplete implementation of property and an unnecessary conflation with normal functions. A property function should not be treated like a normal function. It turns the function into a variable-like entity that *no longer acts like a function to the outsider*. Neither should normal functions for whatever strange reasoning be conflated with property functions, because functions are not variables. It's actually very straightforward once you remove all the unnecessary conflations, and disregard, for the time being, the problems in the current implementation. T -- There is no gravity. The earth sucks.
Jan 25 2013
parent reply Johannes Pfau <nospam example.com> writes:
Am Fri, 25 Jan 2013 12:12:55 -0800
schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:

 
 
	struct Type
	{
	     property void native(int);
	}
This should behave as though you wrote this: struct Type { // const because there is no setter const int native; }
Only if the getter is marked as const. We can discuss if that should be required, but in the code above, native isn't necessarily const.
 
 All of the confusing/unclear/ambiguous cases come from an incomplete
 implementation of  property and an unnecessary conflation with normal
 functions. A  property function should not be treated like a normal
 function. It turns the function into a variable-like entity that *no
 longer acts like a function to the outsider*. Neither should normal
 functions for whatever strange reasoning be conflated with  property
 functions, because functions are not variables.
 
Please add you proposed changes to Proposal 1 in this wiki page or add another proposal to it: http://wiki.dlang.org/Property_Discussion_Wrap-up
Jan 25 2013
parent Johannes Pfau <nospam example.com> writes:
Am Fri, 25 Jan 2013 21:28:34 +0100
schrieb Johannes Pfau <nospam example.com>:

 Am Fri, 25 Jan 2013 12:12:55 -0800
 schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:
 
 
 
	struct Type
	{
	     property void native(int);
	}
This should behave as though you wrote this: struct Type { // const because there is no setter const int native; }
Only if the getter is marked as const. We can discuss if that should be required, but in the code above, native isn't necessarily const.
Ah you fooled me! There is only a setter in the first example!
Jan 25 2013
prev sibling next sibling parent "Adam Wilson" <flyboynw gmail.com> writes:
On Fri, 25 Jan 2013 10:39:50 -0800, H. S. Teoh <hsteoh quickfur.ath.cx>  
wrote:

 On Thu, Jan 24, 2013 at 12:34:42AM -0800, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns
 somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the
 return value taking (), the () go on the return value.

 2. the:
    f = g
 rewrite to:
    f(g)
 only happens if f is a function that only has overloads for () and
 (one argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
I've refrained so far from participating in this thread, but maybe it's time to say something. 1) property and optional parentheses are orthogonal issues. Let's not conflate them and cause more unnecessary confusion in what is already a complex and convoluted discussion. 2) Personally, I don't like leaving out parentheses, but I don't really care either way. In any case, this has nothing to do with property. 3) So, as far as property is concerned, let's forget about optional parentheses or not. 3) property is necessary for good abstraction. Yes, there have been precedents of abuse (like .dup and .idup, which really should *not* be properties but methods), and there are problems in the current implementation of property, but the _concept_ of property itself is a sound one. People have already mentioned the use case of a member variable that needs to be replaced with a getter/setter method. Conceptually speaking, the user of the class should not need to know or care whether it's just a POD field or an abstract entity manipulated by property functions. For example, an Array class has a .length property, and user code should not need to know nor care if this length is an actual size_t field, or something else. All it needs to know is you can get a size_t out of it, and (optionally) change its value (if it's non-const, or if there's a setter method). Sometimes, you get into the situation where it's *possible* to implement a property as a plain old field, but not desirable because of the SSOT (single source of truth) principle. It could be a computed value based on implementation-specific parameters, for example. It would not be nice if you had to store its value, then change code everywhere to make sure that it's always updated when the underlying parameters change. Lots of ugly, unnecessary, inefficient, and fragile code. Therefore, property is necessary. If it causes a problem with the syntax, well, that's a problem with the syntax, not with the concept of property itself. As far as syntax is concerned, it should be very straightforward. Given that the goal of property is to simulate a variable, it should syntactically be identical to a variable, regardless of what it returns. So, given: struct S { property T prop() { ... } } S s; Then: a) Writing s.prop returns a value of type T, for any type T (POD or struct or class or delegate or whatever); b) Writing s.prop() invokes opCall on the *return value* (because .prop behaves exactly as though it were an actual field); c) As a corollary, if T is not callable, then s.prop() is illegal; d) &s.prop returns a pointer to T (if .prop returns a ref). e) As for taking the address of the .prop function itself, my take on it is that (i) from a user's POV, .prop should be indistinguishable from a plain old field, so you shouldn't ever need to do this, and therefore (ii) it's impossible, and (iii) if you *really* need to do it, do this instead: struct S { property T prop() { return this.propImpl(); } // You really only need to know about propImpl if you're // inside S's implementation anyway, so this is private. private T propImpl() { ... } void someMethod() { auto ptr = &propImpl; // There, now you have it. } } f) IOW, .prop cannot be distinguished from an actual field under normal circumstances. If you *really* need to do this (e.g. in serialization code), then use __traits. Consequently: - Assignment syntax like f=g should NOT be treated equivalently to f(g) because conceptually it makes no sense. Writing writeln = "abc"; makes no sense because writeln is not a value that you write to. Writing s.prop = "abc" *does* make sense, because S.prop is a property, and therefore behaves like a variable. Writeln is a function, not a property, so this is illegal. - Syntax like s.prop++ should work automatically (equivalent to s.prop(s.prop+1)), if .prop has both a getter and setter property. It should NOT be allowed for arbitrary methods m just because m has both overloads of m() and m(T). - It's illegal to mark a function that takes 2 or more arguments as property, because it makes no sense. The bottom line is, if you mark a function as property, then it should behave as if it were a variable of its return type. This has nothing to do with optional parentheses or not, and assignment syntax should be reserved for variables (and by extension property, because property means something behaves like a variable), not arbitrary functions. T
++ -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 25 2013
prev sibling next sibling parent reply Johannes Pfau <nospam example.com> writes:
Am Fri, 25 Jan 2013 10:39:50 -0800
schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:


 - It's illegal to mark a function that takes 2 or more arguments as
    property, because it makes no sense.
 
3 or more arguments. UFCS properties have 2 arguments: property void age(Person p, int value); //OK, bad example, but you get the idea
Jan 25 2013
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Jan 25, 2013 at 09:06:44PM +0100, Johannes Pfau wrote:
 Am Fri, 25 Jan 2013 10:39:50 -0800
 schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:
 
 
 - It's illegal to mark a function that takes 2 or more arguments as
    property, because it makes no sense.
 
3 or more arguments. UFCS properties have 2 arguments: property void age(Person p, int value); //OK, bad example, but you get the idea
[...] Good point, so it's 2 or more arguments for member functions, and 3 or more for module-level functions. Another thing I forgot to mention: once a function has been declared property, you cannot call it like a normal function anymore. So if you declare at the module level: property void age(Person p, int value); then: void main() { Person p; //age(p, 123); // Error: cannot call age like a normal function //p.age(123); // ditto p.age = 123; // OK } The second case (p.age(123)) is valid only if age() returns a delegate. Again, property turns the function into a variable-like entity that does not behave like a normal function to the outside world. T -- Lottery: tax on the stupid. -- Slashdotter
Jan 25 2013
prev sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
25-Jan-2013 22:39, H. S. Teoh пишет:
 On Thu, Jan 24, 2013 at 12:34:42AM -0800, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns
 somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the
 return value taking (), the () go on the return value.

 2. the:
     f = g
 rewrite to:
     f(g)
 only happens if f is a function that only has overloads for () and
 (one argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
I've refrained so far from participating in this thread, but maybe it's time to say something. 1) property and optional parentheses are orthogonal issues. Let's not conflate them and cause more unnecessary confusion in what is already a complex and convoluted discussion. 2) Personally, I don't like leaving out parentheses, but I don't really care either way. In any case, this has nothing to do with property. 3) So, as far as property is concerned, let's forget about optional parentheses or not. 3) property is necessary for good abstraction. Yes, there have been precedents of abuse (like .dup and .idup, which really should *not* be properties but methods), and there are problems in the current implementation of property, but the _concept_ of property itself is a sound one. People have already mentioned the use case of a member variable that needs to be replaced with a getter/setter method. Conceptually speaking, the user of the class should not need to know or care whether it's just a POD field or an abstract entity manipulated by property functions. For example, an Array class has a .length property, and user code should not need to know nor care if this length is an actual size_t field, or something else. All it needs to know is you can get a size_t out of it, and (optionally) change its value (if it's non-const, or if there's a setter method). Sometimes, you get into the situation where it's *possible* to implement a property as a plain old field, but not desirable because of the SSOT (single source of truth) principle. It could be a computed value based on implementation-specific parameters, for example. It would not be nice if you had to store its value, then change code everywhere to make sure that it's always updated when the underlying parameters change. Lots of ugly, unnecessary, inefficient, and fragile code. Therefore, property is necessary. If it causes a problem with the syntax, well, that's a problem with the syntax, not with the concept of property itself. As far as syntax is concerned, it should be very straightforward. Given that the goal of property is to simulate a variable, it should syntactically be identical to a variable, regardless of what it returns. So, given: struct S { property T prop() { ... } } S s; Then: a) Writing s.prop returns a value of type T, for any type T (POD or struct or class or delegate or whatever); b) Writing s.prop() invokes opCall on the *return value* (because .prop behaves exactly as though it were an actual field); c) As a corollary, if T is not callable, then s.prop() is illegal; d) &s.prop returns a pointer to T (if .prop returns a ref). e) As for taking the address of the .prop function itself, my take on it is that (i) from a user's POV, .prop should be indistinguishable from a plain old field, so you shouldn't ever need to do this, and therefore (ii) it's impossible, and (iii) if you *really* need to do it, do this instead: struct S { property T prop() { return this.propImpl(); } // You really only need to know about propImpl if you're // inside S's implementation anyway, so this is private. private T propImpl() { ... } void someMethod() { auto ptr = &propImpl; // There, now you have it. } } f) IOW, .prop cannot be distinguished from an actual field under normal circumstances. If you *really* need to do this (e.g. in serialization code), then use __traits. Consequently: - Assignment syntax like f=g should NOT be treated equivalently to f(g) because conceptually it makes no sense. Writing writeln = "abc"; makes no sense because writeln is not a value that you write to. Writing s.prop = "abc" *does* make sense, because S.prop is a property, and therefore behaves like a variable. Writeln is a function, not a property, so this is illegal. - Syntax like s.prop++ should work automatically (equivalent to s.prop(s.prop+1)), if .prop has both a getter and setter property. It should NOT be allowed for arbitrary methods m just because m has both overloads of m() and m(T). - It's illegal to mark a function that takes 2 or more arguments as property, because it makes no sense. The bottom line is, if you mark a function as property, then it should behave as if it were a variable of its return type. This has nothing to do with optional parentheses or not, and assignment syntax should be reserved for variables (and by extension property, because property means something behaves like a variable), not arbitrary functions. T
Good summary of what property should do. Let's just not forget that works like plain variable must clearly tackle contexts such as: a.b.c.d = xyz; //where b, c, d are properties And things like: a.prop += qwerty; I can see how it must work from your proposal but listing some "canonical" re-writes won't hurt. -- Dmitry Olshansky
Jan 25 2013
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 10:39:50 H. S. Teoh wrote:
 I've refrained so far from participating in this thread, but maybe it's
 time to say something.
[snip] I agree with pretty much everything that you said, and it's exactly why we need explicit properties. So, we need to keep property and make whatever adjustments are necessary in order to make it function like a variable would to the point that you can swap out variables and property functions without breaking code (though that will probably mean allowing something like marking variables with property to make them be treated as rvalues rather than just improving the handling of property functions). - Jonathan M Davis
Jan 25 2013
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 25, 2013 10:39:50 H. S. Teoh wrote:
 I've refrained so far from participating in this thread, but maybe it's
 time to say something.
[snip] Another issue that you didn't mention (and which hasn't come up in this particular discussion, I don't believe) is what to do about disambiguating property functions that conflict. You can't use the full import path for a function when using the property syntax, so there's not currently a way to disambiguate property functions which conflict. So, we'll need to find a solution for that. - Jonathan M Davis
Jan 25 2013
prev sibling next sibling parent reply "Zach the Mystic" <reachBUTMINUSTHISzach gOOGLYmail.com> writes:
Here are my two cents:

First, about optional parentheses:

Optional parentheses = ambiguity.

int foo() { return 4; }
auto x = foo; // gives 4 or gives function foo?

It seems to me any ambiguity should be an error. However… it only 
matters when the type system can't provide the missing detail, as 
above.

The ambiguity may be resolved either in the function signature or 
at the call site.  property partly helps resolve it at the 
function signature, but it is a different issue from optional 
parentheses.

Ambiguity can also be resolved at the call site instead of the 
function signature. It needs to be as clear and concise as 
possible in addition to being unambiguous. D's method of 
disambiguating cases often uses the keyword "cast". Applying it 
in this case would lead to "cast(function)" or "cast(delegate)" 
to indicate the function and not the return value, where the 
default is to indicate the return value.

int foo() { return 4; }
int function() goo() { return foo; }

auto doh = foo(); // gives 4
auto go = foo; // Error: can't deduce type of expression foo
auto fun = cast(function) foo; // gives foo

auto ae = goo; // Error: can't deduce type (either goo or 
function int() foo )
auto fe = goo(); // Error: can't deduce type (either foo or 4)
auto ga = goo()(); // gives 4
auto gu = cast(function) (goo()); // gives foo
auto gi = cast(function) goo; // gives goo

This solution is unambiguous and clear, but unfortunately not 
very concise. In fact, "cast(function) foo" is rather a long way 
of saying "&foo", but much clearer and possibly safer. The type 
system can probably resolve most of these ambiguities anyway, 
which would mean the cast wouldn't appear very often, but I'm not 
sure.

I have no real opinion about  property. Ideally the compiler 
could deduce what is and isn't a property without the ugly 
 property attached to all the signatures, but it might invite so 
many abuses of this process that it's not worth it.
Jan 25 2013
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/25/2013 10:44 PM, Zach the Mystic wrote:
 Here are my two cents:

 First, about optional parentheses:

 Optional parentheses = ambiguity.
 ...
No, you can definitely have ambiguity without optional parentheses. Unless that is supposed to be a destructive update. Is your statement ambiguous?
 int foo() { return 4; }
 auto x = foo; // gives 4 or gives function foo?

 It seems to me any ambiguity should be an error. However… it only
 matters when the type system can't provide the missing detail, as above.
 ...
That is not ambiguous.
Jan 25 2013
parent reply "Zach the Mystic" <reachBUTMINUSTHISzach gOOGLYmail.com> writes:
On Friday, 25 January 2013 at 22:02:06 UTC, Timon Gehr wrote:
 On 01/25/2013 10:44 PM, Zach the Mystic wrote:
 Here are my two cents:

 First, about optional parentheses:

 Optional parentheses = ambiguity.
 ...
No, you can definitely have ambiguity without optional parentheses. Unless that is supposed to be a destructive update. Is your statement ambiguous?
Actually, you're right. I meant: Optional parentheses as a feature leads to ambiguity precisely when they are not used.
 int foo() { return 4; }
 auto x = foo; // gives 4 or gives function foo?

 It seems to me any ambiguity should be an error. However… it 
 only
 matters when the type system can't provide the missing detail, 
 as above.
 ...
That is not ambiguous.
But this time *your* comment is ambiguous! If you mean my *statement* is not ambiguous, then yes.
Jan 25 2013
parent "Zach the Mystic" <reachBUTMINUSTHISzach gOOGLYmail.com> writes:
On Saturday, 26 January 2013 at 00:47:38 UTC, Zach the Mystic 
wrote:
 That is not ambiguous.
But this time *your* comment is ambiguous! If you mean my *statement* is not ambiguous, then yes.
Actually, that's ambiguous too. My English language statement.
Jan 25 2013
prev sibling parent "Jesse Phillips" <Jessekphillips+d gmail.com> writes:
On Friday, 25 January 2013 at 21:44:28 UTC, Zach the Mystic wrote:
 Here are my two cents:

 First, about optional parentheses:

 Optional parentheses = ambiguity.

 int foo() { return 4; }
 auto x = foo; // gives 4 or gives function foo?\
4, we are talking about D not C.
Jan 25 2013
prev sibling next sibling parent luka8088 <luka8088 owave.net> writes:
On 24.1.2013 9:34, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return
 value taking (), the () go on the return value.

 2. the:
 f = g
 rewrite to:
 f(g)
 only happens if f is a function that only has overloads for () and (one
 argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
Maybe one possible issue to note. I am sorry if someone already noted this but I didn't saw it so here it is. In druntime's object_.d AssociativeArray has: property size_t length() { return _aaLen(p); } By removing property typeof([].length) is no longer uint or ulong. It would change into uint() or ulong(). And not just for length, but any other properties type's would change. I think that this is one big possible code breaker for everyone that uses something similar to the following: typeof([].length) l = [].length; Maybe I am wrong but my personal opinion is that code like this should compile because semantically length is a property and the fact that it is a functions is just a implementation detail.
Jan 26 2013
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
I was just working on some work code and noticed this line that I 
wrote a while ago:

public  property string userId(string file = __FILE__, size_t 
line = __LINE__) {


That's a getter, I always use it "getUser(userId);" etc..... but 
it "takes" two arguments.

If we require getters to have zero arguments, it will break this, 
and that will annoy me. We need to be careful about arbitrarily 
deciding something doesn't make sense and restricting it when 
there's no real technical reason for it.


(Wondering why I did this? If you aren't logged in, this throws a 
Not Logged In Exception. The file and line are passed to the 
exception constructor, meaning then the error message will tell 
me exactly where I forgot the nicer login check.

After wasting cumulative hours on similar problems in earlier 
iterations, I put this in there to eliminate that time sink.)
Jan 27 2013
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, January 28, 2013 00:18:15 Adam D. Ruppe wrote:
 I was just working on some work code and noticed this line that I
 wrote a while ago:
 
 public  property string userId(string file = __FILE__, size_t
 line = __LINE__) {
 
 
 That's a getter, I always use it "getUser(userId);" etc..... but
 it "takes" two arguments.
 
 If we require getters to have zero arguments, it will break this,
 and that will annoy me. We need to be careful about arbitrarily
 deciding something doesn't make sense and restricting it when
 there's no real technical reason for it.
 
 
 (Wondering why I did this? If you aren't logged in, this throws a
 Not Logged In Exception. The file and line are passed to the
 exception constructor, meaning then the error message will tell
 me exactly where I forgot the nicer login check.
 
 After wasting cumulative hours on similar problems in earlier
 iterations, I put this in there to eliminate that time sink.)
I think that one of two things would be likely to happen were property to stay and properly enforce that it be called with no parens: 1. Your function would be illegal because it had too many arguments. 2. It would be legal, but you could never call it with any arguments for file or line except the defaults, because there would be no syntactic way to do so. But then again, if all you want is a getter and not a setter, and we allow optional parens to continue (which appears to be the case), then you wouldn't have to declare it as property to get the syntax that you want. It just wouldn't be possible to guarantee that you could swap it out for a variable later without breaking code, since it would be possible for someone to call it with parens. - Jonathan M Davis
Jan 27 2013
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 24 Jan 2013 03:34:42 -0500, Walter Bright  
<newshound2 digitalmars.com> wrote:

 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.

 1. Empty parens are optional. If there is an ambiguity with the return  
 value taking (), the () go on the return value.

 2. the:
     f = g
 rewrite to:
     f(g)
 only happens if f is a function that only has overloads for () and (one  
 argument). No variadics.

 3. Parens are required for calling delegates or function pointers.

 4. No more  property.
Disagree. property serves a very good purpose -- specifying intent. If the intention of a function is to be used as a dynamic field, use property, otherwise do not. Whether or not parentheses should be required on non- property functions, I've given up that struggle. It's not too terrible, and the benefits are difficult to argue against. But please, please, PLEASE do not let normal functions be called as setters. If we get rid of property, we are back to this. Your simple requirements will leave too many functions open to abuse. When you take away property, you take away the expression power of an API designer. I contend that the issue with property was that it was half-implemented. When a half-implemented feature is used for 4 years, it leads to confusion when it doesn't work as specified. In other words, we asked you to build a fence. You built one, but didn't finish it, left a gaping hole. Then you complain about how the fence was useless. I would be satisfied with Kenji's implementation. As I understand it: property on a getter would mean implicit calling of the function. property on a setter would mean calling x = y as x(y). property functions could not be called like normal functions. Parentheses are optional on normal no-arg functions when used as getters. Normal single arg or variadic functions are NOT ALLOWED to be used as setters. Do it. I think 99% of the people here would be OK with this. -Steve
Jan 27 2013
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Jan 28, 2013 at 12:22:01AM -0500, Steven Schveighoffer wrote:
[...]
 Disagree.   property serves a very good purpose -- specifying
 intent.  If the intention of a function is to be used as a dynamic
 field, use  property, otherwise do not.
 
 Whether or not parentheses should be required on non- property
 functions, I've given up that struggle.  It's not too terrible, and
 the benefits are difficult to argue against.
 
 But please, please, PLEASE do not let normal functions be called as
 setters.  If we get rid of  property, we are back to this.  Your
 simple requirements will leave too many functions open to abuse.
 When you take away  property, you take away the expression power of
 an API designer.
 
 I contend that the issue with  property was that it was
 half-implemented.  When a half-implemented feature is used for 4
 years, it leads to confusion when it doesn't work as specified.
 
 In other words, we asked you to build a fence.  You built one, but
 didn't finish it, left a gaping hole.  Then you complain about how
 the fence was useless.
 
 I would be satisfied with Kenji's implementation.  As I understand it:
 
  property on a getter would mean implicit calling of the function.
  property on a setter would mean calling x = y as x(y).
  property functions could not be called like normal functions.
 Parentheses are optional on normal no-arg functions when used as getters.
 Normal single arg or variadic functions are NOT ALLOWED to be used
 as setters.
 
 Do it.  I think 99% of the people here would be OK with this.
[...] +1. T -- May you live all the days of your life. -- Jonathan Swift
Jan 27 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/28/2013 06:22 AM, Steven Schveighoffer wrote:
 ...

 I would be satisfied with Kenji's implementation.  As I understand it:

  property on a getter would mean implicit calling of the function.
  property on a setter would mean calling x = y as x(y).
  property functions could not be called like normal functions.
 Parentheses are optional on normal no-arg functions when used as getters.
 Normal single arg or variadic functions are NOT ALLOWED to be used as
 setters.
 ...
This proposal unfortunately does not work too well because of UFCS.
Jan 28 2013
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 28 Jan 2013 11:31:33 -0500, Timon Gehr <timon.gehr gmx.ch> wrote:

 On 01/28/2013 06:22 AM, Steven Schveighoffer wrote:
 ...

 I would be satisfied with Kenji's implementation.  As I understand it:

  property on a getter would mean implicit calling of the function.
  property on a setter would mean calling x = y as x(y).
  property functions could not be called like normal functions.
 Parentheses are optional on normal no-arg functions when used as  
 getters.
 Normal single arg or variadic functions are NOT ALLOWED to be used as
 setters.
 ...
This proposal unfortunately does not work too well because of UFCS.
As many have stated in the past, UFCS getter properties can annotate their "this" argument: property void by5(this int x) { return x * 5;} by5 = 1; // error Another possibility is to only define property for setters. This is something I've come to realize that if we are simply going to allow omittable parens on getters, there is no functional value to property on them except for the rare case of a delegate property. That was always one of those things where I think too much emphasis was on that as a reason for property existence, it's very rare. -Steve
Jan 28 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-01-28 18:07, Steven Schveighoffer wrote:

 Another possibility is to only define  property for setters.  This is
 something I've come to realize that if we are simply going to allow
 omittable parens on getters, there is no functional value to  property
 on them except for the rare case of a delegate property.  That was
 always one of those things where I think too much emphasis was on that
 as a reason for  property existence, it's very rare.
I think property adds clarity and shows intent. For example, now that we have UDA's I have create a struct called "attribute" which I use as an attribute for other structs to should be attributes: struct attribute {} attribute struct foo {} foo int a; Here attribute shows the intent. This is also why I like to have explicit interfaces and abstract classes compared with C++ which doesn't not. -- /Jacob Carlborg
Jan 28 2013
prev sibling next sibling parent reply "eles" <eles eles.com> writes:
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns 
 somewhere.
Progressively, I start considering this as a not-so-bad idea. Anyway, the issue of property should be cleared up. The current state of affairs is poisoning the language.
Jul 19 2013
parent reply "Stian Pedersen" <stian.pedersen gmail.com> writes:
To add to the mess - or maybe suggest a new approach, what about:

class A
{
     int foo();
     void foo=(int a);
     private foo_;
}

Then a.foo = 42; calls the foo= method. No other conversions from 
a=b to a method invocation.

It may be suggested in one of these 46 pages which I haven't 
read. And it'll probably break a lot of stuff.
Aug 10 2013
next sibling parent "Stian Pedersen" <stian.pedersen gmail.com> writes:
Missing an int before foo_ there.
Aug 10 2013
prev sibling next sibling parent "Borislav Kosharov" <boby_dsm abv.bg> writes:
On Saturday, 10 August 2013 at 10:29:51 UTC, Stian Pedersen wrote:
 To add to the mess - or maybe suggest a new approach, what 
 about:

 class A
 {
     int foo();
     void foo=(int a);
     private foo_;
 }

 Then a.foo = 42; calls the foo= method. No other conversions 
 from a=b to a method invocation.

 It may be suggested in one of these 46 pages which I haven't 
 read. And it'll probably break a lot of stuff.
I like this. It is something like in Ruby. And Ruby also has some meta programming support and there are these 3 "templates" attr_reader, attr_writer and attr_accessor (both of the previous together). And one could write (in Ruby): class Foo attr_writer :name, :number #Ruby has symbols(something like enums) end And translates to: class Foo def name=(name) name = name //the name means class private variable in Ruby end def number=(number) number = number //and they don't need to be declared(dynamicly typed lang) end end So in D those 3 attr 'shortcuts' could be implemented with mixin templates. And instead of those 'symbols' they could be just a list of strings. Example: class Foo { mixin Reader!("name", "number"); } And something similar to happen. Although this not solves all property problems it makes writing them shorter. And I have started experimenting with that and it is almost finished, but it is a little different from what I described above. The file is a part of a thing I started working on in D, but here is a direct link(https://github.com/nikibobi/spine-d/blob/master/src/spine/util/property.d) and the files is isolated from the other things. See the unittests for examples.
Aug 10 2013
prev sibling parent reply "BLM768" <blm768 gmail.com> writes:
On Saturday, 10 August 2013 at 10:29:51 UTC, Stian Pedersen wrote:
 To add to the mess - or maybe suggest a new approach, what 
 about:

 class A
 {
     int foo();
     void foo=(int a);
     private foo_;
 }

 Then a.foo = 42; calls the foo= method. No other conversions 
 from a=b to a method invocation.

 It may be suggested in one of these 46 pages which I haven't 
 read. And it'll probably break a lot of stuff.
The problem with this approach is that the getter is still operating under the semantics of a method, but, as a property, it should be acting like a field. An approach like this would work: class A {
Aug 10 2013
parent "BLM768" <blm768 gmail.com> writes:
On Saturday, 10 August 2013 at 17:48:34 UTC, BLM768 wrote:
 On Saturday, 10 August 2013 at 10:29:51 UTC, Stian Pedersen 
 wrote:
 To add to the mess - or maybe suggest a new approach, what 
 about:

 class A
 {
    int foo();
    void foo=(int a);
    private foo_;
 }

 Then a.foo = 42; calls the foo= method. No other conversions 
 from a=b to a method invocation.

 It may be suggested in one of these 46 pages which I haven't 
 read. And it'll probably break a lot of stuff.
The problem with this approach is that the getter is still operating under the semantics of a method, but, as a property, it should be acting like a field. An approach like this would work: class A {
Sorry; message got cut off when I tried to insert a tab and then pressed space with the "Send" button focused. Continuing... class A { property int foo(); property void foo=(int a); //etc. } However, it doesn't offer any significant advantage over the current property syntax other than providing a clearer distinction between getters and setters, which is only important when dealing with UFCS, as pointed out in an earlier post.
Aug 10 2013
prev sibling next sibling parent reply "JS" <js.mdnq gmail.com> writes:
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns 
 somewhere.

 Perhaps we should revert to a simple set of rules.
Here is my mindless proposal after reading some of the posts. 1. Properties are data. Cannot be called with parenthesis, unless it returns a delegate, in which case the delegate is called. The address of a property is invalid(possibly gotten through a trait). 2. Properties cannot be used in UFCS calls, unless they return a delegate. Only UFCS chaining allows for parenthesis-less calls. e.g., (). -> . why should D? From the little reading, the best I can tell is that the issue comes directly from UFCS and trying to avoid using parenthesis. Conflating the issue between properties and UFCS isn't an issue with properties or UFCS but with distinguishing between them. UFCS wants property like behavior but then that causes problems with properties themselves. Properties want function call behavior but then that makes them look like functions, yet this defeats the purpose of a property. Alternative, use a different syntax for chaining UFCS's. Instead of using ()., use something like func1:func2:func3:func4; where : seems to be a somewhat unused symbol... ~, >, >>, or others could potentially be used. Such a symbol AUTOMATICALLY is replaced with `().` since everything is a function call. (no properties can exist in the chain unless they return delegates, in which case the delegate is uses)
Aug 10 2013
parent Iain Buclaw <ibuclaw ubuntu.com> writes:
On 10 August 2013 13:27, JS <js.mdnq gmail.com> wrote:
 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.

 Perhaps we should revert to a simple set of rules.
Here is my mindless proposal after reading some of the posts. 1. Properties are data. Cannot be called with parenthesis, unless it returns a delegate, in which case the delegate is called. The address of a property is invalid(possibly gotten through a trait). 2. Properties cannot be used in UFCS calls, unless they return a delegate. Only UFCS chaining allows for parenthesis-less calls. e.g., (). -> . D? From the little reading, the best I can tell is that the issue comes directly from UFCS and trying to avoid using parenthesis.
Might be wrong "cause I've only spent 5 minutes looking at it severall -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Aug 10 2013
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
 This has turned into a monster. We've taken 2 or 3 wrong turns 
 somewhere.
My 2 cents on this, very late in the day. Sorry for the essay, hopefully it'll be worth your time. No fancy new ideas, but I *think* I have a nice solution that keeps everyone happy and avoids nasty corner-cases and ambiguities: 1) non-property functions must be called with parenthesis, *except* on UFCS calls. No assignment call syntax for non-properties. fun1.fun2; //illegal fun1.fun2(); //illegal fun1().fun2; //OK fun1().fun2(); //OK fun1; //illegal fun1(); //OK fun2 = var; //not a function call, but a normal assignment where //possible, e.g. initialising a function pointer. iota(100).map!"a+1".filter!"a%5".writeln; //LEGAL :-) Alternative way of saying it: optional paren for single argument calls in UFCS, enforced parenthesis elsewhere. Reason: No one wants writeln = "Hello World!"; but a lot of people want "Hello World!".writeln; Also, this removes visual ambiguity between the name of a function and it's result. That only really matters with alias/variadic template parameters but it is very annoying there. That will never conflict with UFCS so everyone's happy. Note that in the first two examples, fun1 is *NOT* a UFCS call and therefore cannot be done without parens. Preventing optional parens on non-UFCS stops any possible mixing of optional parenthesis and the unary & operator. 2) property enforces parenthesis-less calling for getters and assignment syntax for setters. No properties with more than one argument allowed. If a property returns a callable, any parenthesis will be applied to the callable Reason: Properties are not for general purpose work. The whole point of them is to be used roughly like variables and this is as close to that as we're gonna get. 3) Getting the address of a function is done with the & operator. Callables must always have parenthesis *except* when: Parenthesis would be optional for an equivalent normal function AND not when the callable is the result of an expression: 42.aDelegate.foo; //OK 42.returnsADelegate.foo; //OK, foo acts on the delegate 42.returnsADelegate().foo; //OK, foo acts on the delegate 42.returnsADelegate()().foo; //OK, foo acts on //the return value of the delegate aDelegate; //illegal aDelegate() //OK "blah".aDelegate; //OK "blah".aDelegate(); //OK auto a = &returnsADelegate; //a is function pointer to //returnsADelegate a; //illegal auto b = a(); //OK, calls a and b is a delegate b; //illegal b(); //OK, calls the delegate. //given some struct Bar that overloads opBinary!"+" and opCall Bar x,y; x; //illegal x(); //opCall (x+y) //does not call opCall (x+y)() //does call opCall Reason: This allows them to be used transparently like normal functions where possible, but removes ambiguity elsewhere. 3a) Explicitly taking the address of a property. Attempting to shoe-horn this in with normal syntax causes hell for the rest. I suggest some magic here, e.g. __traits(propertyGetterAddress, a.prop) and __traits(propertySetterAddress, a.prop) A function pointer to a property must be called as a normal function pointer. auto v = __traits(propertyGetterAddress, a.prop); auto n = v; //n is a function pointer to the getter a.prop, //same as v auto n = v(); //n is equal to the return of the getter a.prop auto h = __traits(propertySetterAddress, a.prop); auto j = h; //j is a function pointer to the setter a.prop //same as h h = 3; //illegal h(3); //OK, equates to a.prop = 3; Reason: This needs to be possible, but using & for it is broken. The most important thing is to keep the syntax of common use-cases clean and unsurprising. ***any other workable syntax for this is ok, __traits is just an (ugly, verbose) example*** Losing all property-ness when working through a function pointer keeps things simple. 4) OPTIONAL: Free functions can be marked as properties, with the same rules applied to them as properties in aggregates, except they must take 1 or 2 arguments instead of 0 or 1. Reason: Free functions and ufcs => good for encapsulation and nice to look at. Is there any reason why not to allow us to declare free properties? These rules should provide the least possible surprise and breakage, as far as I can tell. I don't think personally I would have to alter a single line of my code. What inevitable corner-cases have I missed?
Aug 10 2013
prev sibling parent "Jason den Dulk" <public2 jasondendulk.com> writes:
Part 1 - Ordinary Functions (the rewrite rules)
--------------------------
Not strictly the discussion topic, but it was a big issue and is 
related, so:

Q: Do you think the "property" rewrite rules (ie optional opCall 
operators) are a bad idea.
A: Yes I do
Q: Why?
A1: Look at all the confusion its caused!
A2: Because I have shot myself in the foot too many times because 
of this to be convinced otherwise. Judging from the posts, I am 
not the only one hopping around on one foot.
Q: Accepting that it's here to stay, what can you do about it?
A: Pretend they don't exist and always write expressions the 
"correct" way.

Basically If you're having problems with the "property" rewrite 
rules, then stop trying to use them. Adopt the habit of always 
writing your function calls verbosely (even with UFCS) and your 
problems should go away.

Unless they are going to be gotten rid of entirely, the rewrite 
rules should not be changed. All of the suggestions I've seen 
(including Walter's original one) will only lead to more 
complexity, more special cases, more inconsistency, more 
confusion, and more problems.

Part 2 -  property
--------------------------

A big problem with  property is that people are thinking of them 
as functions, no small part due to the "property" rewrite rules 
discussed above. Even people who suggest that  properties should 
not use opCall still talk about calling properties, as though 
they are functions.

The trick is to stop thinking of properties in terms of 
functions, and to think of them as variables. To "call" a 
property should make as much sense as calling a variable.

Some have mentioned this, and others have hinted at it, but I 
think that it has not been made fully clear.

To illustrate, consider this:

    int v;

v is a reference to a block of memory which is accessed by a 
machine code getter and setter. So

    int a;

is really

     property { int a() { fetch from memory }; int a(int) { write 
to memory } }

When you're declaring a true property, you're still declaring a 
variable, but you're simply providing the complier with 
altertives to the traditional fetch/write instructions.

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

Here is another (admittedly more complex) way to look at it.

struct {
   int opAssign(int) { ... };
   int opCast!(int) { ... } ;
} Property

Property prop;

You will need to imagine the opCast as an implicit cast for it to 
work, but hopefully you will get what I mean.

Here prop is a variable, so it would be parsed like one by the 
compiler.

The expression "prop = 3" would assign 3 to the contents of prop, 
Which would result in the opAssign (the setter) being called.

In the expression "y = prop++", we get the contents of prop (via 
opCast, the getter), apply the ++ operator to it, and assign the 
result to y.

If prop were an actual integer, the above expressions would work 
exactly the same way.

Using struct for this is a little ugly, so you could say instead:

 property { int prop(int) { ... }; int prop() { ... }; }

A little neater, but would work the same way.

Part 3 - functions returning delegates.
---------------------------------------

When it comes to delegate properties (ie the getter returns a 
delegate), I'm sensing that people are having trouble getting 
their heads around it, always needing to treat it like a special 
case. Let's try to see it in a way that it is not special.

Lets have

     delegate int() f1;

and

      property delegate int() f2() { ... };

In the eyes of the greater world f1 and f2 should work the same 
way.

In the expression y = f1(), we get the contents of f1 (the 
delegate), apply the "()" operator to it, and assign the result 
to y;

In the expression y = f2(), we get the contents of f2 (via the 
getter, which gives us the delegate), apply the "()" operator to 
it, and assign the result to y;

In both cases y is an int.

Recall an eariler statement:

In the expression "y = prop++", we get the contents of prop (via 
opCast, the getter), apply the ++ operator to it, and assign the 
result to y.

Note the similarity. () is like other operators and is no longer 
special.

How does this work for ordinary functions?

     int func()

can be seen as

     auto func = function int()

func is a variable and its contents is the function. The 
expression func() means "get the contents of func (the function) 
an apply () to it (gives int)".

For

     delegate int() delg()

which can be seen as

     auto delg = function (delegate int())()

The expression delg() means "get the contents of delg (the 
function) and apply () to it (gives delegate)", and delg()() 
would apply () to whatever delg() gives and, ultimately, give us 
an int.

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

How come people are getting confused about it? That damn optional 
opCall rewrite rule.

Some people probably think that, for functions returning 
delegates, if
    f becomes f()
then
    f() becomes f()()

THIS DOES NOT HAPPEN! Nor should it. Remember that and you should 
be OK. Otherwise consider my suggestion in Part 1.

Part 4 - Answering the original question.
----------------------------------------

Should  property be shot?

No, but it should be reworked

Regards
Jason
Aug 11 2013