[phobos] Time to get ready for the next release

Jonathan M Davis jmdavisProg at gmx.com
Thu Apr 21 17:14:22 PDT 2011


> On Thu, 21 Apr 2011 18:28:10 -0400, Jonathan M Davis <jmdavisProg at gmx.com>
> 
> wrote:
> >> On Thu, 21 Apr 2011 17:17:33 -0400, Jonathan M Davis
> >> <jmdavisProg at gmx.com>
> >> 
> >> wrote:
> >> >> On Thu, 21 Apr 2011 16:14:22 -0400, Jonathan M Davis
> >> >> <jmdavisProg at gmx.com>
> >> >> 
> >> >> wrote:
> >> >> >> On Thu, 21 Apr 2011 15:57:57 -0400, Jonathan M Davis
> >> >> >> <jmdavisProg at gmx.com>
> >> >> >> 
> >> >> >> wrote:
> >> >> >> >> How about the amount of existing code it breaks? How about the
> >> >> 
> >> >> fact
> >> >> 
> >> >> >> >> that
> >> >> >> >> it breaks using the same function for both method chaining and
> >> >> 
> >> >> with
> >> >> 
> >> >> >> >> property syntax?
> >> >> >> > 
> >> >> >> > Something like
> >> >> >> > 
> >> >> >> > auto b = a.prop1.prop2.prop3;
> >> >> >> > 
> >> >> >> > should work. I doesn't at present, but it should. There's a bug
> >> >> 
> >> >> report
> >> >> 
> >> >> >> > on it.
> >> >> >> 
> >> >> >> What about auto b = a.prop1(5).prop2(6).prop3(7); ?
> >> >> > 
> >> >> > I'd consider that to be the same. It should work, but it doesn't.
> >> >> > There's a
> >> >> > bug report for it.
> >> >> 
> >> >> Ahem, so you'd consider auto b = a.prop1(7); valid code under strict
> >> >> property rules?
> >> > 
> >> > Oh wait. You're right. I didn't read that right. No, that wouldn't be
> >> > legal.
> >> > That would be both getting and setting. Why would you even try and do
> >> > that
> >> > with a property, let alone with several chained together?
> >> > 
> >> > - Jonathan M Davis
> >> 
> >> First, remember that basic assignments can be chained: x = y = 1; So a
> >> property should never return void, whether it's a setter or a getter
> >> logically.
> > 
> > Actually, setters _should_ return void. The chaining should be done by
> > calling
> > both the getter and setter functions. The other options is a property
> > function
> > which takes nothing but returns a ref. In either case, the chaining would
> > work.
> 
> But that would be changing the fundamental meaning of the expression from
> 
> x = y = 1;
> 
> to
> 
> x = y, y = 1;

Why? It should be

y = 1;
x = y;

Assignment is done from right to left, not left to right.

x = y = 1;

should have identical semantics to

y = 1;
x = y;

It's true that in the case of an overloaded opAssign, it might not, but when 
it's not, it's pretty much guranteed to be a bug unless the programmer is 
trying to do something weird, which would almost certainly be an abuse of 
overloaded operators. So,

auto b = a.prop1 = 3;

should translate to

a.prop1 = 3;
auto b = a.prop1;

> >> Second, there are situations where you want to be able to support:
> >> 
> >> a.prop1 = 5;
> > 
> > Okay. So the setter property prop1 gets called and given a value of 5.
> > That's
> > perfectly normal.
> > 
> >> and
> >> 
> >> auto b = a.prop1(5).prop2(6);
> >> 
> >> or simply
> >> 
> >> a.prop1(5).prop2(6).prop3(7);
> > 
> > Those don't look like property calls at all unless prop1, prop2, and
> > prop3 all
> > return a value which is callable with a single integer.
> 
> Quite correct. I'm not using field call syntax. I'm using method syntax.
> 
> > I don't see the
> > problem. I don't see how this relates to
> > 
> > a.prop1 = 5;
> > 
> > If prop1 is setter property function, a.prop1 = 5; makes sense, but then
> > it
> > doesn't make sense to call it as a.prop1(5).
> 
> prop1 is like schrodinger's cat; sometimes you want to call it like a
> setter property and sometimes you want to call it like a method.
> 
> > That wouldn't be calling it as a
> > property, and the setter shouldn't be returning anything.
> 
> For this example's case, let's let prop1 return this.
> 
> > Are you trying to set prop1 to 5, then set prop1's prop2 to 6, and then
> > set
> > prop2's prop3 to 7?
> 
> Yes.
> 
> > As long as setters return void (which they're supposed to
> > do), that doesn't make any sense at all.
> 
> The setter's aren't returning void.
> 
> > A property function is either a
> > getter by taking nothing and returning a value, a setter by returning
> > nothing
> > and taking a value, or both by taking nothing and returning a ref.
> 
> Actually, since assignments have a result, a setters can also return a
> value and still be logically correct. You've also forgotten the setter via
> getter ref return, which is often used for forwarding/aliasing.
> 
> > I don't see
> > how you could have a getter which took a value or a setter which
> > returned one.
> > 
> > @property T prop1(T val){...}
> > 
> > You couldn't call that as a getter, since something like
> > 
> > auto b = a.prop1;
> > 
> > wouldn't have a value to pass as the parameter. I suppose that
> > 
> > a.prop1 = 7;
> > 
> > would work with that definition for prop1, but you'd be throwing away the
> > return value unless you did something like
> > 
> > auto b = a.prop1 = 7;
> > 
> > and then something like
> > 
> > auto c = a.prop1;
> > 
> > would be inconsistent with
> > 
> > auto b = a.prop1 = 7;
> > 
> > because in you're using the exact same syntax to mean two very different
> > things: in one case a.prop1 is returning using the getter and in
> > another, it's
> > returning using the setter. Given the fact that assignment is done right
> > to
> > left, the compiler can probably figure out to use the setter's return
> > value
> > rather than calling the getter, but if it doesn't assume that, then it's
> > ambiguous.
> 
> I responded to this in another thread.
> 
> > I definitely think that chained assignment should be done by calling the
> > setter and then calling the getter, _not_ by using the return value of
> > the
> > setter. It was my understanding that a setter _couldn't_ return a value,
> > and I
> > think that it's just asking for trouble to allow it.
> > 
> > So, I don't think that the chaining that you're attempting to do makes
> > any
> > sense in the first place when using property functions, unless I've just
> > totally misunderstood what you're doing.
> 
> I think you've got the gist of it. :) However I think you missed the
> point: The field syntax/chaining combo is a perfectly valid piece of API
> design, but can't be expressed under the limits of strict @property
> enforcement.

I'd argue that it's _not_ a good piece of API design. It's treating a function 
as a property in some cases and not in others. It makes it impossible to 
replace a property function with an actual member variable at a later date. Is 
it a property or isn't it? It really doesn't make sense IMHO to make it so 
that something is sometimes a member variable and sometimes and member 
function and that's essentially what you're trying to do.

I do think that there are cases where it makes sense for a function to be a 
property function for a particular overload and not in another (e.g. 
std.file.isDir), but that's not currently allowed by the compiler. That's 
completely different though from having the same function called as a property 
in some cases and called as a function in others. I do _not_ think that should 
ever be happening.

> >> syntactically. There's also times/uses for functions to be chained
> >> together using property syntax i.e.
> >> 
> >> a.verb1.verb2.verb3.verb4;
> >> 
> >> instead of
> >> 
> >> a.verb1().verb2().verb3().verb4();
> > 
> > If they're properties, the first version is correct. If they're not
> > properties, then the second version is correct.
> 
> Good question. Should they be properties? Or methods? Which syntax do you
> think is cleaner? Better? Other metric I haven't thought of?

That depends entirely on what you're doing. If it's really a verb rather than 
a noun, then the second syntax would be correct, since it's highly unlikely 
that you're going to find a verb which conceptually makes sense as a property. 
In the general case, nouns should be properties and verbs should be functions, 
but that's up to the programmer who's writing the functions. That's not really 
the question here. The question is what to do about the property _syntax_ and 
@property, not whether a particular function should be marked with @property.

- Jonathan M Davis


More information about the phobos mailing list