July 28, 2009
On 2009-07-28 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)

This may lead to strange issues if both the setter and the getter don't have the same protection attribute, or purity, or constness of arguments.

For instance:

	protected void foo(Object o);
	public pure const const(Object) foo();

Here, you can assign to foo using the property syntax only from a non-pure functions of this class or a derived classes and when the value you're assinging is a const(Object). Elsewhere, you can only assign using the function syntax. Anything else would break "auto __x = foo, __x = bar".


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

July 28, 2009
Michel Fortin wrote:
> On 2009-07-28 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:
> 
>> Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)
> 
> This may lead to strange issues if both the setter and the getter don't have the same protection attribute, or purity, or constness of arguments.
> 
> For instance:
> 
>     protected void foo(Object o);
>     public pure const const(Object) foo();
> 
> Here, you can assign to foo using the property syntax only from a non-pure functions of this class or a derived classes and when the value you're assinging is a const(Object). Elsewhere, you can only assign using the function syntax. Anything else would break "auto __x = foo, __x = bar".

Well I chose the rule that makes bar look and feel as much as an assignable value as possible. The rule could be relaxed (e.g. by dropping qualifiers), but that means we're departing from assignable value lookalike.

Andrei
July 28, 2009
On Tue, 28 Jul 2009 11:11:09 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> Steven Schveighoffer wrote:
>> On Tue, 28 Jul 2009 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>
>>> I think inferring meaning from the presence or absence of "()" is rather dicey.
>>  Really?  Then why name your functions things like empty, why not ex245, to make them look it up, making *sure* they know what the meaning is before they use it.
>
> I didn't say not to infer meaning from the name.

No, you're saying inferring meaning from parentheses is not a good idea.  I think it's the same thing as saying that inferring the meaning from a function/field name is not a good idea (just in a more sarcastic way...).  When you see parentheses, you infer function.  When you don't you infer field/property.  Note that I'm not just pulling this out of a hat, it's the way people already think, you should acknowledge that.

>
>> As one other person stated, they thought empty() emptied a range.
>
> Well it doesn't.

Exactly, so why do you think he thought that?  Let's take someone who's used a language that uses () do denote a function, and no parens to denote a field (there are a few of them out there).  Would that person ever think that

x.empty;

means "empty the contents of x"?  The answer is no, not ever.  Whether you like it or not or think it's dicey or not PEOPLE WILL INFER MEANING FROM PARENTHESES.  I even do it, even though I *know* that it's dicey.  I hate having to look up usages of things that make no sense because I have no idea what the code is doing.  It's so much better when the meaning is clear from the code itself.

>
>> Being able to read code and understand what it means without resorting to documentation is the sign of a good choice of symbol names.
>
> Sure.
>
>> The presence or absence of parens is a hard-coded accepted meaning of field vs. function.
>
> I understand how some people want to derive meaning from obj.foo() versus obj.foo. I think they shouldn't in D. I mean D has had for years the behavior that you could drop the trailing empty parentheses.

And for years, there have been complaints about it.  This will continuously be a thorn in the side of D adoption until it is resolved.

>> Properties build on this notion by making a virtual field that actually resolves to a function (but behaves like a field, and this is an important accepted meaning).
>
> Not quite. C# has allocated a language feature for properties. Yet they allow you to write write-only properties, which do NOT behave at all like fields

I'll give you that one, but that's an uncommon "because we can" case.

> and also read-only properties, which also don't behave like fields.

Ever heard of readonly fields?  Yes, they exist in C#.  Besides, that's one of the benefits of properties, you can do things that you can't do with fields, otherwise why have them?

> Guess what - they both behave like functions. So their properties are an elaborate mechanism that is actually thoroughly unchecked, thus going back to what you could do by calling functions. So why the hell did they define the feature in the first place? Oh, for allowing people to write a.foo() instead of a.foo. You know what, that's a bit disappointing for an entire language feature.

No, they did it to *force* you to write a.foo instead of a.foo(), to make it more defined that foo is a field-like entity.  There's a subtle, yet very important difference.  They saw the implementation of properties in Java as a good thing, but Java relied on a social standard that a method that begins with get is a getter, a method that begins with set is a setter, and a method that begins with is is a boolean.  C# provides a better way to convey that contract via properties.

D's implementation looks to me like a quick hack so D can say "look, we have properties!"  They don't provide any of the interface benefits that true properties do.  Might as well go back to Java style, where you have to name your properties getX, setX or isX.  But now, normal functions are corrupted with the ability to use them as properties.

>>> Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)
>>  This is a band-aid fix, easily broken.
>>  int select(int timeoutMS = -1); // method on a socket, for example
>>  Hell, even my TimeSpan problem would still fail.
>
> Well maybe you could change TimeSpan.

Lovely.  Force the developer to rename his functions because D is too weak to allow defining a correct interface.  You didn't even address the select example, I think that's a very compelling example of something that breaks your rule.

My point is that your rule only works if you write code in a certain way, and I don't think that should be a determination of whether something is a property or not by the compiler, because the naming of functions is supposed to be up to the developer, not the spec.  It's like a prejudice against certain coding styles without any good reason.

>
>> Also you are forgoing the ability to have overloaded setters, which could be useful.  Not to mention getters for delegates.
>
> Wait, overloaded setters do NOT make the thing behave like a field, but you were stating how nice that is a few paragraphs ago! So what is it that you think is good?

Yes they do.  It makes them behave like a variant field.

e.g.

x.timeout = 5.5; // set timeout to 5.5 seconds
x.timeout = TimeSpan.seconds(5); // set timeout to 5 seconds exactly

And what about getters for delegates?  That problem is still unresolved by your rule.

-Steve
July 28, 2009
On 2009-07-28 11:37:05 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> Michel Fortin wrote:
>> On 2009-07-28 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:
>> 
>>> Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)
>> 
>> This may lead to strange issues if both the setter and the getter don't have the same protection attribute, or purity, or constness of arguments.
>> 
>> For instance:
>> 
>>     protected void foo(Object o);
>>     public pure const const(Object) foo();
>> 
>> Here, you can assign to foo using the property syntax only from a non-pure functions of this class or a derived classes and when the value you're assinging is a const(Object). Elsewhere, you can only assign using the function syntax. Anything else would break "auto __x = foo, __x = bar".
> 
> Well I chose the rule that makes bar look and feel as much as an assignable value as possible. The rule could be relaxed (e.g. by dropping qualifiers), but that means we're departing from assignable value lookalike.

Also, what if a derived class implements a getter while the base class only has a setter. Does that mean that only the derived class can use the property syntax on the base class' setter?

What I don't like about that proposal is that that how to call a setter is bound to the existence of another function in the same scope using pretty non-obvious rules. Also, it doesn't solve the problem of the getter that returns a delegate since you can continue using the function notation with properties and you can continue to call functions with no parenthesis.

While I like too being able to call functions with no argument by skipping the tailing parenthesis, I'd easily give up on that if it means I can get a language with less ambiguities.

I also happen to agree with Walter and you that it wouldn't be so great to just decorate functions with a keyword to give them a different syntax. I've propsed earlier a namespace-like syntax where you can have functions like "foo.opAssign" inside a class (or anywhere really) that you can call with "foo = x", unifying properties with operator overloading.

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

July 28, 2009
Steven Schveighoffer wrote:
> On Tue, 28 Jul 2009 11:11:09 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> 
>> Steven Schveighoffer wrote:
>>> On Tue, 28 Jul 2009 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>>
>>>> I think inferring meaning from the presence or absence of "()" is rather dicey.
>>>  Really?  Then why name your functions things like empty, why not ex245, to make them look it up, making *sure* they know what the meaning is before they use it.
>>
>> I didn't say not to infer meaning from the name.
> 
> No, you're saying inferring meaning from parentheses is not a good idea.  I think it's the same thing as saying that inferring the meaning from a function/field name is not a good idea (just in a more sarcastic way...).  When you see parentheses, you infer function.  When you don't you infer field/property.  Note that I'm not just pulling this out of a hat, it's the way people already think, you should acknowledge that.

I acknowledge that in C, C++, and Java, you must add () to call an argument-less function. I also acknowledge that in C# a.b could mean either a field access or execution of arbitrary code.

>>> As one other person stated, they thought empty() emptied a range.
>>
>> Well it doesn't.
> 
> Exactly, so why do you think he thought that?  Let's take someone who's used a language that uses () do denote a function, and no parens to denote a field (there are a few of them out there).  Would that person ever think that
> 
> x.empty;
> 
> means "empty the contents of x"?  The answer is no, not ever.  Whether you like it or not or think it's dicey or not PEOPLE WILL INFER MEANING FROM PARENTHESES.  I even do it, even though I *know* that it's dicey.  I hate having to look up usages of things that make no sense because I have no idea what the code is doing.  It's so much better when the meaning is clear from the code itself.

I acknowledge that some people infer meaning from parentheses. I mean, there's at least one :o).

>>> Being able to read code and understand what it means without resorting to documentation is the sign of a good choice of symbol names.
>>
>> Sure.
>>
>>> The presence or absence of parens is a hard-coded accepted meaning of field vs. function.
>>
>> I understand how some people want to derive meaning from obj.foo() versus obj.foo. I think they shouldn't in D. I mean D has had for years the behavior that you could drop the trailing empty parentheses.
> 
> And for years, there have been complaints about it.  This will continuously be a thorn in the side of D adoption until it is resolved.

Again, most complaints have been directed towards writeln = 5. I think that's the major problem to be resolved.

>>> Properties build on this notion by making a virtual field that actually resolves to a function (but behaves like a field, and this is an important accepted meaning).
>>
>> Not quite. C# has allocated a language feature for properties. Yet they allow you to write write-only properties, which do NOT behave at all like fields
> 
> I'll give you that one, but that's an uncommon "because we can" case.

I acknowledge that you give me that one.

>> and also read-only properties, which also don't behave like fields.
> 
> Ever heard of readonly fields?  Yes, they exist in C#.  Besides, that's one of the benefits of properties, you can do things that you can't do with fields, otherwise why have them?

So now C# has two ways of providing a readonly field. Doesn't quite look like an example to follow.

>> Guess what - they both behave like functions. So their properties are an elaborate mechanism that is actually thoroughly unchecked, thus going back to what you could do by calling functions. So why the hell did they define the feature in the first place? Oh, for allowing people to write a.foo() instead of a.foo. You know what, that's a bit disappointing for an entire language feature.
> 
> No, they did it to *force* you to write a.foo instead of a.foo(), to make it more defined that foo is a field-like entity.

Which is not, because it can execute arbitrary code that is not restricted in any way. How good a design is that? Back to semantics by convention?

That's what I'm saying: if it could do anything, at least don't pretend it's anything special. It's a function!

> There's a subtle, yet very important difference.  They saw the implementation of properties in Java as a good thing, but Java relied on a social standard that a method that begins with get is a getter, a method that begins with set is a setter, and a method that begins with is is a boolean.  C# provides a better way to convey that contract via properties.

Why is C#'s way better?

> D's implementation looks to me like a quick hack so D can say "look, we have properties!"  They don't provide any of the interface benefits that true properties do.

What are the interface benefits that "true" properties do? What is a "true" property? Something that could do anything. Surprise, that was already the charter of functions. Well thank you very much.

> Might as well go back to Java style, where you have to name your properties getX, setX or isX.  But now, normal functions are corrupted with the ability to use them as properties.

Yum.

>>>> Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)
>>>  This is a band-aid fix, easily broken.
>>>  int select(int timeoutMS = -1); // method on a socket, for example
>>>  Hell, even my TimeSpan problem would still fail.
>>
>> Well maybe you could change TimeSpan.
> 
> Lovely.  Force the developer to rename his functions because D is too weak to allow defining a correct interface.

Or maybe because her use of name was too ambiguous.

> You didn't even address the select example, I think that's a very compelling example of something that breaks your rule.

I agree that that example reveals a problem. I also think that that problem could be solved, but I doubt that you'll be pleased.

> My point is that your rule only works if you write code in a certain way,

Your rule also works if you write code in a certain way.

> and I don't think that should be a determination of whether something is a property or not by the compiler, because the naming of functions is supposed to be up to the developer, not the spec.

opXxx are up to the spec.

> It's like a prejudice against certain coding styles without any good reason.

I don't see that. I more see a prejudice against dropping "()" when calling a function.

>>> Also you are forgoing the ability to have overloaded setters, which could be useful.  Not to mention getters for delegates.
>>
>> Wait, overloaded setters do NOT make the thing behave like a field, but you were stating how nice that is a few paragraphs ago! So what is it that you think is good?
> 
> Yes they do.  It makes them behave like a variant field.

Then write a function that takes a variant instead of overloading.

> e.g.
> 
> x.timeout = 5.5; // set timeout to 5.5 seconds
> x.timeout = TimeSpan.seconds(5); // set timeout to 5 seconds exactly
> 
> And what about getters for delegates?  That problem is still unresolved by your rule.

I believe it's a minor problem that does not impede people from getting work done.


Andrei
July 28, 2009
Michel Fortin wrote:
> On 2009-07-28 11:37:05 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:
> 
>> Michel Fortin wrote:
>>> On 2009-07-28 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:
>>>
>>>> Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)
>>>
>>> This may lead to strange issues if both the setter and the getter don't have the same protection attribute, or purity, or constness of arguments.
>>>
>>> For instance:
>>>
>>>     protected void foo(Object o);
>>>     public pure const const(Object) foo();
>>>
>>> Here, you can assign to foo using the property syntax only from a non-pure functions of this class or a derived classes and when the value you're assinging is a const(Object). Elsewhere, you can only assign using the function syntax. Anything else would break "auto __x = foo, __x = bar".
>>
>> Well I chose the rule that makes bar look and feel as much as an assignable value as possible. The rule could be relaxed (e.g. by dropping qualifiers), but that means we're departing from assignable value lookalike.
> 
> Also, what if a derived class implements a getter while the base class only has a setter. Does that mean that only the derived class can use the property syntax on the base class' setter?

It all follows normal language rules. That's what I like about rewrites (lowerings): they allow you to reason about a new mini-feature (that in this case is absolutely nothing beyond a minor syntactic convenience) in terms of the rest of the language.

> What I don't like about that proposal is that that how to call a setter is bound to the existence of another function in the same scope using pretty non-obvious rules.

I think the rules are very obvious.

> Also, it doesn't solve the problem of the getter that returns a delegate since you can continue using the function notation with properties and you can continue to call functions with no parenthesis.

It doesn't solve the problem with a getter that returns a delegate. People who want to return delegates must use an extra pair of parens.

> While I like too being able to call functions with no argument by skipping the tailing parenthesis, I'd easily give up on that if it means I can get a language with less ambiguities.

I wouldn't want to hurt the majority of my code for an obscure case. I do agree I'd rather not have an obscure case in the first place.

> I also happen to agree with Walter and you that it wouldn't be so great to just decorate functions with a keyword to give them a different syntax. I've propsed earlier a namespace-like syntax where you can have functions like "foo.opAssign" inside a class (or anywhere really) that you can call with "foo = x", unifying properties with operator overloading.

That would work. Many things would work.


Andrei
July 28, 2009
On Tue, 28 Jul 2009 12:30:00 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> Steven Schveighoffer wrote:
>>  And for years, there have been complaints about it.  This will continuously be a thorn in the side of D adoption until it is resolved.
>
> Again, most complaints have been directed towards writeln = 5. I think that's the major problem to be resolved.

Yes, I agree.  But there is also a subtle problem we can solve at the same time.  You keep missing the point.

Let me come at another angle.  You can't view properties as some sort of enforcement by the compiler.  The compiler is not guaranteeing that if you call something without parentheses, it doesn't execute arbitrary code, it has nothing to do with what the compiler guarantees.  But the *meaning* that the author of the function wishes to convey is available via the requirement of parentheses or lack thereof.  The author of the code is saying "I wrote this function as if it were a field."

It's the same thing as function names.  The compiler allows you to name your functions how you wish, and enforces that foo is different than bar.  Why is this important?  Because foo does something different than bar.  And to a user, that's obvious, because in english foo means something different than bar.  What if the compiler allowed you to call functions as long as what you typed was an unambiguous prefix of the function name.  For example:

struct S
{
   int foo();
   int flu();
   int bar();
}

This is valid code:

S s;
s.fl();
s.b();
// s.f(); // doesn't compile because its not unambiguous

Why is this advantageous?  Well, it saves you from having to type the whole function name.  It's unambiguous, so there is no problems as far as the compiler is concerned, so its easily implemented.  But why don't we have a wonderful time-saving feature like this?  Because it would be a nightmare to read.  You can change the implied english meaning of the function by just using its prefix.  But the compiler doesn't care, because it has no idea what the english meaning of the words are, and it's satisfied that you made an unambiguous decision.

Back to our problem at hand, by allowing one to call functions with or without parentheses you are not only changing the implied meaning of the function, but you have removed the ability of the author to convey that meaning with simply the requirement of parentheses.  He has to explain "this is a property" through by making the function name reflect that fact, or be an ass and say "well you shouldn't assume things based on parentheses, look it up dummy!"

Yes, if we solve the problem of setters, we have killed a huge wart on D, but why ignore the other warts?

>>> and also read-only properties, which also don't behave like fields.
>>  Ever heard of readonly fields?  Yes, they exist in C#.  Besides, that's one of the benefits of properties, you can do things that you can't do with fields, otherwise why have them?
>
> So now C# has two ways of providing a readonly field. Doesn't quite look like an example to follow.

Just like D!

struct S
{
  const int readonlyfield;
  int readonlyproperty();
}

Yes, that's right.  readonly is analogous to const.

>>> Guess what - they both behave like functions. So their properties are an elaborate mechanism that is actually thoroughly unchecked, thus going back to what you could do by calling functions. So why the hell did they define the feature in the first place? Oh, for allowing people to write a.foo() instead of a.foo. You know what, that's a bit disappointing for an entire language feature.
>>  No, they did it to *force* you to write a.foo instead of a.foo(), to make it more defined that foo is a field-like entity.
>
> Which is not, because it can execute arbitrary code that is not restricted in any way. How good a design is that? Back to semantics by convention?
>
> That's what I'm saying: if it could do anything, at least don't pretend it's anything special. It's a function!

I explained this above.  I'll reiterate: The enforcement of "field-like" by the compiler is not the point of properties, the ability given to the author to document that fact is the point.

>
>> There's a subtle, yet very important difference.  They saw the implementation of properties in Java as a good thing, but Java relied on a social standard that a method that begins with get is a getter, a method that begins with set is a setter, and a method that begins with is is a boolean.  C# provides a better way to convey that contract via properties.
>
> Why is C#'s way better?

It's less verbose, makes the code read better, allows you to avoid using functions to do everything.  As another example, Java doesn't have operator overloading, so BigInteger is horrific to use, calling functions for each operation.  So would you argue that C# or D with operator overloading isn't better because operators are just functions, why call them something else?

>> D's implementation looks to me like a quick hack so D can say "look, we have properties!"  They don't provide any of the interface benefits that true properties do.
>
> What are the interface benefits that "true" properties do? What is a "true" property? Something that could do anything. Surprise, that was already the charter of functions. Well thank you very much.

No.  The interface benefits are explained above.

>>> Well maybe you could change TimeSpan.
>>  Lovely.  Force the developer to rename his functions because D is too weak to allow defining a correct interface.
>
> Or maybe because her use of name was too ambiguous.

I want to use the parentheses or lack thereof as part of the human meaning for the function/property.  Making them optional means I can't do that.

>
>> You didn't even address the select example, I think that's a very compelling example of something that breaks your rule.
>
> I agree that that example reveals a problem. I also think that that problem could be solved, but I doubt that you'll be pleased.

I would be pleased, how can it be solved?

>> My point is that your rule only works if you write code in a certain way,
>
> Your rule also works if you write code in a certain way.

But my way is orthogonal to writing normal functions.  Your rule mistakenly identifies normal functions as properties.

>
>> and I don't think that should be a determination of whether something is a property or not by the compiler, because the naming of functions is supposed to be up to the developer, not the spec.
>
> opXxx are up to the spec.

Yes, and it is well established that opXxx shouldn't be used for arbitrary function names.  But you are expanding that rule to basically any function name, which means all functions are subject to being misinterpreted by the compiler, no matter what you name them.

>> It's like a prejudice against certain coding styles without any good reason.
>
> I don't see that. I more see a prejudice against dropping "()" when calling a function.

It's a sacrifice in the name of clarity.

>>>> Also you are forgoing the ability to have overloaded setters, which could be useful.  Not to mention getters for delegates.
>>>
>>> Wait, overloaded setters do NOT make the thing behave like a field, but you were stating how nice that is a few paragraphs ago! So what is it that you think is good?
>>  Yes they do.  It makes them behave like a variant field.
>
> Then write a function that takes a variant instead of overloading.

I can live without overloading setters, I don't think it's a requirement, but it would be possible with my method.  That's the only point I was trying to make.

-Steve
July 28, 2009
Andrei Alexandrescu wrote:
> Steven Schveighoffer wrote:
>> On Tue, 28 Jul 2009 11:11:09 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>> Guess what - they both behave like functions. So their properties are an elaborate mechanism that is actually thoroughly unchecked, thus going back to what you could do by calling functions. So why the hell did they define the feature in the first place? Oh, for allowing people to write a.foo() instead of a.foo. You know what, that's a bit disappointing for an entire language feature.
>>
>> No, they did it to *force* you to write a.foo instead of a.foo(), to make it more defined that foo is a field-like entity.
> 
> Which is not, because it can execute arbitrary code that is not restricted in any way. How good a design is that? Back to semantics by convention?

Back to semantics by convention?

Whenever you write *anything*, there's always semantic by convention.

writefln("Foo");

That writefln could just do antyhing with it's argument, maybe return it twice. So how do you enforce writefln to actually write something? Aaaah... D sucks because it can't enforce that.
July 28, 2009
Andrei Alexandrescu wrote:
> Steven Schveighoffer wrote:
>> On Tue, 28 Jul 2009 11:11:09 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>> D's implementation looks to me like a quick hack so D can say "look, we have properties!"  They don't provide any of the interface benefits that true properties do.
> 
> What are the interface benefits that "true" properties do? What is a "true" property? Something that could do anything. Surprise, that was already the charter of functions. Well thank you very much.

Just because it could do anything doesn't mean it *has* to do anything. Again, D ranges suck because the compiler can't enforce you that empty, pop, etc., actually do what their name says.
July 28, 2009
Ary Borenszweig wrote:
> Andrei Alexandrescu wrote:
>> Steven Schveighoffer wrote:
>>> On Tue, 28 Jul 2009 11:11:09 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>>> Guess what - they both behave like functions. So their properties are an elaborate mechanism that is actually thoroughly unchecked, thus going back to what you could do by calling functions. So why the hell did they define the feature in the first place? Oh, for allowing people to write a.foo() instead of a.foo. You know what, that's a bit disappointing for an entire language feature.
>>>
>>> No, they did it to *force* you to write a.foo instead of a.foo(), to make it more defined that foo is a field-like entity.
>>
>> Which is not, because it can execute arbitrary code that is not restricted in any way. How good a design is that? Back to semantics by convention?
> 
> Back to semantics by convention?
> 
> Whenever you write *anything*, there's always semantic by convention.
> 
> writefln("Foo");
> 
> That writefln could just do antyhing with it's argument, maybe return it twice. So how do you enforce writefln to actually write something? Aaaah... D sucks because it can't enforce that.

I was replying to the expectation that a.foo() does an action and a.foo allegedly does not.

Andrei