January 24, 2013
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
January 24, 2013
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
January 24, 2013
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


January 24, 2013
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 :)
January 24, 2013
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.
January 24, 2013
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
January 24, 2013
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.
January 24, 2013
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
January 24, 2013
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
January 24, 2013
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.