August 02, 2009
Andrei Alexandrescu wrote:
> Michiel Helvensteijn wrote:
>> Andrei Alexandrescu wrote:
>>
>>> Then in a later message you mention:
>>>
>>> bool empty.get() { ... }
>>> void empty.set(bool b) { ... }
>>>
>>> which I like and which does not seem to have difficulties; the names
>>> "get" and "set" will be never used as such.
>>
>> Yes, those are two notations for the same thing, and they have the same
>> problem. Let me demonstrate:
>>
>> --------------------------------------------------
>> struct S {
>>     int get() { return 42; }
>> };
>>
>> struct T {
>>     S _s;
>>     S property.get() { return _s; }
>>     void property.set(S s) { _s = s; }
>> }
>>
>> T t;
>>
>> auto X = t.property.get();
>> --------------------------------------------------
>>
>> What is the type of X? It can be either S or int, depending on how D handles
>> the situation.
>>
>> The ambiguity is in the possibility to directly reference the getter and
>> setter methods. In that other subthread (the older one) I listed some
>> possible solutions.
>>
>> The first is to make such a program an error.
>>
>> The second is not to allow a direct reference to a getter/setter (so X is an
>> int).
>>
>> The third is to let the getter/setter overshadow S members (so X is an S).
> 
> I see. My view is that .get and .set are simply symbolic placeholders, but indeed some may get confused.
> 
> Andrei

Does the ambiguity go away if we replace the '.' with a space?

Declaration:

bool empty get();
void empty set(bool);

Declaration:

bool empty get() { return empty_; }
void empty set(bool b) { empty_ = b; }
August 02, 2009
On 2009-08-02 15:07:37 -0400, Michiel Helvensteijn <m.helvensteijn.remove@gmail.com> said:

> In my design, they are actual functions with actual names.
> 
> For D this doesn't really work. If you want symbolic placeholders, you may
> want to use something other than 'get' and 'set'. For example, 'in'
> and 'out' have been suggested by some. They are already keywords.

One thing with in and out makes me uneasy. Imagine a setter/getter with a contract:

	int prop.out()
	out (result) { assert(result > 3); }
	body { return something; }

	void prop.in(int v)
	in { assert(v > 3); }
	body { something = v; }

Wouldn't it be a little confusing having twice the same keyword so close but with a completly different meaning?

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

August 02, 2009
Michel Fortin wrote:

>> In my design, they are actual functions with actual names.
>> 
>> For D this doesn't really work. If you want symbolic placeholders, you may want to use something other than 'get' and 'set'. For example, 'in' and 'out' have been suggested by some. They are already keywords.
> 
> One thing with in and out makes me uneasy. Imagine a setter/getter with a contract:
> 
> int prop.out()
> out (result) { assert(result > 3); }
> body { return something; }
> 
> void prop.in(int v)
> in { assert(v > 3); }
> body { something = v; }
> 
> Wouldn't it be a little confusing having twice the same keyword so close but with a completly different meaning?

I agree, it's far from ideal. Well, I'm sure a solution can be found. It's now just down to detail.

-- 
Michiel Helvensteijn

August 02, 2009
John C wrote:
> Andrei Alexandrescu wrote:
>> Michiel Helvensteijn wrote:
>>> Andrei Alexandrescu wrote:
>>>
>>>> Then in a later message you mention:
>>>>
>>>> bool empty.get() { ... }
>>>> void empty.set(bool b) { ... }
>>>>
>>>> which I like and which does not seem to have difficulties; the names
>>>> "get" and "set" will be never used as such.
>>>
>>> Yes, those are two notations for the same thing, and they have the same
>>> problem. Let me demonstrate:
>>>
>>> --------------------------------------------------
>>> struct S {
>>>     int get() { return 42; }
>>> };
>>>
>>> struct T {
>>>     S _s;
>>>     S property.get() { return _s; }
>>>     void property.set(S s) { _s = s; }
>>> }
>>>
>>> T t;
>>>
>>> auto X = t.property.get();
>>> --------------------------------------------------
>>>
>>> What is the type of X? It can be either S or int, depending on how D handles
>>> the situation.
>>>
>>> The ambiguity is in the possibility to directly reference the getter and
>>> setter methods. In that other subthread (the older one) I listed some
>>> possible solutions.
>>>
>>> The first is to make such a program an error.
>>>
>>> The second is not to allow a direct reference to a getter/setter (so X is an
>>> int).
>>>
>>> The third is to let the getter/setter overshadow S members (so X is an S).
>>
>> I see. My view is that .get and .set are simply symbolic placeholders, but indeed some may get confused.
>>
>> Andrei
> 
> Does the ambiguity go away if we replace the '.' with a space?
> 
> Declaration:
> 
> bool empty get();
> void empty set(bool);
> 
> Declaration:
> 
> bool empty get() { return empty_; }
> void empty set(bool b) { empty_ = b; }

That should work.

Andrei
August 02, 2009
On Sun, Aug 2, 2009 at 4:21 PM, Nick Sabalausky<a@a.a> wrote:
> "Oliver Hoog" <kingboscop@gmail.com> wrote in message news:h54ccl$1v3l$1@digitalmars.com...
>>
>> 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.
>
> Yes! Or wait, even better yet:
>
> static foo {
> static(static) { ... }
> static static { static ... }
> }
>
> In fact, let's *really* minimize the number of keywords in D:
>
> // From:
> int main(char[][] args)
> {
>    if(args.length == 1)
>        return 1;
>
>    return 0;
> }
>
> // To:
> static static(static[][] static)
> {
>    static(static.static== 1)
>        static 1;
>
>    static 0;
> }
>
> Perfect! Now we'll never have to worry about having too many keywords!

'static' is a woefully underused keyword.  It really does need more uses.
August 02, 2009
On Sun, Aug 2, 2009 at 2:55 PM, Walter Bright<newshound1@digitalmars.com> wrote:
> Jarrett Billingsley wrote:
>>
>> I think it's funny that for a week, Andrei has been arguing against throwing around new syntax to solve this problem, and that's exactly what you guys have come up with.
>
> That's in the nature of debating in order to try to figure out the best solution. It's hard to think of all the ramifications, positives, negatives, and corner cases all at the same time.
>
>
>> Really, how much more complicated
>> would this make the parser, compared to adding a new attribute?
>
> Neither of these proposals is a particular problem for the parser.

What about my other points?  Do you have a response?  I almost had trouble believing this proposal wasn't a joke, given how contrived and unintuitive it is.  Shouldn't that be an important consideration?
August 02, 2009
Jarrett Billingsley wrote:
> What about my other points?  Do you have a response?

I talked with Derek about the same issue. He pointed out cases where the principles conflicted with the actual design. I replied that in real engineering work, *everything* is a compromise between multiple competing principles.

For example, auto company executives will say that "safety is our top priority." Of course it isn't, as such a principle will produce unusable cars that cannot move an inch.

The art of engineering, and it is an art, is to balance the competing principles and find the best compromise.

It's not a binary thing - violating principle A over here is in no way saying A is worthless, and is not a justification for violating it over there.


> I almost had
> trouble believing this proposal wasn't a joke, given how contrived and
> unintuitive it is.  Shouldn't that be an important consideration?

Of course it is important. It is far from the only consideration, though.

Someone changing their mind about something after extensive debate is a good indication they are engaging in an honest and productive discussion.
August 03, 2009
On Sun, 02 Aug 2009 12:02:22 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> Jarrett Billingsley wrote:
>> I think it's funny that for a week, Andrei has been arguing against
>> throwing around new syntax to solve this problem, and that's exactly
>> what you guys have come up with.  Really, how much more complicated
>> would this make the parser, compared to adding a new attribute?
>
> We couldn't find a good solution without adding new syntax, so this is now on the table. Adding syntax or keywords is the next thing to look at. I'd still be unsatisfied if:
>
> (a) there would be significant syntactic noise to defining a read-only property
>
> (b) we had to add a keyword
>
>
> Andrei

I'd also still like to be able to do stuff like this:

auto data = std.file.readText(filename).chomp.split;
August 03, 2009
On Sun, 02 Aug 2009 09:39:41 -0400, Michel Fortin <michel.fortin@michelf.com> wrote:

> On 2009-08-02 03:43:43 -0400, Walter Bright <newshound1@digitalmars.com> said:
>
>> 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) { ... }
>
> Looking at it more carefully, this looks like an invitation to omit parenthesis for functions with no argument. I mean, look at this and tell me what it is?
>
> 	T transform { ... }
>
> Is this a transform property (returning and affine transform) or an action function returning transform? I'd guess it's a property since it has no parenthesis, but nothing makes this very clear.
>
> And could you do this? Would Andrei be tempted by this?
>
> 	void popFront { ... }
>
> Note that I'm brigning this as an observation. Style guidelines can be written mandating parenthesis for actions functions, which means my problem of writing a coherent naming guideline is solved. But who read the style guidelines?
>
> While I like this syntax, the "getProperty()"/"setProperty()" syntax (and also the "property" keyword syntax) has one advantage over this one: it forces the interface to explicitly say "this is a getter/setter" or "this is a property", which I expect would reduce abuses. It's the same difference between as "opAdd" vs. "op+".
>

I also like the idea of omitting parenthesis for functions with no argument.
August 03, 2009
On 2009-08-02 20:18:51 -0400, "Robert Jacques" <sandford@jhu.edu> said:

> I also like the idea of omitting parenthesis for functions with no  argument.

I like it too. But the problem with the current approach D are:

1. A syntax that permits function to be called both without and with empty parenthesis creates ambiguities when it returns a callable type (a delegate or an object with an opCall member).

2. We want properties to be nouns, and actions to be verbs. In english a lot of words are both nouns and verbs, which makes it impractical to distinguish a property from a function by its name alone.

Solving 1 involves having a way to say functions that can and must be called without parenthesis. Unless we want to force all functions with no parameter to be called without "()", we must have some kind of flag to tell us that a function expects or does not expect "()".

Solving 2 involves making a difference in the call syntax between property and action functions. Since the idea behind a property is to mimic a field, it follows that the best differentiator for properties is the lack of parenthesis.

I'd be glad too if we could continue to skip parenthesis for calls to functions with no arguments, but I think fixing the two problems above is more important.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/