February 04, 2013
On Monday, 4 February 2013 at 03:13:07 UTC, Andrei Alexandrescu wrote:
> On 2/3/13 9:58 PM, David Nadlinger wrote:
>> My point is precisely that. I think there are much simpler solutions
>> than adding some magic properties to a pair of parentheses in the right
>> position, even if it might look like a convenient hack.
>
> I don't think it's a hack at all. Think it over, […]

I've done that. What about *you* thinking it over? :P

> and compare it with the language semantics even today.

I thought we agreed that today's semantics are hopelessly broken. Actually, we might already have some of the &a vs. &(a) stuff, I remember Kenji opening a pull request about that at some point, but don't know if it went in OTOH.

David
February 04, 2013
On Sunday, February 03, 2013 22:06:27 Andrei Alexandrescu wrote:
> Yes. No static properties.

So, properties such as Duration.max would simply be normal functions called without parens if they have they have to be property functions rather than variables or enums?

- Jonathan M Davis
February 04, 2013
On Monday, 4 February 2013 at 02:36:41 UTC, Timon Gehr wrote:
> On 02/04/2013 03:23 AM, kenji hara wrote:
>> Unfortunately, I can present a counterexample.
>>
>> struct S {
>>     static int value;
>>     static @property int foo() { return value; }
>>     static @property void foo(int n) { value = n; }
>>
>> }
>> void main() {
>>     int n = S.foo;
>>     S.foo = 1;
>> }
>>
>> Should they be disallowed, as like module level properties?
>>
>> Kenji Hara
>
> Probably. (static essentially means module-level, but in a potentially nested name space.)

I disagree. Static properties can be allowed because they're not ambiguous. The problem with module-level:
@property void foo(int n) {}
...are the two interpretations of foo as either a setter taking an int or a getter property of int type. So, one of those interpretations must be disallowed. But, with static member properties, there aren't multiple interpretations.
February 04, 2013
On Monday, 4 February 2013 at 03:15:51 UTC, David Nadlinger wrote:
> On Monday, 4 February 2013 at 03:11:25 UTC, Andrei Alexandrescu wrote:
>> I really think you are wrong about this. Parenthesizing has nothing to do with this. &a.b is punctuation that creates an indivizible unit.
>
> a.b already is an indivisible unit, the result of the function call.

Actually, let me illustrate this point a bit further, sorry for the hasty reply.

The problem I see is that usually, one can insert grouping pairs of parentheses into an expression according to the operator precedence/associativity rules at will without changing the result. This isn't merely a theoretical exercise, but the way (well, in the form of trees) I tend to reason about source code intuitively.

Now, grouping the expression »&a.b« according to the precedence rules yields »&(a.b)« – but in your proposal, they mean completely different things.

You could argue that &<expression>.<identifier> is a special construct different from the normal address-of operator. But where do you mentally draw the line? What about &a.b.c <-> &(a.b).c <-> &((a.b).c)? &(a + b).c <-> &((a + b).c)?

Again, from an user's perspective the change in behavior seems to be completely at odds with the usual rule in C-family languages that grouping parens can be added without changing the meaning of an expression. Thus, this part of the proposed syntax strikes me as being extremely misleading, which is especially bad because the situation with the two possible meanings is confusing enough to start out with already.

And how often do you think you'll find yourself in the situation of needing to get a delegate from a property anyway? Can't we just make »@property getter expressions are always equivalent to their return value« a hard (simple!) rule and add something like __traits(propertyGetter, ...) for the rare cases where you really need to get hold of the underlying function?

David
February 04, 2013
On Monday, 4 February 2013 at 04:00:28 UTC, David Nadlinger wrote:
> On Monday, 4 February 2013 at 03:15:51 UTC, David Nadlinger wrote:
>
> And how often do you think you'll find yourself in the situation of needing to get a delegate from a property anyway? Can't we just make »@property getter expressions are always equivalent to their return value« a hard (simple!) rule and add something like __traits(propertyGetter, ...) for the rare cases where you really need to get hold of the underlying function?
>
> David

I like this solution; it follows the Principle of Least Surprise
quite well. The syntax may be a bit longer, but it's immediately
obvious even to a beginning/intermediate D user what's going on
without having to worry about too many nuances.
February 04, 2013
On Monday, 4 February 2013 at 02:58:55 UTC, David Nadlinger wrote:
> Not sure I'm following – you are arguing that the whole endeavor is futile as long as we keep parens-less function calls?
>
> I actually think that DIP23 is a big step in the right direction, given that parens-less function calls are *very* unlikely to go away. Contrary to some of the previous proposals, it's actually a principled approach, like Adam and others (including me) have asked for. Now it's just a matter of getting the details right.
>

My point is that we try to pack fundamentally different concept into one. Which is doomed to produce a three headed monster.

> My point is precisely that. I think there are much simpler solutions than adding some magic properties to a pair of parentheses in the right position, even if it might look like a convenient hack.
>

Convenient hack is not good design.
February 04, 2013
On Monday, 4 February 2013 at 03:13:07 UTC, Andrei Alexandrescu wrote:
> On 2/3/13 9:58 PM, David Nadlinger wrote:
>> My point is precisely that. I think there are much simpler solutions
>> than adding some magic properties to a pair of parentheses in the right
>> position, even if it might look like a convenient hack.
>
> I don't think it's a hack at all. Think it over, and compare it with the language semantics even today.
>

Going from complete crap to bearable don't make bearable good.
February 04, 2013
On Monday, February 04, 2013 05:00:21 David Nadlinger wrote:
> On Monday, 4 February 2013 at 03:15:51 UTC, David Nadlinger wrote:
> > On Monday, 4 February 2013 at 03:11:25 UTC, Andrei Alexandrescu
> > 
> > wrote:
> >> I really think you are wrong about this. Parenthesizing has nothing to do with this. &a.b is punctuation that creates an indivizible unit.
> > 
> > a.b already is an indivisible unit, the result of the function call.
> 
> Actually, let me illustrate this point a bit further, sorry for the hasty reply.
> 
> The problem I see is that usually, one can insert grouping pairs of parentheses into an expression according to the operator precedence/associativity rules at will without changing the result. This isn't merely a theoretical exercise, but the way (well, in the form of trees) I tend to reason about source code intuitively.
> 
> Now, grouping the expression »&a.b« according to the precedence rules yields »&(a.b)« – but in your proposal, they mean completely different things.
> 
> You could argue that &<expression>.<identifier> is a special
> construct different from the normal address-of operator. But
> where do you mentally draw the line? What about &a.b.c <->
> &(a.b).c <-> &((a.b).c)? &(a + b).c <-> &((a + b).c)?
> 
> Again, from an user's perspective the change in behavior seems to be completely at odds with the usual rule in C-family languages that grouping parens can be added without changing the meaning of an expression. Thus, this part of the proposed syntax strikes me as being extremely misleading, which is especially bad because the situation with the two possible meanings is confusing enough to start out with already.
> 
> And how often do you think you'll find yourself in the situation of needing to get a delegate from a property anyway? Can't we just make »@property getter expressions are always equivalent to their return value« a hard (simple!) rule and add something like __traits(propertyGetter, ...) for the rare cases where you really need to get hold of the underlying function?

I tend to agree that making the parens change the nature of the expression is a bad idea. I'm also concerned that making it legal to take the address of a property function is going to cause serious issues when anyone tries to actually try and swap between variables and property functions. But there's also the issue of it not being terribly common to need the address of a property function. The biggest concern there would be what happens when someone takes the address of a variable which then gets turned into a property. It's not going to work, and the way that that it doesn't work is going to vary depending on what & does on a property function and what they're trying to assign it to.

- Jonathan M Davis
February 04, 2013
On Sunday, February 03, 2013 03:16:08 Andrei Alexandrescu wrote:
> Destroy.

Another thing to consider would be to allow putting @property on a variable with the idea that variables marked as such would not be usable in any situation where a property function wouldn't be - such as taking their address or passing them by ref. That would reduce code breakage when switching between public variables and property functions.

The alternative would be to make it so that putting @property on a variable would lower it to property functions. So,

struct S
{
    @property int prop;
}

becomes something like

struct S
{
    private int __prop;

    @property int prop() @safe inout pure nothrow
    { return __prop; }

    @property int prop(int value) @safe pure nothrow
    { return __prop = value; }
}

One of the main ideas behind properties is to make it so that you can make something a variable when you don't the extra boilerplate for setter and getter functions (e.g. because you don't need to check the value it's being set to), but it's still easy to swap it out with an actual getter and setter function later when you actually _do_ need extra stuff in those functions. And if we don't do something to indicate that a variable could be swapped out with a property function later, then you risk code doing stuff like taking its address or passing it by ref, and that code will then break if the variable ever does become a property function.

- Jonathan M Davis
February 04, 2013
On Sun, 03 Feb 2013 22:06:27 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> On 2/3/13 9:23 PM, kenji hara wrote:
>> 2013/2/4 Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org
>> <mailto:SeeWebsiteForEmail@erdani.org>>
>>
>>     On 2/3/13 3:16 AM, Andrei Alexandrescu wrote:
>>     [snip]
>>
>>     Some more thinking got me to three simple principles that guide the
>>     proposed property design:
>>
>>     http://wiki.dlang.org/DIP23#__In_a_nutshell
>>     <http://wiki.dlang.org/DIP23#In_a_nutshell>
>>
>>
>>  > 2. A @property may have EXACTLY ONE or EXACTLY TWO parameters,
>> counting the implicit this parameter if at all. The ONE-parameter
>> version is ALWAYS a getter, and the TWO-parameter version is ALWAYS a
>> setter. There's no variadics, defaulted parameters, and such.
>>
>> Unfortunately, I can present a counterexample.
>>
>> struct S {
>>      static int value;
>>      static @property int foo() { return value; }
>>      static @property void foo(int n) { value = n; }
>>
>> }
>> void main() {
>>      int n = S.foo;
>>      S.foo = 1;
>> }
>>
>> Should they be disallowed, as like module level properties?
>
> Yes. No static properties.

Hm... can't see the reason why.  Static properties play no part in UFCS (which is what makes global properties confusing).  I hope it's not because you like your new nutshell rules too much...

Then again, @properties are for syntax, easy enough to make functions instead.

-Steve
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19