December 05, 2012
On Tuesday, 4 December 2012 at 18:28:55 UTC, Rob T wrote:
> On Tuesday, 4 December 2012 at 16:24:27 UTC, Minas Mina wrote:
>> Isn't it possible to have parentheses optional only for UFCS?
>>
>> E.g.
>>
>> Allow:
>> I 5.writeln
>>
>> Dissallow:
>>
>> void f()
>> {
>> 	writeln("hi");
>> }
>>
>> f; // this currently works
>>
>>
>> I don't know if this is possible to implement.
>
>
> module main;
>
> void f()
> {
> 	writeln("hi");
> }
>
> main.f; // OK or not?
>
> I think the argument for vs against is simply a coding style
> issue, some like dropping empty braces, some do not.
>
> --rt

It is also a ambiguity issue and the extra need of & to not call the function (which also introduce ambiguity).
December 05, 2012
On Wednesday, 5 December 2012 at 18:32:16 UTC, deadalnix wrote:
>>
>> I think the argument for vs against is simply a coding style
>> issue, some like dropping empty braces, some do not.
>>
>> --rt
>
> It is also a ambiguity issue

The () acts like a naming convention, and with or without enforcement you are free to choose whatever naming convention you desire, thus reducing ambiguity.

> and the extra need of & to not call the function (which also introduce ambiguity).

If you dislike it, rather than use &, I suppose you can add on the () instead. In fact you can specify () everywhere if you prefer.

--rt
December 05, 2012
On Wednesday, 5 December 2012 at 20:27:18 UTC, Rob T wrote:
> On Wednesday, 5 December 2012 at 18:32:16 UTC, deadalnix wrote:
>>>
>>> I think the argument for vs against is simply a coding style
>>> issue, some like dropping empty braces, some do not.
>>>
>>> --rt
>>
>> It is also a ambiguity issue
>
> The () acts like a naming convention, and with or without enforcement you are free to choose whatever naming convention you desire, thus reducing ambiguity.
>
>> and the extra need of & to not call the function (which also introduce ambiguity).
>
> If you dislike it, rather than use &, I suppose you can add on the () instead. In fact you can specify () everywhere if you prefer.
>

I'll do like I've not read anything and let you rethink about that.
December 06, 2012
On 12/03/12 03:23, kenji hara wrote:
> I had been trying to advance the phase to the next.
> Now, an experimental pull request is here.
> https://github.com/D-Programming-Language/dmd/pull/1311
> 
> ----
> This change can distinguish almost usages between property and non-property syntax
> 
> int func() { return 1; }
> void func(int n) { }
> @property int prop() { return 2; }
> @property void prop(int n) { }
> void main() {
>   // Without -property switch, all lines can compile.
>   // With -property switch:
>   func();     // OK -> OK
>   func(1);    // OK -> OK
>   func;       // OK -> OK [*]
>   func = 1;   // OK -> NG (fixed!)
>   prop();     // OK -> NG (fixed!)
>   prop(1);    // OK -> NG (fixed!)
>   prop;       // OK -> OK
>   prop = 1;   // OK -> OK
> }
> 
> First exception is [*], keeping the line is necessary to allow UFCS chain without redundant parentheses (e.g. r.map!(a=>a*2).array). It is acceptable to me, at least.

Reasonable middle-term compromise; can't really disallow ()-ess calls w/o something else to migrate to, which doesn't exist yet.


> I also implemented that calling function pointer which returned by property function.
> 
> @property foo(){ return (int n) => n * 2; }
> auto n = foo(10);  // `foo` is resolved to property function call in advance
> assert(n == 20);
> 
> But, we cannot support it immediately, because it will *always* introduce breaking of existing code.
> 
> - If enable always this feature, propfunc() is implicitly translated to (propfunc())(),
>   then much existing correct code without "-property" switch will break.
> - If enable this only when -property switch is specified, a code propfunc() will have
>   _two_ meanings. When propfunc returns a function pointer,
>   * If -property is on, propfunc() is translated to propfunc()(), then
>     call returned function pointer and returns its result.
>   * If -property is off, propfunc() is jsut call property function, then
>     returns function pointer.
> 
> Changing compilation behavior by compile switch is bad.

'Bad' doesn't begin to describe it. It's unacceptable, as such a compiler
switch would create a different language.
So it has to be the first option. Which isn't that bad as the "correct" term
isn't really appropriate here. This /is/ a change that will break legacy code,
but the failures should happen mostly at compile time and the fix is both
trivial and backwards compatible.
Delaying these kind of changes would only make things worse.


> The third exception is in AddressExpression (&exp).
> 
> In current, both &func and &propfunc return their function pointers. Some peoples argues
> that the latter should return an address of the returned value of propfunc after implementing more property enforcement, but I'm difficult to accept that.
> 
> The root cause is: AddressExpression is just only one built-in feature for getting an exact type of property function (Note that typeof(propfunc) returns the type of propfunc result).
> 
> If compiler will always translate the code &propfunc to &(propfunc()), we will lost a way to get an exact type of propfunc, and then std.traits.FunctionTypeOf will never work for propfunc.
> 
> To resolve the issue, I have proposed a small enhancement for AddressExpression. http://d.puremagic.com/issues/show_bug.cgi?id=9062
> 
> It will distinguish &propfunc and &(propfunc), the former returns a function poiinter of propfunc, and the latter returns an address of propfunc result.

No, extremely bad idea; parens shouldn't make any difference.

   &cast(function)prop // or 'cast(delegate)', as appropriate


> The real example about that is here. https://github.com/D-Programming-Language/phobos/pull/968/files#L0L1136
> 
> ----
> How about that?

The property situation is as bad as it is in part because the migration was
handled wrongly. What should have happened is that the 'property' compiler
switch should have enabled legacy code to compile and property enforcement
should have been on by default, to the extent supported by the compiler.
Doing it the other way meant that people are writing incorrect code even
today. [1]
Your changes seem to go in the right direction. Committing to such property
enforcement will however be necessary, as keeping the current optional
status forever won't work, because of issues like the ones you list above.

artur

[1] Yeah, "incorrect" means /just/ "incompatible with property enforcement".
    But the alternative is /no/ enforcement, and if you believe that to be
    the right approach then every trace of @property should go.
January 28, 2013
On Sat, 01 Dec 2012 20:03:21 -0500, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> I'd _love_ to make it illegal to call non-property functions without parens,
> and there are definitely folks around here who agree with me, including some on
> the Phobos dev team (e.g. Steven has always agreed with me when this has come
> up), but there are enough folks around here here who like to call functions
> without parens - especially with UFCS and templated functions like map or
> filter - that I don't think that that's going to fly at this point.

Oh, shit.  I missed another important @property discussion.

OK, I will say my peace:

The issue I have with not implementing this is takes power away from the designer.

There are three intentions when creating a function w/ regards to properties:

1. You intend the function to be called without parentheses to clarify it is a property.
2. You intend the function to be only called with parentheses to clarify it is a function.
3. You don't care whether it's called with parentheses or not, because the name of the function is clearly a property or a function.

These distinctions are important because of the human meaning of the function.  i.e. x.read() vs. x.read.  The former looks to me like "read using x", the latter looks like "is x read."

With @property, the idea was to implement 1 and 2, and leave nothing for poor #3.  It's this #3 which throws a big fat wrench into my evil plans.  Things like map or filter, which clearly aren't properties by their name/usage.

I had a compromise that void parameterless functions could be unambiguously called without parentheses.  For example, if x.read() doesn't return a value, then the statement:

x.read;

Can't really be misinterpreted as "is x read" because the code isn't using the (implied) result.

So that is why I always thought, make non-property functions require parentheses.

But here we are almost 4? years later and still have the same situation.  I give.  As long as we can't call arbitrary functions as setters, I think the other failures of allowing the choice of removing parentheses are far less severe.  At least we get #1.

The proposed DIP does not look bad, I say do it.

-Steve
January 28, 2013
@property use:

I'd like to point out, that regardless of the "with parens/without parens" stuff, marking properties with @property makes sense. So that tools and frameworks can recognize them as such. This also implies that fields that are meant as properties should be declared @property and the compiler should generate getter/setter so it behaves exactly like a manually created property. May I add this to DIP21?

Having the compiler lower the following:

@property int a;

to

private int __a;

@property int a() {
return __a;
}
@property int a(int new_a) {
  __a=new_a;
  return __a;
}

would make properties and property declared fields really exchangeable, namely you can no longer take the reference of an @property field, just like you can't take the address of a property with get/set.

Best regards,

Robert

On Sun, 2013-01-27 at 22:24 -0500, Steven Schveighoffer wrote:
> On Sat, 01 Dec 2012 20:03:21 -0500, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> 
> > I'd _love_ to make it illegal to call non-property functions without
> > parens,
> > and there are definitely folks around here who agree with me, including
> > some on
> > the Phobos dev team (e.g. Steven has always agreed with me when this has
> > come
> > up), but there are enough folks around here here who like to call
> > functions
> > without parens - especially with UFCS and templated functions like map or
> > filter - that I don't think that that's going to fly at this point.
> 
> Oh, shit.  I missed another important @property discussion.
> 
> OK, I will say my peace:
> 
> The issue I have with not implementing this is takes power away from the designer.
> 
> There are three intentions when creating a function w/ regards to properties:
> 
> 1. You intend the function to be called without parentheses to clarify it
> is a property.
> 2. You intend the function to be only called with parentheses to clarify
> it is a function.
> 3. You don't care whether it's called with parentheses or not, because the
> name of the function is clearly a property or a function.
> 
> These distinctions are important because of the human meaning of the function.  i.e. x.read() vs. x.read.  The former looks to me like "read using x", the latter looks like "is x read."
> 
> With @property, the idea was to implement 1 and 2, and leave nothing for poor #3.  It's this #3 which throws a big fat wrench into my evil plans. Things like map or filter, which clearly aren't properties by their name/usage.
> 
> I had a compromise that void parameterless functions could be unambiguously called without parentheses.  For example, if x.read() doesn't return a value, then the statement:
> 
> x.read;
> 
> Can't really be misinterpreted as "is x read" because the code isn't using the (implied) result.
> 
> So that is why I always thought, make non-property functions require parentheses.
> 
> But here we are almost 4? years later and still have the same situation. I give.  As long as we can't call arbitrary functions as setters, I think the other failures of allowing the choice of removing parentheses are far less severe.  At least we get #1.
> 
> The proposed DIP does not look bad, I say do it.
> 
> -Steve


January 28, 2013
On 2013-01-28 12:44, Robert wrote:
> @property use:
>
> I'd like to point out, that regardless of the "with parens/without
> parens" stuff, marking properties with @property makes sense. So that
> tools and frameworks can recognize them as such.

I completely agree. I have created a struct called "attribute" only to be used as an attribute for other types that should only be attributes:

struct attribute {}

@attribute struct foo {}

Even though @attribute in this case doesn't to anything it shows the intent clearly. Same thing why I like explicit interfaces and abstract classes compared with C++.

> This also implies that
> fields that are meant as properties should be declared @property and the
> compiler should generate getter/setter so it behaves exactly like a
> manually created property. May I add this to DIP21?
>
> Having the compiler lower the following:
>
> @property int a;
>
> to
>
> private int __a;
>
> @property int a() {
> return __a;
> }
> @property int a(int new_a) {
>    __a=new_a;
>    return __a;
> }

I would love that. But the setter should return void and the compiler should to property rewrites.

-- 
/Jacob Carlborg
January 28, 2013
On Monday, 28 January 2013 at 12:31:35 UTC, Jacob Carlborg wrote:
> On 2013-01-28 12:44, Robert wrote:
>> @property use:
>>
>> I'd like to point out, that regardless of the "with parens/without
>> parens" stuff, marking properties with @property makes sense. So that
>> tools and frameworks can recognize them as such.
>
> I completely agree. I have created a struct called "attribute" only to be used as an attribute for other types that should only be attributes:
>
> struct attribute {}
>
> @attribute struct foo {}
>
> Even though @attribute in this case doesn't to anything it shows the intent clearly. Same thing why I like explicit interfaces and abstract classes compared with C++.
>
>> This also implies that
>> fields that are meant as properties should be declared @property and the
>> compiler should generate getter/setter so it behaves exactly like a
>> manually created property. May I add this to DIP21?
>>
>> Having the compiler lower the following:
>>
>> @property int a;
>>
>> to
>>
>> private int __a;
>>
>> @property int a() {
>> return __a;
>> }
>> @property int a(int new_a) {
>>   __a=new_a;
>>   return __a;
>> }
>
> I would love that. But the setter should return void and the compiler should to property rewrites.

Returning void instead of int in the example break assignment chaining a = b = c. Besides, how such implicitly defined functions may call user defined code (check input validity, call events, etc.)?
January 28, 2013
On Monday, 28 January 2013 at 14:00:16 UTC, Maxim Fomin wrote:
> Returning void instead of int in the example break assignment chaining a = b = c. Besides, how such implicitly defined functions may call user defined code (check input validity, call events, etc.)?

It should not if evaluating the value of (b = c) will call getter for b.
January 28, 2013
On Monday, 28 January 2013 at 14:09:20 UTC, Dicebot wrote:
> On Monday, 28 January 2013 at 14:00:16 UTC, Maxim Fomin wrote:
>> Returning void instead of int in the example break assignment chaining a = b = c. Besides, how such implicitly defined functions may call user defined code (check input validity, call events, etc.)?
>
> It should not if evaluating the value of (b = c) will call getter for b.

Why getter and not setter? Expression a = b = c = d should call getter for d and setter for rest of them. And if c setter returns void the chain breaks.


struct S
{
    int _priv;
    @property void /*int*/foo(int i) //uncommment to fix
    {
        _priv = i;
        //return i;
    }
    @property int foo()
    {
        return _priv;
    }
}

void main()
{
    int a, b, c;
    a = b = c;

    S s1, s2, s3;
    s1.foo = s2.foo = s3.foo = 1;
}