Possible @property compromise
Steven Schveighoffer
schveiguy at yahoo.com
Thu Jan 31 07:57:12 PST 2013
On Thu, 31 Jan 2013 10:40:18 -0500, Michel Fortin
<michel.fortin at michelf.ca> wrote:
> On 2013-01-31 14:50:40 +0000, "Steven Schveighoffer"
> <schveiguy at yahoo.com> said:
>
>> It actually is a bit depressing, we have to reset the clock back to
>> late 2009 to start over with properties...
>
> By the way I was a big proponent of properties with no semantic
> ambiguities back in 2009. I even proposed a getX/setX scheme, which I
> still like very much. I'd like to see real properties in D, but I don't
> think it's realistic at this point.
Yes, I saw your post when looking for my post about the C# style which I
couldn't find.
> And you have to admit that the way D does properties today is both
> simple, clever, and appealing. It does have some error-prone liabilities
> when it comes to callable types and generic programming especially, but
> beside that I do like the design of the thing. It's a natural extension
> of UFCS, even though it predates UFCS. Perhaps we should just call it a
> day and live with the ambiguities. I don't like it, but I don't see any
> viable alternative.
I liked it when I first saw it. Seems, as you say, clever and intuitive.
However, it left a bad taste in my mouth when I had a certain situation
that I was forced to deal with.
In Tango, I developed a struct called TimeSpan, which was a span of time
(we have Duration in std.datetime which is similar).
I created constructors for spans of time that were named after the units
they used. For example, if you wanted a 10 minute, 30 second timespan you
could do:
auto ts = TimeSpan.minutes(10) + TimeSpan.seconds(30);
The idea was to avoid having to document such a line, the above looks
obvious.
Now, I also had accessors for a given timespan to return the timespan in
those units. For example:
assert(ts.seconds == 10 * 60 + 30);
The problem arose when someone complained that the seconds "setter" wasn't
working:
ts.seconds = 5;
assert(ts.seconds != 5);
Wait, what? I never made seconds a settable property!
Turns out, this translates to:
ts.seconds(5);
and because you can call static methods from an instance (another thing I
don't really like), it made the constructor act like a property! A
completely unintended consequence.
The only viable solution (this was D1), was to rename the functions so
they couldn't be mistaken as properties. So they all became "fromSeconds"
e.g. Yuck!
This is one of the reasons I was so excited about D2 getting full-fledged
properties. I had used C# and liked the way those properties worked.
But we never got what was promised, and now we basically have the same
junk with some duct-taped garbage keyword that half works. No wonder
people don't like @property!
At this point, I think it would be a huge step backwards not to solve (or
at least have a yet-to-be implemented solution for) the above problem. I
can live with getters simply being parentheses-less functions, that isn't
so bad (though as an API designer, I'd like to have full control over
that). But using any function as a setter is crap, and will forever be a
wart on D unless we fix it. It will result in bizarre things like mystery
setters that don't exist, especially with UFCS.
-Steve
More information about the Digitalmars-d
mailing list