@property
Adam D. Ruppe
destructionator at gmail.com
Sun Aug 5 07:32:49 PDT 2012
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.
More information about the Digitalmars-d
mailing list