January 25, 2013
Meaning of @property for free functions is well-defined. Most likely because languages like C# does not have UFCS as far as I rememeber.

I see two possible approaches here:

1)
-----
@property void symbol1(Data);
@property Data symbol1();
Data symbol2;
...
symbol1 = symbol2; // allowed, symbol1 behaves same as symbol2 for user
symbol2.symbol1; // prohibited, symbol1 is semantically a global variable
-----

2)
-----
@property void symbol1(Data);
@property Data symbol1();
Data symbol2;
...
symbol1 = symbol2; // prohibited, symbol1 has meaning only within UFCS and imitates Data member.
symbol2.symbol1; // Fine, rewritten as symbol1(symbol2), follows general property rules but for compound symbol
-----

First one seems more natural to me, but I can live with either approach. Not both. Also please mote that UFCS is meant for enhancing data type functionality with free functions, not implementing every possible feature available to that data type with native syntax.
January 25, 2013
On 2013-01-25 15:55, mist wrote:
> Meaning of @property for free functions is well-defined. Most likely
> because languages like C# does not have UFCS as far as I rememeber.

C# doesn't have UFCS but it does have a syntax for adding new methods for existing classes. The end result is the same.

-- 
/Jacob Carlborg
January 25, 2013
On Friday, 25 January 2013 at 14:55:09 UTC, mist wrote:
> Meaning of @property for free functions is well-defined. Most likely because languages like C# does not have UFCS as far as I rememeber.
>
> I see two possible approaches here:
>
> 1)
> -----
> @property void symbol1(Data);
> @property Data symbol1();
> Data symbol2;
> ...
> symbol1 = symbol2; // allowed, symbol1 behaves same as symbol2 for user
> symbol2.symbol1; // prohibited, symbol1 is semantically a global variable
> -----
>
> 2)
> -----
> @property void symbol1(Data);
> @property Data symbol1();
> Data symbol2;
> ...
> symbol1 = symbol2; // prohibited, symbol1 has meaning only within UFCS and imitates Data member.
> symbol2.symbol1; // Fine, rewritten as symbol1(symbol2), follows general property rules but for compound symbol
> -----
>
> First one seems more natural to me, but I can live with either approach. Not both. Also please mote that UFCS is meant for enhancing data type functionality with free functions, not implementing every possible feature available to that data type with native syntax.

See what is proposed here : http://forum.dlang.org/thread/kdqrnl$13ft$1@digitalmars.com?page=3#post-uagknsecziepoedcabvr:40forum.dlang.org
January 25, 2013
On Friday, 25 January 2013 at 15:02:46 UTC, Jacob Carlborg wrote:
> On 2013-01-25 15:55, mist wrote:
>> Meaning of @property for free functions is well-defined. Most likely
>> because languages like C# does not have UFCS as far as I rememeber.
>
> C# doesn't have UFCS but it does have a syntax for adding new methods for existing classes. The end result is the same.

Great, could you give a sample? Does it work on compile time or injects in run-time? Is calling of such methods allowed in usual free form?

Unfortunately I have never been using C# in practice, only following materials available in the internet, would be really interesting to learn from their approach.
January 25, 2013
On 2013-01-25 16:05, mist wrote:

> Great, could you give a sample? Does it work on compile time or injects
> in run-time? Is calling of such methods allowed in usual free form?
>
> Unfortunately I have never been using C# in practice, only following
> materials available in the internet, would be really interesting to
> learn from their approach.

The secret is to add "this" in front of the argument type you want to the method to extend:

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' },
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }
}

using ExtensionMethods;

string s = "Hello Extension Methods";
int i = s.WordCount();

http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx

-- 
/Jacob Carlborg
January 25, 2013
On Friday, 25 January 2013 at 15:05:11 UTC, deadalnix wrote:
> See what is proposed here : http://forum.dlang.org/thread/kdqrnl$13ft$1@digitalmars.com?page=3#post-uagknsecziepoedcabvr:40forum.dlang.org

Looks somewhat solid to me, with some disagreement on UFCS side :) Will reply with comments to that post.
January 25, 2013
On Friday, 25 January 2013 at 15:13:21 UTC, Jacob Carlborg wrote:
> The secret is to add "this" in front of the argument type you want to the method to extend:
>
> namespace ExtensionMethods
> {
>     public static class MyExtensions
>     {
>         public static int WordCount(this String str)
>         {
>             return str.Split(new char[] { ' ', '.', '?' },
>                              StringSplitOptions.RemoveEmptyEntries).Length;
>         }
>     }
> }
>
> using ExtensionMethods;
>
> string s = "Hello Extension Methods";
> int i = s.WordCount();
>
> http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx

Good. Main questions remain though: is property syntax allowed on extension methods? Is WordCount(s) call allowed?
January 25, 2013
On Thursday, 24 January 2013 at 13:41:42 UTC, deadalnix wrote:
> For regular functions :
> 1. funName is the function itself :
>   void funName() {}
>   static assert(is(typeof(funName) == void function())); // Pass.
>   funName has no address, it is equivalent to enum function void() funName = {};
>   &funName become a NOOP and is deprecated, for compatibility reasons. It is not ambiguous as funName has no address anyway.
Agree with differentiation but why no address? For me funName looks like function pointer variable, why prohibiting to cast this to raw address? &funName is legacy, agree.

> 2. funName() call the function.
And if funName is a getter returning delegate?

> 3. @getter is an attribute. A function marked @getter is automatically executed : () is added automatically :
>     @getter void funName() {}
>     funName; // function get executed.
>     funName(); // Error, void is not callable.
Agree, but @property is enough. I ll insist below that ambiguous cases should be simply an error. And I'd also like to prohibit getters returning void ;)

> 4. @getter can be used as UFCS.
>    @getter void funName(T t) {}
>    T t; t.funName; // function gets executed.
>    funName(t); // Error, funName require 1 argument, 0 given.
Fine by me, but error message is weird. Better "Error, funName is not usable with free-from syntax".

> 5. @setter is an attribute. A setter method can *only* be used in rhs of an expression. The assigned value is used as argument.
>    @setter void funName(T t) {}
>    T t; funName = t; // function gets executed.
>    funName(t); // Error, funName must be used in an assign expression.
Disagree, it is inconsistent with getter.  @property ... funName(T t ... ) should always behave as t.funName property. It is unnecessary complication.

> 6. @setter can as well be used as UFCS :
>    @getter void funName(T t, U u) {}
>    T t; U u; t.funName = u; // function gets executed.
>    t.funName(u); // Error, funName must be used in an assign expression.
And this is exactly the syntax I'd like to see. Again, as void return should be disallowed for getters, no ambiguity here and same @property suits just fine.

> 7a. A function can be defined as both @setter and @getter, and cumulate both behavior.
Feels like unnecessary complication. But if you want to, simply having both return type and 2 parameters is enough.

> 7b. @property is deprecated and redefined as @setter *and* @getter for a transitional period.
;)

> 8. method behave as functions :
>     class A { void foo() {} }
>     A a;
>     static assert(is(typeof(a.foo) : void delegate())); // Pass.
>     &a.foo; // deprecated NOOP for compatibility.
>     a.foo(); // call a.foo
Agree;

> 9. UFCS without () are delegate like construct :
> 10. To allow chain of UFCS calls without () everywhere, an opDispatch is defined in object.d
Very complicated for no real gain. Just prohibit function call without (), including (). Profit!

> Waiting for the shitstorm . . .
Welcome ;)
January 25, 2013
On 01/24/2013 12:57 PM, Andrei Alexandrescu wrote:
> On 1/24/13 8:41 AM, deadalnix wrote:
> [snip]
>> Waiting for the shitstorm . . .
>
> Nothing like that at least from me but I can plainly say this proposal
> has merit but will never get implemented.
>
> Andrei

Wait, so Walter would be willing to ice @property, but deprecating it in favor of this meritorious proposal will never happen?

I, for one, would love to see good ideas go into the language that I like to use.  I'd be willing to s/@property/@getter|@setter/ all of my code for this.

I wonder how hard it would be to write a tool that does the conversion and gets the disambiguation right in 90% of the cases...
January 25, 2013
On Friday, 25 January 2013 at 15:32:13 UTC, mist wrote:
> On Thursday, 24 January 2013 at 13:41:42 UTC, deadalnix wrote:
>> For regular functions :
>> 1. funName is the function itself :
>>  void funName() {}
>>  static assert(is(typeof(funName) == void function())); // Pass.
>>  funName has no address, it is equivalent to enum function void() funName = {};
>>  &funName become a NOOP and is deprecated, for compatibility reasons. It is not ambiguous as funName has no address anyway.
> Agree with differentiation but why no address? For me funName looks like function pointer variable, why prohibiting to cast this to raw address? &funName is legacy, agree.
>

No adress because :
 - it would now be impossible to ensure transition using & as NOOP.
 - this address is useless anyway. That'd be a pointer to a pointer to instructions.

I played with that using modified version of SDC, and this is clearly what does work best.

If you really need an address, you can do :
immutable f = function void() {};

>> 2. funName() call the function.
> And if funName is a getter returning delegate?
>

funName is not a getter and don't return a delegate. How a getter behave is explained below. Mixing everything together is the perfect way to create a mess.

>> 3. @getter is an attribute. A function marked @getter is automatically executed : () is added automatically :
>>    @getter void funName() {}
>>    funName; // function get executed.
>>    funName(); // Error, void is not callable.
> Agree, but @property is enough. I ll insist below that ambiguous cases should be simply an error. And I'd also like to prohibit getters returning void ;)
>

You didn't addressed why @property. Answer you gave to point 5 and 6 make me think you aren't aware of the ambiguities @property causes with UFCS. Please note that :
[1, 2].front and front = [1, 2] are semantically 100% equivalent.

I do agree that a getter returning void is weird, but that wasn't really important here.

>> 4. @getter can be used as UFCS.
>>   @getter void funName(T t) {}
>>   T t; t.funName; // function gets executed.
>>   funName(t); // Error, funName require 1 argument, 0 given.
> Fine by me, but error message is weird. Better "Error, funName is not usable with free-from syntax".
>

The above code is rewritten ad funName()(t) . That is why you get that error message. The error message goes out before the compiler has even considered funName was used in a call expression.

Your proposal may be an improvement for that very case, but isn't in general the error presented above.

>> 7a. A function can be defined as both @setter and @getter, and cumulate both behavior.
> Feels like unnecessary complication. But if you want to, simply having both return type and 2 parameters is enough.
>

7a is required for 7b to work. That is not complication, that is simplification.

>> 7b. @property is deprecated and redefined as @setter *and* @getter for a transitional period.
>> 9. UFCS without () are delegate like construct :
>> 10. To allow chain of UFCS calls without () everywhere, an opDispatch is defined in object.d
> Very complicated for no real gain. Just prohibit function call without (), including (). Profit!
>

Many people here disagree. I tend to be amongst thoses people. This specific case imply no ambiguity, and is similar to other simplification D already make like . dereferencing pointers.