January 24, 2013
On Thursday, January 24, 2013 01:33:29 Andrei Alexandrescu wrote:
> If you find this not wanting and not improvable we might have reached an irreducible position.

I think that it's been clear for some time that there's no way to please both the folks who want strong property enforcement and those who want weak property enforcement. One side is going to lose out, and much as I'm very much in favor strong property enforcement (and Nick clearly is as well), I think that it's fairly clear at this point that the majority of folks arond here are not (in great part due to UFCS). Not to mention, sorting out proper property enforcement has taken so long given all of the other priorities, that doing strong property enforcement would probably break quite a lot of code at this point.

- Jonathan M Davis
January 24, 2013
On 2013-01-24 03:17, Brad Anderson wrote:
> On Wednesday, 23 January 2013 at 23:39:50 UTC, Andrei Alexandrescu wrote:
>> We need a good DIP on this. [snip]
>
> DIPs are good in theory but I think the process really needs to be
> formalized.  In the past 3 years there have been thirteen DIPs with only
> one being approved and implemented.

According to this there's been four implemented:

http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs

It think it seems correctly.

-- 
/Jacob Carlborg
January 24, 2013
On 2013-01-24 03:02, Nick Sabalausky wrote:

> foo.bar() // Perform action
> foo.bar   // Access data

Who says it has to be like this.

-- 
/Jacob Carlborg
January 24, 2013
I've always secretly hated the ambiguity in D's syntax. E.g:

foo.bar

What could foo and bar be? D has many more answers than C++:

                    D           C++
                    foo bar     foo bar
Module/Namespace    x   x
Type                x   x
Variable            x   x       x   x
Method                  x
Free function       x   x

For this reason I initially agreed with Nick Sabalausky on disallowing calling non-property functions without parenthesis.

...but now I'm thinking that this ambiguity stops being an issue once we have an IDE that can render different things in different colors (or different fonts or with other visual cues if you're color-blind). Color is a much stronger and faster visual cue than having parenthesis at the end of a name. For this reason, I think that it's fine to allow non-property functions to be called without parenthesis. But I still think that property functions should not be allowed to be called with parenthesis.
January 24, 2013
On 2013-01-23 22:59, monarch_dodra wrote:

> In this context, what does it mean then to have something be "a property" ?
>
> I think we should remember what "@property" (as I understood it) is
> meant for: a function that can emulate being a object. The de-facto
> example being "front".

It's for a method emulating being a field/public instance variable.

> The "final" objective (as I understood it), is that you can publish your
> interface, and later, swap object/members for functions (and vice versa).

You cannot do this in D. There are at least two issues:

1. You cannot replace a non-final property, i.e. a method, with a field. Someone might have overridden the method in a subclass. In other languages like Scala a public instance variable is implemented as a method. In these cases you can switch freely between a property and an instance variable.

2. There are some issues with fields of a struct type being changed to a property, since they are usually passed by value. Example:

struct Bar
{
    int a;
}

class Foo
{
    Bar bar;
}

void main ()
{
    auto foo = new Foo;
    foo.bar.a = 1;
    assert(foo.bar.a == 1);
}

Changing Foo.bar to be a porperty like this:

class Foo
{
    Bar bar_;

    @property Bar bar ()
    {
        return bar_;
    }

    @property Bar bar (Bar bar)
    {
        return bar_ = bar;
    }
}

Now the assertion in main won't pass since the property is returning a value type that is copied. If you instead return by reference it will work, but then you can also set "bar" directly, bypassing the setter.

For this to work properly we would need property rewrite:

foo.bar.a = 1;

Should be turned into:

auto _tmp = foo.bar();
_tmp.a = 1;
foo.bar(_tmp);

-- 
/Jacob Carlborg
January 24, 2013
On 2013-01-24 06:16, Nick Sabalausky wrote:

> Heh, actually, case in point, take a look at my normal work setup:
>
> http://66.228.38.161/download/img/jobs-would-have-hung-employees-for-doing-this.jpg
>
> (Yes, I need to get a wireless keyboard/trackball ;) )

That's not a good work setup, in any way. Close the laptop and get a real, external monitor, or two. I'm serious, you're going to break your neck, sooner or later.

>> Now, for @property setters, we might use them for other
>> operations too.
>>
>> @property int a() { return 10; }
>> @property void a(int v) { ... }
>>
>> a += 10;
>>
>> should be transformed into a(a() + 10); which is not currently
>> done.
>
> Geez, we still don't have that?

No we don't :( That's also one reason why a public fields cannot be changed to a property without breaking the API, see: http://forum.dlang.org/thread/ceukykobasewoexsrveb@forum.dlang.org?page=8#post-kdqs3u:2414i1:241:40digitalmars.com

-- 
/Jacob Carlborg
January 24, 2013
On 2013-01-24 00:16, Nick Sabalausky wrote:

> I'll certainly grant that, insofar as the written order is backwards
> from the execution order. I think the "ago" is that part that bugs me
> the most. It's too clever. I could live with "2.days", but I'd prefer
> "days(2)" since that looks like a type constructor, and "days" isn't a
> property of 2. Maybe "2.toDays()", but at that point I'd still rather
> just do the simpler "days(2)".

If you don't have "ago" how would you determine the differences compared to the opposite, which looks like this in Ruby on Rails:

time = 2.days.from_now

"2" is the duration, "days" is the unit and ago/from_now indicates if it's positive or negative.

-- 
/Jacob Carlborg
January 24, 2013
On 2013-01-24 00:07, Nick Sabalausky wrote:

> Honestly, I really don't like that. It trades clear semantics for a
> bunch of magic to achieve the dubious goal of making code look more
> like English (a notably high-ambiguity language). If I valued languages
> imitating English, I'd be doing everything in HyperCard or COBOL or
> some other such design blunder.

That's unclear with the semantics?

-- 
/Jacob Carlborg
January 24, 2013
On Thursday, 24 January 2013 at 08:41:34 UTC, Jacob Carlborg wrote:
> On 2013-01-23 22:59, monarch_dodra wrote:
>
>> In this context, what does it mean then to have something be "a property" ?
>>
>> I think we should remember what "@property" (as I understood it) is
>> meant for: a function that can emulate being a object. The de-facto
>> example being "front".
>
> It's for a method emulating being a field/public instance variable.
>
>> The "final" objective (as I understood it), is that you can publish your
>> interface, and later, swap object/members for functions (and vice versa).
>
> You cannot do this in D. There are at least two issues:
>
> 1. You cannot replace a non-final property, i.e. a method, with a field. Someone might have overridden the method in a subclass. In other languages like Scala a public instance variable is implemented as a method. In these cases you can switch freely between a property and an instance variable.

Ture, it *is* a one way street, but would at least be a street none the less.

Imagine you used to have a field in the base class "myInt", but now you need a virtual myInt. You can replace your field with a virtual property that returns by ref. Your old code:

//----
int* p = &myClass.myInt;
//----

Will still work, but the actual field will be resolved at runtime. This does require my "point 2" to be implemented though: You can't take the address of a property.

If "myInt" was implemented as a simple function, here, you'd end up taking the address of the function myInt, and break code.

> 2. There are some issues with fields of a struct type being changed to a property, since they are usually passed by value. Example:

They shouldn't have to. That'd be an interface change. If you do that, then breakage is inevitable, property or no.

> If you instead return by reference it will work, but then you can also set "bar" directly, bypassing the setter.

I think this is a limitation. If bar is a property, and has a setter, then "bar = 5" should *always* call the setter, regardless of ref or not.

IMO, it not currently doing so is a limitation
January 24, 2013
On Thursday, 24 January 2013 at 06:34:58 UTC, Andrei Alexandrescu wrote:
> On 1/24/13 1:18 AM, monarch_dodra wrote:
>> On Wednesday, 23 January 2013 at 23:39:50 UTC, Andrei Alexandrescu wrote:
>>>
>>> We need a good DIP on this. UFCS has destroyed all arguments in favor
>>> of requiring parens. There is no question we must do this. Anyone
>>> inclined toward writing a detailed DIP?
>>>
>>> Andrei
>>
>> What about optional parens on non-UFCS calls, is there a case for this?
>> Honest question.
>
> Let them be.
>
>> I'm inclined to writing a DIP.
>
> That would be great!
>
>
> Andrei

We actually have one, which I think I agree with:
http://wiki.dlang.org/DIP21

The gist of the DIP is that something marked with @property is always and immediately expanded into a call.

This fits into my proposal of:
1) properties never have parens (they are added by the compiler)
2) You can't take the address of a property function: "&foo" would become "&foo()", so you'd always get the address of the return value.

- make parens optional for everything else.
- allow the "foo = 5" rewrite into "foo(5)" only for properties.
-- Note that if foo is a non-property that returns by ref, then "foo = 5" remains legal
-- However, "writeln = 5" would be illegal.

I think properties is a really cool & powerful concept. It got conflated into "optional parens". This doesn't mean we should just "take it out back"...