November 20, 2012
Le 19/11/2012 21:55, Andrei Alexandrescu a écrit :
> On 11/20/12 12:28 AM, deadalnix wrote:
>> Le 18/11/2012 22:52, Andrei Alexandrescu a écrit :
>>> On 11/19/12 1:02 AM, Rob T wrote:
>>>> So what's up with @property?
>>>
>>> It's a mistake on top of another. We need to redesign it to such that
>>> the keyword '@property' is only required in cases that otherwise would
>>> be ambiguous (functions returning functions).
>>>
>>> Andrei
>>>
>>
>> It isn't the only ambiguous case.
>
> That's why it's good to enumerate them all in
> http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP21.
>
> Thanks,
>
> Andrei

I'm not sure how it fit in the DIP but &funName is ambiguous when funName return a reference.

In general, mixes of returning callables or references, @properties, auto calling functions and &syntax does a really bad mix.
November 20, 2012
On Monday, 19 November 2012 at 21:44:35 UTC, Jonathan M Davis wrote:
> Excep that i don't think that it's really a question of style. It's treating a
> function as if it were a variable, when it's not only not a variable, but it's
> not even acting like one. It's implying that the code has one set of semantics when it has another.

This is just an old habit to see identifier with parens as a function call and identifier without parens as a variable, so calling functions without parens seem too unconventional to you. However there are many languages which dropped this tradition and they are known for being expressive and concise, that's why people love them. Recently we saw an article from Walter about component programming which one could say was really about function composition. It's really convenient to write code in conveyor-style, this is what we see often in functional languages, as well as some dynamic OO ones. For example, the task of reversing words in a string may look like:

"one two three".split.map{|s| s.reverse}.join(' ')
in Ruby

print . unwords . map reverse . words $ "one two three"
in Haskell

"one two three" |> split " " |> List.map reverse |> String.join " " |> print_string
in OCaml
and something similar and even without dots in Scala.
Ease of chaining functions together is one of the things that make those languages so pleasant to work with. I love to have the same in current D and it would be a pity to lose it due to a clash with some old-fashioned tradition.

November 20, 2012
Am 20.11.2012 05:12, schrieb Andrei Alexandrescu:
> On 11/19/12 5:23 PM, Rob T wrote:
>> I don't have an answer, but there may be more to the picture than we think.
> 
> I agree. In particular I find it a specious argument to insist on religiously associating "()" with function calling and the lack thereof with variable access. I don't see myself, when seeing an expression like "generator(x, y, z).map!(x => x * x)()", going like "holy cow, good I saw those trailing parens, otherwise I would've sworn it was a variable". Trailing parens in UFCS chains are just warts, this is the reality. Let's deal with it.
> 
> 
> Andrei

Isn't it more that they seem like warts whenever a parameterless (or pseudo-parameterless in the case of UFCS) template function is called, because template instantiations already look a lot like function calls?

Anyway, my take on this is, while I find it a bit sad, that there is no visual distinction between variables and functions for various reasons, in the presence of properties this distinction has already gone long time ago. So realistically this argument has no weight anymore. Personally, I started to like a partially relaxed approach like the one Adam Ruppe describes a lot, so a DIP would definitely be a great step.

November 20, 2012
On 2012-11-19 23:23, Rob T wrote:

> Also do not forget that we can not only drop the (), but also perform
> assignments to functions that take in one variable, but I'm not sure if
> the return must be void for that to work. It seems strange to allow
> arbitrarily dual function/variable constructs for functions, but being
> strange does not necessarily mean it is wrong.

The return value doesn't have to be void. I always return the new value from my setters, to allow chained assignments. If chained assignment can't be used the property hasn't emulated a variable properly.

class Foo
{
    private int bar_;

    @property int bar () { return bar_; }
    @property int bar (int value) { return bar_ = value; }
}


auto foo = new Foo;
int a = foo.bar = 3;

Of course the correct solution would be to implement a form of property rewrite in the compiler. Transforming the following code:

int a = foo.bar = 3;

To:

foo.bar = 3;
int a = foo.bar;

If "foo.bar" is a method/@property.

-- 
/Jacob Carlborg
November 20, 2012
On 11/20/12 2:48 AM, thedeemon wrote:
[snip]
> "one two three".split.map{|s| s.reverse}.join(' ')
> in Ruby
>
> print . unwords . map reverse . words $ "one two three"
> in Haskell
>
> "one two three" |> split " " |> List.map reverse |> String.join " " |>
> print_string
> in OCaml
> and something similar and even without dots in Scala.
> Ease of chaining functions together is one of the things that make those
> languages so pleasant to work with. I love to have the same in current D
> and it would be a pity to lose it due to a clash with some old-fashioned
> tradition.

A very good argument. Thanks!

Andrei

November 20, 2012
On 2012-11-20 08:48, thedeemon wrote:

> This is just an old habit to see identifier with parens as a function
> call and identifier without parens as a variable, so calling functions
> without parens seem too unconventional to you. However there are many
> languages which dropped this tradition and they are known for being
> expressive and concise, that's why people love them. Recently we saw an
> article from Walter about component programming which one could say was
> really about function composition. It's really convenient to write code
> in conveyor-style, this is what we see often in functional languages, as
> well as some dynamic OO ones. For example, the task of reversing words
> in a string may look like:

I completely agree.

> "one two three".split.map{|s| s.reverse}.join(' ')
> in Ruby

In this particular case you can use a shorter form of the map call:

"one two three".split.map(&:reverse).join(' ')

> print . unwords . map reverse . words $ "one two three"
> in Haskell
>
> "one two three" |> split " " |> List.map reverse |> String.join " " |>
> print_string
> in OCaml
> and something similar and even without dots in Scala.

Wouldn't the Scala syntax look fairly similar to Ruby:

"one two three".split.map(reverse).join(' ')

> Ease of chaining functions together is one of the things that make those
> languages so pleasant to work with. I love to have the same in current D
> and it would be a pity to lose it due to a clash with some old-fashioned
> tradition.

I completely agree again.

-- 
/Jacob Carlborg
November 20, 2012
On 2012-11-19 19:02, Adam D. Ruppe wrote:
> On Monday, 19 November 2012 at 15:01:36 UTC, Andrei Alexandrescu wrote:
>> Would you please start a DIP with a paste of this idea?
>
> here it is:
> http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP21
>
> I tried to implement this a while ago and hit some pain after some early
> success. The pain was trying to get assignments to work without breaking
> other cases like returning ref.
>
> My plan was to make any reference to a @property change to a CallExp or
> whatever. But if you do that and it is on the left hand side of an
> assignment, you do the wrong thing.
>
> foo = foo + 1;
>
> should generally become:
>
> foo(foo() + 1);
>
> but if there isn't a setter, we should leave it as foo() = foo() + 1;
> and finding the setter is a bit of a pain. Then, of course, we ideally
> want foo += 1 to work too..

It would be really nice if we could implement property rewriting in the compiler.

> Maybe someone who knows the compiler better than me will make it look
> easy though.

Should this be allowed for functions that isn't marked with @property:

foo = 3;

-- 
/Jacob Carlborg
November 20, 2012
On Tuesday, 20 November 2012 at 12:44:44 UTC, Jacob Carlborg wrote:
> Should this be allowed for functions that isn't marked with @property:
>
> foo = 3;

Hell no!
November 20, 2012
On Tuesday, 20 November 2012 at 12:44:44 UTC, Jacob Carlborg wrote:
> Should this be allowed for functions that isn't marked with @property:
>
> foo = 3;

Yes. We should *only* be changing the way @property is implemented. (Namely, actually implementing it!)

Don't want to break existing code. The new changes must be opt in.


If there's both an @property setter and a regular function, the property should be used here.
November 20, 2012
On Tuesday, 20 November 2012 at 06:06:21 UTC, deadalnix wrote:
> I'm not sure how it fit in the DIP but &funName is ambiguous when funName return a reference.

We can just define this away: &funName if it isn't a @property is the address of the function.

If it is a @property, ALL operations work on the return value, so it is rewritten as &(funName()).