August 02, 2009
Andrei Alexandrescu escribió:
> Marianne Gagnon wrote:
>>> The alternative is to have a unique syntax for properties. Ideally, the syntax should be intuitive and mimic its use. After much fiddling, and based on n.g. suggestions, Andrei and I penciled in:
>>>
>>>    bool empty { ... }
>>>    void empty=(bool b) { ... }
>>>
>>> The only problem is when a declaration but not definition is desired:
>>>
>>>    bool empty;
>>>
>>> but oops! That defines a field. So we came up with essentially a hack:
>>>
>>>    bool empty{}
>>>
>>> i.e. the {} means the getter is declared, but defined elsewhere.
>>>
>>> What do you think?
>>
>> I liked the original idea... but this declaration syntax is a total can of worms. Like others pointed out, would the compiler automatically turn all functions with empty bodies into declarations? Would empty setters be considered a declaration? What if I actually *want*
>>  to use an empty body as definition? Or what if I accidentally leave a body empty when I didn't want to?
>>
>> Like someone else pointed out, existing keywords could be reused :
>>
>> bool empty
>> {
>>     in(bool value)
>>     {
>>         _my_empty = value;
>>     }
>>     out
>>     {
>>         return _my_empty;
>>     }
>> }
>>
>> I like this quite a bit.  I never wrote any compiler, granted, but I don't think it'd be that hard to implement - and doesn't introduce any new keyword.
> 
> Please, please, could we look at something that does NOT go through two scopes to get to the code?
> 
>> Or, alternatively, if you really wish to keep them separate, bool empty= { ... } isn't intuitive, as Andrei pointed out, but is already less error-prone than the empty-body declaration idea I believe
> 
> I think void empty=(bool b) { ... } is a net win, which the forced bool empty=() diminishes. It would be great to keep the setter and find something as nice for a getter.
> 
> 
> Andrei

int =empty() { } // getter
int empty=(int value) { } // setter
August 02, 2009
Ary Borenszweig escribió:
> Andrei Alexandrescu escribió:
>> Marianne Gagnon wrote:
>>>> The alternative is to have a unique syntax for properties. Ideally, the syntax should be intuitive and mimic its use. After much fiddling, and based on n.g. suggestions, Andrei and I penciled in:
>>>>
>>>>    bool empty { ... }
>>>>    void empty=(bool b) { ... }
>>>>
>>>> The only problem is when a declaration but not definition is desired:
>>>>
>>>>    bool empty;
>>>>
>>>> but oops! That defines a field. So we came up with essentially a hack:
>>>>
>>>>    bool empty{}
>>>>
>>>> i.e. the {} means the getter is declared, but defined elsewhere.
>>>>
>>>> What do you think?
>>>
>>> I liked the original idea... but this declaration syntax is a total can of worms. Like others pointed out, would the compiler automatically turn all functions with empty bodies into declarations? Would empty setters be considered a declaration? What if I actually *want*
>>>  to use an empty body as definition? Or what if I accidentally leave a body empty when I didn't want to?
>>>
>>> Like someone else pointed out, existing keywords could be reused :
>>>
>>> bool empty
>>> {
>>>     in(bool value)
>>>     {
>>>         _my_empty = value;
>>>     }
>>>     out
>>>     {
>>>         return _my_empty;
>>>     }
>>> }
>>>
>>> I like this quite a bit.  I never wrote any compiler, granted, but I don't think it'd be that hard to implement - and doesn't introduce any new keyword.
>>
>> Please, please, could we look at something that does NOT go through two scopes to get to the code?
>>
>>> Or, alternatively, if you really wish to keep them separate, bool empty= { ... } isn't intuitive, as Andrei pointed out, but is already less error-prone than the empty-body declaration idea I believe
>>
>> I think void empty=(bool b) { ... } is a net win, which the forced bool empty=() diminishes. It would be great to keep the setter and find something as nice for a getter.
>>
>>
>> Andrei
> 
> int =empty() { } // getter
> int empty=(int value) { } // setter

Hmm... where's the "undo send" button? I can't find it... I saw it in gmail, but why isn't it here?
August 02, 2009
KennyTM~ schrieb:
> Frank Benoit wrote:
>> Or how about making it a single method?
>>
>> bool empty=(bool* value){
>>     if( value ) _empty = *value;
>>     return _empty;
>> }
>>
>> The compiler rewrites the calling code to either pass the address or null.
> 
> So properties can't be used in SafeD?

Hm, right pointers are not allowed there. So the "in" operator for AAs is also disallowed? That surprises me.
August 02, 2009
Michiel Helvensteijn wrote:
> JPF wrote:
> 
>> 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.
> 
> This may be acceptable. I don't much like that the double-underscore is necessary, but it may be the best solution there is.
> 
>> auto getter = &empty.__get()
> 
> You meant without the parentheses here, right?

sure (damn copy & paste) ;-)
>> As an addition
>> --------------------------------------------------
>> auto b = &empty
>> --------------------------------------------------
>> would then return a pointer to the returned value.
> 
> That would be a pointer to a temporary value, though. Not very useful. But lexically, it works, yes.
> 

It was mentioned in another thread, that's why I mentioned it as well.
August 02, 2009
Oliver Hoog wrote:
> 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 ... }
> }
> ---
I just took the basic syntax from above, but I agree in/out is way better than the double underscores.

> 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.
August 02, 2009
Michiel Helvensteijn wrote:
> Andrei Alexandrescu wrote:
> 
>> I'd like to have an easy enough syntax for defining read-only properties
>> (often in my code). With the proposed syntax, one writes
>>
>> bool empty { ... }
>>
>> and calls it a day, but with the elaborate getters and setters there are
>> two scopes to get through:
>>
>> bool empty { auto get() { ... } }
>>
>> which is quite some aggravation.
> 
> The point is not really the grouping of elements within brackets. That just
> eliminates some redundancy. It can also look like the following:
> 
> void empty.set(bool value) { ... }
> bool empty.get() { ... }
> 
> and have the same meaning as my earlier example.

Yah, I was thinking the same. This is my #1 fave so far.

Andrei
August 02, 2009
Ary Borenszweig wrote:
> Andrei Alexandrescu escribió:
>> Marianne Gagnon wrote:
>>>> The alternative is to have a unique syntax for properties. Ideally, the syntax should be intuitive and mimic its use. After much fiddling, and based on n.g. suggestions, Andrei and I penciled in:
>>>>
>>>>    bool empty { ... }
>>>>    void empty=(bool b) { ... }
>>>>
>>>> The only problem is when a declaration but not definition is desired:
>>>>
>>>>    bool empty;
>>>>
>>>> but oops! That defines a field. So we came up with essentially a hack:
>>>>
>>>>    bool empty{}
>>>>
>>>> i.e. the {} means the getter is declared, but defined elsewhere.
>>>>
>>>> What do you think?
>>>
>>> I liked the original idea... but this declaration syntax is a total can of worms. Like others pointed out, would the compiler automatically turn all functions with empty bodies into declarations? Would empty setters be considered a declaration? What if I actually *want*
>>>  to use an empty body as definition? Or what if I accidentally leave a body empty when I didn't want to?
>>>
>>> Like someone else pointed out, existing keywords could be reused :
>>>
>>> bool empty
>>> {
>>>     in(bool value)
>>>     {
>>>         _my_empty = value;
>>>     }
>>>     out
>>>     {
>>>         return _my_empty;
>>>     }
>>> }
>>>
>>> I like this quite a bit.  I never wrote any compiler, granted, but I don't think it'd be that hard to implement - and doesn't introduce any new keyword.
>>
>> Please, please, could we look at something that does NOT go through two scopes to get to the code?
>>
>>> Or, alternatively, if you really wish to keep them separate, bool empty= { ... } isn't intuitive, as Andrei pointed out, but is already less error-prone than the empty-body declaration idea I believe
>>
>> I think void empty=(bool b) { ... } is a net win, which the forced bool empty=() diminishes. It would be great to keep the setter and find something as nice for a getter.
>>
>>
>> Andrei
> 
> int =empty() { } // getter

I suggested that but Walter mentioned there may be parsing problems when int is replaced with an elaborate type. (I am not seeing any.)

Andrei
August 02, 2009
Andrei Alexandrescu wrote:

>> void empty.set(bool value) { ... }
>> bool empty.get() { ... }
> 
> Yah, I was thinking the same. This is my #1 fave so far.

You should read my reply to myself, though. It describes an ambiguity in the approach. Several solutions are discussed. (Just translate them from grouping to non-grouping solutions.)

-- 
Michiel Helvensteijn

August 02, 2009
Michiel Helvensteijn wrote:
> Andrei Alexandrescu wrote:
> 
>>> void empty.set(bool value) { ... }
>>> bool empty.get() { ... }
>> Yah, I was thinking the same. This is my #1 fave so far.
> 
> You should read my reply to myself, though. It describes an ambiguity in the
> approach. Several solutions are discussed. (Just translate them from
> grouping to non-grouping solutions.)
> 

My reader does not show that message.

Andrei
August 02, 2009
Andrei Alexandrescu wrote:

>> You should read my reply to myself, though. It describes an ambiguity in the approach. Several solutions are discussed. (Just translate them from grouping to non-grouping solutions.)
>
> My reader does not show that message.

How strange.

http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=94712

-- 
Michiel Helvensteijn