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

January 25, 2013
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.
> >
> > #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.
>
> 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
> that #2 needs to happen with @property (unless Walter's horrid plan gets
> put
> into effect and we lose @property entirely). And #1 seems reasonable
> 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


January 25, 2013
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
January 25, 2013
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, simplify, simplify. Your #1 proposal to ratify current behavior and 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
January 25, 2013
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.

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


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


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

#1 preserves the status quo (important)
#2 is the key result I want from @property

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:

#1:

Callable bar();
bar; // must work, returns the callable
bar(); // according to rule #1, this also just returns the callable
bar()(); // calls the callable

#2:

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