JPF schrieb:
Michiel Helvensteijn schrieb:
Michiel Helvensteijn wrote:

--------------------------------------------------
bool empty {
    void set(auto value) { ... }
    auto get() { ... }
}

empty = false; // empty.set(false)
auto b = empty; // auto b = empty.get()
--------------------------------------------------

for example, requires no hacks and no keywords. And has the added
advantage that you can still use the getter and setter methods directly.
It should be noted that there is an ambiguity if the type of the property is
a struct/class with members named 'get' and 'set'. As I see it, there are
three ways to resolve it:

* Disallow properties with such a struct/class. This seems a little bit
excessive and silly. But it is one way.

* The 'set' and 'get' from the property are only used for the
property-calling syntax. They can not be referenced directly. The members
of the struct/class would all be accessable. This would work about the same
way as, for example, the suggestion from John C in this thread. And if you
go down this path, you might as well condense the syntax, as he did.

* The 'set' and 'get' from the property are accessable functions and they
overshadow possible member functions with those names.

My language uses the third way, but there is no problem with overshadowing.
The 'set' and 'get' functions have the same special purpose for every type,
and the property is meant to override them.

I guess D could do something similar using, instead of my 'get' and 'set',
D's 'this' and 'opAssign' respectively.

There's at least one more solution:
define the property as
--------------------------------------------------
bool empty {
    void set(auto value) { ... }
    auto get() { ... }
}
--------------------------------------------------
but rewrite empty.get/set to empty.__get/__set. As far as I know names
beginning with __ are reserved, so the returned type of the property
couldn't define it. Accessing the setter/getter directly could still be
done using
--------------------------------------------------
empty = false; // empty.__set(false)
auto b = empty; // auto b = empty.__get()

auto getter = &empty.__get()
--------------------------------------------------
This also allows getting function pointers for the setter and the
getter. As an addition
--------------------------------------------------
auto b = &empty
--------------------------------------------------
would then return a pointer to the returned value.

But you would have to write more than necessary. Simpler is:
---
bool foo {
        in(bar) { ... }
        out { return ... }
}
---
in is translated to: void in(bool bar) {...}
out is translated to: bool out() {...}

To get a delegate to in:
auto f = &foo.in;

foo = 5; is equivalent to foo.in(5);

This way you don't need any new keywords or ugly (double) underscores.
And it's unambiguous and pretty clear.

Reply via email to