On Sunday, 5 August 2012 at 04:12:23 UTC, Jonathan M Davis wrote:
I'd be very surprised if all that many people compile with -property.

Indeed. Sometimes I try it just to see what happens, and always the same results: it doesn't solve problems and complains about code.

Some examples of things that break:

import std.algorithm;
foreach(i; [1,2,3].map!"a+1") {

}
prophate.d(5): Error: not a property [1,2,3].map!("a+1")


Of course, this is relatively new, using ufcs in 2.059, so the breakage probably isn't too bad, but I'm not the only one who writes it this way - I've seen a number of reddit and newsgroup comments do this too, especially when chaining it.

Another thing I do is I have a template function called getDocument in a lot of my code. It takes the document name as a template param, because in a lot of cases, I want to build the doc at compile time.

auto document = getDocument!"about-me";

Is that a function or a property? I think it is a function, it does a lot work. But, the arguments are there already... do we really need to say getDocument!"about-me"() just to appease a compiler switch?

(This function also can take some runtime params, but it has defaults so param less calling works as well.)



What about std.conv? This works fine in all old code - its functions either naturally require parens (such as to!(int)("10"), gotta have at least the outer set, or octal!"555" - it is an enum, so gotta not use them).... but with UFCS, that's actually out the window now:

        int i = "10".to!int;
prophate.d(4): Error: not a property "10".to!(int)


Now, I've never actually written this. With map!(), I do that in the real world, but not with this. Still, I could imagine someone who might. If we had the strictness before 2.059, I could live with it. Just add the () (though, then queue the people complaining about syntatic noise!).


But, now we're several months past that. I say that ship has sailed.



The big breakage for me is something I have been doing for years though, and that's using my dom.d with chaining:

import arsd.dom;

// in one place I might use:
auto ele = Element.make("span", "Hello").className("hello").setAttribute("foo", "bar");

// but in another I say:

ele.className = "something";



Now, many of my newer functions obviate this kind of thing; Element.make now offers overloads for inner text, inner html, and common attributes. There's now an addClass() so it isn't all dependent on className.

But, there's still hundreds of lines of me using the older functions like this, and every so often, it still comes up.

What happens with -property?


prophate.d(7): Error: not a property ele.className
arsd/domconvenience.d(49): Error: not a property className
arsd/domconvenience.d(81): Error: not a property n.strip
arsd/domconvenience.d(81): Error: not a property className
arsd/domconvenience.d(88): Error: not a property className
arsd/domconvenience.d(218): Error: not a property e.innerHTML
arsd/dom.d(201): Error: not a property e.innerText
arsd/dom.d(212): Error: not a property e.innerText
arsd/dom.d(217): Error: not a property e.innerText
arsd/dom.d(232): Error: not a property e.innerText
arsd/dom.d(234): Error: not a property e.className
arsd/dom.d(242): Error: not a property m.innerHTML
arsd/dom.d(506): Error: not a property name.toLower
arsd/dom.d(508): Error: not a property value.strip
arsd/dom.d(1162): Error: not a property child.innerText
arsd/dom.d(1634): Error: not a property innerText
arsd/dom.d(1831): Error: not a property e.innerText
arsd/dom.d(1859): Error: not a property child.innerText
arsd/dom.d(1913): Error: not a property e.innerText
arsd/dom.d(2135): Error: not a property this.captionElement().innerText arsd/dom.d(2140): Error: not a property this.captionElement().innerText



wooo, but only the first line is this specific example. You can also see in here strip() and toLower() on which is just me being lax:

                        auto v = value.strip.toLower();

for example. Adding the inner parens would be annoying but it wouldn't require changing the form of the code like changing the dual use ones.




....huh, my example here actually does work if I set @property, but still use it as a function. Buggy switch. But I know I've tried this before and had one set of usages break with @property and another break without it. Maybe it was innerHTML, which can also be overloaded to take an Appender argument.

Yeah, then I get this:
arsd/dom.d(982): Error: cannot overload both property and non-property functions


There's just no winning without redoing a LOT of code, changing names, changing some expressions into statements since the chaining is out, duplicating functionality across two functions when one could do...


It was at that point that I decided it'd be better to put my effort into killing -property than trying to "fix" my code to appease its idiotic demands.




And now the UFCS map, filter, etc. chains and whatnot are just icing on the cake. Bearophile, I've seen you complain about the mess of parenthesis in std.algorithm before. With ufcs and template arguments, you can be rid of many of them. It is actually pretty beautiful, even to me.

Do you really want to break that now?


My position right now is @property has a strict syntax out of necessity. Stuff without @property should work the way it does now - thus minimizing broken code to that which already opted-in to @property (which generally does it right anyway), while keeping the status quo on the rest. It can turn out ugly, I'll agree, but it can be beautiful too and just plain isn't worth the code breakage either way.

Reply via email to