On 2009-08-01 17:38:46 -0400, Jarrett Billingsley <[email protected]> said:

On Sat, Aug 1, 2009 at 4:01 PM, Michel Fortin<[email protected]> wrote:

3. There is no naming ambiguity.

A set/get prefix removes pretty much all ambiguity too.

I mean, the current syntax is "T transform()" and you can't know if
transform is a noun or a verb. With my prefix it's "T getTransform()" which
makes it pretty clear what it does. With yours it's "property T transform()"
and it's pretty clear too.

class X
{
    int foo;
    int getFoo() { return 5; }
    int blah() { return foo; /* um.. which? */ }
}

Ok. There's two fronts on "ambiguity". You can have ambiguity in meaning, that's what I was talking about. By writing "setTransform()"/"getTransform()" you remove that ambiguity about "transform" being either a noun (property) or a verb (action). Having a keyword property does also removes that ambiguity. That's what I was talking about.

Your example describe a syntaxic ambiguity when there's already a symbol named with the property name. There is a few way to solve that ambiguity:

1. Make it ambiguous (thus an error) to invoke foo at all.
2. Make foo, the variable, shadow the property.
3. Make the property shadow the variable.

Number 3 is a bad idea because you have absolutely no way to access the field, even from inside the getter and setter. I'm not sure 2 is safe with multiple imported modules and with classes hierarchies. Number 1 is much restrictive, but you know when you're doing something fishy.

- - -

That said, a property keyword may also have some overloading problems to solve; it can't behave excaty as a function:

class X
{
        property void delegate(float) foo() { ... }
        property void foo(void delegate(float) f) { ... }
        void foo(float f) { ... }

        void blah() { foo(1.0); } // what is this?
}

You'll need a rule to forbid overloaded functions that mix property and non-property. That is, in class X and any derived class.

Also, overload sets accross modules will need to be revised to become ambiguous when not all members are properties or non-properties. For instance, this would need to become ambiguous:

        module a;
        property void delegate(int) foo();

        module b;
        int foo(float);

        module c;
        import a, b;
        unittest
        {
                foo(1); // which one?
        }

This applies to a "getFoo()" syntax too.


And to compensate that +1 for you above, I'd point out that there is an
alternative with no case issue (get_thing/set_thing) and that your proposal
requires a keyword.

Then let's introduce annotations and be done with it.  No more pure,
shared, __gshared, nothrow, and probably a whole slew of other silly
attribute keywords.

To me, wether the keyword is "property" or a "@property" annotation, I don't really care, both are fine with me. I still find "getFoo()"/"setFoo()" simpler and aesthetically better, but as I said before, the property keyword (be it a keyword or an annotation) is acceptable to me.


About your idea, I find it confusing that (&something) and &(something) may
not have the same meaning.

That's true.  Then again, how often do you need to get the address of
a returned ref value?

Every time you want to pass it to a C API.

That said, perhaps I have a solution for that problem. The compiler could be smart about it, just like it already is when you take the address of an overloaded function: it could check if the variable you put the address into match the type of the property in addition to the type of the setter and the type of the getter.

        property ref int something();
        property void something(int s);

        int delegate() getter = &something; // address of getter
        void delegate(int) setter = &something; // address of setter
        int* value = &something; // address of returned ref value

Obviously, this doesn't work with auto, but that's a general problem with overloading, not something inehrent to properties.

--
Michel Fortin
[email protected]
http://michelf.com/

Reply via email to