Thread overview
Optional function invocation parentheses
Sep 20, 2012
Will Rubin
Sep 20, 2012
Jonathan M Davis
Sep 20, 2012
Will Rubin
Sep 20, 2012
monarch_dodra
Sep 20, 2012
Will Rubin
Sep 20, 2012
monarch_dodra
Sep 20, 2012
Jesse Phillips
Sep 20, 2012
monarch_dodra
September 20, 2012
I'm new to D. While poking around the site I stumbled across Uniform Function Call Syntax. This lead me here: http://www.reddit.com/r/programming/comments/vvpfy/uniform_function_call_syntax_in_d_gamedevnet/c58f8yy

I seem to remember reading that empty function invocation parens were now optional so I tried it and it worked fine. But the comments in the above thread indicate that there is something special about removing them and it shouldn't be done so casually.

Are the following two "results" equivalent or is there something special going on behind the scenes that makes result2 less desirable?

import std.stdio;
import std.algorithm;

void main() {
  auto result1 = [1, 2, 3, 4].filter!(a => a < 4)().reduce!((a, b) => a + b)();
  writeln("Result1: ", result1);

  auto result2 = [1, 2, 3, 4].filter!(a => a < 4).reduce!((a, b) => a + b);
  writeln("Result2: ", result2);
}

September 20, 2012
On Thursday, September 20, 2012 09:40:53 Will Rubin wrote:
> I'm new to D. While poking around the site I stumbled across
> Uniform Function Call Syntax. This lead me here:
> http://www.reddit.com/r/programming/comments/vvpfy/uniform_function_call_syn
> tax_in_d_gamedevnet/c58f8yy
> 
> I seem to remember reading that empty function invocation parens were now optional so I tried it and it worked fine. But the comments in the above thread indicate that there is something special about removing them and it shouldn't be done so casually.
> 
> Are the following two "results" equivalent or is there something special going on behind the scenes that makes result2 less desirable?
> 
> import std.stdio;
> import std.algorithm;
> 
> void main() {
>    auto result1 = [1, 2, 3, 4].filter!(a => a < 4)().reduce!((a,
> b) => a + b)();
>    writeln("Result1: ", result1);
> 
>    auto result2 = [1, 2, 3, 4].filter!(a => a < 4).reduce!((a, b)
> => a + b);
>    writeln("Result2: ", result2);
> }

Historically in D, you could leave out the parens on any function call which didn't take any arguments (originally due to a compiler bug IIRC, though people liked it enough that it stayed). That caused some problems with delegates and whatnot (e.g. if you returned a delegate from a function, it didn't get called with only one set of parens, even if you wanted to treat that function as a property function).

@property was introduced to solve this with the idea that any function marked with @property would be used like a property (i.e. it was an abstraction for a variable and would be used like a variable - without parens) and functions without @property would have to be called with parens. It was partially implemented and the -property flag was added to indicate that you wanted this enforced, but neither @property or -property is really fully implemented, and you can still leave off the parens whenever you feel like it. When -property was introduced, it was with the idea that its implementation issues would be sorted out and then it would become the normal behavior.

In part because of UFCS and templated functions where you pass a predicate but (like reduce), some people have expressed a dislike for the idea that they would be forced to use or not use parens based on @property, so what exactly is going to happen in the long run is a bit up in the air at this point.

My guess is that what's going to happen is that eventually, @property functions will be forced to be called without parens (fixing the aforementioned problem with delegates) but that non-@property functions will be able to use parens or not as you please, but I don't know. Personally, I think that it should always be enforced that @property doesn't use parens and everything else does, but while plenty of people agree with me, plenty of others disagree.  It's a very devisive subject. So, we'll just have to wait and see how it turns out.

In the meantime however, you can use parens or not as you like.

- Jonathan M Davis
September 20, 2012
Thanks for the detailed reply. It's too early for me to have much of an opinion but I'll take your approach and use @Property without parens (as I would in C# for example) and stick with the empty parens for non-property functions as it's a bit clearer to see what's really going on at this right now.

A bit interesting to see I can declare a write property that returns a value rather than void.

On Thursday, 20 September 2012 at 07:56:09 UTC, Jonathan M Davis wrote:
>
> My guess is that what's going to happen is that eventually, @property
> functions will be forced to be called without parens (fixing the aforementioned
> problem with delegates) but that non-@property functions will be able to use
> parens or not as you please, but I don't know. Personally, I think that it
> should always be enforced that @property doesn't use parens and everything
> else does, but while plenty of people agree with me, plenty of others
> disagree.  It's a very devisive subject. So, we'll just have to wait and see
> how it turns out.
>
> In the meantime however, you can use parens or not as you like.
September 20, 2012
On Thursday, 20 September 2012 at 12:59:51 UTC, Will Rubin wrote:
> Thanks for the detailed reply. It's too early for me to have much of an opinion but I'll take your approach and use @Property without parens (as I would in C# for example) and stick with the empty parens for non-property functions as it's a bit clearer to see what's really going on at this right now.

FYI, you can use the -d compile option to enforce the "proper" usage.

> A bit interesting to see I can declare a write property that returns a value rather than void.
>
Why would a property return void. If anything, it would return a non void:

auto a = someRange.front;

front is a property that returns a value.
September 20, 2012
Just a _write_ property:

struct Bleem {
  int _value;
public:
  //@property int value() { return _value; }
  @property int value(int newValue) { return _value = newValue; }
}

void main() {
  auto bleem = Bleem();
  writeln("Result: ", bleem.value = 9);
}

Application Output
Result: 9

Off the top of my head (C#, Delphi, Python) have them return void. Maybe it's not so uncommon though.

On Thursday, 20 September 2012 at 13:57:54 UTC, monarch_dodra wrote:
>> A bit interesting to see I can declare a write property that returns a value rather than void.
>>
> Why would a property return void. If anything, it would return a non void:
>
> auto a = someRange.front;
>
> front is a property that returns a value.

September 20, 2012
On Thursday, 20 September 2012 at 14:31:55 UTC, Will Rubin wrote:
> Just a _write_ property:
>
> struct Bleem {
>   int _value;
> public:
>   //@property int value() { return _value; }
>   @property int value(int newValue) { return _value = newValue; }
> }
>
> void main() {
>   auto bleem = Bleem();
>   writeln("Result: ", bleem.value = 9);
> }
>
> Application Output
> Result: 9
>
> Off the top of my head (C#, Delphi, Python) have them return void. Maybe it's not so uncommon though.
>
> On Thursday, 20 September 2012 at 13:57:54 UTC, monarch_dodra wrote:
>>> A bit interesting to see I can declare a write property that returns a value rather than void.
>>>
>> Why would a property return void. If anything, it would return a non void:
>>
>> auto a = someRange.front;
>>
>> front is a property that returns a value.

It is usually more common to just have a read property that returns a reference, which can be written to.

If the property needs an explicit write version, then usually, returning a value is considered "costly".

But the point is you can do whatever you want anyways.
September 20, 2012
On Thursday, 20 September 2012 at 13:57:54 UTC, monarch_dodra wrote:
> On Thursday, 20 September 2012 at 12:59:51 UTC, Will Rubin wrote:
>> Thanks for the detailed reply. It's too early for me to have much of an opinion but I'll take your approach and use @Property without parens (as I would in C# for example) and stick with the empty parens for non-property functions as it's a bit clearer to see what's really going on at this right now.
>
> FYI, you can use the -d compile option to enforce the "proper" usage.

What do you mean by this, -d allows deprecated features to be compiled in, wouldn't that be allowing "unproper" usage?
September 20, 2012
On Thursday, 20 September 2012 at 17:13:09 UTC, Jesse Phillips wrote:
> On Thursday, 20 September 2012 at 13:57:54 UTC, monarch_dodra wrote:
>> On Thursday, 20 September 2012 at 12:59:51 UTC, Will Rubin wrote:
>>> Thanks for the detailed reply. It's too early for me to have much of an opinion but I'll take your approach and use @Property without parens (as I would in C# for example) and stick with the empty parens for non-property functions as it's a bit clearer to see what's really going on at this right now.
>>
>> FYI, you can use the -d compile option to enforce the "proper" usage.
>
> What do you mean by this, -d allows deprecated features to be compiled in, wouldn't that be allowing "unproper" usage?

Oops, I meant:
-property      enforce property syntax