January 23, 2013
On Wed, 23 Jan 2013 21:48:32 +0100
"Adam D. Ruppe" <destructionator@gmail.com> wrote:

> On Wednesday, 23 January 2013 at 20:37:23 UTC, Jacob Carlborg wrote:
> > What about functions not marked with @property?
> >
> > writeln = "asd";
> >
> > Doesn't look very nice.
> 
> struct FileNotFound {
>     int payload;  FileNotFound opBinary(string op :
> "+")(FileNotFound rhs) {
> return this.payload * rhs.payload;
>                  }
>                          } /* LOL INDENTATION */
> 
> FileNotFound descriptiveVariableNamesArentMyThingLOLOLOLOL; descriptiveVariableNamesArentMyThingLOLOLOLOL.payload = 20;
> 
> auto rofl = descriptiveVariableNamesArentMyThingLOLOLOLOL + FileNotFound(100);
> 
> 
> // LOLOLOLOL rofl.payload == 2000!!!!!!!!!!!!!!!!
> 
> 
> 
> 
> All of that looks pretty terrible too, from the awful names, the broken indentation, the useless comment, and of course, the + operator being overloaded to mean multiplication too.
> 
> But that's no reason to for the compiler to reject operator overloading, comments, or long variable names, because these things are useful, when not abused by a deranged lunatic.
> 
> 
> 
> Simlarly, writeln = 10 might not look very nice, but className = "foo" does.... and it is the same feature, used in real world D code now (that would break if we changed it).

1. Bad comparison because operator overloading, symbol names, etc are determined by the *callee*, not the caller. That is as it should be.

2. Strawman. The ability to write bad code is NOT valid justification for offering a feature (ie the ability to call *any* arbitrary single-arg function, rather than just properties, using assignment syntax) that provides absolutely no useful value whatsoever.

Note that properties are *not* functions, they're only implemented using functions (though D's syntax unfortunately does its best to conflate the two notions - at least in part because those who originally designed @property openly didn't understand and didn't like the whole concept of properties).

Properties are fundamentally different from functions as they are used for a fundamentally different conceptual model (yes, sometimes there is a grey area - *SOMETIMES*, not usually). And this is a distinction that is *inherently* made by the *callee*. The caller doesn't have a damn thing to do with the choice other than to either get it right or get it wrong - so why *allow* them to get it wrong? What does that gain anyone? Not a damn thing.

Overly long variable names are NOT an accurate comparison here because
the border between good/bad variable names is impossibly fuzzy. Whereas
this, OTOH is binary: Either the author designed it as a property
or didn't. You can maybe argue with their choice in *some* cases, but
bottom line, it's either a property or it isn't. The caller doesn't
have jack shit to do with it.

What you're suggesting is comparable to allowing the caller to determine member visibility. Or member existence, for that matter. Or capitalization (I hate case-insensitive languages - what the hell does that ability gain anybody other than helping to introduce inconsistency and sloppiness? It's a non-feature - ditch it.)

(FWIW, I'm not advocating making dur a property. "minutes" is
obviously not a property of 10.)

January 23, 2013
On Wed, 23 Jan 2013 15:11:35 -0500
Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> On 1/23/13 1:18 PM, Johannes Pfau wrote:
> > Please do not forget the main reason for @property: Returning a delegate from a function can become ambiguous without it:
> >
> > int a(){return 42;}
> > void b() {return&a;}
> >
> > auto var = b; //OK
> > auto var2 = b(); //is var2 == b or == 42?
> >
> > It might be an extreme corner case, but it's inconsistent behavior and confusing.
> 
> Agreed. I think we should require @property only for those cases, and not any others.
> 
> Andrei

I'd rather not see more "Sometimes the language lets me skip XXXX, and sometimes it complains" get introduced into the language. That complicates the language and makes the language harder to understand.

There are cases where that strategy has certainly made sense, but at this point I think you're just grasping for ways to justify leaving in the non-beneficial "Use either 'foo' or 'foo()', whichever you want, anytime you want" sloppiness. And making sure that non-feature can remain by introducing more special-cases into the language to patch over the problems with the non-feature.

January 23, 2013
On Wed, 23 Jan 2013 15:14:21 -0500
Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> On 1/23/13 1:48 PM, Nick Sabalausky wrote:
> > Having the *caller* decide whether something is a property or not makes as much sense as having the caller decide the function's name, signature and semantics.
> 
> No. The caller does get to decide a variety of syntactic aspects of the invocation.
> 

Yes, but it's unfortunate that includes a part of the syntax that
carries semantic/conceptual implications for something (action or
data) that is already *inherently* determined by writer of the *callee*.

> > If anything, that's an issue with template syntax, it has nothing to do with properties, let alone the beloved practice of abusing properties for the sake of things that clearly are not properties.
> 
> The implied assumption here is that if it doesn't have parens it's a property. Well it's a function call.
> 

Right, it's a function call. So what in the world do we gain by allowing the caller to make it look like something it isn't? Nothing.

January 23, 2013
On Wed, 23 Jan 2013 21:29:14 +0100
Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:

> On 1/23/13, Adam D. Ruppe <destructionator@gmail.com> wrote:
> > On Wednesday, 23 January 2013 at 17:13:05 UTC, Timon Gehr wrote: Amen! -property MUST die. @property should fix the real problems with properties, not leave that broken while adding new problems.
> 
> About @property problems, I've recently ran into this: ModuleInfo.unitTest is defined as
> 
> @property void function() unitTest() nothrow pure;
> 
> And if I use it:
> 
>     foreach (m; ModuleInfo)
>     {
>         if (m is null)
>             continue;
> 
>         if (auto fp = m.unitTest)
>         {
>             fp();           // calls it
>             m.unitTest();   // doesn't call it
>             m.unitTest()(); // calls it
>         }
>     }
> 
> This is regardless of the -property switch. I would expect the second call to work. Anyone know if this is filed already?

Don't know if it's filed, but yea: Optional empty-parens and
the practice of conflating properties with functions is riddled with
corner-cases. We can either try to patch over these corner cases
with increasingly detailed new rules, as Andrei is proposing, or we
can just accept "the writing on the wall" (if you'll pardon my 80's-ism)
that properties != functions.

January 23, 2013
On Wednesday, 23 January 2013 at 22:24:20 UTC, Nick Sabalausky wrote:
> that provides absolutely no useful value whatsoever.

Do you think so many of us would be arguing for it and using it if it was of no value whatsoever?

> Note that properties are *not* functions

Indeed, which is why I separate out -property, a stupid waste of time, and @property, a good idea.

Parenthesis and properties have nothing to do with each other. But when @property was proposed, we didn't talk about what it *is* (indistinguishable semantics from the return value), but instead what it *looks like* (must not be called with parenthesis).

That's where all this pain comes from. Two separate features got intertwined due to a sloppy DIP.


You're talking about removing a feature (optional parenthesis) from the language. We need to be weary of doing that. You say it is useless... but it *is* used by many of us. Changing it now has a cost. Even if it was worthless, the benefit of killing a worthless feature is smaller than the harm caused by breaking the code.

Similarly, I feel the new keyword is a detriment (indeed, I think new is less useful than optional parens). It doesn't do anything that can't be done in the library and gives special treatment to one preferred allocator (the gc), discouraging others and preventing easy replacement with user defined types (e.g. a create method that returns NotNull!T instead of T).

But the fact is that new is a feature in D today, and removing it would break a heck of a lot of code, so if I was given a vote on removing it... I'd vote to keep it how it is.




Now, property semantics are an entirely different issue, and thanks to the @property decoration, we CAN fix them without breaking anything else. That's a no-brainer to me, we should definitely do that.
January 23, 2013
On Wednesday, 23 January 2013 at 20:29:24 UTC, Andrej Mitrovic wrote:
> This is regardless of the -property switch. I would expect the second call to work.

Indeed. I don't know if it is filed (I think I saw it mentioned on irc yesterday though, so it might be), but this is exactly why -property is so useless: it doesn't even solve the problem (exactly what you saw there!) that @property was supposed to address!

The current implementation ONLY checks syntax. That's completely backward: if we got the semantics right, the syntax of @properties would take care of itself.
January 23, 2013
On Wed, 23 Jan 2013 21:33:07 +0100
Jacob Carlborg <doob@me.com> wrote:
> 
> This is how it should look like. Date ranges in Ruby on Rails can be really beautiful:
> 
> date = 2.days.ago
> 

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.

January 23, 2013
On Wednesday, 23 January 2013 at 22:07:20 UTC, anonymous wrote:
> alias int delegate() C;
> C c;
> auto noprop() {return c;}
> void noprop(C v) {c = v;}
> @property auto prop() {return c;}
> @property void prop(C v) {c = v;}

> && is(typeof( {return noprop;}() ) == C) /* fails with -property. that's goofy */
Actually, this may be alright; have to be explicit with non-properties. Just don't apply that rule to UFCS.

Some more:

static assert(
   is(typeof( noprop(c)          )) /* of course */
&& is(typeof( prop(c)            )) /* should error */
);

void noprop(C, int);
@property void prop(C, int);

static assert(
   is(typeof( {c.noprop;}        )) /* fails with -property, should work, is explicit enough */
&& is(typeof( {c.prop;}          )) /* should error */

&& is(typeof( {c.noprop();}      )) /* ok */
&& is(typeof( {c.prop();}        )) /* should error */

&& is(typeof( {c.noprop(0);}     )) /* ok */
&& is(typeof( {c.prop(0);}       )) /* should error */

&& is(typeof( {c.noprop = 0;}    )) /* fails with -property, alright */
&& is(typeof( {c.prop = 0;}      )) /* ok */
);
January 23, 2013
On Wed, 23 Jan 2013 21:54:54 +0100
Jacob Carlborg <doob@me.com> wrote:

> On 2013-01-23 21:46, Jonathan M Davis wrote:
> 
> > I confess that it's syntax like that that makes dislike UFCS. I can see why you might like it, but personally, I find it to be hideous.
> >
> > But as long as you're not using -property, you can do 2.days to get a Duration of 2 days, much as I wish that you couldn't.
> 
> The point is that the code should read like regular text. But if you do:
> 
> auto t = ago(days(2));
> 
> It's backwards[...]

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)".

January 23, 2013
On 01/23/2013 11:40 PM, Nick Sabalausky wrote:
> On Wed, 23 Jan 2013 15:14:21 -0500
> Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>
>> On 1/23/13 1:48 PM, Nick Sabalausky wrote:
>>> Having the *caller* decide whether something is a property or not
>>> makes as much sense as having the caller decide the function's name,
>>> signature and semantics.
>>
>> No. The caller does get to decide a variety of syntactic aspects of
>> the invocation.
>>
>
> Yes, but it's unfortunate that includes a part of the syntax that
> carries semantic/conceptual implications for something (action or
> data) that is already *inherently* determined by writer of the *callee*.
>

Keeping or leaving out the parens has no semantic implications.

>>> If anything, that's an issue with template syntax, it has nothing
>>> to do with properties, let alone the beloved practice of abusing
>>> properties for the sake of things that clearly are not properties.
>>
>> The implied assumption here is that if it doesn't have parens it's a
>> property. Well it's a function call.
>>
>
> Right, it's a function call. So what in the world do we gain by
> allowing the caller to make it look like something it isn't? Nothing.
>

That does not make any sense. It still looks just like a function call, because that is how a function call might look.