January 25, 2013
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.

(Personally, i'd beg to differ, I work with C# UFCS every, 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.)

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/
January 25, 2013
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).
January 25, 2013
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.
January 25, 2013
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/
January 25, 2013
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
>


January 25, 2013
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.
January 25, 2013
On 01/25/2013 01:42 AM, Adam Wilson wrote:
> ...
> (Personally, i'd beg to differ, I work with C# UFCS every, 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.)
> ...

That might explain your bias. I had to work with C# for a project recently, and sometimes experienced a handful C#-induced hiccups when working in other languages.

(Furthermore, C# does not have !() brackets into the mix.)
January 25, 2013
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:
>>
>>> ...
>>>
>>> All I can say is that in this case even with UFCS C# enforces parens 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 C#
>>> 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.

#1 is a ratification of current behavior. It allows the combination of UFCS
and removing redundant ()s.
#2 is a breaking change. If we need it, community consent is required.

Kenji Hara


January 25, 2013
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:
>>>
>>>> ...
>>>>
>>>> All I can say is that in this case even with UFCS C# enforces parens
>>>> 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 C#
>>>> 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.
>
> #1 is a ratification of current behavior. It allows the combination of UFCS
> and removing redundant ()s.
> #2 is a breaking change. If we need it, community consent is 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

-- 
Adam Wilson
IRC: LightBender
Project Coordinator
The Horizon Project
http://www.thehorizonproject.org/
January 25, 2013
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.
>>
>> #1 is a ratification of current behavior. It allows the combination of
>> UFCS
>> and removing redundant ()s.
>> #2 is a breaking change. If we need it, community consent is 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
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