Revised RFC on range design for D2

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Mon Sep 29 10:19:33 PDT 2008


Steven Schveighoffer wrote:
> "Andrei Alexandrescu" wrote
>> Steven Schveighoffer wrote:
>>> "Andrei Alexandrescu" wrote
>>>> Steven Schveighoffer wrote:
>>>>> "Andrei Alexandrescu" wrote
>>>>>>> P.S. If src.next() is too lengthy, why not just adopt ++src?
>>>>>> Because people (in wake of the recently introduced array operations) 
>>>>>> may legitimately expect that to mean "increment all elements of src".
>>>>> So in one case, you believe people's assumptions aren't important, i.e. 
>>>>> an assumption that .next without parens will not change anything on the 
>>>>> object, yet in another case you believe people's assumptions are the 
>>>>> main argument. This doesn't sound consistent.
>>>> Of course it is. One expectation has to do with operational consistency 
>>>> (albeit a tad far-fetched), the other has to do with being used to a 
>>>> mistaken decision in the C language design.
>>> You are assuming that the C language decision to require parentheses for 
>>> all functions was a design mistake.  I would argue that the design was on 
>>> purpose and correctly served that purpose.  The purpose was to remove 
>>> ambiguity when faced with understanding code without all the context.
>> I have stated my assumption and its basis.
> 
> Forgive me, but I must have missed it.  I saw only your assumption (or 
> supposition) that the C designers made a mistake.

My post on 25 Sep 2008 17:58:52 -0500 mentions:

"One principle that I consider universal is that a language should 
minimize the number of syntactic constructs that are semantically and/or 
pragmatically meaningless. Another that I also consider universal is 
that the more frequently-used constructs should be given syntactic 
priority over the less-used constructs, particularly when the latter are 
also at risk of breaking the first principle."

>> What is the basis of yours?
> 
> I don't have any actual proof that they did this on purpose, I wasn't 
> working at Bell labs when C was invented, in fact, I don't even think I was 
> born ;)
> 
> But it makes logical sense, and still does.  If you want to call a function, 
> you have to use parentheses.  If you want to access the function address, no 
> parentheses.

This is no logic. Your proof is just stating the conclusion. It's a 
logical fallacy called proof by assertion.

http://en.wikipedia.org/wiki/Proof_by_assertion

> It follows other design decisions they made:
> 
> pointers:  Access what it's pointing to, use ->, get address it's pointing 
> to, use symbol alone.

This is wrong too. If you use symbol alone, you are not getting its 
address. You are referring the pointer, which is an address. It would 
have been consistent with other design decisions if referring a variable 
alone would take its address.

>>> But that isn't even the questioned practice here.  C designers didn't 
>>> even come across the question of whether an accessor-property should 
>>> imply no changes to the object, because they don't have properties.  The 
>>> real problem is that no matter how you define next(), you can use it in a 
>>> way which makes it appear like an accessor, not a function which modifies 
>>> the object.  The source of the problem is D's lack of expressiveness, 
>>> where I cannot define whether a function cannot be used as a property.
>> I understand your argument, but it hinges on its own definitions and 
>> assumptions. You define "accessor" and then complain that something looks 
>> like one unexpectedly. Well in some languages a.b does not change 
>> anything. In others it does. What gives?
> 
> There is no hard-fast rule that an accessor cannot change things.  The issue 
> is that since any function can be an accessor you can't even try to adopt a 
> policy in your library that says 'accessors will not change things'. 
> Because you can't define which functions can be used as accessors and which 
> ones can't.

Const takes care of that.

> I WANT a.b to be able to be a function call, I just want to specify which 
> functions can be called that way, and which ones cannot, so I can define how 
> my library behaves and someone reading code that uses it will know that my 
> rules were followed.

Why do you want to specify that? What difference does it make? Why would 
you complicate the language just for a hypothetical convention that's 
not even compiler-checked?

>>> Even with a true property definition syntax, you cannot prevent someone 
>>> from changing an object while inside an accessor, that should be defined 
>>> by the constancy of the object in question.  But indicating that it is 
>>> preferred to use the property-style means to access the next() member 
>>> function seems to be misleading to some people.
>> So that further weakens your argument.
> 
> How so?  I'm not talking about whether or not the compiler should restrict 
> the developer on being able to make changes in accessors.  That is what 
> const is for.  I'm talking about being able to specify a coding convention 
> that says 'accessors shall not change things'.  Currently, there's no way to 
> prevent any function from being used as an accessor, so a library developer 
> cannot enforce this rule to people using his library.

I personally think it's great that any function can be used as an 
accessor. I'd be convinced otherwise presented a good arguments against 
it. What problems are you foreseeing with not being able to enforce 
against not using ()?

>>> The problem I have with your argument is how you used one case to say 
>>> 'this is misleading to people, so it's not a valid solution', and in 
>>> another case say 'it's only misleading because you are used to it, that 
>>> doesn't matter.' The assumption of which people are important to please 
>>> is the issue.  I understand you can't please everyone, but you shouldn't 
>>> use the 'people won't like it' argument without real evidence or proof.
>> I agree that ++array may not be easily confused with ++array[]. The 
>> situation I am trying to help is improve on a mistake in the C language 
>> design that we got so used to, we actually think it's the right thing.
> 
> According to comments on this newsgroup, and some quoted bug reports, many 
> believe that it's the D methodology of not requiring parentheses that is a 
> mistake.  As far as I can tell, it's a matter of opinion, not fact.
> 
>>>>> Not that I care too much :)  I am also in the camp of 'defined 
>>>>> properties should be a language feature,' but I admit to using 
>>>>> D-properties quite often.
>>>>>
>>>>> The two things that bug me the most about D property syntax:
>>>>>
>>>>> stuff like this:
>>>>>
>>>>> x;
>>>>>
>>>>> What the hell does this mean?  It looks like it does nothing.  But it 
>>>>> could be a function call.  If explicit properties were required, and x 
>>>>> was defined as a function, not a property, then x; would be a syntax 
>>>>> error.
>>>> And what would be the advantage? I routinely use writeln; without 
>>>> feeling it makes for inferior style.
>>> The advantage is not to you, it is to the reader of your code.  writeln; 
>>> is a complete misuse of property syntax, and IMO should not be allowed. 
>>> writeln is not a property, and shouldn't be used like a property.
>> Aside from just saying it, do you have any substantive argument?
> 
> The arguments have been made.   As I stated, it's my opinion.
> 
>>> I routinely use Tango's Stdout.newline; which I admit goes against what I 
>>> am saying, but it's because I know what Stdout.newline does, and that it 
>>> is a function.  I would gladly change everything to Stdout.newline() if 
>>> it was required.
>> To what benefit? You seem to be using it today, and that makes your own 
>> style incongruent with your argument, yet surely you'd change the style in 
>> an iffy if you thought it has serious drawbacks.
> 
> The benefit is clarity.
> 
> Stdout.newline;
> 
> looks like a property or field of Stdout.  By itself, it's somewhat jarring, 
> but it's somewhat clear that newline is a function if you know the rules of 
> D.

But you do use Stdout.newline and the alleged loss in clarity doesn't 
seem to be phasing you.

> However, something like this isn't so clear:
> 
> Stdout.newline.formatln("Hi there {}", var);
> 
> Is newline a property of Stdout, on which I'm calling formatln, or is 
> newline a function that I'm calling, and then using the result of that 
> function to call formatln?  Compare with:
> 
> Stdout.newline().formatln("Hi there {}", var);
> 
> There is no ambiguity.  newline is clearly a function, not a property.

There is no ambiguity either case. You evaluate Stdout.newline. The 
evaluation yields a value of some type. Then you evaluate formatln 
against that value.

What's missing is the unstated assumption that "if it doesn't have 
trailing parens, it must be a field". I don't think it is useful to be 
making that assumption.

> My personal habits are ones I would like to change.  I'd prefer to write 
> clearer code, not shorter code.  I consider writing Stdout.newline; a bad 
> habit fostered by the lax function calling rules of D ;)

Giving the choice of shorter vs. clearer is a false choice, another 
fallacy if I remember correctly. Put another way, wouldn't you at best 
write shorter and clearer code?

>>> The problem is not that you or anyone might forget that writeln is a 
>>> function and not a property, the problem is when you start using the 
>>> property syntax to call functions that aren't so standard, someone 
>>> reading the code will be confused as to what the code is supposed to do.
>>>
>>> The advantage is, you are able to define how a symbol behaves, what the 
>>> rules are for using it.  It makes for clearer code.
>> I am not sure.
> 
> Neither answer is definitely the 'correct' one, there are tradeoffs between 
> both styles.  I like the how D properties are so easy to write, and can be 
> accessed like functions when needed, but I don't like how you can have weird 
> looking code to have to decipher.  Having written properties in C# quite a 
> bit, I prefer that method of requiring a formal property definition.

I am not seeing weird code that is there to be deciphered. There is this 
"writeln = 3" weirdness that I'd love to weed out, but all this required 
trailing parens stuff simply doesn't have any good argument working in 
its favor.


Andrei



More information about the Digitalmars-d-announce mailing list